📄 fileindex.c
字号:
* C: #include <xxx/yyy/zzz.h> * #include "xxx/yyy/zzz.h" * PHP: include('xxx/yyy/zzz'); */ p = image; while (*p && isspace((unsigned char)*p)) /* skip space */ p++; if (!*p) return NULL; if (*p == '#') { if (is_php) return NULL; p++; while (*p && isspace((unsigned char)*p)) /* skip space */ p++; if (!*p) return NULL; } /* * If match to one of the include keywords then points * the following character of the keyword. * p * v * ... include .... */ if (is_php) { if ((p = locatestring(p, "include", MATCH_AT_FIRST)) == NULL) return NULL; } else { char *q; if (((q = locatestring(p, "include_next", MATCH_AT_FIRST)) == NULL) && ((q = locatestring(p, "import", MATCH_AT_FIRST)) == NULL) && ((q = locatestring(p, "include", MATCH_AT_FIRST)) == NULL)) return NULL; p = q; } while (*p && isspace((unsigned char)*p)) /* skip space */ p++; if (is_php && *p == '(') { p++; while (*p && isspace((unsigned char)*p)) /* skip space */ p++; } sep = *p; if (is_php) { if (sep != '\'' && sep != '"') return NULL; } else { if (sep != '<' && sep != '"') return NULL; } if (sep == '<') sep = '>'; p++; if (!*p) return NULL; q = buf; while (*p && *p != '\n' && *p != sep) *q++ = *p++; *q = '\0'; if (*p == sep) { q = locatestring(buf, "/", MATCH_LAST); if (q) q++; else q = buf; return q; } return NULL;}/* * makefileindex: make file index. * * i) file * o) files */intmakefileindex(file, files) const char *file; STRBUF *files;{ FILE *FIND, *FILEMAP, *FILES, *STDOUT, *op = NULL; char *_; int count = 0; const char *indexlink = (Fflag) ? "../files" : "../mains"; STRBUF *sb = strbuf_open(0); STRBUF *input = strbuf_open(0); const char *target = (Fflag) ? "mains" : "_top"; struct dirstack *dirstack = make_stack("dirstack"); struct dirstack *fdstack = make_stack("fdstack"); const char *command = (other_files) ? "gtags --find --other | gnusort -t / -k 2" : "gtags --find"; struct dirstack *push = make_stack("push"); struct dirstack *pop = make_stack("pop"); /* * for collecting include files. */ int flags = REG_EXTENDED; regex_t is_include_file; if (w32) flags |= REG_ICASE; strbuf_reset(sb); strbuf_puts(sb, "\\.("); { const char *p = include_file_suffixes; int c; while ((c = (unsigned char)*p++) != '\0') { if (isregexchar(c)) strbuf_putc(sb, '\\'); else if (c == ',') c = '|'; strbuf_putc(sb, c); } } strbuf_puts(sb, ")$"); if (regcomp(&is_include_file, strbuf_value(sb), flags) != 0) die("cannot compile regular expression '%s'.", strbuf_value(sb)); /* * preparations. */ if ((FIND = popen(command, "r")) == NULL) die("cannot fork."); if ((FILES = fopen(makepath(distpath, file, NULL), "w")) == NULL) die("cannot open file '%s'.", file); fputs_nl(gen_page_begin(title_file_index, TOPDIR), FILES); fputs_nl(body_begin, FILES); fputs(header_begin, FILES); fputs(gen_href_begin(NULL, "files", normal_suffix, NULL), FILES); fputs(title_file_index, FILES); fputs(gen_href_end(), FILES); fputs_nl(header_end, FILES); if (!no_order_list) fputs_nl(list_begin, FILES); STDOUT = FILES; FILEMAP = NULL; if (map_file) { if (!(FILEMAP = fopen(makepath(distpath, "FILEMAP", NULL), "w"))) die("cannot open '%s'.", makepath(distpath, "FILEMAP", NULL)); } while ((_ = strbuf_fgets(input, FIND, STRBUF_NOCRLF)) != NULL) { char fname[MAXPATHLEN]; int notsource = 0; /* It seems like README or ChangeLog. */ if (*_ == ' ') { if (!other_files) continue; _++; if (test("b", _)) continue; notsource = 1; } _ += 2; /* remove './' */ count++; message(" [%d] adding %s", count, _); set_stack(push, _); strlimcpy(fname, pop_stack(push), sizeof(fname)); copy_stack(pop, dirstack); while (count_stack(push) && count_stack(pop) && !strcmp(bottom_stack(push), bottom_stack(pop))) { (void)shift_stack(push); (void)shift_stack(pop); } if (count_stack(push) || count_stack(pop)) { const char *parent, *path, *suffix; while (count_stack(pop)) { (void)pop_stack(dirstack); if (count_stack(dirstack)) { parent = path2fid(join_stack(dirstack)); suffix = HTML; } else { parent = indexlink; suffix = normal_suffix; } if (no_order_list) fputs_nl(br, STDOUT); else fputs_nl(list_end, STDOUT); fputs(gen_href_begin_with_title(NULL, parent, suffix, NULL, "Parent Directory"), STDOUT); if (icon_list) fputs(gen_image(PARENT, back_icon, ".."), STDOUT); else fputs("[..]", STDOUT); fputs_nl(gen_href_end(), STDOUT); fputs_nl(body_end, STDOUT); fputs_nl(gen_page_end(), STDOUT); path = pop_stack(fdstack); close_file_queue(path); file_count++; if (count_stack(fdstack)) STDOUT = select_file_queue(top_stack(fdstack)); pop_stack(pop); } while (count_stack(push)) { char parent[MAXPATHLEN], cur[MAXPATHLEN], tmp[MAXPATHLEN]; const char *last; if (count_stack(dirstack)) { strlimcpy(parent, path2fid(join_stack(dirstack)), sizeof(parent)); suffix = HTML; } else { strlimcpy(parent, indexlink, sizeof(parent)); suffix = normal_suffix; } push_stack(dirstack, shift_stack(push)); path = join_stack(dirstack); snprintf(cur, sizeof(cur), "%s/files/%s.%s", distpath, path2fid(path), HTML); last = (full_path) ? path : top_stack(dirstack); strbuf_reset(sb); if (!no_order_list) strbuf_puts(sb, item_begin); snprintf(tmp, sizeof(tmp), "%s/", path); strbuf_puts(sb, gen_href_begin_with_title(count_stack(dirstack) == 1 ? "files" : NULL, path2fid(path), HTML, NULL, tmp)); if (icon_list) { strbuf_puts(sb, gen_image(count_stack(dirstack) == 1 ? CURRENT : PARENT, dir_icon, tmp)); strbuf_puts(sb, quote_space); } strbuf_sprintf(sb, "%s/%s", last, gen_href_end()); if (!no_order_list) strbuf_puts(sb, item_end); else strbuf_puts(sb, br); strbuf_putc(sb, '\n'); if (count_stack(dirstack) == 1) strbuf_puts(files, strbuf_value(sb)); else fputs(strbuf_value(sb), STDOUT); op = open_file_queue(cur); STDOUT = op; push_stack(fdstack, cur); strbuf_reset(sb); strbuf_puts(sb, path); strbuf_putc(sb, '/'); fputs_nl(gen_page_begin(strbuf_value(sb), SUBDIR), STDOUT); fputs_nl(body_begin, STDOUT); fprintf(STDOUT, "%s%sroot%s/", header_begin, gen_href_begin(NULL, indexlink, normal_suffix, NULL), gen_href_end()); { struct dirstack *p = make_stack("tmp"); const char *s; int anchor; for (s = bottom_stack(dirstack); s; s = next_stack(dirstack, s)) { push_stack(p, s); anchor = count_stack(p) < count_stack(dirstack) ? 1 : 0; if (anchor) fputs(gen_href_begin(NULL, path2fid(join_stack(p)), HTML, NULL), STDOUT); fputs(s, STDOUT); if (anchor) fputs(gen_href_end(), STDOUT); fputc('/', STDOUT); } delete_stack(p); } fputs_nl(header_end, STDOUT); fputs(gen_href_begin_with_title(NULL, parent, suffix, NULL, "Parent Directory"), STDOUT); if (icon_list) fputs(gen_image(PARENT, back_icon, ".."), STDOUT); else fputs("[..]", STDOUT); fputs_nl(gen_href_end(), STDOUT); if (!no_order_list) fputs_nl(list_begin, STDOUT); else fprintf(STDOUT, "%s%s\n", br, br); } } /* * We assume the file which has one of the following suffixes * as a candidate of include file. * * C: .h * C++: .hxx, .hpp, .H * PHP: .inc.php */ if (regexec(&is_include_file, _, 0, 0, 0) == 0) put_inc(fname, _, count); strbuf_reset(sb); if (!no_order_list) strbuf_puts(sb, item_begin); { char tmp[1024]; const char *file, *suffix = NULL, *dir = NULL; if (notsource && dynamic) { if (!(*action == '/' || count_stack(dirstack) == 0)) dir = ".."; snprintf(tmp, sizeof(tmp), "%s?pattern=%s%stype=source", action, encode(_), quote_amp); file = tmp; } else { dir = count_stack(dirstack) ? upperdir(SRCS) : SRCS; file = path2fid(_); suffix = HTML; } strbuf_puts(sb, gen_href_begin_with_title_target(dir, file, suffix, NULL, _, target)); } if (icon_list) { const char *lang, *suffix, *text_icon; if ((suffix = locatestring(_, ".", MATCH_LAST)) != NULL && (lang = decide_lang(suffix)) != NULL && (strcmp(lang, "c") == 0 || strcmp(lang, "cpp") == 0 || strcmp(lang, "yacc") == 0)) text_icon = c_icon; else text_icon = file_icon; strbuf_puts(sb, gen_image(count_stack(dirstack) == 0 ? CURRENT : PARENT, text_icon, _)); strbuf_puts(sb, quote_space); } if (full_path) { strbuf_puts(sb, _); } else { const char *last = locatestring(_, "/", MATCH_LAST); if (last) last++; else last = _; strbuf_puts(sb, last); } strbuf_puts(sb, gen_href_end()); if (!no_order_list) strbuf_puts(sb, item_end); else strbuf_puts(sb, br); strbuf_putc(sb, '\n'); if (map_file) fprintf(FILEMAP, "%s\t%s/%s.%s\n", _, SRCS, path2fid(_), HTML); if (count_stack(dirstack) == 0) strbuf_puts(files, strbuf_value(sb)); else fputs(strbuf_value(sb), STDOUT); } if (map_file) fclose(FILEMAP); if (pclose(FIND) != 0) die("cannot traverse directory.(%s)", command); while (count_stack(dirstack) > 0) { const char *parent, *suffix; pop_stack(dirstack); if (count_stack(dirstack) > 0) { parent = path2fid(join_stack(dirstack)); suffix = HTML; } else { parent = indexlink; suffix = normal_suffix; } if (no_order_list) fputs_nl(br, STDOUT); else fputs_nl(list_end, STDOUT); fputs(gen_href_begin_with_title(NULL, parent, suffix, NULL, "Parent Directory"), STDOUT); if (icon_list) fputs(gen_image(PARENT, back_icon, ".."), STDOUT); else fputs("[..]", STDOUT); fputs_nl(gen_href_end(), STDOUT); fputs_nl(body_end, STDOUT); fputs_nl(gen_page_end(), STDOUT); close_file_queue(pop_stack(fdstack)); file_count++; if (count_stack(fdstack) > 0) STDOUT = select_file_queue(top_stack(fdstack)); } fputs(strbuf_value(files), FILES); if (no_order_list) fputs_nl(br, FILES); else fputs_nl(list_end, FILES); fputs_nl(body_end, FILES); fputs_nl(gen_page_end(), FILES); fclose(FILES); file_count++; delete_stack(dirstack); delete_stack(fdstack); delete_stack(push); delete_stack(pop); strbuf_close(sb); strbuf_close(input); return count;}voidmakeincludeindex(void){ FILE *PIPE; STRBUF *input = strbuf_open(0); char *ctags_x; struct data *inc; char *target = (Fflag) ? "mains" : "_top"; const char *command = "global -gnx \"^[ \\t]*(#[ \\t]*(import|include)|include[ \\t]*\\()\""; /* * Pick up include pattern. * * C: #include "xxx.h" * PHP: include("xxx.inc.php"); */ if ((PIPE = popen(command, "r")) == NULL) die("cannot fork."); strbuf_reset(input); while ((ctags_x = strbuf_fgets(input, PIPE, STRBUF_NOCRLF)) != NULL) { SPLIT ptable; char buf[MAXBUFLEN]; int is_php = 0; const char *last, *lang, *suffix; if (split(ctags_x, 4, &ptable) < 4) { recover(&ptable); die("too small number of parts in makefileindex()."); } if ((suffix = locatestring(ptable.part[PART_PATH].start, ".", MATCH_LAST)) != NULL && (lang = decide_lang(suffix)) != NULL && strcmp(lang, "php") == 0) is_php = 1; last = extract_lastname(ptable.part[PART_LINE].start, is_php); if (last == NULL || get_inc(last) == NULL) continue; recover(&ptable); /* * s/^[^ \t]+/$last/; */ { const char *p; char *q = buf; for (p = last; *p; p++) *q++ = *p; for (p = ctags_x; *p && *p != ' ' && *p != '\t'; p++) ; for (; *p; p++) *q++ = *p; *q = '\0'; } put_included(last, buf); } if (pclose(PIPE) != 0) die("terminated abnormally."); for (inc = first_inc(); inc; inc = next_inc()) { const char *last = inc->name; int no = inc->id; struct data *data; FILE *INCLUDE; if (inc->count > 1) { char path[MAXPATHLEN]; snprintf(path, sizeof(path), "%s/%s/%d.%s", distpath, INCS, no, HTML); INCLUDE = open_file_queue(path); fputs_nl(gen_page_begin(last, SUBDIR), INCLUDE); fputs_nl(body_begin, INCLUDE); fputs_nl(verbatim_begin, INCLUDE); { const char *filename = strbuf_value(inc->contents); int count = inc->count; for (; count; filename += strlen(filename) + 1, count--) { fputs(gen_href_begin_with_title_target(upperdir(SRCS), path2fid(filename), HTML, NULL, NULL, target), INCLUDE); fputs(filename, INCLUDE); fputs_nl(gen_href_end(), INCLUDE); } } fputs_nl(verbatim_end, INCLUDE); fputs_nl(body_end, INCLUDE); fputs_nl(gen_page_end(), INCLUDE); close_file_queue(path); file_count++; /* * inc->path == NULL means that information already * written to file. */ strbuf_reset(inc->contents); } data = get_included(last); if (!data) continue; if (data->count == 1) { SPLIT ptable; char buf[1024]; if (split(strbuf_value(data->contents), 4, &ptable) < 4) { recover(&ptable); die("too small number of parts in makefileindex()."); } snprintf(buf, sizeof(buf), "%s %s", ptable.part[PART_LNO].start, ptable.part[PART_PATH].start); recover(&ptable); strbuf_reset(data->contents); strbuf_puts(data->contents, buf); } else { char path[MAXPATHLEN]; snprintf(path, sizeof(path), "%s/%s/%d.%s", distpath, INCREFS, no, HTML); INCLUDE = open_file_queue(path); fputs_nl(gen_page_begin(last, SUBDIR), INCLUDE); fputs_nl(body_begin, INCLUDE); fputs_nl(gen_list_begin(), INCLUDE); { const char *line = strbuf_value(data->contents); int count = data->count; for (; count; line += strlen(line) + 1, count--) fputs_nl(gen_list_body(upperdir(SRCS), line), INCLUDE); } fputs_nl(gen_list_end(), INCLUDE); fputs_nl(body_end, INCLUDE); fputs_nl(gen_page_end(), INCLUDE); close_file_queue(path); file_count++; /* * inc->path == NULL means that information already * written to file. */ strbuf_reset(data->contents); data->id = no; } } strbuf_close(input);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -