root/git/ui-tree.c
/*DEFINITIONS
This source file includes following definitions.1 #include <stdio.h> 2 #include <string.h> 3 #include <unistd.h> 4 #include <sys/wait.h> 5 #include <git2.h> 6 7 #include "html.h" 8 #include "ui-tree.h" 9 #include "git.h" 10 11 /* TODO: support blame, or is that too slow? */ 12 13 static void 14 dump_blob_raw(git_blob *blob, const char *name) 15 { 16 const void *raw; 17 size_t sz = git_blob_rawsize(blob); 18 19 raw = git_blob_rawcontent(blob); 20 21 binary_xfer = 1; 22 http_header_attachment(git_blob_is_binary(blob), name); 23 http_header_end(query.can_compress); 24 25 fwrite(raw, sz, 1, stdout); 26 } 27 28 29 static void 30 dump_blob(git_blob *blob, const char *name) 31 { 32 git_buf cn = GIT_BUF_INIT; 33 git_blob_filter_options cno = GIT_BLOB_FILTER_OPTIONS_INIT; 34 char cidbuf[MINB]; 35 #ifdef USE_INTERNAL_BLOB_PRINT 36 char *cp, *cp2; 37 size_t i = 0; 38 #else 39 pid_t p; 40 int pfd[2]; 41 #endif 42 43 if (query.tool == T_BLOB) { 44 dump_blob_raw(blob, name); 45 46 return; 47 } 48 49 html("<span class=\"git-blob-hdr\">blob: %s (%s)</span>", 50 git_oid_tostr(cidbuf, MINB, git_blob_id(blob)), 51 my_html_make_link(make_query_simple(T_BLOB, NULL, NULL), "plain")); 52 53 if (git_blob_is_binary(blob)) { 54 html("<span class=\"git-notice\">file is raw binary</span>\n"); 55 56 return; 57 } 58 59 check_sgerr(git_blob_filter(&cn, blob, name, &cno)); 60 61 html("<pre class=\"git-blob-content\">\n"); 62 #ifdef USE_INTERNAL_BLOB_PRINT 63 cp = cn.ptr; do { 64 cp2 = strchr(cp, '\n'); 65 if (cp2) { 66 *cp2 = '\0'; 67 cp2++; 68 } 69 html("<span class=\"git-lineno\">%04zu</span> %s\n", 70 i++, my_html_encode(check_sptr(html_conv_tab(cp, 8)))); 71 } while (cp = cp2); 72 #else 73 fflush(stdout); 74 pipe(pfd); 75 76 p = check_sgerr(fork()); 77 if (p == 0) { 78 char cmdbuf[MINB]; 79 dup_pat(pfd , 1, 0, STDIN_FILENO); 80 81 /* XXX: handle this without an extra buffer via strrchr? */ 82 snprintf(cmdbuf, MINB, "--syntax-by-name=%s", name); 83 execlp("highlight", 84 "highlight", cmdbuf, "--force", 85 "-O", "html", "-f", "-l", "-t", "8", "-a", 86 (char *) NULL); 87 } else { 88 close(pfd[0]); 89 dprintf(pfd[1], "%s", cn.ptr); 90 close(pfd[1]); 91 92 waitpid(p, NULL, 0); 93 } 94 #endif 95 html("</pre>\n"); 96 97 git_buf_free(&cn); 98 } 99 100 101 void 102 dump_tree(void) 103 { 104 const char *name; 105 git_commit *commit; 106 git_tree *tree; 107 git_blob *blob; 108 git_tree_entry *entry = NULL; 109 size_t nidx, i; 110 111 check_sgerr(git_commit_lookup(&commit, grepo, gbase)); 112 check_sgerr(git_commit_tree(&tree, commit)); 113 114 if (query.path[0] != '\0') 115 check_sgerr(git_tree_entry_bypath(&entry, tree, query.path)); 116 117 if (entry) { 118 name = git_tree_entry_name(entry); 119 120 if (git_tree_entry_type(entry) == GIT_OBJECT_TREE) { 121 git_tree_free(tree); 122 check_sgerr(git_tree_lookup(&tree, grepo, 123 git_tree_entry_id(entry))); 124 } else { 125 check_sgerr(git_blob_lookup(&blob, grepo, 126 git_tree_entry_id(entry))); 127 128 dump_blob(blob, name); 129 git_blob_free(blob); 130 131 goto dump_tree_cleanup; 132 } 133 134 git_tree_entry_free(entry); 135 } 136 137 page_setup(0); 138 139 html_table_begin(3, "Mode", "Name", "Size"); 140 html_table_row(3, "<code>d---------</code>", 141 my_html_make_link( 142 make_query_simple(T_TREE, NULL, "../"), 143 "<code>..</code>"), 144 ""); 145 nidx = git_tree_entrycount(tree); 146 for (i = 0; i < nidx; i++) { 147 const git_tree_entry *entry2 = git_tree_entry_byindex(tree, i); 148 const char *mode; 149 git_tree *tree2; 150 size_t tesz; 151 152 name = git_tree_entry_name(entry2); 153 154 switch (git_tree_entry_filemode(entry2)) { 155 default: mode = "?---------"; break; 156 case GIT_FILEMODE_TREE: mode = "d---------"; break; 157 case GIT_FILEMODE_BLOB: mode = "-rw-r--r--"; break; 158 case GIT_FILEMODE_BLOB_EXECUTABLE: mode = "-rwxr-xr-x"; break; 159 case GIT_FILEMODE_LINK: mode = "lrwxrwxrwx"; break; 160 case GIT_FILEMODE_COMMIT: mode = "c---------"; break; 161 } 162 163 if (*mode == 'd') { 164 check_sgerr(git_tree_lookup(&tree2, grepo, 165 git_tree_entry_id(entry2))); 166 tesz = git_tree_entrycount(tree2); 167 168 git_tree_free(tree2); 169 } else { 170 check_sgerr(git_blob_lookup(&blob, grepo, 171 git_tree_entry_id(entry2))); 172 tesz = git_blob_rawsize(blob); 173 174 git_blob_free(blob); 175 } 176 177 html("<tr>\n\ 178 <td class=\"git-flat\"><code>%s</code></td>\n\ 179 <td class=\"git-long\"><code>%s</code></td>\n\ 180 <td class=\"git-flat\"><code>%zu</code></td>\n\ 181 </tr>\n", mode, my_html_make_link( 182 make_query_simple(T_TREE, NULL, name), 183 my_html_encode(name)), tesz); 184 } 185 html_table_end(); 186 187 dump_tree_cleanup: 188 git_commit_free(commit); 189 git_tree_free(tree); 190 }
/*