📄 global.c
字号:
/* * completion: print completion list of specified prefix * * i) dbpath dbpath directory * i) root root directory * i) prefix prefix of primary key */voidcompletion(dbpath, root, prefix) const char *dbpath; const char *root; const char *prefix;{ const char *p; int flags = GTOP_KEY; GTOP *gtop; int db; flags |= GTOP_NOREGEX; if (prefix && *prefix == 0) /* In the case global -c '' */ prefix = NULL; if (prefix) flags |= GTOP_PREFIX; db = (sflag) ? GSYMS : GTAGS; gtop = gtags_open(dbpath, root, db, GTAGS_READ, 0); for (p = gtags_first(gtop, prefix, flags); p; p = gtags_next(gtop)) { fputs(p, stdout); fputc('\n', stdout); } gtags_close(gtop);}/* * printtag: print a tag's line * * i) op output stream * i) line tag's line */voidprinttag(op, line) FILE *op; const char *line; /* virtually const */{ if (xflag) { fputs(line, op); } else { SPLIT ptable; int n; /* * Split tag line. */ n = split((char *)line, 4, &ptable); if (tflag) { fputs(ptable.part[0].start, op); /* tag */ (void)putc('\t', op); fputs(ptable.part[2].start, op); /* path */ (void)putc('\t', op); fputs(ptable.part[1].start, op); /* line number */ } else { fputs(ptable.part[2].start, op); /* path */ } recover(&ptable); } fputc('\n', op);}/* * idutils: lid(id-utils) pattern * * i) pattern POSIX regular expression * i) dbpath GTAGS directory */voididutils(pattern, dbpath) const char *pattern; const char *dbpath;{ FILE *ip, *op; STRBUF *ib = strbuf_open(0); char edit[IDENTLEN+1]; const char *path, *lno, *lid; int linenum, count; char *p, *line; lid = usable("lid"); if (!lid) die("lid(id-utils) not found."); /* * convert spaces into %FF format. */ ffformat(edit, sizeof(edit), pattern); /* * make lid command line. */ strbuf_puts(ib, lid); strbuf_puts(ib, " --separator=newline"); if (!tflag && !xflag) strbuf_puts(ib, " --result=filenames --key=none"); else strbuf_puts(ib, " --result=grep"); if (iflag) strbuf_puts(ib, " --ignore-case"); if (extra_options) { strbuf_putc(ib, ' '); strbuf_puts(ib, extra_options); } strbuf_putc(ib, ' '); strbuf_puts(ib, quote_string(pattern)); if (debug) fprintf(stderr, "id-utils: %s\n", strbuf_value(ib)); if (!(ip = popen(strbuf_value(ib), "r"))) die("cannot execute '%s'.", strbuf_value(ib)); if (!(op = openfilter())) die("cannot open output filter."); count = 0; while ((line = strbuf_fgets(ib, ip, STRBUF_NOCRLF)) != NULL) { p = line; /* extract filename */ path = p; while (*p && *p != ':') p++; if ((xflag || tflag) && !*p) die("invalid lid(id-utils) output format. '%s'", line); *p++ = 0; if (lflag) { if (!locatestring(path, localprefix + 2, MATCH_AT_FIRST)) continue; } count++; if (!xflag && !tflag) { fprintf(op, "./%s\n", path); continue; } /* extract line number */ while (*p && isspace(*p)) p++; lno = p; while (*p && isdigit(*p)) p++; if (*p != ':') die("invalid lid(id-utils) output format. '%s'", line); *p++ = 0; linenum = atoi(lno); if (linenum <= 0) die("invalid lid(id-utils) output format. '%s'", line); /* * print out. */ if (tflag) fprintf(op, "%s\t./%s\t%d\n", edit, path, linenum); else { char buf[MAXPATHLEN+1]; snprintf(buf, sizeof(buf), "./%s", path); fprintf(op, "%-16s %4d %-16s %s\n", edit, linenum, buf, p); } } if (pclose(ip) < 0) die("terminated abnormally."); closefilter(op); strbuf_close(ib); if (vflag) { if (count == 0) fprintf(stderr, "object not found"); if (count == 1) fprintf(stderr, "%d object located", count); if (count > 1) fprintf(stderr, "%d objects located", count); fprintf(stderr, " (using id-utils index in '%s').\n", dbpath); }}/* * grep: grep pattern * * i) pattern POSIX regular expression */voidgrep(pattern) const char *pattern;{ FILE *op, *fp; STRBUF *ib = strbuf_open(MAXBUFLEN); const char *path, *p; char edit[IDENTLEN+1]; const char *buffer; int linenum, count; int flags = 0; regex_t preg; /* * convert spaces into %FF format. */ ffformat(edit, sizeof(edit), pattern); if (!Gflag) flags |= REG_EXTENDED; if (iflag) flags |= REG_ICASE; if (regcomp(&preg, pattern, flags) != 0) die("invalid regular expression."); if (!(op = openfilter())) die("cannot open output filter."); count = 0; for (vfind_open(localprefix, oflag); (p = vfind_read()) != NULL; ) { path = (*p == ' ') ? ++p : p; if (!(fp = fopen(path, "r"))) die("cannot open file '%s'.", path); linenum = 0; while ((buffer = strbuf_fgets(ib, fp, STRBUF_NOCRLF)) != NULL) { linenum++; if (regexec(&preg, buffer, 0, 0, 0) == 0) { count++; if (tflag) fprintf(op, "%s\t%s\t%d\n", edit, path, linenum); else if (!xflag) { fputs(path, op); fputc('\n', op); break; } else { fprintf(op, "%-16s %4d %-16s %s\n", edit, linenum, path, buffer); } } } fclose(fp); } vfind_close(); closefilter(op); strbuf_close(ib); regfree(&preg); if (vflag) { if (count == 0) fprintf(stderr, "object not found"); if (count == 1) fprintf(stderr, "%d object located", count); if (count > 1) fprintf(stderr, "%d objects located", count); fprintf(stderr, " (no index used).\n"); }}/* * pathlist: print candidate path list. * * i) dbpath */voidpathlist(dbpath, av) const char *dbpath; const char *av;{ FILE *op; const char *path, *p; regex_t preg; int count; if (av) { int flags = 0; if (!Gflag) flags |= REG_EXTENDED; if (iflag || getconfb("icase_path")) flags |= REG_ICASE;#ifdef _WIN32 flags |= REG_ICASE;#endif /* _WIN32 */ if (regcomp(&preg, av, flags) != 0) die("invalid regular expression."); } if (!localprefix) localprefix = "."; if (!(op = openfilter())) die("cannot open output filter."); count = 0; for (vfind_open(localprefix, oflag); (p = vfind_read()) != NULL; ) { path = (*p == ' ') ? ++p : p; /* * skip localprefix because end-user doesn't see it. */ p = path + strlen(localprefix) - 1; if (av && regexec(&preg, p, 0, 0, 0) != 0) continue; if (xflag) fprintf(op, "path\t1 %s \n", path); else if (tflag) fprintf(op, "path\t%s\t1\n", path); else { fputs(path, op); fputc('\n', op); } count++; } vfind_close(); closefilter(op); if (av) regfree(&preg); if (vflag) { if (count == 0) fprintf(stderr, "path not found"); if (count == 1) fprintf(stderr, "%d path located", count); if (count > 1) fprintf(stderr, "%d paths located", count); fprintf(stderr, " (using '%s').\n", makepath(dbpath, dbname(GPATH), NULL)); }}/* * parsefile: parse file to pick up tags. * * i) argc * i) argv * i) cwd current directory * i) root root directory of source tree * i) dbpath dbpath * i) db type of parse */voidparsefile(argc, argv, cwd, root, dbpath, db) int argc; char **argv; const char *cwd; const char *root; const char *dbpath; int db;{ char rootdir[MAXPATHLEN+1]; char buf[MAXPATHLEN+1], *path; FILE *op; int count; STRBUF *comline = strbuf_open(0); STRBUF *path_list = strbuf_open(MAXPATHLEN); int path_list_max; snprintf(rootdir, sizeof(rootdir), "%s/", root); /* * teach parser where is dbpath. */ set_env("GTAGSDBPATH", dbpath); /* * get parser. */ if (!getconfs(dbname(db), comline)) die("cannot get parser for %s.", dbname(db)); /* * determine the maximum length of the list of paths. */ path_list_max = exec_line_limit(strbuf_getlen(comline)); if (!(op = openfilter())) die("cannot open output filter."); if (gpath_open(dbpath, 0) < 0) die("GPATH not found."); count = 0; for (; argc > 0; argv++, argc--) { const char *av = argv[0]; if (!test("f", av)) { if (test("d", av)) { if (!qflag) fprintf(stderr, "'%s' is a directory.\n", av); } else { if (!qflag) fprintf(stderr, "'%s' not found.\n", av); } continue; } /* * convert path into relative from root directory of source tree. */ path = realpath(av, buf); if (path == NULL) die("realpath(%s, buf) failed. (errno=%d).", av, errno); if (!isabspath(path)) die("realpath(3) is not compatible with BSD version."); /* * Remove the root part of path and insert './'. * rootdir /a/b/ * path /a/b/c/d.c -> c/d.c -> ./c/d.c */ path = locatestring(path, rootdir, MATCH_AT_FIRST); if (path == NULL) { if (!qflag) fprintf(stderr, "'%s' is out of source tree.\n", path); continue; } path -= 2; *path = '.'; if (!gpath_path2fid(path)) { if (!qflag) fprintf(stderr, "'%s' not found in GPATH.\n", path); continue; } /* * 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(path_list)) { if (strbuf_getlen(path_list) + strlen(path) > path_list_max) { count += exec_parser(strbuf_value(comline), path_list, cwd, root, op); strbuf_reset(path_list); } } /* * Add a path to the path list. */ strbuf_puts0(path_list, path); } if (strbuf_getlen(path_list)) count += exec_parser(strbuf_value(comline), path_list, cwd, root, op); gpath_close(); closefilter(op); strbuf_close(comline); strbuf_close(path_list); if (vflag) { if (count == 0) fprintf(stderr, "object not found"); if (count == 1) fprintf(stderr, "%d object located", count); if (count > 1) fprintf(stderr, "%d objects located", count); fprintf(stderr, " (no index used).\n"); }}/* * exec_parser: execute parser * * i) parser template of command line * i) path_list \0 separated list of paths * i) cwd current directory * i) root root directory of source tree * i) op filter to output * r) number of objects found */static intexec_parser(parser, path_list, cwd, root, op) const char *parser; STRBUF *path_list; const char *cwd; const char *root; FILE *op;{ const char *p; FILE *ip; int count; STRBUF *com = strbuf_open(0); STRBUF *ib = strbuf_open(MAXBUFLEN); if (chdir(root) < 0) die("cannot move to '%s' directory.", root); /* * make command line. */ makecommand(parser, path_list, com); if (debug) fprintf(stderr, "executing %s\n", strbuf_value(com)); if (!(ip = popen(strbuf_value(com), "r"))) die("cannot execute '%s'.", strbuf_value(com)); count = 0; while ((p = strbuf_fgets(ib, ip, STRBUF_NOCRLF)) != NULL) { count++; printtag(op, p); } if (pclose(ip) < 0) die("terminated abnormally."); if (chdir(cwd) < 0) die("cannot move to '%s' directory.", cwd); strbuf_close(com); strbuf_close(ib); return count;}/* * search: search specified function * * i) pattern search pattern * i) root root of source tree * i) dbpath database directory * i) db GTAGS,GRTAGS,GSYMS * r) count of output lines */intsearch(pattern, root, dbpath, db) const char *pattern; const char *root; const char *dbpath; int db;{ const char *p; int count = 0; FILE *op; GTOP *gtop; int flags = 0; STRBUF *sb = NULL; /* * open tag file. */ gtop = gtags_open(dbpath, root, db, GTAGS_READ, 0); if (!(op = openfilter())) die("cannot open output filter."); /* * search through tag file. */ if (nflag > 1) flags |= GTOP_NOSOURCE; if (iflag) { if (!isregex(pattern)) { sb = strbuf_open(0); strbuf_putc(sb, '^'); strbuf_puts(sb, pattern); strbuf_putc(sb, '$'); pattern = strbuf_value(sb); } flags |= GTOP_IGNORECASE; } if (Gflag) flags |= GTOP_BASICREGEX; for (p = gtags_first(gtop, pattern, flags); p; p = gtags_next(gtop)) { if (lflag) { const char *q; /* locate start point of a path */ q = locatestring(p, "./", MATCH_FIRST); if (!locatestring(q, localprefix, MATCH_AT_FIRST)) continue; } printtag(op, p); count++; } closefilter(op); if (sb) strbuf_close(sb); gtags_close(gtop); return count;}/* * ffformat: string copy with converting blank chars into %ff format. * * o) to result * i) size size of 'to' buffer * i) from string */voidffformat(to, size, from) char *to; int size; const char *from;{ const char *p; char *e = to; for (p = from; *p; p++) { if (*p == '%' || *p == ' ' || *p == '\t') { if (size <= 3) break; snprintf(e, size, "%%%02x", *p); e += 3; size -= 3; } else { if (size <= 1) break; *e++ = *p; size--; } } *e = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -