/** * Generate upper directory. * * Just returns the parent path of @a dir. (Adds @FILE{../} to it). */ const char * upperdir(const char *dir) { STATIC_STRBUF(sb); strbuf_clear(sb); strbuf_sprintf(sb, "../%s", dir); return strbuf_value(sb); }
/** * Generate beginning of frameset (@CODE{\<frameset\>}) * * @param[in] contents target */ const char * gen_frameset_begin(const char *contents) { STATIC_STRBUF(sb); strbuf_clear(sb); strbuf_sprintf(sb, "<frameset %s>", contents); return strbuf_value(sb); }
/* * Generate beginning of frame * * i) target target */ const char * gen_frame(const char *name, const char *src) { STATIC_STRBUF(sb); strbuf_clear(sb); strbuf_sprintf(sb, "<frame name='%s' id='%s' src='%s'%s>", name, name, src, empty_element); return strbuf_value(sb); }
/** * usable: check if command is executable or not. * * @param[in] command * @return ==NULL: not found. <br> * !=NULL: absolute path of @a command. */ char * usable(const char *command) { STRBUF *sb; char *p; const char *dir; static char path[MAXPATHLEN]; #if defined(_WIN32) || defined(__DJGPP__) int i, lim = sizeof(suffix)/sizeof(char *); #endif if (isabspath(command) || locatestring(command, "./", MATCH_AT_FIRST) || locatestring(command, "../", MATCH_AT_FIRST)) { if (test("fx", command)) { strlimcpy(path, command, sizeof(path)); return path; } return NULL; } /* * If found in BINDIR then use it. */ if (test("fx", makepath(BINDIR, command, NULL))) { strlimcpy(path, makepath(BINDIR, command, NULL), sizeof(path)); return path; } /* * Locate the command for each path in PATH. */ *path = 0; /* Don't use fixed length buffer for environment variable * because it brings buffer overflow. */ sb = strbuf_open(0); strbuf_puts(sb, getenv("PATH")); p = strbuf_value(sb); while (p) { dir = p; if ((p = locatestring(p, PATHSEP, MATCH_FIRST)) != NULL) *p++ = 0; if (test("fx", makepath(dir, command, NULL))) { strlimcpy(path, makepath(dir, command, NULL), sizeof(path)); goto finish; } #if defined(_WIN32) || defined(__DJGPP__) for (i = 0; i < lim; i++) if (test("f", makepath(dir, command, suffix[i]))) { strlimcpy(path, makepath(dir, command, suffix[i]), sizeof(path)); goto finish; } #endif } finish: strbuf_close(sb); return *path ? path : NULL; }
/** * 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); }
/** * xargs_open_with_strbuf: open xargs stream using string buffer * * @param[in] command command skeleton. * @param[in] max_args 0: no limit, \>0: max argument * @param[in] sb string buffer * @return xargs structure * * The @CODE{'\%s'} in the command skeleton is replaced with given arguments. <br> * If @CODE{'\%s'} doesn't exist, the arguments is appended to the tail of the * skeleton. */ XARGS * xargs_open_with_strbuf(const char *command, int max_args, STRBUF *sb) { XARGS *xp = xargs_open_generic(command, max_args); xp->type = XARGS_STRBUF; xp->curp = strbuf_value(sb); xp->endp = xp->curp + strbuf_getlen(sb); return xp; }
/* * makesearchpart: make search part * * @param[in] target $target * @return html */ static char * makesearchpart(const char *target) { STATIC_STRBUF(sb); strbuf_clear(sb); strbuf_puts(sb, header_begin); if (Fflag) strbuf_puts(sb, gen_href_begin(NULL, "search", normal_suffix, NULL)); strbuf_puts(sb, "SEARCH"); if (Fflag) strbuf_puts(sb, gen_href_end()); strbuf_puts_nl(sb, header_end); if (!target) { strbuf_puts(sb, "Please input object name and select [Search]. POSIX's regular expression is allowed."); strbuf_puts_nl(sb, br); } strbuf_puts_nl(sb, gen_form_begin(target)); strbuf_puts_nl(sb, gen_input("pattern", NULL, NULL)); strbuf_puts_nl(sb, gen_input(NULL, "Search", "submit")); strbuf_puts(sb, gen_input(NULL, "Reset", "reset")); strbuf_puts_nl(sb, br); strbuf_puts(sb, gen_input_radio("type", "definition", 1, "Retrieve the definition place of the specified symbol.")); strbuf_puts_nl(sb, target ? "Def" : "Definition"); strbuf_puts(sb, gen_input_radio("type", "reference", 0, "Retrieve the reference place of the specified symbol.")); strbuf_puts_nl(sb, target ? "Ref" : "Reference"); strbuf_puts(sb, gen_input_radio("type", "symbol", 0, "Retrieve the place of the specified symbol is used.")); strbuf_puts_nl(sb, target ? "Sym" : "Other symbol"); strbuf_puts(sb, gen_input_radio("type", "path", 0, "Look for path name which matches to the specified pattern.")); strbuf_puts_nl(sb, target ? "Path" : "Path name"); if (enable_grep) { strbuf_puts(sb, gen_input_radio("type", "grep", 0, "Retrieve lines which matches to the specified pattern.")); strbuf_puts_nl(sb, target ? "Grep" : "Grep pattern"); } if (enable_idutils && test("f", makepath(dbpath, "ID", NULL))) { strbuf_puts(sb, gen_input_radio("type", "idutils", 0, "Retrieve lines which matches to the specified pattern using idutils(1).")); strbuf_puts_nl(sb, target ? "Id" : "Id pattern"); } strbuf_puts_nl(sb, br); strbuf_puts(sb, gen_input_checkbox("icase", NULL, "Ignore case distinctions in the pattern.")); strbuf_puts_nl(sb, target ? "Icase" : "Ignore case"); if (other_files) { strbuf_puts(sb, gen_input_checkbox("other", NULL, "Files other than the source code are also retrieved.")); strbuf_puts_nl(sb, target ? "Other" : "Other files"); } if (other_files && !target) { strbuf_puts_nl(sb, br); strbuf_puts(sb, "('Other files' is effective only to 'Path name'"); if (enable_grep) strbuf_puts(sb, " and 'Grep pattern'"); strbuf_puts_nl(sb, ".)"); } strbuf_puts_nl(sb, gen_form_end()); return strbuf_value(sb); }
/** * 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); }
/* * Read line with a prompt. * * This is part of cscope protocol. */ static char * get_line(void) { STATIC_STRBUF(sb); /* Prompt */ fputs(">> ", stdout); fflush(stdout); if (strbuf_fgets(sb, stdin, STRBUF_NOCRLF) == NULL) return NULL; return strbuf_value(sb); }
/** * gtags_put_using: put tag record with packing. * * @param[in] gtop descripter of #GTOP * @param[in] tag tag name * @param[in] lno line number * @param[in] fid file id * @param[in] img line image */ void gtags_put_using(GTOP *gtop, const char *tag, int lno, const char *fid, const char *img) { const char *key; if (gtop->format & GTAGS_COMPACT) { struct sh_entry *entry; /* * Register each record into the pool. * * Pool image: * * tagname lno * ------------------------------ * "funcA" | 1| 3| 7|23|11| 2|... * "funcB" |34| 2| 5|66| 3|... * ... */ entry = strhash_assign(gtop->path_hash, tag, 1); if (entry->value == NULL) entry->value = varray_open(sizeof(int), 100); *(int *)varray_append((VARRAY *)entry->value) = lno; return; } /* * 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(tag, ".", MATCH_LAST)) != NULL) key++; else if ((key = locatestring(tag, "::", MATCH_LAST)) != NULL) key += 2; else key = tag; } else { key = tag; } strbuf_reset(gtop->sb); strbuf_puts(gtop->sb, fid); strbuf_putc(gtop->sb, ' '); strbuf_puts(gtop->sb, (gtop->format & GTAGS_COMPNAME) ? compress(tag, key) : tag); strbuf_putc(gtop->sb, ' '); strbuf_putn(gtop->sb, lno); strbuf_putc(gtop->sb, ' '); strbuf_puts(gtop->sb, (gtop->format & GTAGS_COMPRESS) ? compress(img, key) : img); dbop_put(gtop->dbop, key, strbuf_value(gtop->sb)); }
/** * Generate beginning of form (@CODE{\<form\>}) * * @param[in] target target attribute or @VAR{NULL} for no target. */ const char * gen_form_begin(const char *target) { STATIC_STRBUF(sb); strbuf_clear(sb); strbuf_sprintf(sb, "<form method='get' action='%s'", fix_attr_value(action)); if (Fflag && target) strbuf_sprintf(sb, " target='%s'", fix_attr_value(target)); strbuf_puts(sb, ">"); return strbuf_value(sb); }
/** * Load file. */ void loadfile(const char *file, STRBUF *result) { STRBUF *sb = strbuf_open(0); FILE *ip = fopen(file, "r"); if (!ip) die("file '%s' not found.", file); while (strbuf_fgets(sb, ip, STRBUF_NOCRLF) != NULL) strbuf_puts_nl(result, strbuf_value(sb)); fclose(ip); strbuf_close(sb); }
/** * load configuration variables. */ static void configuration(void) { STRBUF *sb = strbuf_open(0); /* * Config variables. */ strbuf_reset(sb); if (!getconfs("datadir", sb)) die("cannot get datadir directory name."); strlimcpy(datadir, strbuf_value(sb), sizeof(datadir)); strbuf_reset(sb); if (!getconfs("localstatedir", sb)) die("cannot get localstatedir directory name."); strlimcpy(localstatedir, strbuf_value(sb), sizeof(localstatedir)); strbuf_reset(sb); if (getconfs("prolog_script", sb)) prolog_script = check_strdup(strbuf_value(sb)); strbuf_reset(sb); if (getconfs("epilog_script", sb)) epilog_script = check_strdup(strbuf_value(sb)); if (getconfb("colorize_warned_line")) colorize_warned_line = 1; strbuf_reset(sb); if (getconfs("include_file_suffixes", sb)) include_file_suffixes = check_strdup(strbuf_value(sb)); strbuf_reset(sb); if (getconfs("langmap", sb)) langmap = check_strdup(strbuf_value(sb)); strbuf_close(sb); }
/** * quote string. * * Non-alphanumeric characters are quoted/escaped. * * Examples: * 'a:a,a' => 'a\:a\,a' */ const char * quote_string(const char *s) { STATIC_STRBUF(sb); strbuf_clear(sb); for (; *s; s++) { if (!isalnum((unsigned char)*s)) strbuf_putc(sb, '\\'); strbuf_putc(sb, *s); } return strbuf_value(sb); }
char * dbop3_quote(char *string) { STATIC_STRBUF(sb); char *p; strbuf_clear(sb); for (p = string; *p; p++) { if (*p == '\'') strbuf_putc(sb, '\''); strbuf_putc(sb, *p); } return strbuf_value(sb); }
/** * quote characters in the string. * * Examples: * quote_char('a:a,a', :) => 'a\:a,a' */ const char * quote_chars(const char *s, unsigned int c) { STATIC_STRBUF(sb); strbuf_clear(sb); for (; *s; s++) { if ((unsigned char)*s == c) strbuf_putc(sb, '\\'); strbuf_putc(sb, *s); } return strbuf_value(sb); }
/* * tagsearch: execute tag search * * i) pattern search pattern * i) cwd current directory * i) root root of source tree * i) dbpath database directory * i) db GTAGS,GRTAGS,GSYMS */ void tagsearch(const char *pattern, const char *cwd, const char *root, const char *dbpath, int db) { int count, total = 0; char libdbpath[MAXPATHLEN]; /* * search in current source tree. */ count = search(pattern, root, cwd, dbpath, db); total += count; /* * search in library path. */ if (db == GTAGS && getenv("GTAGSLIBPATH") && (count == 0 || Tflag) && !lflag) { STRBUF *sb = strbuf_open(0); char *libdir, *nextp = NULL; strbuf_puts(sb, getenv("GTAGSLIBPATH")); /* * search for each tree in the library path. */ for (libdir = strbuf_value(sb); libdir; libdir = nextp) { if ((nextp = locatestring(libdir, PATHSEP, MATCH_FIRST)) != NULL) *nextp++ = 0; if (!gtagsexist(libdir, libdbpath, sizeof(libdbpath), 0)) continue; if (!strcmp(dbpath, libdbpath)) continue; if (!test("f", makepath(libdbpath, dbname(db), NULL))) continue; /* * search again */ count = search(pattern, libdir, cwd, libdbpath, db); total += count; if (count > 0 && !Tflag) { /* for verbose message */ dbpath = libdbpath; break; } } strbuf_close(sb); } if (vflag) { print_count(total); if (!Tflag) fprintf(stderr, " (using '%s')", makepath(dbpath, dbname(db), NULL)); fputs(".\n", stderr); } }
/** * xargs_read: read a record from xargs stream * * @param[in] xp xargs structure * @return result line */ char * xargs_read(XARGS *xp) { assert(xp != NULL); if (xp->end_of_arg) return NULL; if (xp->unread) { xp->unread = 0; return strbuf_value(xp->result); } if (xp->pipe && strbuf_fgets(xp->result, xp->pipe, STRBUF_NOCRLF) != NULL) { if (xp->trim_line) strbuf_trim(xp->result); return strbuf_value(xp->result); } if (xp->pipe) if (pclose(xp->pipe) != 0 && !xp->ignore_error) die("command failed in xargs_read()."); /* * Switch to the next segment. */ do { xp->pipe = execute_command(xp); if (xp->pipe && strbuf_fgets(xp->result, xp->pipe, STRBUF_NOCRLF) != NULL) { if (xp->trim_line) strbuf_trim(xp->result); return strbuf_value(xp->result); } if (xp->pipe) { if (pclose(xp->pipe) != 0 && !xp->ignore_error) die("command failed in xargs_read()."); } else { xp->end_of_arg = 1; } } while (!xp->end_of_arg); return NULL; }
/* * uncompress source line. * * i) in compressed string * i) name replaced string * r) uncompressed string */ char * uncompress(const char *in, const char *name) { STATIC_STRBUF(sb); const char *p; int i; strbuf_clear(sb); for (p = in; *p; p++) { if (*p == '@') { int spaces = 0; switch (*++p) { case '@': strbuf_putc(sb, '@'); break; case 'n': strbuf_puts(sb, name); break; case '{': /* } */ for (p++; *p && isdigit((unsigned char)*p); p++) spaces = spaces * 10 + *p - '0'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': spaces = *p - '0'; break; default: if (*p < 'a' || *p > 'z') die("Abbrev character must be a lower alphabetic character. (%c)", *p); i = *p - 'a'; if (ab2name[i].name) strbuf_puts(sb, ab2name[i].name); break; } strbuf_nputc(sb, ' ', spaces); } else { strbuf_putc(sb, *p); } } return strbuf_value(sb); }
/** * 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; }
/** * Generate image tag (@CODE{\<img\>}) * * @param[in] where Where is the icon directory? <br> * #CURRENT: current directory <br> * #PARENT: parent directory * @param[in] file icon file without suffix. * @param[in] alt alt string (the @CODE{alt} attribute is always added) * * @note Images are assumed to be in the @FILE{icons} or @FILE{../icons} directory, only. */ const char * gen_image(int where, const char *file, const char *alt) { STATIC_STRBUF(sb); const char *dir = (where == PARENT) ? "../icons" : "icons"; strbuf_clear(sb); if (enable_xhtml) strbuf_sprintf(sb, "<img class='icon' src='%s/%s.%s' alt='[%s]'%s>", dir, file, icon_suffix, fix_attr_value(alt), empty_element); else strbuf_sprintf(sb, "<img src='%s/%s.%s' alt='[%s]' %s%s>", dir, file, icon_suffix, fix_attr_value(alt), icon_spec, empty_element); return strbuf_value(sb); }
/** * set_env: put environment variable. * * @param[in] var environment variable * @param[in] val value * * Machine independent version of @XREF{setenv,3}. */ void set_env(const char *var, const char *val) { /* * sparc-sun-solaris2.6 doesn't have setenv(3). */ #ifdef HAVE_PUTENV STRBUF *sb = strbuf_open(0); strbuf_sprintf(sb, "%s=%s", var, val); putenv(strbuf_value(sb)); /* Don't free memory. putenv(3) require it. */ #else setenv(var, val, 1); #endif }
/* * get pattern which match to #include lines. * * i) arg include file name * r) pattern which match to #include lines */ static char * include_pattern(const char *arg) { #if defined(_WIN32) #define INCLUDE "^[ \t]*#[ \t]*include[ \t].*[\\\"\"</\\]%s[\\\"\">]" #elif defined(__DJGPP__) #define INCLUDE "^[ \t]*#[ \t]*include[ \t].*[\"</\\]%s[\">]" #else #define INCLUDE "^[ \t]*#[ \t]*include[ \t].*[\"</]%s[\">]" #endif STATIC_STRBUF(pat); strbuf_clear(pat); strbuf_sprintf(pat, INCLUDE, quote_string(arg)); return strbuf_value(pat); }
/** * 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); }
/* * getURL: get URL of the specified file. * * i) file file name * i) htmldir HTML directory * o) URL URL begin with 'file:' */ void getURL(const char *file, const char *htmldir, STRBUF *URL) { char *p; char buf[MAXPATHLEN]; STRBUF *sb = strbuf_open(0); if (!test("f", file) && !test("d", file)) die("file '%s' not found.", file); p = normalize(file, get_root_with_slash(), cwd, buf, sizeof(buf)); if (p != NULL && convertpath(dbpath, htmldir, p, sb) == 0) makefileurl(strbuf_value(sb), linenumber, URL); else makefileurl(realpath(file, buf), 0, URL); strbuf_close(sb); }
/** * 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, "'"); else strbuf_putc(sb, c); ++cptr; } return strbuf_value(sb); }
const char * dbop3_get(DBOP *dbop, const char *name) { int rc; char *errmsg = 0; STRBUF *sql = strbuf_open_tempbuf(); strbuf_sprintf(sql, "select dat, extra from %s where key = '%s' limit 1", dbop->tblname, name); dbop->lastdat = NULL; dbop->lastsize = 0; dbop->lastflag = NULL; rc = sqlite3_exec(dbop->db3, strbuf_value(sql), single_select_callback, dbop, &errmsg); if (rc != SQLITE_OK) { sqlite3_close(dbop->db3); die("dbop3_get failed: %s", errmsg); } strbuf_release_tempbuf(sql); return dbop->lastdat; }
/* * printconf: print configuration data. * * i) name label of config data * r) exit code */ int printconf(const char *name) { int num; int exist = 1; if (getconfn(name, &num)) fprintf(stdout, "%d\n", num); else if (getconfb(name)) fprintf(stdout, "1\n"); else { STRBUF *sb = strbuf_open(0); if (getconfs(name, sb)) fprintf(stdout, "%s\n", strbuf_value(sb)); else exist = 0; strbuf_close(sb); } return exist; }
/** * completion: 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 */ void completion(const char *dbpath, const char *root, const char *prefix, int db) { int count, total = 0; char libdbpath[MAXPATHLEN]; if (prefix && *prefix == 0) /* In the case global -c '' */ prefix = NULL; count = completion_tags(dbpath, root, prefix, db); /* * search in library path. */ if (db == GTAGS && getenv("GTAGSLIBPATH") && (count == 0 || Tflag) && !Sflag) { STRBUF *sb = strbuf_open(0); char *libdir, *nextp = NULL; strbuf_puts(sb, getenv("GTAGSLIBPATH")); /* * search for each tree in the library path. */ for (libdir = strbuf_value(sb); libdir; libdir = nextp) { if ((nextp = locatestring(libdir, PATHSEP, MATCH_FIRST)) != NULL) *nextp++ = 0; if (!gtagsexist(libdir, libdbpath, sizeof(libdbpath), 0)) continue; if (!strcmp(dbpath, libdbpath)) continue; if (!test("f", makepath(libdbpath, dbname(db), NULL))) continue; /* * search again */ count = completion_tags(libdbpath, libdir, prefix, db); total += count; if (count > 0 && !Tflag) break; } strbuf_close(sb); } /* return total; */ }
/** * Generate name tag (@CODE{\<a name='xxx'\>}). * * Uses attribute @CODE{'id'}, if is @NAME{XHTML}. */ const char * gen_name_string(const char *name) { STATIC_STRBUF(sb); strbuf_clear(sb); if (enable_xhtml) { /* * Since some browser cannot understand "<a id='xxx' />", * we put both of 'id=' and 'name=' as long as XHTML1.1 * is not required. XHTML1.1 prohibit 'name='. */ if (strict_xhtml) strbuf_sprintf(sb, "<a id='%s'></a>", name); else strbuf_sprintf(sb, "<a id='%s' name='%s'></a>", name, name); } else { strbuf_sprintf(sb, "<a name='%s'></a>", name); } return strbuf_value(sb); }