📄 htags.c
字号:
fputc(' ', op); } else { fprintf(op, "[%s]", label[n]); } } if (show_position) fprintf(op, "[+line file]"); fputs(" */", op); if (!icon_list) fputs_nl(verbatim_end, op); else fputc('\n', op); fputs_nl(define_list_begin, op); for (n = 0; n <= last; n++) { fputs(define_term_begin, op); if (icon_list) { fputs(gen_image(CURRENT, icons[n], label[n]), op); } else { fprintf(op, "[%s]", label[n]); } fputs(define_term_end, op); fputs(define_desc_begin, op); fputs(msg[n], op); fputs_nl(define_desc_end, op); } if (show_position) { fputs(define_term_begin, op); fputs("[+line file]", op); fputs(define_term_end, op); fputs(define_desc_begin, op); fputs("Current position (line number and file name).", op); fputs_nl(define_desc_end, op); } fputs_nl(define_list_end, op); fputs_nl(body_end, op); fputs_nl(gen_page_end(), op); fclose(op); file_count++;}/* * makesearchpart: make search part * * i) $action action url * i) $id hidden variable * i) $target target * r) html */static char *makesearchpart(action, id, target) const char *action; const char *id; const char *target;{ STATIC_STRBUF(sb); strbuf_clear(sb); strbuf_puts(sb, header_begin); if (Fflag) strbuf_puts(sb, gen_href_begin(NULL, "search", normal_suffix, NULL)); strbuf_puts(sb, "SEARCH"); if (Fflag) strbuf_puts(sb, gen_href_end()); strbuf_puts_nl(sb, header_end); if (!target) { strbuf_puts(sb, "Please input object name and select [Search]. POSIX's regular expression is allowed."); strbuf_puts_nl(sb, br); } strbuf_puts_nl(sb, gen_form_begin(target)); strbuf_puts_nl(sb, gen_input("pattern", NULL, NULL)); if (id == NULL) id = ""; strbuf_puts_nl(sb, gen_input("id", id, "hidden")); strbuf_puts_nl(sb, gen_input(NULL, "Search", "submit")); strbuf_puts(sb, gen_input(NULL, "Reset", "reset")); strbuf_puts_nl(sb, br); strbuf_puts(sb, gen_input_radio("type", "definition", 1, "Retrieve the definition place of the specified symbol.")); strbuf_puts_nl(sb, target ? "Def" : "Definition"); strbuf_puts(sb, gen_input_radio("type", "reference", 0, "Retrieve the reference place of the specified symbol.")); strbuf_puts_nl(sb, target ? "Ref" : "Reference"); if (test("f", makepath(dbpath, dbname(GSYMS), NULL))) { strbuf_puts(sb, gen_input_radio("type", "symbol", 0, "Retrieve the place of the specified symbol is used.")); strbuf_puts_nl(sb, target ? "Sym" : "Other symbol"); } strbuf_puts(sb, gen_input_radio("type", "path", 0, "Look for path name which matches to the specified pattern.")); strbuf_puts(sb, target ? "Path" : "Path name"); strbuf_puts_nl(sb, br); if (enable_grep) { strbuf_puts(sb, gen_input_radio("type", "grep", 0, "Retrieve lines which matches to the specified pattern.")); strbuf_puts_nl(sb, target ? "Grep" : "Grep pattern"); } if (enable_idutils && test("f", makepath(dbpath, "ID", NULL))) { strbuf_puts(sb, gen_input_radio("type", "idutils", 0, "Retrieve lines which matches to the specified pattern using idutils(1).")); strbuf_puts_nl(sb, target ? "Id" : "Id pattern"); } strbuf_puts(sb, gen_input_checkbox("icase", "1", "Ignore case distinctions in the pattern.")); strbuf_puts_nl(sb, target ? "Icase" : "Ignore case"); if (other_files) { strbuf_puts(sb, gen_input_checkbox("other", "1", "Files other than the source code are also retrieved.")); strbuf_puts_nl(sb, target ? "Other" : "Other files"); } strbuf_puts_nl(sb, gen_form_end()); return strbuf_value(sb);}/* * makeindex: make index file * * i) file file name * i) title title of index file * i) index common part */static voidmakeindex(file, title, index) const char *file; const char *title; const char *index;{ FILE *op; op = fopen(makepath(distpath, file, NULL), "w"); if (!op) die("cannot make file '%s'.", file); if (Fflag) { fputs_nl(gen_page_frameset_begin(title), op); fputs_nl(gen_frameset_begin("cols='200,*'"), op); if (fflag) { fputs_nl(gen_frameset_begin("rows='33%,33%,*'"), op); fputs_nl(gen_frame("search", makepath(NULL, "search", normal_suffix)), op); } else { fputs_nl(gen_frameset_begin("rows='50%,*'"), op); } /* * id='xxx' for XHTML * name='xxx' for HTML */ fputs_nl(gen_frame("defines", makepath(NULL, "defines", normal_suffix)), op); fputs_nl(gen_frame("files", makepath(NULL, "files", normal_suffix)), op); fputs_nl(gen_frameset_end(), op); fputs_nl(gen_frame("mains", makepath(NULL, "mains", normal_suffix)), op); fputs_nl(noframes_begin, op); fputs_nl(body_begin, op); fputs(index, op); fputs_nl(body_end, op); fputs_nl(noframes_end, op); fputs_nl(gen_frameset_end(), op); fputs_nl(gen_page_end(), op); } else { fputs_nl(gen_page_begin(title, TOPDIR), op); fputs_nl(body_begin, op); if (insert_header) fputs(gen_insert_header(TOPDIR), op); fputs(index, op); if (insert_footer) fputs(gen_insert_footer(TOPDIR), op); fputs_nl(body_end, op); fputs_nl(gen_page_end(), op); } fclose(op); file_count++;}/* * makemainindex: make main index * * i) file file name * i) index common part */static voidmakemainindex(file, index) const char *file; const char *index;{ FILE *op; op = fopen(makepath(distpath, file, NULL), "w"); if (!op) die("cannot make file '%s'.", file); fputs_nl(gen_page_begin(title, TOPDIR), op); fputs_nl(body_begin, op); if (insert_header) fputs(gen_insert_header(TOPDIR), op); fputs(index, op); if (insert_footer) fputs(gen_insert_footer(TOPDIR), op); fputs_nl(body_end, op); fputs_nl(gen_page_end(), op); fclose(op); file_count++;}/* * makesearchindex: make search html * * i) file file name */static voidmakesearchindex(file) const char *file;{ FILE *op; op = fopen(makepath(distpath, file, NULL), "w"); if (!op) die("cannot create file '%s'.", file); fputs_nl(gen_page_begin("SEARCH", TOPDIR), op); fputs_nl(body_begin, op); fputs(makesearchpart(action, id, "mains"), op); fputs_nl(body_end, op); fputs_nl(gen_page_end(), op); fclose(op); file_count++;}/* * makehtaccess: make .htaccess skeleton file. */static voidmakehtaccess(file) const char *file;{ FILE *op; op = fopen(makepath(distpath, file, NULL), "w"); if (!op) die("cannot make .htaccess skeleton file."); fputs_nl("#", op); fputs_nl("# Skeleton file for .htaccess -- This file was generated by htags(1).", op); fputs_nl("#", op); fputs_nl("# Htags have made gzipped hypertext because you specified -c option.", op); fputs_nl("# If your browser doesn't decompress gzipped hypertext, you will need to", op); fputs_nl("# setup your http server to treat this hypertext as gzipped files first.", op); fputs_nl("# There are many way to do it, but one of the method is to put .htaccess", op); fputs_nl("# file in 'HTML' directory.", op); fputs_nl("#", op); fputs_nl("# Please rewrite '/cgi-bin/ghtml.cgi' to the true value in your web site.", op); fputs_nl("#", op); fprintf(op, "AddHandler htags-gzipped-html %s\n", gzipped_suffix); fputs_nl("Action htags-gzipped-html /cgi-bin/ghtml.cgi", op); fclose(op);}/* * Wrapper of src2html() */static intdo_src2html(path_list, count, total) STRBUF *path_list; int count; int total;{ int notsource; char path[MAXPATHLEN]; const char *_ = strbuf_value(path_list); const char *end = _ + strbuf_getlen(path_list); const char *p; while (_ < end) { notsource = *_++; count++; message(" [%d/%d] converting %s", count, total, _); p = path2fid(_); snprintf(path, sizeof(path), "%s/%s/%s.%s", distpath, SRCS, p, HTML); src2html(_, path, notsource); _ += strlen(_) + 1; } return count;}/* * makehtml: make html files * * i) total number of files. */static voidmakehtml(total) int total;{ FILE *ip; const char *_; int count = 0; char command[MAXFILLEN]; STRBUF *sb = strbuf_open(0); STRBUF *alllist = strbuf_open(0); STRBUF *srclist = strbuf_open(0); int path_list_max; /* * Calculate the limit of path list. */ { int db; int max = 0; /* * Get the longest command line length except path list. */ for (db = GTAGS; db < GTAGLIM; db++) { if (!symbol && db == GSYMS) continue; strbuf_reset(sb); if (!getconfs(dbname(db), sb)) die("cannot get parser for %s.", dbname(db)); if (strbuf_getlen(sb) > max) max = strbuf_getlen(sb); } path_list_max = exec_line_limit(max); strbuf_reset(sb); } if (other_files && !dynamic) snprintf(command, sizeof(command), "%s --other | gnusort -t / -k 2", findcom); else strlimcpy(command, findcom, sizeof(command)); ip = popen(command, "r"); if (!ip) die("cannot execute command '%s'.", command); while ((_ = strbuf_fgets(sb, ip, STRBUF_NOCRLF)) != NULL) { int notsource = 0; if (*_ == ' ') { if (!other_files) continue; _++; if (test("b", _)) { if (wflag) warning("'%s' is binary file. (skipped)", _); continue; } notsource = 1; } else { /* * Execute parser when path name collects enough. * Though the path_list is \0 separated list of string, * we can think its length equals to the length of * argument string because each \0 can be replaced * with a blank. */ if (strbuf_getlen(srclist)) { if (strbuf_getlen(srclist) + strlen(_) > path_list_max) { anchor_prepare(srclist); count = do_src2html(alllist, count, total); strbuf_reset(srclist); strbuf_reset(alllist); } } /* * Add a path to the path list. */ strbuf_puts0(srclist, _); } strbuf_putc(alllist, notsource); strbuf_puts0(alllist, _ + 2); } if (strbuf_getlen(alllist)) { if (strbuf_getlen(srclist)) anchor_prepare(srclist); do_src2html(alllist, count, total); } if (pclose(ip) != 0) die("cannot traverse directory.(%s)", command); strbuf_close(sb); strbuf_close(alllist); strbuf_close(srclist);}/* * copy file. */static voidcopyfile(from, to) const char *from; const char *to;{ int ip, op, size; char buf[8192]; ip = open(from, O_RDONLY); if (ip < 0) die("cannot open input file '%s'.", from); op = open(to, O_WRONLY|O_CREAT|O_TRUNC, 0775); if (op < 0) die("cannot create output file '%s'.", to); while ((size = read(ip, buf, sizeof(buf))) != 0) { if (size < 0) die("file read error."); if (write(op, buf, size) != size) die("file write error."); } close(op); close(ip);}/* * duplicate file. * By default, htags uses link system call without making a copy. */static voidduplicatefile(file, from, to) const char *file; const char *from; const char *to;{ char from_path[MAXPATHLEN]; char to_path[MAXPATHLEN]; snprintf(from_path, sizeof(from_path), "%s/%s", from, file); snprintf(to_path, sizeof(to_path), "%s/%s", to, file); if (copy_files) { copyfile(from_path, to_path); } else { if (link(from_path, to_path) < 0) copyfile(from_path, to_path); }}/* * makecommonpart: make a common part for mains.html and index.html * * i) title * i) defines * i) files * r) index common part */static char *makecommonpart(title, defines, files) const char *title; const char *defines; const char *files;{ FILE *ip; STRBUF *sb = strbuf_open(0); STRBUF *ib = strbuf_open(0); char command[MAXFILLEN]; const char *_; strbuf_puts(sb, title_begin); strbuf_puts(sb, title); strbuf_puts_nl(sb, title_end); strbuf_puts_nl(sb, gen_div_begin("right")); strbuf_sprintf(sb, "Last updated %s%s\n", now(), br); strbuf_sprintf(sb, "This hypertext was generated by %sGLOBAL-%s%s.%s\n", gen_href_begin_with_title_target(NULL, www, NULL, NULL, "Go to the GLOBAL project page.", "_top"), get_version(), gen_href_end(), br); strbuf_puts_nl(sb, gen_div_end()); strbuf_puts_nl(sb, hr); if (caution) { strbuf_puts_nl(sb, caution_begin); strbuf_sprintf(sb, "<font size='+2' color='red'>CAUTION</font>%s\n", br); strbuf_sprintf(sb, "This hypertext consist of %d files.\n", file_count); strbuf_puts_nl(sb, "Please don't download whole hypertext using hypertext copy tools."); strbuf_puts_nl(sb, "Our network cannot afford such traffic."); strbuf_puts_nl(sb, "Instead, you can generate same thing in your computer using"); strbuf_puts(sb, gen_href_begin_with_title_target(NULL, www, NULL, NULL, NULL, "_top")); strbuf_puts(sb, "GLOBAL source code tag system"); strbuf_puts_nl(sb, gen_href_end()); strbuf_puts_nl(sb, "Thank you."); strbuf_puts_nl(sb, caution_end); strbuf_sprintf(sb, "\n%s\n", hr); } if (fflag) { strbuf_puts(sb, makesearchpart(action, id, NULL)); strbuf_puts_nl(sb, hr); } strbuf_sprintf(sb, "%sMAINS%s\n", header_begin, header_end); snprintf(command, sizeof(command), "%s -nx %s | gnusort -k 1,1 -k 3,3 -k 2,2n", global_path, main_func); ip = popen(command, "r"); if (!ip) die("cannot execute command '%s'.", command); strbuf_puts_nl(sb, gen_list_begin()); while ((_ = strbuf_fgets(ib, ip, STRBUF_NOCRLF)) != NULL) { strbuf_puts_nl(sb, gen_list_body(SRCS, _)); } strbuf_puts_nl(sb, gen_list_end()); if (pclose(ip) != 0) die("cannot execute command '%s'.", command); strbuf_puts_nl(sb, hr); if (aflag && !Fflag) { strbuf_puts(sb, header_begin); strbuf_puts(sb, title_define_index); strbuf_puts_nl(sb, header_end); strbuf_puts(sb, defines); } else { strbuf_puts(sb, header_begin); strbuf_puts(sb, gen_href_begin(NULL, "defines", normal_suffix, NULL)); strbuf_puts(sb, title_define_index); strbuf_puts(sb, gen_href_end()); strbuf_puts_nl(sb, header_end); } strbuf_puts_nl(sb, hr); if (Fflag) { strbuf_puts(sb, header_begin); strbuf_puts(sb, gen_href_begin(NULL, "files", normal_suffix, NULL)); strbuf_puts(sb, title_file_index); strbuf_puts(sb, gen_href_end()); strbuf_puts_nl(sb, header_end); } else { strbuf_puts(sb, header_begin); strbuf_puts(sb, title_file_index); strbuf_puts_nl(sb, header_end); if (!no_order_list) strbuf_puts_nl(sb, list_begin); strbuf_puts(sb, files); if (!no_order_list) { strbuf_puts_nl(sb, list_end); } else { strbuf_puts_nl(sb, br); } strbuf_puts_nl(sb, hr); } strbuf_close(ib); return strbuf_value(sb); /* doesn't close string buffer */}/* * basic check. */static voidbasic_check(void){ const char *p; /* * COMMAND EXISTENCE CHECK */ if (!(p = usable("gnusort"))) die("gnusort command required but not found."); strlimcpy(sort_path, p, sizeof(sort_path));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -