📄 htags.c
字号:
/* * Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 * Tama Communications Corporation * * This file is part of GNU GLOBAL. * * GNU GLOBAL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GNU GLOBAL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#ifdef STDC_HEADERS#include <stdlib.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h>#else#include <sys/file.h>#endif#include <signal.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/param.h>#include <time.h>#include "getopt.h"#include "regex.h"#include "global.h"#include "anchor.h"#include "cache.h"#include "common.h"#include "htags.h"#include "incop.h"#include "path2url.h"#include "const.h"void src2html(const char *, const char *, int);int makedupindex(void);int makedefineindex(const char *, int, STRBUF *);int makefileindex(const char *, STRBUF *);void makeincludeindex();#if defined(_WIN32) && !defined(__CYGWIN__)#define mkdir(path,mode) mkdir(path)#define link(one,two) (-1)#endif/* * Global data. */int w32 = W32; /* Windows32 environment */const char *www = "http://www.gnu.org/software/global/";int file_count = 0;int sep = '/';const char *save_config;const char *save_argv;char cwdpath[MAXPATHLEN];char dbpath[MAXPATHLEN];char distpath[MAXPATHLEN];char gtagsconf[MAXPATHLEN];char datadir[MAXPATHLEN];char sort_path[MAXFILLEN];char gtags_path[MAXFILLEN];char global_path[MAXFILLEN];char findcom[MAXFILLEN];const char *null_device = NULL_DEVICE;const char *tmpdir = "/tmp";/* * options */int aflag; /* --alphabet(-a) option */int cflag; /* --compact(-c) option */int fflag; /* --form(-f) option */int Fflag; /* --frame(-F) option */int nflag; /* --line-number(-n) option */int gflag; /* --gtags(-g) option */int Sflag; /* --secure-cgi(-S) option */int qflag;int vflag; /* --verbose(-v) option */int wflag; /* --warning(-w) option */int debug; /* --debug option */int show_help; /* --help command */int show_version; /* --version command */int caution; /* --caution option */int dynamic; /* --dynamic(-D) option */int symbol; /* --symbol(-s) option */int statistics; /* --statistics option */int copy_files; /* 1: copy tag files */int no_map_file; /* 1: doesn't make map file */int no_order_list; /* 1: doesn't use order list */int other_files; /* 1: list other files */int enable_grep; /* 1: enable grep */int enable_idutils; /* 1: enable idutils */int enable_xhtml; /* 1: enable XHTML */const char *action_value;const char *id_value;const char *cgidir;const char *main_func = "main";const char *style_sheet;const char *cvsweb_url;const char *cvsweb_cvsroot;const char *gtagslabel;const char *title;const char *xhtml_version = "1.0";const char *insert_header; /* --insert-header=<file> */const char *insert_footer; /* --insert-footer=<file> *//* * Constant values. */const char *title_define_index = "DEFINITIONS";const char *title_file_index = "FILES";const char *title_included_from = "INCLUDED FROM";/* * Function header items. */const char *anchor_label[] = { "<", ">", "^", "v", "top", "bottom", "index", "help"};const char *anchor_icons[] = { "left", "right", "first", "last", "top", "bottom", "index", "help"};const char *anchor_comment[] = { "previous", "next", "first", "last", "top", "bottom", "index", "help"};const char *anchor_msg[] = { "Previous definition.", "Next definition.", "First definition in this file.", "Last definition in this file.", "Top of this file.", "Bottom of this file.", "Return to index page.", "You are seeing now."};const char *back_icon = "back";const char *dir_icon = "dir";const char *c_icon = "c";const char *file_icon = "text";/* * Configuration parameters. */int ncol = 4; /* columns of line number */int tabs = 8; /* tab skip */char stabs[8]; /* tab skip (string) */int full_path = 0; /* file index format */int map_file = 1; /* 1: create MAP file */const char *icon_list = NULL; /* use icon list */const char *icon_suffix = "png"; /* icon suffix (jpg, png etc) */const char *icon_spec = "border='0' align='top'";/* parameter in IMG tag*/const char *prolog_script = NULL; /* include script at first */const char *epilog_script = NULL; /* include script at last */int show_position = 0; /* show current position */int table_list = 0; /* tag list using table tag */int colorize_warned_line = 0; /* colorize warned line */const char *script_alias = "/cgi-bin"; /* script alias of WWW server */const char *gzipped_suffix = "ghtml"; /* suffix of gzipped html file */const char *normal_suffix = "html"; /* suffix of normal html file */const char *HTML;const char *action = "cgi-bin/global.cgi";/* default action */const char *saction; /* safe action */const char *id = NULL; /* id (default non) */int cgi = 1; /* 1: make cgi-bin/ */int definition_header=NO_HEADER; /* (NO|BEFORE|RIGHT|AFTER)_HEADER */const char *htags_options = NULL;const char *include_file_suffixes = "h,hxx,hpp,H,inc.php";static const char *langmap = DEFAULTLANGMAP;static struct option const long_options[] = { {"alphabet", no_argument, NULL, 'a'}, {"compact", no_argument, NULL, 'c'}, {"dynamic", no_argument, NULL, 'D'}, {"dbpath", required_argument, NULL, 'd'}, {"form", no_argument, NULL, 'f'}, {"frame", no_argument, NULL, 'F'}, {"gtags", no_argument, NULL, 'g'}, {"main-func", required_argument, NULL, 'm'}, {"line-number", no_argument, NULL, 'n'}, {"other", no_argument, NULL, 'o'}, {"symbol", no_argument, NULL, 's'}, {"secure-cgi", required_argument, NULL, 'S'}, {"title", required_argument, NULL, 't'}, {"verbose", no_argument, NULL, 'v'}, {"warning", no_argument, NULL, 'w'}, {"xhtml", no_argument, NULL, 'x'}, /* long name only */ {"action", required_argument, NULL, 1}, {"cvsweb", required_argument, NULL, 1}, {"cvsweb-cvsroot", required_argument, NULL, 1}, {"caution", no_argument, &caution, 1}, {"debug", no_argument, &debug, 1}, {"gtagsconf", required_argument, NULL, 1}, {"gtagslabel", required_argument, NULL, 1}, {"id", required_argument, NULL, 1}, {"nocgi", no_argument, NULL, 1}, {"no-map-file", no_argument, &no_map_file, 1}, {"insert-header", required_argument, NULL, 1}, {"insert-footer", required_argument, NULL, 1}, {"statistics", no_argument, &statistics, 1}, {"style-sheet", required_argument, NULL, 1}, {"version", no_argument, &show_version, 1}, {"help", no_argument, &show_help, 1}, { 0 }};static voidusage(void){ if (!qflag) fputs(usage_const, stderr); exit(2);}static voidhelp(void){ fputs(usage_const, stdout); fputs(help_const, stdout); exit(0);}/* * Htags catch signal even if the parent ignore it. */voidclean(void){ unload_gpath(); cache_close();}/* * Signal handler. * * This handler is set up in signal_setup(). */static voidsuddenly(signo) int signo;{ signo = 0; /* to satisfy compiler */ clean(); exit(1);}/* * Setup signal hander. */static voidsignal_setup(void){ signal(SIGINT, suddenly); signal(SIGTERM, suddenly);#ifdef SIGHUP signal(SIGHUP, suddenly);#endif#ifdef SIGQUIT signal(SIGQUIT, suddenly);#endif}/* * generate_file: generate file with replacing macro. * * i) dist directory where the file should be created * i) file file name */static voidgenerate_file(dist, file) const char *dist; const char *file;{ regex_t preg; regmatch_t pmatch[2]; STRBUF *sb = strbuf_open(0); FILE *ip, *op; char *_; int i; struct map { const char *name; const char *value; } tab[] = { /* dynamic initialization */ {"@page_begin@", NULL}, {"@page_end@", NULL}, {"@lineno_anchor@", NULL}, /* static initialization */ {"@body_begin@", body_begin}, {"@body_end@", body_end}, {"@title_begin@", title_begin}, {"@title_end@", title_end}, {"@error_begin@", error_begin}, {"@error_end@", error_end}, {"@message_begin@", message_begin}, {"@message_end@", message_end}, {"@verbatim_begin@", verbatim_begin}, {"@verbatim_end@", verbatim_end}, {"@global_path@", global_path}, {"@gtags_path@", gtags_path}, {"@normal_suffix@", normal_suffix}, {"@tabs@", stabs}, {"@hr@", hr}, {"@br@", br}, {"@HTML@", HTML}, {"@action@", action}, {"@null_device@", null_device}, {"@globalpath@", global_path}, {"@gtagspath@", gtags_path}, }; int tabsize = sizeof(tab) / sizeof(struct map); tab[0].value = gen_page_begin("Result", SUBDIR); tab[1].value = gen_page_end(); tab[2].value = gen_name_string("L$."); /* * construct regular expression. */ strbuf_putc(sb, '('); for (i = 0; i < tabsize; i++) { strbuf_puts(sb, tab[i].name); strbuf_putc(sb, '|'); } strbuf_unputc(sb, '|'); strbuf_putc(sb, ')'); if (regcomp(&preg, strbuf_value(sb), REG_EXTENDED) != 0) die("cannot compile regular expression."); /* * construct skeleton file name in the system datadir directory. */ strbuf_reset(sb); strbuf_sprintf(sb, "%s/gtags/%s.tmpl", datadir, file); ip = fopen(strbuf_value(sb), "r"); if (!ip) die("skeleton file '%s' not found.", strbuf_value(sb)); op = fopen(makepath(dist, file, NULL), "w"); if (!op) die("cannot create file '%s'.", file); strbuf_reset(sb); /* * Read templete file and evaluate macros. */ while ((_ = strbuf_fgets(sb, ip, STRBUF_NOCRLF)) != NULL) { const char *p; /* Pick up macro name */ for (p = _; !regexec(&preg, p, 2, pmatch, 0); p += pmatch[0].rm_eo) { const char *start = p + pmatch[0].rm_so; int length = pmatch[0].rm_eo - pmatch[0].rm_so; /* print before macro */ for (i = 0; i < pmatch[0].rm_so; i++) fputc(p[i], op); for (i = 0; i < tabsize; i++) if (!strncmp(start, tab[i].name, length)) break; if (i >= tabsize) die("something wrong."); /* print macro value */ if (i < tabsize) { const char *q; /* * Double quote should be quoted using '\\'. */ for (q = tab[i].value; *q; q++) { if (*q == '"') fputc('\\', op); else if (*q == '\n') fputc('\\', op); fputc(*q, op); } } } fputs_nl(p, op); } fclose(op); fclose(ip); strbuf_close(sb); regfree(&preg); file_count++;}/* * makeprogram: make CGI program */static voidmakeprogram(cgidir, file) const char *cgidir; const char *file;{ generate_file(cgidir, file);}/* * makebless: make bless.sh file. */static voidmakebless(file) const char *file;{ const char *save = action; action = saction; generate_file(distpath, file); action = save;}/* * makeghtml: make ghtml.cgi file. * * i) cgidir directory where the file should be created * i) file file name */static voidmakeghtml(cgidir, file) const char *cgidir; const char *file;{ FILE *op; op = fopen(makepath(cgidir, file, NULL), "w"); if (!op) die("cannot make unzip script."); fputs_nl("#!/bin/sh", op); fputs_nl("echo \"content-type: text/html\"", op); fputs_nl("echo", op); fprintf(op, "gzip -S %s -d -c \"$PATH_TRANSLATED\"\n", HTML); fclose(op);}/* * makerebuild: make rebuild script */static voidmakerebuild(file) const char *file;{ FILE *op; op = fopen(makepath(distpath, file, NULL), "w"); if (!op) die("cannot make rebuild script."); fputs_nl("#!/bin/sh", op); fputs_nl("#", op); fputs_nl("# rebuild.sh: rebuild hypertext with the previous context.", op); fputs_nl("#", op); fputs_nl("# Usage:", op); fputs_nl("#\t% sh rebuild.sh", op); fputs_nl("#", op); fprintf(op, "cd %s && GTAGSCONF='%s' htags%s\n", cwdpath, save_config, save_argv); fclose(op);}/* * makehelp: make help file */static voidmakehelp(file) const char *file;{ const char **label = icon_list ? anchor_comment : anchor_label; const char **icons = anchor_icons; const char **msg = anchor_msg; int n, last = 7; FILE *op; op = fopen(makepath(distpath, file, NULL), "w"); if (!op) die("cannot make help file."); fputs_nl(gen_page_begin("HELP", TOPDIR), op); fputs_nl(body_begin, op); fputs(header_begin, op); fputs("Usage of Links", op); fputs_nl(header_end, op); if (!icon_list) fputs(verbatim_begin, op); fputs("/* ", op); for (n = 0; n <= last; n++) { if (icon_list) { fputs(gen_image(CURRENT, icons[n], label[n]), op); if (n < last)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -