/** * completion_tags: print completion list of specified @a prefix * * @param[in] dbpath dbpath directory * @param[in] root root directory * @param[in] prefix prefix of primary key * @param[in] db #GTAGS,#GRTAGS,#GSYMS * @return number of words */ int completion_tags(const char *dbpath, const char *root, const char *prefix, int db) { int flags = GTOP_KEY | GTOP_NOREGEX | GTOP_PREFIX; GTOP *gtop = gtags_open(dbpath, root, db, GTAGS_READ, 0); GTP *gtp; int count = 0; if (iflag) flags |= GTOP_IGNORECASE; for (gtp = gtags_first(gtop, prefix, flags); gtp; gtp = gtags_next(gtop)) { fputs(gtp->tag, stdout); fputc('\n', stdout); count++; } if (debug) gtags_show_statistics(gtop); gtags_close(gtop); return count; }
/** * @fn int search(const char *pattern, const char *root, const char *cwd, const char *dbpath, int db) * * search: search specified function * * @param[in] pattern search pattern * @param[in] root root of source tree * @param[in] cwd current directory * @param[in] dbpath database directory * @param[in] db #GTAGS,#GRTAGS,#GSYMS * @return count of output lines */ int search(const char *pattern, const char *root, const char *cwd, const char *dbpath, int db) { CONVERT *cv; int count = 0; GTOP *gtop; GTP *gtp; int flags = 0; start_output(); /* * open tag file. */ gtop = gtags_open(dbpath, root, db, GTAGS_READ, debug ? GTAGS_DEBUG : 0); cv = convert_open(type, format, root, cwd, dbpath, stdout, db); /* * search through tag file. */ if (nofilter & SORT_FILTER) flags |= GTOP_NOSORT; if (Gflag) flags |= GTOP_BASICREGEX; if (format == FORMAT_PATH) flags |= GTOP_PATH; if (iflag) flags |= GTOP_IGNORECASE; for (gtp = gtags_first(gtop, pattern, flags); gtp; gtp = gtags_next(gtop)) { if (Sflag && !locatestring(gtp->path, localprefix, MATCH_AT_FIRST)) continue; count += output_with_formatting(cv, gtp, gtop->format); } convert_close(cv); if (debug) gtags_show_statistics(gtop); gtags_close(gtop); end_output(); return count; }
int main(int argc, char **argv) { const char *av = NULL; int func_total, file_total; char arg_dbpath[MAXPATHLEN]; const char *index = NULL; int optchar; int option_index = 0; STATISTICS_TIME *tim; arg_dbpath[0] = 0; basic_check(); /* * Setup GTAGSCONF and GTAGSLABEL environment variable * according to the --gtagsconf and --gtagslabel option. */ preparse_options(argc, argv); /* * Load configuration values. */ if (!vgetcwd(cwdpath, sizeof(cwdpath))) die("cannot get current directory."); openconf(cwdpath); configuration(); /* * setup_langmap() is needed to use decide_lang(). */ setup_langmap(langmap); save_environment(argc, argv); /* * insert htags_options at the head of argv. */ setenv_from_config(); { char *env = getenv("HTAGS_OPTIONS"); if (env && *env) argv = prepend_options(&argc, argv, env); } while ((optchar = getopt_long(argc, argv, "acd:DfFghIm:nNoqst:Tvwx", long_options, &option_index)) != EOF) { switch (optchar) { case 0: /* already flags set */ break; case OPT_AUTO_COMPLETION: auto_completion = 1; if (optarg) { if (atoi(optarg) > 0) auto_completion_limit = optarg; else die("The option value of --auto-completion must be numeric."); } break; case OPT_CFLOW: call_file = optarg; break; case OPT_CALL_TREE: call_file = optarg; break; case OPT_CALLEE_TREE: callee_file = optarg; break; case OPT_CVSWEB: cvsweb_url = optarg; break; case OPT_CVSWEB_CVSROOT: cvsweb_cvsroot = optarg; break; case OPT_GTAGSCONF: case OPT_GTAGSLABEL: /* These options are already parsed in preparse_options() */ break; case OPT_INSERT_FOOTER: insert_footer = optarg; break; case OPT_INSERT_HEADER: insert_header = optarg; break; case OPT_HTML_HEADER: { STATIC_STRBUF(sb); if (!test("r", optarg)) die("file '%s' not found.", optarg); strbuf_clear(sb); loadfile(optarg, sb); html_header = strbuf_value(sb); } break; case OPT_ITEM_ORDER: item_order = optarg; break; case OPT_TABS: if (atoi(optarg) > 0) tabs = atoi(optarg); else die("--tabs option requires numeric value."); break; case OPT_NCOL: if (atoi(optarg) > 0) ncol = atoi(optarg); else die("--ncol option requires numeric value."); break; case OPT_TREE_VIEW: tree_view = 1; if (optarg) tree_view_type = optarg; break; case 'a': aflag++; break; case 'd': strlimcpy(arg_dbpath, optarg, sizeof(arg_dbpath)); break; case 'D': dynamic = 1; break; case 'f': fflag++; break; case 'F': Fflag++; break; case 'g': gflag++; break; case 'h': definition_header = AFTER_HEADER; if (optarg) { if (!strcmp(optarg, "before")) definition_header = BEFORE_HEADER; else if (!strcmp(optarg, "right")) definition_header = RIGHT_HEADER; else if (!strcmp(optarg, "after")) definition_header = AFTER_HEADER; else die("The option value of --func-header must be one of 'before', 'right' and 'after'."); } break; case 'I': Iflag++; break; case 'm': main_func = optarg; break; case 'n': nflag++; if (optarg) { if (atoi(optarg) > 0) ncol = atoi(optarg); else die("The option value of --line-number must be numeric."); } break; case 'o': other_files = 1; break; case 's': symbol = 1; break; case 'T': table_flist = 1; if (optarg) { if (atoi(optarg) > 0) flist_fields = atoi(optarg); else die("The option value of the --table-flist must be numeric."); } break; case 't': title = optarg; break; case 'q': qflag++; setquiet(); break; case 'v': vflag++; setverbose(); break; case 'w': wflag++; break; default: usage(); break; } } /* * Leaving everything to htags. * Htags selects popular options for you. */ if (suggest2) suggest = 1; if (suggest) { int gtags_not_found = 0; char dbpath[MAXPATHLEN]; aflag = Iflag = nflag = vflag = 1; setverbose(); definition_header = AFTER_HEADER; other_files = symbol = show_position = table_flist = fixed_guide = 1; if (arg_dbpath[0]) { if (!test("f", makepath(arg_dbpath, dbname(GTAGS), NULL))) gtags_not_found = 1; } else if (gtagsexist(".", dbpath, sizeof(dbpath), 0) == 0) { gtags_not_found = 1; } if (gtags_not_found) gflag = 1; } if (suggest2) { Fflag = 1; /* uses frame */ fflag = dynamic = 1; /* needs a HTTP server */ auto_completion = tree_view = 1; /* needs javascript */ } if (call_file && !test("fr", call_file)) die("cflow file not found. '%s'", call_file); if (callee_file && !test("fr", callee_file)) die("cflow file not found. '%s'", callee_file); if (insert_header && !test("fr", insert_header)) die("page header file '%s' not found.", insert_header); if (insert_footer && !test("fr", insert_footer)) die("page footer file '%s' not found.", insert_footer); if (!fflag) auto_completion = 0; argc -= optind; argv += optind; if (!av) av = (argc > 0) ? *argv : NULL; if (debug) setdebug(); settabs(tabs); /* setup tab skip */ if (qflag) { setquiet(); vflag = 0; } if (show_version) version(av, vflag); if (show_help) help(); /* * Invokes gtags beforehand. */ if (gflag) { STRBUF *sb = strbuf_open(0); strbuf_puts(sb, gtags_path); if (vflag) strbuf_puts(sb, " -v"); if (wflag) strbuf_puts(sb, " -w"); if (suggest2 && enable_idutils && usable("mkid")) strbuf_puts(sb, " -I"); if (arg_dbpath[0]) { strbuf_putc(sb, ' '); strbuf_puts(sb, arg_dbpath); } if (system(strbuf_value(sb))) die("cannot execute gtags(1) command."); strbuf_close(sb); } /* * get dbpath. */ if (arg_dbpath[0]) { strlimcpy(dbpath, arg_dbpath, sizeof(dbpath)); } else { int status = setupdbpath(0); if (status < 0) die_with_code(-status, "%s", gtags_dbpath_error); strlimcpy(dbpath, get_dbpath(), sizeof(dbpath)); } if (!title) { char *p = strrchr(cwdpath, sep); title = p ? p + 1 : cwdpath; } if (cvsweb_url && test("d", "CVS")) use_cvs_module = 1; /* * decide directory in which we make hypertext. */ if (av) { char realpath[MAXPATHLEN]; if (!test("dw", av)) die("'%s' is not writable directory.", av); if (chdir(av) < 0) die("directory '%s' not found.", av); if (!vgetcwd(realpath, sizeof(realpath))) die("cannot get current directory"); if (chdir(cwdpath) < 0) die("cannot return to original directory."); snprintf(distpath, sizeof(distpath), "%s/HTML", realpath); } else { snprintf(distpath, sizeof(distpath), "%s/HTML", cwdpath); } /* * Existence check of tag files. */ { int i; const char *path; GTOP *gtop; for (i = GPATH; i < GTAGLIM; i++) { path = makepath(dbpath, dbname(i), NULL); gtags_exist[i] = test("fr", path); } /* * Real GRTAGS includes virtual GSYMS. */ gtags_exist[GSYMS] = symbol ? 1 : 0; if (!gtags_exist[GPATH] || !gtags_exist[GTAGS] || !gtags_exist[GRTAGS]) die("GPATH, GTAGS and/or GRTAGS not found. Please reexecute htags with the -g option."); /* * version check. * Do nothing, but the version of tag file will be checked. */ gtop = gtags_open(dbpath, cwdpath, GTAGS, GTAGS_READ, 0); gtags_close(gtop); /* * Check whether GRTAGS is empty. */ gtop = gtags_open(dbpath, cwdpath, GRTAGS, GTAGS_READ, 0); if (gtags_first(gtop, NULL, 0) == NULL) grtags_is_empty = 1; gtags_close(gtop); } /* * make dbpath absolute. */ { char buf[MAXPATHLEN]; if (realpath(dbpath, buf) == NULL) die("cannot get realpath of dbpath."); strlimcpy(dbpath, buf, sizeof(dbpath)); } /* * The older version (4.8.7 or former) of GPATH doesn't have files * other than source file. The oflag requires new version of GPATH. */ if (other_files) { GFIND *gp = gfind_open(dbpath, NULL, 0, 0); if (gp->version < 2) die("GPATH is old format. Please remake it by invoking gtags(1)."); gfind_close(gp); } /* * for global(1) and gtags(1). */ set_env("GTAGSROOT", cwdpath); set_env("GTAGSDBPATH", dbpath); set_env("GTAGSLIBPATH", ""); /*------------------------------------------------------------------ * MAKE FILES *------------------------------------------------------------------ * HTML/cgi-bin/global.cgi ... CGI program (1) * HTML/cgi-bin/ghtml.cgi ... unzip script (1) * HTML/.htaccess ... skeleton of .htaccess (1) * HTML/help.html ... help file (2) * HTML/R/ ... references (3) * HTML/D/ ... definitions (3) * HTML/search.html ... search index (4) * HTML/defines.html ... definitions index (5) * HTML/defines/ ... definitions index (5) * HTML/files/ ... file index (6) * HTML/index.html ... index file (7) * HTML/mains.html ... main index (8) * HTML/null.html ... main null html (8) * HTML/S/ ... source files (9) * HTML/I/ ... include file index (9) * HTML/rebuild.sh ... rebuild script (10) * HTML/style.css ... style sheet (11) *------------------------------------------------------------------ */ /* for clean up */ signal_setup(); sethandler(clean); HTML = normal_suffix; message("[%s] Htags started", now()); init_statistics(); /* * (#) check if GTAGS, GRTAGS is the latest. */ if (get_dbpath()) message(" Using %s/GTAGS.", get_dbpath()); if (grtags_is_empty) message(" GRTAGS is empty."); if (gpath_open(dbpath, 0) < 0) die("GPATH not found."); if (!w32) { /* UNDER CONSTRUCTION */ } if (auto_completion || tree_view) { STATIC_STRBUF(sb); strbuf_clear(sb); strbuf_puts_nl(sb, "<script type='text/javascript' src='js/jquery.js'></script>"); if (auto_completion) loadfile(makepath(datadir, "gtags/jscode_suggest", NULL), sb); if (tree_view) loadfile(makepath(datadir, "gtags/jscode_treeview", NULL), sb); jscode = strbuf_value(sb); } /* * (0) make directories */ message("[%s] (0) making directories ...", now()); if (!test("d", distpath)) if (mkdir(distpath, 0777) < 0) die("cannot make directory '%s'.", distpath); make_directory_in_distpath("files"); make_directory_in_distpath("defines"); make_directory_in_distpath(SRCS); make_directory_in_distpath(INCS); make_directory_in_distpath(INCREFS); if (!dynamic) { make_directory_in_distpath(DEFS); make_directory_in_distpath(REFS); if (symbol) make_directory_in_distpath(SYMS); } if (fflag || dynamic) make_directory_in_distpath("cgi-bin"); if (Iflag) make_directory_in_distpath("icons"); if (auto_completion || tree_view) make_directory_in_distpath("js"); /* * (1) make CGI program */ if (fflag || dynamic) { char cgidir[MAXPATHLEN]; snprintf(cgidir, sizeof(cgidir), "%s/cgi-bin", distpath); message("[%s] (1) making CGI program ...", now()); if (fflag || dynamic) makeprogram(cgidir, "global.cgi", 0755); if (auto_completion) makeprogram(cgidir, "completion.cgi", 0755); makehtaccess(cgidir, ".htaccess", 0644); } else { message("[%s] (1) making CGI program ...(skipped)", now()); } if (av) { const char *path = makepath(distpath, "GTAGSROOT", NULL); FILE *op = fopen(path, "w"); if (op == NULL) die("cannot make file '%s'.", path); fputs(cwdpath, op); fputc('\n', op); fclose(op); } /* * (2) make help file */ message("[%s] (2) making help.html ...", now()); makehelp("help.html"); /* * (#) load GPATH */ load_gpath(dbpath); /* * (3) make function entries (D/ and R/) * MAKING TAG CACHE */ message("[%s] (3) making tag lists ...", now()); cache_open(); tim = statistics_time_start("Time of making tag lists"); func_total = makedupindex(); statistics_time_end(tim); message("Total %d functions.", func_total); /* * (4) search index. (search.html) */ if (Fflag && fflag) { message("[%s] (4) making search index ...", now()); makesearchindex("search.html"); } { STRBUF *defines = strbuf_open(0); STRBUF *files = strbuf_open(0); /* * (5) make definition index (defines.html and defines/) * PRODUCE @defines */ message("[%s] (5) making definition index ...", now()); tim = statistics_time_start("Time of making definition index"); func_total = makedefineindex("defines.html", func_total, defines); statistics_time_end(tim); message("Total %d functions.", func_total); /* * (6) make file index (files.html and files/) * PRODUCE @files, %includes */ message("[%s] (6) making file index ...", now()); init_inc(); tim = statistics_time_start("Time of making file index"); file_total = makefileindex("files.html", files); statistics_time_end(tim); message("Total %d files.", file_total); html_count += file_total; /* * (7) make call tree using cflow(1)'s output (cflow.html) */ if (call_file || callee_file) { message("[%s] (7) making cflow index ...", now()); tim = statistics_time_start("Time of making cflow index"); if (call_file) if (makecflowindex("call.html", call_file) < 0) call_file = NULL; if (callee_file) if (makecflowindex("callee.html", callee_file) < 0) callee_file = NULL; statistics_time_end(tim); } /* * [#] make include file index. */ message("[%s] (#) making include file index ...", now()); tim = statistics_time_start("Time of making include file index"); makeincludeindex(); statistics_time_end(tim); /* * [#] make a common part for mains.html and index.html * USING @defines @files */ message("[%s] (#) making a common part ...", now()); index = makecommonpart(title, strbuf_value(defines), strbuf_value(files)); strbuf_close(defines); strbuf_close(files); } /* * (7)make index file (index.html) */ message("[%s] (7) making index file ...", now()); makeindex("index.html", title, index); /* * (8) make main index (mains.html) */ message("[%s] (8) making main index ...", now()); makemainindex("mains.html", index); /* * (9) make HTML files (SRCS/) * USING TAG CACHE, %includes and anchor database. */ message("[%s] (9) making hypertext from source code ...", now()); tim = statistics_time_start("Time of making hypertext"); makehtml(file_total); statistics_time_end(tim); /* * (10) rebuild script. (rebuild.sh) * * Don't grant execute permission to rebuild script. */ makerebuild("rebuild.sh"); if (chmod(makepath(distpath, "rebuild.sh", NULL), 0640) < 0) die("cannot chmod rebuild script."); /* * (11) style sheet file (style.css) */ if (enable_xhtml) { char src[MAXPATHLEN]; char dist[MAXPATHLEN]; snprintf(src, sizeof(src), "%s/gtags/style.css", datadir); snprintf(dist, sizeof(dist), "%s/style.css", distpath); copyfile(src, dist); } if (auto_completion || tree_view) { char src[MAXPATHLEN]; char dist[MAXPATHLEN]; snprintf(src, sizeof(src), "%s/gtags/jquery", datadir); snprintf(dist, sizeof(dist), "%s/js", distpath); copydirectory(src, dist); snprintf(src, sizeof(src), "%s/gtags/jquery/images", datadir); snprintf(dist, sizeof(dist), "%s/js/images", distpath); copydirectory(src, dist); } message("[%s] Done.", now()); if (vflag && (fflag || dynamic || auto_completion)) { message("\n[Information]\n"); message(" o Htags was invoked with the -f, -c, -D or --auto-completion option. You should"); message(" start http server so that cgi-bin/*.cgi is executed as a CGI script."); message("\n If you are using Apache, 'HTML/.htaccess' might be helpful for you.\n"); message(" Good luck!\n"); } if (Iflag) { char src[MAXPATHLEN]; char dist[MAXPATHLEN]; snprintf(src, sizeof(src), "%s/gtags/icons", datadir); snprintf(dist, sizeof(dist), "%s/icons", distpath); copydirectory(src, dist); } gpath_close(); /* * Print statistics information. */ print_statistics(statistics); clean(); return 0; }
/* * completion: print completion list of specified prefix * * i) dbpath dbpath directory * i) root root directory * i) prefix prefix of primary key */ void completion(const char *dbpath, const char *root, const char *prefix) { int flags = GTOP_KEY; GTOP *gtop = gtags_open(dbpath, root, (sflag) ? GSYMS : GTAGS, GTAGS_READ, 0); GTP *gtp; if (prefix && *prefix == 0) /* In the case global -c '' */ prefix = NULL; if (prefix && isalpha(*prefix) && iflag) { /* * If the -i option is specified, we use both of regular * expression and prefix read for performance. It is done * by connecting two prefix reading. */ STRBUF *sb = strbuf_open(0); regex_t preg; int i, firstchar[2]; flags |= GTOP_NOREGEX; flags |= GTOP_PREFIX; /* * make regular expression. */ strbuf_putc(sb, '^'); strbuf_puts(sb, prefix); if (regcomp(&preg, strbuf_value(sb), REG_ICASE) != 0) die("invalid regular expression."); /* * Two prefix reading: * * prefix = 'main' * v * firstchar[0] = 'M'; /^M/ the first time * firstchar[1] = 'm'; /^m/ the second time */ firstchar[0] = firstchar[1] = *prefix; if (isupper(firstchar[0])) firstchar[1] = tolower(firstchar[0]); else firstchar[0] = toupper(firstchar[0]); for (i = 0; i < 2; i++) { strbuf_reset(sb); strbuf_putc(sb, firstchar[i]); for (gtp = gtags_first(gtop, strbuf_value(sb), flags); gtp; gtp = gtags_next(gtop)) { if (regexec(&preg, gtp->tag, 0, 0, 0) == 0) { fputs(gtp->tag, stdout); fputc('\n', stdout); } } } strbuf_close(sb); } else { flags |= GTOP_NOREGEX; if (prefix) flags |= GTOP_PREFIX; for (gtp = gtags_first(gtop, prefix, flags); gtp; gtp = gtags_next(gtop)) { fputs(gtp->tag, stdout); fputc('\n', stdout); } } gtags_close(gtop); }
int search(const char *pattern, const char *root, const char *cwd, const char *dbpath, int db) { CONVERT *cv; int count = 0; GTOP *gtop; GTP *gtp; int flags = 0; STRBUF *sb = NULL, *ib = NULL; char curpath[MAXPATHLEN], curtag[IDENTLEN]; FILE *fp = NULL; const char *src = ""; int lineno, last_lineno; lineno = last_lineno = 0; curpath[0] = curtag[0] = '\0'; /* * open tag file. */ gtop = gtags_open(dbpath, root, db, GTAGS_READ, 0); cv = convert_open(type, format, root, cwd, dbpath, stdout); /* * search through tag file. */ if (nofilter & SORT_FILTER) flags |= GTOP_NOSORT; 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; if (format == FORMAT_PATH) flags |= GTOP_PATH; if (gtop->format & GTAGS_COMPACT) ib = strbuf_open(0); for (gtp = gtags_first(gtop, pattern, flags); gtp; gtp = gtags_next(gtop)) { if (lflag && !locatestring(gtp->path, localprefix, MATCH_AT_FIRST)) continue; if (format == FORMAT_PATH) { convert_put_path(cv, gtp->path); count++; } else if (gtop->format & GTAGS_COMPACT) { /* * Compact format: * a b * tagline = <file id> <tag name> <line no>,... */ char *p = (char *)gtp->tagline; const char *fid, *tagname; int n = 0; fid = p; while (*p != ' ') p++; *p++ = '\0'; /* a */ tagname = p; while (*p != ' ') p++; *p++ = '\0'; /* b */ /* * Reopen or rewind source file. */ if (!nosource) { if (strcmp(gtp->path, curpath) != 0) { if (curpath[0] != '\0' && fp != NULL) fclose(fp); strlimcpy(curtag, tagname, sizeof(curtag)); strlimcpy(curpath, gtp->path, sizeof(curpath)); /* * Use absolute path name to support GTAGSROOT * environment variable. */ fp = fopen(makepath(root, curpath, NULL), "r"); if (fp == NULL) warning("source file '%s' is not available.", curpath); last_lineno = lineno = 0; } else if (strcmp(gtp->tag, curtag) != 0) { strlimcpy(curtag, gtp->tag, sizeof(curtag)); if (atoi(p) < last_lineno && fp != NULL) { rewind(fp); lineno = 0; } last_lineno = 0; } } /* * Unfold compact format. */ if (!isdigit(*p)) die("illegal compact format."); if (gtop->format & GTAGS_COMPLINE) { /* * * If GTAGS_COMPLINE flag is set, each line number is expressed as * the difference from the previous line number except for the head. * Please see flush_pool() in libutil/gtagsop.c for the details. */ int last = 0, cont = 0; while (*p || cont > 0) { if (cont > 0) { n = last + 1; if (n > cont) { cont = 0; continue; } } else if (isdigit(*p)) { GET_NEXT_NUMBER(p); } else if (*p == '-') { GET_NEXT_NUMBER(p); cont = n + last; n = last + 1; } else if (*p == ',') { GET_NEXT_NUMBER(p); n += last; } if (last_lineno != n && fp) { while (lineno < n) { if (!(src = strbuf_fgets(ib, fp, STRBUF_NOCRLF))) { src = ""; fclose(fp); fp = NULL; break; } lineno++; } } if (gtop->format & GTAGS_COMPNAME) tagname = (char *)uncompress(tagname, gtp->tag); convert_put_using(cv, tagname, gtp->path, n, src, fid); count++; last_lineno = last = n; } } else { /* * In fact, when GTAGS_COMPACT is set, GTAGS_COMPLINE is allways set. * Therefore, the following code are not actually used. * However, it is left for some test. */ while (*p) { for (n = 0; isdigit(*p); p++) n = n * 10 + *p - '0'; if (*p == ',') p++; if (last_lineno == n) continue; if (last_lineno != n && fp) { while (lineno < n) { if (!(src = strbuf_fgets(ib, fp, STRBUF_NOCRLF))) { src = ""; fclose(fp); fp = NULL; break; } lineno++; } } if (gtop->format & GTAGS_COMPNAME) tagname = (char *)uncompress(tagname, gtp->tag); convert_put_using(cv, tagname, gtp->path, n, src, fid); count++; last_lineno = n; } } } else { /* * Standard format: * a b c * tagline = <file id> <tag name> <line no> <line image> */ char *p = (char *)gtp->tagline; char namebuf[IDENTLEN]; const char *fid, *tagname, *image; fid = p; while (*p != ' ') p++; *p++ = '\0'; /* a */ tagname = p; while (*p != ' ') p++; *p++ = '\0'; /* b */ if (gtop->format & GTAGS_COMPNAME) { strlimcpy(namebuf, (char *)uncompress(tagname, gtp->tag), sizeof(namebuf)); tagname = namebuf; } if (nosource) { image = " "; } else { while (*p != ' ') p++; image = p + 1; /* c + 1 */ if (gtop->format & GTAGS_COMPRESS) image = (char *)uncompress(image, gtp->tag); } convert_put_using(cv, tagname, gtp->path, gtp->lineno, image, fid); count++; } } convert_close(cv); if (sb) strbuf_close(sb); if (ib) strbuf_close(ib); if (fp) fclose(fp); gtags_close(gtop); return count; }