📄 src2html.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#include <ctype.h>#include "global.h"#include "anchor.h"#include "cache.h"#include "common.h"#include "incop.h"#include "path2url.h"#include "htags.h"/*----------------------------------------------------------------------*//* Parser switch *//*----------------------------------------------------------------------*//* * This is the linkage section of each parsers. * If you want to support new language, you must define two procedures: * 1. Initializing procedure. * Called once first with an input file descripter. * 2. Executing procedure. * Called repeatedly until returning EOF. * It should read from above descripter and write HTML * using output procedures in this module. */struct lang_entry { const char *lang_name; void (*init_proc)(FILE *); /* initializing procedure */ int (*exec_proc)(void); /* executing procedure */};/* initializing procedures */void c_parser_init(FILE *);void yacc_parser_init(FILE *);void cpp_parser_init(FILE *);void java_parser_init(FILE *);void php_parser_init(FILE *);void asm_parser_init(FILE *);/* executing procedures */int c_lex(void);int cpp_lex(void);int java_lex(void);int php_lex(void);int asm_lex(void);/* * The first entry is default language. */struct lang_entry lang_switch[] = { /* lang_name init_proc exec_proc */ {"c", c_parser_init, c_lex}, /* DEFAULT */ {"yacc", yacc_parser_init, c_lex}, {"cpp", cpp_parser_init, cpp_lex}, {"java", java_parser_init, java_lex}, {"php", php_parser_init, php_lex}, {"asm", asm_parser_init, asm_lex}};#define DEFAULT_ENTRY &lang_switch[0]/* * get language entry. * * i) lang language name (NULL means 'not specified'.) * r) language entry */static struct lang_entry *get_lang_entry(lang) const char *lang;{ int i, size = sizeof(lang_switch) / sizeof(struct lang_entry); /* * if language not specified, it assumes default language. */ if (lang == NULL) return DEFAULT_ENTRY; for (i = 0; i < size; i++) if (!strcmp(lang, lang_switch[i].lang_name)) return &lang_switch[i]; /* * if specified language not found, it assumes default language. */ return DEFAULT_ENTRY;}/*----------------------------------------------------------------------*//* Input/Output *//*----------------------------------------------------------------------*//* * Input/Output descriptor. */static FILE *out;static FILE *in;STATIC_STRBUF(outbuf);static const char *curpfile;static int warned;static int last_lineno;/* * Open source file. * * i) file source file name * r) file pointer */static FILE *open_input_file(file) const char *file;{ FILE *ip; ip = fopen(file, "r"); if (!ip) die("cannot open file '%s'.", file); curpfile = file; warned = 0; return ip;}/* * Close source file. */static voidclose_input_file(ip) FILE *ip;{ fclose(ip);}/* * Open HTML file. * * i) file HTML file name * r) file pointer */static FILE *open_output_file(file) const char *file;{ char command[MAXFILLEN]; FILE *op; if (cflag) { snprintf(command, sizeof(command), "gzip -c >%s", file); op = popen(command, "w"); if (!op) die("cannot execute '%s'.", command); } else { op = fopen(file, "w"); if (!op) die("cannot create file '%s'.", file); } strbuf_clear(outbuf); return op;}/* * Close HTML file. */static voidclose_output_file(op) FILE *op;{ if (cflag) { if (pclose(op) != 0) die("command 'gzip -c' failed."); } else fclose(op);}/* * Put a character to HTML as is. * * You should use this function to put a control character. */voidechoc(c) int c;{ strbuf_putc(outbuf, c);}/* * Put a string to HTML as is. * * You should use this function to put a control sequence. */voidechos(s) const char *s;{ strbuf_puts(outbuf, s);}/*----------------------------------------------------------------------*//* HTML output *//*----------------------------------------------------------------------*//* * fill_anchor: fill anchor into file name * * i) $root root or index page * i) $path path name * r) hypertext file name string */const char *fill_anchor(root, path) const char *root; const char *path;{ STATIC_STRBUF(sb); char buf[MAXBUFLEN], *limit, *p; strbuf_clear(sb); strlimcpy(buf, path, sizeof(buf)); for (p = buf; *p; p++) if (*p == sep) *p = '\0'; limit = p; strbuf_sprintf(sb, "%sroot%s/", gen_href_begin_simple(root), gen_href_end()); { const char *next; for (p = buf; p < limit; p += strlen(p) + 1) { const char *path = buf; const char *unit = p; next = p + strlen(p) + 1; if (next > limit) { strbuf_puts(sb, unit); break; } if (p > buf) *(p - 1) = sep; strbuf_puts(sb, gen_href_begin("../files", path2fid(path), HTML, NULL)); strbuf_puts(sb, unit); strbuf_puts(sb, gen_href_end()); strbuf_putc(sb, '/'); } } return strbuf_value(sb);}/* * link_format: make hypertext from anchor array. * * i) (previous, next, first, last, top, bottom) * -1: top, -2: bottom, other: line number * r) HTML */const char *link_format(ref) int ref[A_SIZE];{ STATIC_STRBUF(sb); const char **label = icon_list ? anchor_comment : anchor_label; const char **icons = anchor_icons; int i; strbuf_clear(sb); for (i = 0; i < A_LIMIT; i++) { if (i == A_INDEX) { strbuf_puts(sb, gen_href_begin("..", "mains", normal_suffix, NULL)); } else if (i == A_HELP) { strbuf_puts(sb, gen_href_begin("..", "help", normal_suffix, NULL)); } else if (ref[i]) { char tmp[32], *key = tmp; if (ref[i] == -1) key = "TOP"; else if (ref[i] == -2) key = "BOTTOM"; else snprintf(tmp, sizeof(tmp), "%d", ref[i]); strbuf_puts(sb, gen_href_begin(NULL, NULL, NULL, key)); } if (icon_list) { char tmp[MAXPATHLEN]; snprintf(tmp, sizeof(tmp), "%s%s", (i != A_INDEX && i != A_HELP && ref[i] == 0) ? "n_" : "", icons[i]); strbuf_puts(sb, gen_image(PARENT, tmp, label[i])); } else { strbuf_sprintf(sb, "[%s]", label[i]); } if (i == A_INDEX || i == A_HELP || ref[i] != 0) strbuf_puts(sb, gen_href_end()); } return strbuf_value(sb);}/* * generate_guide: generate guide string for definition line. * * i) lineno line number * r) guide string */const char *generate_guide(lineno) int lineno;{ STATIC_STRBUF(sb); int i = 0; strbuf_clear(sb); if (definition_header == RIGHT_HEADER) i = 4; else if (nflag) i = ncol + 1; if (i > 0) for (; i > 0; i--) strbuf_putc(sb, ' '); strbuf_sprintf(sb, "%s/* ", comment_begin); strbuf_puts(sb, link_format(anchor_getlinks(lineno))); if (show_position) strbuf_sprintf(sb, "%s[+%d %s]%s", position_begin, lineno, curpfile, position_end); strbuf_sprintf(sb, " */%s", comment_end); return strbuf_value(sb);}/* * tooltip: generate tooltip string * * i) type I,R,Y,D,M * i) lno line number * i) opt * r) tooltip string */const char *tooltip(type, lno, opt) int type; int lno; const char *opt;{ STATIC_STRBUF(sb); strbuf_clear(sb); if (lno > 0) { if (type == 'I') strbuf_puts(sb, "Included from"); else if (type == 'R') strbuf_puts(sb, "Defined at"); else if (type == 'Y') strbuf_puts(sb, "Used at"); else strbuf_puts(sb, "Refered from"); strbuf_putc(sb, ' '); strbuf_putn(sb, lno); if (opt) { strbuf_puts(sb, " in "); strbuf_puts(sb, opt); } } else { strbuf_puts(sb, "Multiple "); if (type == 'I') strbuf_puts(sb, "included from"); else if (type == 'R') strbuf_puts(sb, "defined in"); else if (type == 'Y') strbuf_puts(sb, "used in"); else strbuf_puts(sb, "refered from"); strbuf_putc(sb, ' '); strbuf_puts(sb, opt); strbuf_putc(sb, ' '); strbuf_puts(sb, "places"); } strbuf_putc(sb, '.'); return strbuf_value(sb);}/* * put_anchor: output HTML anchor. * * i) name tag * i) type tag type * i) lineno current line no */voidput_anchor(name, type, lineno) char *name; int type; int lineno;{ const char *line; int db; if (type == 'R') db = GTAGS; else if (type == 'Y') db = GSYMS; else /* 'D', 'M' or 'T' */ db = GRTAGS; line = cache_get(db, name); if (line == NULL) { if ((type == 'R' || type == 'Y') && wflag) { warning("%s %d %s(%c) found but not defined.", curpfile, lineno, name, type); if (colorize_warned_line) warned = 1; } strbuf_puts(outbuf, name); } else { /* * About cache record format, please see the comment in cache.c. */ if (*line == ' ') { char tmp[MAXPATHLEN]; const char *id = strmake(++line, " "); const char *count = locatestring(line, " ", MATCH_FIRST) + 1; const char *dir, *file, *suffix = NULL; if (dynamic) { const char *s; dir = (*action == '/') ? NULL : ".."; if (db == GTAGS) s = "definitions"; else if (db == GRTAGS) s = "reference"; else s = "symbol"; snprintf(tmp, sizeof(tmp), "%s?pattern=%s%stype=%s", action, name, quote_amp, s); file = tmp; } else { if (type == 'R') dir = upperdir(DEFS); else if (type == 'Y') dir = upperdir(SYMS); else /* 'D', 'M' or 'T' */ dir = upperdir(REFS); file = id; suffix = HTML; } strbuf_puts(outbuf, gen_href_begin_with_title(dir, file, suffix, NULL, tooltip(type, -1, count))); strbuf_puts(outbuf, name); strbuf_puts(outbuf, gen_href_end()); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -