Example #1
0
static strbuf inline _overrun_quote(strbuf sb, char quote, const char *suffix)
{
  if (strbuf_overrun(sb)) {
    strbuf_trunc(sb, -strlen(suffix) - 1);
    strbuf_putc(sb, quote);
    strbuf_puts(sb, suffix);
  }
  return sb;
}
Example #2
0
void logArgv(int level, struct __sourceloc where, const char *label, int argc, const char *const *argv)
{
    if (_log_prepare(level, where)) {
        if (label) {
            strbuf_puts(&logbuf, label);
            strbuf_putc(&logbuf, ' ');
        }
        int i;
        for (i = 0; i < argc; ++i) {
            if (i)
                strbuf_putc(&logbuf, ' ');
            if (argv[i])
                strbuf_toprint_quoted(&logbuf, "\"\"", argv[i]);
            else
                strbuf_puts(&logbuf, "NULL");
        }
        _log_finish(level);
    }
}
Example #3
0
/**
 * append @CODE{'/'} after the path name
 *
 *	@param[in]	path	path name
 *	@return		appended path name
 *
 *	@note Doesn't check if ends with a @CODE{'/'} already.
 *
 * @par Examples:
 * @code
 * appendslash("a")	=> "a/"
 * @endcode
 */
static const char *
appendslash(const char *path)
{
	STATIC_STRBUF(sb);

	strbuf_clear(sb);
	strbuf_puts(sb, path);
	strbuf_putc(sb, '/');
	return strbuf_value(sb);
}
Example #4
0
/*
 * makefileurl: make url which start with 'file:'.
 *
 *	i)	path	path name (absolute)
 *	i)	line	!=0: line number
 *	o)	url	URL
 *
 * makefileurl('/dir/a.html', 10)   => 'file:///dir/a.html#L10'
 *
 * (Windows32 environment)
 * makefileurl('c:/dir/a.html', 10) => 'file://c|/dir/a.html#L10'
 */
void
makefileurl(const char *path, int line, STRBUF *url)
{
	strbuf_puts(url, "file://");
#if _WIN32 || __DJGPP__
	/*
	 * copy drive name. (c: -> c|)
	 */
	if (isalpha(*path) && *(path+1) == ':') {
		strbuf_putc(url, *path);
		strbuf_putc(url, '|');
		path += 2;
	}
#endif
	strbuf_puts(url, path);
	if (line) {
		strbuf_puts(url, "#L");
		strbuf_putn(url, line);
	}
}
Example #5
0
/**
 * print file name.
 *
 *	@param[in]	level	0,1,2...
 *	@param[in]	path	path of the file
 */
static const char *
print_file_name(int level, const char *path)
{
	STATIC_STRBUF(sb);
	char *target = (Fflag) ? "mains" : "_top";
	int size = filesize(path);
	char tips[80];

	message(" [%d] adding %s", ++src_count, removedotslash(path));
	/*
	 * We assume the file which has one of the following suffixes
	 * as a candidate of include file.
	 *
	 * C: .h
	 * C++: .hxx, .hpp, .H, .hh
	 * PHP: .inc.php
	 */
	if (regexec(&is_include_file, path, 0, 0, 0) == 0)
		put_inc(lastpart(path), path, src_count);
	strbuf_clear(sb);
	if (table_flist)
		strbuf_puts(sb, fitem_begin);
	else if (!no_order_list)
		strbuf_puts(sb, item_begin);
	if (size > 1)
		snprintf(tips, sizeof(tips), "%s bytes", insert_comma(size));
	else
		snprintf(tips, sizeof(tips), "%s byte", insert_comma(size));
	strbuf_puts(sb, gen_href_begin_with_title_target(level == 0 ? SRCS: upperdir(SRCS),
			path2fid(path), HTML, NULL, tips, target));
	if (Iflag) {
		const char *lang, *suffix, *text_icon;

		if ((suffix = locatestring(path, ".", 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(level == 0 ? CURRENT : PARENT, text_icon, removedotslash(path)));
		strbuf_puts(sb, quote_space);
	}
	strbuf_puts(sb, full_path ? removedotslash(path) : lastpart(path));
	strbuf_puts(sb, gen_href_end());
	if (table_flist)
		strbuf_puts(sb, fitem_end);
	else if (!no_order_list)
		strbuf_puts(sb, item_end);
	else
		strbuf_puts(sb, br);
	strbuf_putc(sb, '\n');
	return (const char *)strbuf_value(sb);
}
Example #6
0
strbuf strbuf_append_poll_events(strbuf sb, short events)
{
  static struct { short flags; const char *name; } symbols[] = {
      { POLLIN, "IN" },
      { POLLPRI, "PRI" },
      { POLLOUT, "OUT" },
      { POLLERR, "ERR" },
      { POLLHUP, "HUP" },
      { POLLNVAL, "NVAL" },
      { POLLRDNORM, "RDNORM" },
      { POLLRDBAND, "RDBAND" },
#ifdef POLLWRNORM
      { POLLWRNORM, "WRNORM" },
#endif
#ifdef POLLWRBAND
      { POLLWRBAND, "WRBAND" },
#endif
#ifdef POLLMSG
      { POLLMSG, "MSG" },
#endif
#ifdef POLLREMOVE
      { POLLREMOVE, "REMOVE" },
#endif
#ifdef POLLRDHUP
      { POLLRDHUP, "RDHUP" },
#endif
      { 0, NULL }
    }, *sp;
  int n = 0;
  for (sp = symbols; sp->name; ++sp) {
    if (events & sp->flags) {
      if (n)
	strbuf_putc(sb, '|');
      strbuf_puts(sb, sp->name);
      ++n;
    }
  }
  if (!n)
    strbuf_putc(sb, '0');
  return sb;
}
Example #7
0
/*
 * convertpath: convert source file into hypertext path.
 *
 *	i)	dbpath	dbpath
 *	i)	htmldir	HTML directory made by htags(1)
 *	i)	path	source file path
 *	o)	sb	string buffer
 *	r)		0: normal, -1: error
 */
int
convertpath(const char *dbpath, const char *htmldir, const char *path, STRBUF *sb)
{
	static const char *suffix[] = {".html", ".htm"};
	static const char *gz = ".gz";
	int i, lim = sizeof(suffix)/sizeof(char *);
	const char *p;

	strbuf_reset(sb);
	strbuf_puts(sb, htmldir);
	strbuf_puts(sb, "/S/");
	/*
	 * new style.
	 */
	if (gpath_open(dbpath, 0) == 0) {
		int tag1 = strbuf_getlen(sb);

		p = gpath_path2fid(path, NULL);
		if (p == NULL) {
			gpath_close();
			return -1;
		}
		gpath_close();
		strbuf_puts(sb, p);
		for (i = 0; i < lim; i++) {
			int tag2 = strbuf_getlen(sb);
			strbuf_puts(sb, suffix[i]);
			if (test("f", strbuf_value(sb)))
				return 0;
			strbuf_puts(sb, gz);
			if (test("f", strbuf_value(sb)))
				return 0;
			strbuf_setlen(sb, tag2);
		}
		strbuf_setlen(sb, tag1);
	}
	/*
	 * old style.
	 */
	for (p = path + 1; *p; p++)
		strbuf_putc(sb, (*p == '/') ? ' ' : *p);
	for (i = 0; i < lim; i++) {
		int tag = strbuf_getlen(sb);
		strbuf_puts(sb, suffix[i]);
		if (test("f", strbuf_value(sb)))
			return 0;
		strbuf_puts(sb, gz);
		if (test("f", strbuf_value(sb)))
			return 0;
		strbuf_setlen(sb, tag);
	}
	return -1;
}
Example #8
0
/*
 * decode_path: decode encoded path name.
 *
 *	i)	path	encoded path name
 *	r)		decoded path name
 */
char *
decode_path(const unsigned char *path)
{
	STATIC_STRBUF(sb);
	const unsigned char *p;

	if (strchr((const char *)path, '%') == NULL)
		return (char *)path;
	strbuf_clear(sb);
	for (p = path; *p; p++) {
		if (*p == '%') {
			unsigned char c1, c2;
			c1 = *++p;
			c2 = *++p;
			if (outofrange(c1) || outofrange(c2))
				die("decode_path: unexpected character. (%%%c%c)", c1, c2);
			strbuf_putc(sb, h2int(c1) * 16 + h2int(c2));
		} else
			strbuf_putc(sb, *p);
	}
	return strbuf_value(sb);
}
Example #9
0
/*
 * Update tag files.
 */
static void
update(void)
{
	STATIC_STRBUF(command);

	strbuf_clear(command);
	strbuf_sprintf(command, "%s -u", global_path);
	if (vflag) {
		strbuf_putc(command, 'v');
		fprintf(stderr, "gscope: %s\n", strbuf_value(command));
	}
	system(strbuf_value(command));
}
Example #10
0
/**
 * makedirectories: make directories on the path like @XREF{mkdir,1} with the @OPTION{-p} option.
 *
 *	@param[in]	base	base directory
 *	@param[in]	rest	path from the base
 *	@param[in]	verbose 1: verbose mode, 0: not verbose mode
 *	@return		0: success <br>
 *			-1: base directory not found <br>
 *			-2: permission error <br>
 *			-3: cannot make directory
 */
int
makedirectories(const char *base, const char *rest, int verbose)
{
	STRBUF *sb;
	const char *p, *q;

	if (!test("d", base))
		return -1;
	if (!test("drw", base))
		return -2;
	sb = strbuf_open(0);
	strbuf_puts(sb, base);
	if (*rest == SEP)
		rest++;
	for (q = rest; *q;) {
		p = q;
		while (*q && *q != SEP)
			q++;
		strbuf_putc(sb, SEP);
		strbuf_nputs(sb, p, q - p);
		p = strbuf_value(sb);
		if (!test("d", p)) {
			if (verbose)
				fprintf(stderr, " Making directory '%s'.\n", p);
#if defined(_WIN32) && !defined(__CYGWIN__)
			if (mkdir(p) < 0) {
#else
			if (mkdir(p, 0775) < 0) {
#endif /* WIN32 */
				strbuf_close(sb);
				return -3;
			}
		}
		if (*q == SEP)
			q++;
	}
	strbuf_close(sb);
	return 0;
}
/**
 * trimpath: trim path name
 */
const char *
trimpath(const char *path)
{
	if (*path == '.' && *(path + 1) == '/')
		path += 2;
	return path;
}
Example #11
0
/**
 * strtrim: make string from original string with deleting blanks.
 *
 *	@param[in]	p	original string.
 *	@param[in]	flag	TRIM_HEAD:	from only head,
 *			TRIM_TAIL:	from only tail,
 *			TRIM_BOTH:	from head and tail,
 *			TRIM_ALL:	from all
 *	@param[out]	len	length of result string,
 *			if len == NULL then nothing returned.
 *	@return		result string
 *
 * Usage:
 *	strtrim(" # define ", TRIM_HEAD, NULL)	=> "# define "
 *	strtrim(" # define ", TRIM_TAIL, NULL)	=> " # define"
 *	strtrim(" # define ", TRIM_BOTH, NULL)	=> "# define"
 *	strtrim(" # define ", TRIM_ALL, NULL)	=> "#define"
 *
 * [Note] The result string area is function local. So, following call
 *	 to this function may destroy the area.
 */
const char *
strtrim(const char *p, int flag, int *len)
{
	STATIC_STRBUF(sb);
	int cut_off = -1;

	strbuf_clear(sb);
	/*
	 * Delete blanks of the head.
	 */
	if (flag != TRIM_TAIL)
		SKIP_BLANKS(p);
	/*
	 * Copy string.
	 */
	for (; *p; p++) {
		if (isspace(*p)) {
			if (flag != TRIM_ALL) {
				if (cut_off == -1 && flag != TRIM_HEAD)
					cut_off = strbuf_getlen(sb);
				strbuf_putc(sb,*p);
			}
		} else {
			strbuf_putc(sb,*p);
			cut_off = -1;
		}
	}
	/*
	 * Delete blanks of the tail.
	 */
	if (cut_off != -1)
		strbuf_setlen(sb, cut_off);
	if (len)
		*len = strbuf_getlen(sb);
	return strbuf_value(sb);
}
Example #12
0
// Convert an inline list to HTML.  Returns 0 on success, and sets result.
static void inlines_to_plain_html(strbuf *html, node_inl* ils)
{
	node_inl* children;
	bool visit_children;
	render_stack* rstack = NULL;

	while(ils != NULL) {
		visit_children = false;
		switch(ils->tag) {
		case INL_STRING:
		case INL_CODE:
		case INL_RAW_HTML:
			escape_html(html, ils->content.literal.data, ils->content.literal.len);
			break;

		case INL_LINEBREAK:
		case INL_SOFTBREAK:
			strbuf_putc(html, '\n');
			break;

		case INL_LINK:
		case INL_IMAGE:
			children = ils->content.linkable.label;
			visit_children = true;
			rstack = push_inline(rstack, ils->next, "");
			break;

		case INL_STRONG:
		case INL_EMPH:
			children = ils->content.inlines;
			visit_children = true;
			rstack = push_inline(rstack, ils->next, "");
			break;
		}
		if (visit_children) {
			ils = children;
		} else {
			ils = ils->next;
		}
		while (ils == NULL && rstack != NULL) {
			strbuf_puts(html, rstack->literal);
			ils = rstack->next_sibling.inl;
			rstack = pop_render_stack(rstack);
		}
	}

	free_render_stack(rstack);
}
Example #13
0
/**
 * strmake: make string from original string with limit character.
 *
 *	@param[in]	p	original string.
 *	@param[in]	lim	limitter
 *	@return		result string
 *
 * Usage:
 *	strmake("aaa:bbb", ":/=")	=> "aaa"
 *
 * [Note] The result string area is function local. So, following call
 *	 to this function may destroy the area.
 */
const char *
strmake(const char *p, const char *lim)
{
	STATIC_STRBUF(sb);
	const char *c;

	strbuf_clear(sb);
	for (; *p; p++) {
		for (c = lim; *c; c++)
			if (*p == *c)
				goto end;
		strbuf_putc(sb,*p);
	}
end:
	return strbuf_value(sb);
}
Example #14
0
static inline strbuf _toprint(strbuf sb, char c)
{
  if (c == '\0')
    strbuf_puts(sb, "\\0");
  else if (c == '\n')
    strbuf_puts(sb, "\\n");
  else if (c == '\r')
    strbuf_puts(sb, "\\r");
  else if (c == '\t')
    strbuf_puts(sb, "\\t");
  else if (c == '\\')
    strbuf_puts(sb, "\\\\");
  else if (c >= ' ' && c <= '~')
    strbuf_putc(sb, c);
  else
    strbuf_sprintf(sb, "\\x%02x", c);
  return sb;
}
Example #15
0
/**
 * Check and fix an attribute's value; convert all @c ' (single quote) characters
 * into @CODE{\&\#39;} within it.
 */
static const char *
fix_attr_value(const char *value)
{
    STATIC_STRBUF(sb);
    char c;
    const char *cptr;

    strbuf_clear(sb);
    cptr = value;

    while((c = *cptr) != '\0') {
        if(c == ATTR_DELIM)
            strbuf_puts(sb, "&#39;");
        else
            strbuf_putc(sb, c);
        ++cptr;
    }
    return strbuf_value(sb);
}
Example #16
0
static int
single_select_callback(void *v, int argc, char **argv, char **colname) {
	STATIC_STRBUF(sb);
	DBOP *dbop = (DBOP *)v;

	if (argc > 0) {
		strbuf_clear(sb);
		strbuf_puts(sb, argv[0]);
		dbop->lastsize = strbuf_getlen(sb);
		if (argv[1]) {
			strbuf_putc(sb, '\0');
			strbuf_puts(sb, argv[1]);
		}
		dbop->lastdat = strbuf_value(sb);
		dbop->lastflag = argv[1] ? dbop->lastdat + dbop->lastsize + 1 : NULL;
	} else {
		dbop->lastdat = NULL;
		dbop->lastflag = NULL;
		dbop->lastsize = 0;
	}
	return SQLITE_OK;
}
Example #17
0
/**
 * includelabel: procedure for tc= (or include=)
 *
 *	@param[in]	fp	file pointer
 *	@param[out]	sb	string buffer
 *	@param[in]	label	record label
 *	@param[in]	level	nest level for check
 *
 * This function may call itself (recursive)
 */
static void
includelabel(FILE *fp, STRBUF *sb, const char *label, int level)
{
	const char *savep, *p, *q;
	char *file;

	if (++level > allowed_nest_level)
		die("nested include= (or tc=) over flow.");
	/*
	 * Label can include a '@' and a following path name.
	 * Label: <label>[@<path>]
	 */
	if ((file = locatestring(label, "@", MATCH_FIRST)) != NULL) {
		*file++ = '\0';
		if ((p = makepath_with_tilde(file)) == NULL)
			die("config file must be absolute path. (%s)", file);
		fp = fopen(p, "r");
		if (fp == NULL)
			die("cannot open config file. (%s)", p);
	}
	if (!(savep = p = readrecord(fp, label)))
		die("label '%s' not found.", label);
	while ((q = locatestring(p, ":include=", MATCH_FIRST)) || (q = locatestring(p, ":tc=", MATCH_FIRST))) {
		STRBUF *inc = strbuf_open(0);

		strbuf_nputs(sb, p, q - p);
		q = locatestring(q, "=", MATCH_FIRST) + 1;
		for (; *q && *q != ':'; q++)
			strbuf_putc(inc, *q);
		includelabel(fp, sb, strbuf_value(inc), level);
		p = q;
		strbuf_close(inc);
	}
	strbuf_puts(sb, p);
	free((void *)savep);
	if (file)
		fclose(fp);
}
Example #18
0
/**
 * includelabel: procedure for @CODE{tc=} (or @CODE{include=})
 *
 *	@param[out]	sb	string buffer
 *	@param[in]	label	record label
 *	@param[in]	level	nest level for check
 */
static void
includelabel(STRBUF *sb, const char *label, int	level)
{
	const char *savep, *p, *q;

	if (++level > allowed_nest_level)
		die("nested include= (or tc=) over flow.");
	if (!(savep = p = readrecord(label)))
		die("label '%s' not found.", label);
	while ((q = locatestring(p, ":include=", MATCH_FIRST)) || (q = locatestring(p, ":tc=", MATCH_FIRST))) {
		STRBUF *inc = strbuf_open(0);

		strbuf_nputs(sb, p, q - p);
		q = locatestring(q, "=", MATCH_FIRST) + 1;
		for (; *q && *q != ':'; q++)
			strbuf_putc(inc, *q);
		includelabel(sb, strbuf_value(inc), level);
		p = q;
		strbuf_close(inc);
	}
	strbuf_puts(sb, p);
	free((void *)savep);
}
Example #19
0
static void _log_prefix(_log_iterator *it, int level)
{
  if (it->config == &config_file) {
    if (strbuf_is_empty(&_log_file_strbuf))
      strbuf_init(&_log_file_strbuf, _log_file_buf, sizeof _log_file_buf);
    else if (strbuf_len(&_log_file_strbuf))
      strbuf_putc(&_log_file_strbuf, '\n');
    it->xpf = XPRINTF_STRBUF(&_log_file_strbuf);
    _log_prefix_level(it, level);
  }
#ifdef ANDROID
  else if (it->config == &config.log.android) {
    strbuf_init(&_android_strbuf, _log_android_buf, sizeof _log_android_buf);
    it->xpf = XPRINTF_STRBUF(&_android_strbuf);
  }
#endif // ANDROID
  else if (it->config == &config.log.console) {
    it->xpf = XPRINTF_STDIO(logfile_stderr);
    _log_prefix_level(it, level);
  }
  else
    abort();
  if (it->config->show_pid)
    xprintf(it->xpf, "[%5u] ", getpid());
  if (it->config->show_time) {
    if (it->tv.tv_sec == 0) {
      xputs("NOTIME______ ", it->xpf);
    } else {
      char buf[50];
      if (strftime(buf, sizeof buf, "%T", &it->tm) == 0)
	xputs("EMPTYTIME___ ", it->xpf);
      else
	xprintf(it->xpf, "%s.%03u ", buf, (unsigned int)it->tv.tv_usec / 1000);
    }
  }
}
Example #20
0
File: char.c Project: GimXu/global
/**
 * quote for shell.
 *
 *	Examples:
 *	aaa => 'aaa'
 *	a'a => 'a'\''aa'
 */
const char *
quote_shell(const char *s)
{
	STATIC_STRBUF(sb);

	strbuf_clear(sb);
	strbuf_putc(sb, SHELL_QUOTE);
#if defined(__DJGPP__) || (defined(_WIN32) && !defined(__CYGWIN__))
	strbuf_puts(sb, s);
#else
	for (; *s; s++) {
		if (*s == SHELL_QUOTE) {
			strbuf_putc(sb, SHELL_QUOTE);
			strbuf_putc(sb, '\\');
			strbuf_putc(sb, SHELL_QUOTE);
			strbuf_putc(sb, SHELL_QUOTE);
		} else
			strbuf_putc(sb, *s);
	}
#endif
	strbuf_putc(sb, SHELL_QUOTE);
	return strbuf_value(sb);
}
Example #21
0
/**
 * Generate anchor begin tag (@CODE{\<a href='dir/file.suffix\#key'\>}).
 * (complete format)
 *
 *	@param[in]	dir	directory
 *	@param[in]	file	file
 *	@param[in]	suffix	suffix (file extension e.g. @CODE{'.txt'}). A @CODE{'.'} (dot) will be added.
 *	@param[in]	key	key
 *	@param[in]	title	@CODE{title='xxx'} attribute; if @VAR{NULL}, doesn't add it.
 *	@param[in]	target	@CODE{target='xxx'} attribute; if @VAR{NULL}, doesn't add it.
 *	@return		generated anchor tag
 *
 *	@note @a dir, @a file, @a suffix, @a key, @a target and @a title may be @VAR{NULL}.
 *	@note Single quote (@CODE{'}) characters are used with the attribute values.
 */
const char *
gen_href_begin_with_title_target(const char *dir, const char *file, const char *suffix, const char *key, const char *title, const char *target)
{
    STATIC_STRBUF(sb);

    strbuf_clear(sb);
    /*
     * Construct URL.
     * href='dir/file.suffix#key'
     */
    strbuf_puts(sb, "<a href='");
    if (file) {
        if (dir) {
            strbuf_puts(sb, dir);
            strbuf_putc(sb, '/');
        }
        strbuf_puts(sb, file);
        if (suffix) {
            strbuf_putc(sb, '.');
            strbuf_puts(sb, suffix);
        }
    }
    if (key) {
        strbuf_putc(sb, '#');
        /*
         * If the key starts with a digit, it assumed line number.
         * XHTML 1.1 profibits number as an anchor.
         */
        if (isdigit(*key))
            strbuf_putc(sb, 'L');
        strbuf_puts(sb, key);
    }
    strbuf_putc(sb, '\'');
    if (Fflag && target)
        strbuf_sprintf(sb, " target='%s'", fix_attr_value(target));
    if (title)
        strbuf_sprintf(sb, " title='%s'", fix_attr_value(title));
    strbuf_putc(sb, '>');
    return strbuf_value(sb);
}
Example #22
0
/**
 * flush_pool: flush the pool and write is as compact format.
 *
 *	@param[in]	gtop	descripter of #GTOP
 *	@param[in]	s_fid
 */
static void
flush_pool(GTOP *gtop, const char *s_fid)
{
	struct sh_entry *entry;
	int header_offset;
	int i, last;

	if (s_fid == NULL && (s_fid = gpath_path2fid(gtop->cur_path, NULL)) == NULL)
		die("GPATH is corrupted.('%s' not found)", gtop->cur_path);
	/*
	 * Write records as compact format and free line number table
	 * for each entry in the pool.
	 */
	for (entry = strhash_first(gtop->path_hash); entry; entry = strhash_next(gtop->path_hash)) {
		VARRAY *vb = (VARRAY *)entry->value;
		int *lno_array = varray_assign(vb, 0, 0);
		const char *key = entry->name;

		/*
		 * extract method when class method definition.
		 *
		 * Ex: Class::method(...)
		 *
		 * key	= 'method'
		 * data = 'Class::method  103 ./class.cpp ...'
		 */
		if (gtop->flags & GTAGS_EXTRACTMETHOD) {
			if ((key = locatestring(entry->name, ".", MATCH_LAST)) != NULL)
				key++;
			else if ((key = locatestring(entry->name, "::", MATCH_LAST)) != NULL)
				key += 2;
			else
				key = entry->name;
		}
		/* Sort line number table */
		qsort(lno_array, vb->length, sizeof(int), compare_lineno); 

		strbuf_reset(gtop->sb);
		strbuf_puts(gtop->sb, s_fid);
		strbuf_putc(gtop->sb, ' ');
		if (gtop->format & GTAGS_COMPNAME) {
			strbuf_puts(gtop->sb, compress(entry->name, key));
		} else {
			strbuf_puts(gtop->sb, entry->name);
		}
		strbuf_putc(gtop->sb, ' ');
		header_offset = strbuf_getlen(gtop->sb);
		/*
		 * If GTAGS_COMPLINE flag is set, each line number is expressed as the
		 * difference from the previous line number except for the head.
		 * GTAGS_COMPLINE is set by default in format version 5.
		 */
		if (gtop->format & GTAGS_COMPLINE) {
			int cont = 0;

			last = 0;			/* line 0 doesn't exist */
			for (i = 0; i < vb->length; i++) {
				int n = lno_array[i];

				if (n == last)
					continue;
				if (last > 0 && n == last + 1) {
					if (!cont) {
						/*
						 * Don't use range expression at the head.
						 */
						if (strbuf_getlen(gtop->sb) == header_offset)
							strbuf_putn(gtop->sb, n);
						else
							cont = last;
					}
				} else {
					/*
					 * Range expression. ex: 10-2 means 10 11 12
					 */
					if (cont) {
						strbuf_putc(gtop->sb, '-');
						strbuf_putn(gtop->sb, last - cont);
						cont = 0;
					}
					if (strbuf_getlen(gtop->sb) > header_offset) {
						strbuf_putc(gtop->sb, ',');
						strbuf_putn(gtop->sb, n - last);
					} else {
						strbuf_putn(gtop->sb, n);
					}
					if (strbuf_getlen(gtop->sb) > DBOP_PAGESIZE / 4) {
						dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));
						strbuf_setlen(gtop->sb, header_offset);
					}
				}
				last = n;
			}
			if (cont) {
				strbuf_putc(gtop->sb, '-');
				strbuf_putn(gtop->sb, last - cont);
			}
		} else {
			/*
			 * This code is to support older format (version 4).
			 */
			last = 0;			/* line 0 doesn't exist */
			for (i = 0; i < vb->length; i++) {
				int n = lno_array[i];

				if (n == last)
					continue;
				if (strbuf_getlen(gtop->sb) > header_offset)
					strbuf_putc(gtop->sb, ',');
				strbuf_putn(gtop->sb, n);
				if (strbuf_getlen(gtop->sb) > DBOP_PAGESIZE / 4) {
					dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));
					strbuf_setlen(gtop->sb, header_offset);
				}
				last = n;
			}
		}
		if (strbuf_getlen(gtop->sb) > header_offset) {
			dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));
		}
		/* Free line number table */
		varray_close(vb);
	}
}
Example #23
0
/*
 * Make duplicate object index.
 *
 * If referred tag is only one, direct link which points the tag is generated.
 * Else if two or more tag exists, indirect link which points the tag list
 * is generated.
 */
int
makedupindex(void)
{
	STRBUF *sb = strbuf_open(0);
	STRBUF *tmp = strbuf_open(0);
	STRBUF *command = strbuf_open(0);
	int definition_count = 0;
	char srcdir[MAXPATHLEN];
	int db;
	FILEOP *fileop = NULL;
	FILE *op = NULL;
	FILE *ip = NULL;

	snprintf(srcdir, sizeof(srcdir), "../%s", SRCS);
	for (db = GTAGS; db < GTAGLIM; db++) {
		const char *kind = kinds[db];
		const char *option = options[db];
		int writing = 0;
		int count = 0;
		int entry_count = 0;
		const char *ctags_xid, *ctags_x;
		char tag[IDENTLEN], prev[IDENTLEN], first_line[MAXBUFLEN];

		if (gtags_exist[db] == 0)
			continue;
		prev[0] = 0;
		first_line[0] = 0;
		/*
		 * construct command line.
		 */
		strbuf_reset(command);
		strbuf_sprintf(command, "%s -x%s --result=ctags-xid --encode-path=\" \t\" --nofilter=path", quote_shell(global_path), option);
		/*
		 * Optimization when the --dynamic option is specified.
		 */
		if (dynamic) {
			strbuf_puts(command, " --nosource");
			if (db != GSYMS)
				strbuf_puts(command, " --nofilter=sort");
		}
		strbuf_puts(command, " \".*\"");
		if ((ip = popen(strbuf_value(command), "r")) == NULL)
			die("cannot execute command '%s'.", strbuf_value(command));
		while ((ctags_xid = strbuf_fgets(sb, ip, STRBUF_NOCRLF)) != NULL) {
			char fid[MAXFIDLEN];

			ctags_x = parse_xid(ctags_xid, fid, NULL);
			/* tag name */
			(void)strcpy_withterm(tag, ctags_x, sizeof(tag), ' ');
			if (strcmp(prev, tag)) {
				count++;
				if (vflag)
					fprintf(stderr, " [%d] adding %s %s\n", count, kind, tag);
				if (writing) {
					if (!dynamic) {
						fputs_nl(gen_list_end(), op);
						fputs_nl(body_end, op);
						fputs_nl(gen_page_end(), op);
						close_file(fileop);
						html_count++;
					}
					writing = 0;
					/*
					 * cache record: " <fid>\0<entry number>\0"
					 */
					strbuf_reset(tmp);
					strbuf_putc(tmp, ' ');
					strbuf_putn(tmp, count - 1);
					strbuf_putc(tmp, '\0');
					strbuf_putn(tmp, entry_count);
					cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
				}				
				/* single entry */
				if (first_line[0]) {
					char fid[MAXFIDLEN];
					const char *ctags_x = parse_xid(first_line, fid, NULL);
					const char *lno = nextelement(ctags_x);

					strbuf_reset(tmp);
					strbuf_puts_withterm(tmp, lno, ' ');
					strbuf_putc(tmp, '\0');
					strbuf_puts(tmp, fid);
					cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
				}
				/*
				 * Chop the tail of the line. It is not important.
				 * strlimcpy(first_line, ctags_x, sizeof(first_line));
				 */
				strncpy(first_line, ctags_xid, sizeof(first_line));
				first_line[sizeof(first_line) - 1] = '\0';
				strlimcpy(prev, tag, sizeof(prev));
				entry_count = 0;
			} else {
				/* duplicate entry */
				if (first_line[0]) {
					char fid[MAXFIDLEN];
					const char *ctags_x = parse_xid(first_line, fid, NULL);

					if (!dynamic) {
						char path[MAXPATHLEN];

						snprintf(path, sizeof(path), "%s/%s/%d.%s", distpath, dirs[db], count, HTML);
						fileop = open_output_file(path, cflag);
						op = get_descripter(fileop);
						fputs_nl(gen_page_begin(tag, SUBDIR), op);
						fputs_nl(body_begin, op);
						fputs_nl(gen_list_begin(), op);
						fputs_nl(gen_list_body(srcdir, ctags_x, fid), op);
					}
					writing = 1;
					entry_count++;
					first_line[0] = 0;
				}
				if (!dynamic) {
					fputs_nl(gen_list_body(srcdir, ctags_x, fid), op);
				}
				entry_count++;
			}
		}
		if (db == GTAGS)
			definition_count = count;
		if (pclose(ip) != 0)
			die("'%s' failed.", strbuf_value(command));
		if (writing) {
			if (!dynamic) {
				fputs_nl(gen_list_end(), op);
				fputs_nl(body_end, op);
				fputs_nl(gen_page_end(), op);
				close_file(fileop);
				html_count++;
			}
			/*
			 * cache record: " <fid>\0<entry number>\0"
			 */
			strbuf_reset(tmp);
			strbuf_putc(tmp, ' ');
			strbuf_putn(tmp, count);
			strbuf_putc(tmp, '\0');
			strbuf_putn(tmp, entry_count);
			cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
		}
		if (first_line[0]) {
			char fid[MAXFIDLEN];
			const char *ctags_x = parse_xid(first_line, fid, NULL);
			const char *lno = nextelement(ctags_x);

			strbuf_reset(tmp);
			strbuf_puts_withterm(tmp, lno, ' ');
			strbuf_putc(tmp, '\0');
			strbuf_puts(tmp, fid);
			cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1);
		}
	}
	strbuf_close(sb);
	strbuf_close(tmp);
	strbuf_close(command);
	return definition_count;
}
Example #24
0
/**
 * Generate list body.
 *
 * @NAME{ctags_x} with the @CODE{--encode-path=\" \\t\"}
 */
const char *
gen_list_body(const char *srcdir, const char *ctags_x, const char *fid)	/* virtually const */
{
    STATIC_STRBUF(sb);
    char path[MAXPATHLEN];
    const char *p;
    SPLIT ptable;

    strbuf_clear(sb);
    if (split((char *)ctags_x, 4, &ptable) < 4) {
        recover(&ptable);
        die("too small number of parts in list_body().\n'%s'", ctags_x);
    }
    strlimcpy(path, decode_path(ptable.part[PART_PATH].start + 2), sizeof(path));
    if (fid == NULL)
        fid = path2fid(path);
    if (table_list) {
        strbuf_puts(sb, current_row_begin);
        if (enable_xhtml) {
            strbuf_puts(sb, "<td class='tag'>");
            strbuf_puts(sb, gen_href_begin(srcdir, fid, HTML, ptable.part[PART_LNO].start));
            strbuf_puts(sb, ptable.part[PART_TAG].start);
            strbuf_puts(sb, gen_href_end());
            strbuf_sprintf(sb, "</td><td class='line'>%s</td><td class='file'>%s</td><td class='code'>",
                           ptable.part[PART_LNO].start, path);
        } else {
            strbuf_puts(sb, "<td nowrap='nowrap'>");
            strbuf_puts(sb, gen_href_begin(srcdir, fid, HTML, ptable.part[PART_LNO].start));
            strbuf_puts(sb, ptable.part[PART_TAG].start);
            strbuf_puts(sb, gen_href_end());
            strbuf_sprintf(sb, "</td><td nowrap='nowrap' align='right'>%s</td>"
                           "<td nowrap='nowrap' align='left'>%s</td><td nowrap='nowrap'>",
                           ptable.part[PART_LNO].start, path);
        }
        for (p = ptable.part[PART_LINE].start; *p; p++) {
            unsigned char c = *p;

            if (c == '&')
                strbuf_puts(sb, quote_amp);
            else if (c == '<')
                strbuf_puts(sb, quote_little);
            else if (c == '>')
                strbuf_puts(sb, quote_great);
            else if (c == ' ')
                strbuf_puts(sb, quote_space);
            else if (c == '\t') {
                strbuf_puts(sb, quote_space);
                strbuf_puts(sb, quote_space);
            } else
                strbuf_putc(sb, c);
        }
        strbuf_puts(sb, "</td>");
        strbuf_puts(sb, current_row_end);
        recover(&ptable);
    } else {
        /* print tag name with anchor */
        strbuf_puts(sb, current_line_begin);
        strbuf_puts(sb, gen_href_begin(srcdir, fid, HTML, ptable.part[PART_LNO].start));
        strbuf_puts(sb, ptable.part[PART_TAG].start);
        strbuf_puts(sb, gen_href_end());
        recover(&ptable);

        /* print line number */
        for (p = ptable.part[PART_TAG].end; p < ptable.part[PART_PATH].start; p++)
            strbuf_putc(sb, *p);
        /* print file name */
        strbuf_puts(sb, path);
        /* print the rest */
        for (p = ptable.part[PART_PATH].end; *p; p++) {
            unsigned char c = *p;

            if (c == '&')
                strbuf_puts(sb, quote_amp);
            else if (c == '<')
                strbuf_puts(sb, quote_little);
            else if (c == '>')
                strbuf_puts(sb, quote_great);
            else
                strbuf_putc(sb, c);
        }
        strbuf_puts(sb, current_line_end);
    }
    return strbuf_value(sb);
}
Example #25
0
/**
 * getconfs: get property string
 *
 *	@param[in]	name	property name
 *	@param[out]	result	string buffer (if not NULL)
 *	@return		1: found, 0: not found
 */
int
getconfs(const char *name, STRBUF *result)
{
	STRBUF *sb = NULL;
	const char *p;
	char buf[MAXPROPLEN];
	int all = 0;
	int exist = 0;
	int bufsize;

	if (!opened)
		die("configuration file not opened.");
	/* 'path' is reserved name for the current path of configuration file */
	if (!strcmp(name, "path")) {
		if (config_path && result)
			strbuf_puts(result, config_path);
		return 1;
	}
	sb = strbuf_open(0);
	if (!strcmp(name, "skip") || !strcmp(name, "gtags_parser") || !strcmp(name, "langmap"))
		all = 1;
	snprintf(buf, sizeof(buf), ":%s=", name);
	bufsize = strlen(buf);
	p = confline;
	while ((p = locatestring(p, buf, MATCH_FIRST)) != NULL) {
		if (exist && sb)
			strbuf_putc(sb, ',');		
		exist = 1;
		for (p += bufsize; *p; p++) {
			if (*p == ':')
				break;
			if (*p == '\\' && *(p + 1) == ':')	/* quoted character */
				p++;
			if (sb)
				strbuf_putc(sb, *p);
		}
		if (!all)
			break;
	}
	/*
	 * If 'bindir' and 'datadir' are not defined then
	 * return system configuration value.
	 */
	if (!exist) {
		if (!strcmp(name, "bindir")) {
			if (sb)
				strbuf_puts(sb, BINDIR);
			exist = 1;
		} else if (!strcmp(name, "datadir")) {
#if defined(_WIN32) && !defined(__CYGWIN__)
			/*
			 * Test if this directory exists, and if not, take the
			 * directory relative to the binary.
			 */
			if (test("d", DATADIR)) {
				if (sb)
					strbuf_puts(sb, DATADIR);
			} else {
				char path[MAX_PATH], *name, *p;
				GetModuleFileName(NULL, path, MAX_PATH);
				for (p = name = path; *p; ++p) {
					if (*p == '\\') {
						*p = '/';
						name = p+1;
					}
				}
				strcpy(name, "../share");
				if (sb)
					strbuf_puts(sb, path);
			}
#else
			if (sb)
				strbuf_puts(sb, DATADIR);
#endif
			exist = 1;
		} else if (!strcmp(name, "libdir")) {
			if (sb)
				strbuf_puts(sb, LIBDIR);
			exist = 1;
		} else if (!strcmp(name, "localstatedir")) {
			if (sb)
				strbuf_puts(sb, LOCALSTATEDIR);
			exist = 1;
		} else if (!strcmp(name, "sysconfdir")) {
			if (sb)
				strbuf_puts(sb, SYSCONFDIR);
			exist = 1;
		}
	}
	replace_variables(sb);
	if (result)
		strbuf_puts(result, !strcmp(name, "langmap") ? 
			trim_langmap(strbuf_value(sb)) :
			strbuf_value(sb));
	strbuf_close(sb);
	return exist;
}
Example #26
0
/**
 * openconf: load configuration file.
 *
 *	@param[in]	rootdir	Project root directory
 *
 * Globals used (output):
 *	confline:	 specified entry
 */
void
openconf(const char *rootdir)
{
	STRBUF *sb;

	if (opened)
		return;
	opened = 1;
	/*
	 * if config file not found then return default value.
	 */
	if (!(config_path = configpath(rootdir)))
		confline = check_strdup("");
	/*
	 * if it is not an absolute path then assumed config value itself.
	 */
	else if (!isabspath(config_path)) {
		confline = check_strdup(config_path);
		if (!locatestring(confline, ":", MATCH_FIRST))
			die("GTAGSCONF must be absolute path name.");
	}
	/*
	 * else load value from config file.
	 */
	else {
		if (test("d", config_path))
			die("config file '%s' is a directory.", config_path);
		if (!test("f", config_path))
			die("config file '%s' not found.", config_path);
		if (!test("r", config_path))
			die("config file '%s' is not readable.", config_path);
		if ((config_label = getenv("GTAGSLABEL")) == NULL)
			config_label = "default";
	
		if (!(fp = fopen(config_path, "r")))
			die("cannot open '%s'.", config_path);
		ib = strbuf_open(MAXBUFLEN);
		sb = strbuf_open(0);
		includelabel(fp, sb, config_label, 0);
		confline = check_strdup(strbuf_value(sb));
		strbuf_close(ib);
		strbuf_close(sb);
		fclose(fp);
	}
	/*
	 * make up required variables.
	 */
	sb = strbuf_open(0);
	strbuf_puts(sb, confline);
	strbuf_unputc(sb, ':');

	if (!getconfs("langmap", NULL)) {
		strbuf_puts(sb, ":langmap=");
		strbuf_puts(sb, quote_chars(DEFAULTLANGMAP, ':'));
	}
	if (!getconfs("skip", NULL)) {
		strbuf_puts(sb, ":skip=");
		strbuf_puts(sb, DEFAULTSKIP);
	}
	strbuf_unputc(sb, ':');
	strbuf_putc(sb, ':');
	confline = check_strdup(strbuf_value(sb));
	strbuf_close(sb);
	trim(confline);
	return;
}
Example #27
0
int rbm_putc(int c, FILE *stream)
{
    return strbuf_putc((STRBUF *) stream, c);
}
Example #28
0
/**
 * makecommonpart: make a common part for "mains.html" and "index.html"
 *
 *	@param[in]	title
 *	@param[in]	defines
 *	@param[in]	files
 *	@return	index	common part
 */
static char *
makecommonpart(const char *title, const char *defines, const char *files)
{
	FILE *ip;
	STRBUF *sb = strbuf_open(0);
	STRBUF *ib = strbuf_open(0);
	char buf[MAXFILLEN];
	const char *tips = "Go to the GLOBAL project page.";
	const char *_, *item;

	strbuf_puts(sb, title_begin);
	strbuf_puts(sb, title);
	strbuf_puts_nl(sb, title_end);
	strbuf_puts_nl(sb, poweredby_begin);
	strbuf_sprintf(sb, "Last updated %s%s\n", now(), br);
	if (Iflag) {
		snprintf(buf, sizeof(buf), "Powered by GLOBAL-%s.", get_version());
		strbuf_puts(sb, gen_href_begin_with_title_target(NULL, www, NULL, NULL, tips,"_top"));
		strbuf_puts(sb, gen_image(CURRENT, "pglobe", buf));
		strbuf_puts(sb, gen_href_end());
		strbuf_puts(sb, br);
	} else {
		strbuf_sprintf(sb, "Powered by %sGLOBAL-%s%s.%s\n",
			gen_href_begin_with_title_target(NULL, www, NULL, NULL, tips, "_top"),
			get_version(),
			gen_href_end(),
			br);
	}
	strbuf_puts_nl(sb, poweredby_end);
	strbuf_puts_nl(sb, hr);
	/*
	 * Print items according to the value of variable 'item_order'.
	 */
	for (item = item_order; *item; item++) {
		switch (*item) {
		case 'c':
			if (caution) {
				strbuf_puts_nl(sb, caution_begin);
				strbuf_sprintf(sb, "<font size='+2' color='red'>CAUTION</font>%s\n", br);
				strbuf_sprintf(sb, "This hypertext consists of %d files.\n", html_count);
				strbuf_puts_nl(sb, "Please don't download the whole hypertext using a hypertext copy tool.");
				strbuf_puts_nl(sb, "Our network cannot afford such traffic.");
				strbuf_puts_nl(sb, "Instead, you can generate the same thing in your computer using");
				strbuf_puts(sb, gen_href_begin_with_title_target(NULL, www, NULL, NULL, NULL, "_top"));
				strbuf_puts(sb, "GLOBAL source code tag system");
				strbuf_puts_nl(sb, gen_href_end());
				strbuf_puts_nl(sb, "Thank you.");
				strbuf_puts_nl(sb, caution_end);
				strbuf_sprintf(sb, "\n%s\n", hr);
			}
			break;
		case 's':
			if (fflag) {
				strbuf_puts(sb, makesearchpart(NULL));
				strbuf_puts_nl(sb, hr);
			}
			break;
		case 't':
			if (call_file || callee_file) {
				strbuf_puts(sb, header_begin);
				if (call_file) {
					strbuf_puts(sb, gen_href_begin(NULL, "call", normal_suffix, NULL));
					strbuf_puts(sb, title_call_tree);
					strbuf_puts(sb, gen_href_end());
				}
				if (call_file && callee_file)
					strbuf_puts(sb, " / ");
				if (callee_file) {
					strbuf_puts(sb, gen_href_begin(NULL, "callee", normal_suffix, NULL));
					strbuf_puts(sb, title_callee_tree);
					strbuf_puts(sb, gen_href_end());
				}
				strbuf_puts_nl(sb, header_end);
				strbuf_puts_nl(sb, hr);
			}
			break;
		case 'm':
			strbuf_sprintf(sb, "%sMAINS%s\n", header_begin, header_end);

			snprintf(buf, sizeof(buf), PQUOTE "%s --result=ctags-xid --encode-path=\" \t\" --nofilter=path %s" PQUOTE, quote_shell(global_path), main_func);
			ip = popen(buf, "r");
			if (!ip)
				die("cannot execute '%s'.", buf);
			strbuf_puts_nl(sb, gen_list_begin());
			while ((_ = strbuf_fgets(ib, ip, STRBUF_NOCRLF)) != NULL) {
				char fid[MAXFIDLEN];
				const char *ctags_x = parse_xid(_, fid, NULL);

				strbuf_puts_nl(sb, gen_list_body(SRCS, ctags_x, fid));
			}
			strbuf_puts_nl(sb, gen_list_end());
			if (pclose(ip) != 0)
				die("terminated abnormally '%s' (errno = %d).", buf, errno);
			strbuf_puts_nl(sb, hr);
			break;
		case 'd':
			if (aflag && !Fflag) {
				strbuf_puts(sb, header_begin);
				strbuf_puts(sb, title_define_index);
				strbuf_puts_nl(sb, header_end);
				strbuf_puts(sb, defines);
			} else {
				strbuf_puts(sb, header_begin);
				strbuf_puts(sb, gen_href_begin(NULL, "defines", normal_suffix, NULL));
				strbuf_puts(sb, title_define_index);
				strbuf_puts(sb, gen_href_end());
				strbuf_puts_nl(sb, header_end);
			}
			strbuf_puts_nl(sb, hr);
			break;
		case 'f':
			if (Fflag) {
				strbuf_puts(sb, header_begin);
				strbuf_puts(sb, gen_href_begin(NULL, "files", normal_suffix, NULL));
				strbuf_puts(sb, title_file_index);
				strbuf_puts(sb, gen_href_end());
				strbuf_puts_nl(sb, header_end);
			} else {
				strbuf_puts(sb, header_begin);
				strbuf_puts(sb, title_file_index);
				strbuf_puts_nl(sb, header_end);
				if (tree_view) {
					strbuf_puts_nl(sb, tree_control);
					strbuf_puts_nl(sb, tree_loading);
					if (tree_view_type) {
						strbuf_sprintf(sb, tree_begin_using, tree_view_type);
						strbuf_putc(sb, '\n');
					} else {
						strbuf_puts_nl(sb, tree_begin);
					}
				} else if (table_flist)
					strbuf_puts_nl(sb, flist_begin);
				else if (!no_order_list)
					strbuf_puts_nl(sb, list_begin);
				strbuf_puts(sb, files);
				if (tree_view)
					strbuf_puts_nl(sb, tree_end);
				else if (table_flist)
					strbuf_puts_nl(sb, flist_end);
				else if (!no_order_list)
					strbuf_puts_nl(sb, list_end);
				else
					strbuf_puts_nl(sb, br);
			}
			strbuf_puts_nl(sb, hr);
			break;
		default:
			warning("unknown item '%c'. (Ignored)", *item);
			break;
		}
	}
	strbuf_close(ib);

	return strbuf_value(sb);
	/* doesn't close string buffer */
}
Example #29
0
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;
}
Example #30
0
/**
 * save_environment: save configuration data and arguments.
 */
static void
save_environment(int argc, char *const *argv)
{
	char command[MAXFILLEN];
	STRBUF *sb = strbuf_open(0);
	STRBUF *save_c = strbuf_open(0);
	STRBUF *save_a = strbuf_open(0);
	int i;
	const char *p;
	FILE *ip;

	/*
	 * save config values.
	 */
	snprintf(command, sizeof(command), PQUOTE "%s --config" PQUOTE, quote_shell(gtags_path));
	if ((ip = popen(command, "r")) == NULL)
		die("cannot execute '%s'.", command);
	while (strbuf_fgets(sb, ip, STRBUF_NOCRLF) != NULL) {
		for (p = strbuf_value(sb); *p; p++) {
			if (*p == '\'') {
				strbuf_putc(save_c, '\'');
				strbuf_putc(save_c, '"');
				strbuf_putc(save_c, '\'');
				strbuf_putc(save_c, '"');
				strbuf_putc(save_c, '\'');
			} else
				strbuf_putc(save_c, *p);
		}
	}
	if (pclose(ip) != 0)
		die("terminated abnormally '%s' (errno = %d).", command, errno);
	strbuf_close(sb);
	save_config = strbuf_value(save_c);
	/* doesn't close string buffer for save config. */
	/* strbuf_close(save_c); */

	/*
	 * save arguments.
	 */
	{
		char *opt_gtagsconf = "--gtagsconf";

		for (i = 1; i < argc; i++) {
			char *blank;

			/*
			 * skip --gtagsconf because it is already read
			 * as config value.
			 */
			if ((p = locatestring(argv[i], opt_gtagsconf, MATCH_AT_FIRST))) {
				if (*p == '\0')
					i++;
				continue;
			}
			blank = locatestring(argv[i], " ", MATCH_FIRST);
			strbuf_putc(save_a, ' ');
			if (blank)
				strbuf_putc(save_a, '\'');
			strbuf_puts(save_a, argv[i]);
			if (blank)
				strbuf_putc(save_a, '\'');
		}
	}
	save_argv = strbuf_value(save_a);
	/* doesn't close string buffer for save arguments. */
	/* strbuf_close(save_a); */
}