/** * isregex: test whether or not regular expression * * @param[in] s string * @return 1: is regex, 0: not regex */ int isregex(const char *s) { int c; while ((c = *s++) != '\0') if (isregexchar(c)) return 1; return 0; }
/** * gtags_first: return first record * * @param[in] gtop #GTOP structure * @param[in] pattern tag name <br> * - may be regular expression * - may be @VAR{NULL} * @param[in] flags #GTOP_PREFIX: prefix read <br> * #GTOP_KEY: read key only <br> * #GTOP_PATH: read path only <br> * #GTOP_NOREGEX: don't use regular expression. <br> * #GTOP_IGNORECASE: ignore case distinction. <br> * #GTOP_BASICREGEX: use basic regular expression. <br> * #GTOP_NOSORT: don't sort * @return record */ GTP * gtags_first(GTOP *gtop, const char *pattern, int flags) { int dbflags = 0; int regflags = 0; char prefix[IDENTLEN]; static regex_t reg; regex_t *preg = ® const char *key = NULL; const char *tagline; /* Settlement for last time if any */ if (gtop->path_hash) { strhash_close(gtop->path_hash); gtop->path_hash = NULL; } if (gtop->path_array) { free(gtop->path_array); gtop->path_array = NULL; } gtop->flags = flags; if (flags & GTOP_PREFIX && pattern != NULL) dbflags |= DBOP_PREFIX; if (flags & GTOP_KEY) dbflags |= DBOP_KEY; if (!(flags & GTOP_BASICREGEX)) regflags |= REG_EXTENDED; if (flags & GTOP_IGNORECASE) regflags |= REG_ICASE; /* * Get key and compiled regular expression for dbop_xxxx(). */ if (flags & GTOP_NOREGEX) { key = pattern; preg = NULL; } else if (pattern == NULL || !strcmp(pattern, ".*")) { /* * Since the regular expression '.*' matches to any record, * we take sequential read method. */ key = NULL; preg = NULL; } else if (isregex(pattern) && regcomp(preg, pattern, regflags) == 0) { const char *p; /* * If the pattern include '^' + some non regular expression * characters like '^aaa[0-9]', we take prefix read method * with the non regular expression part as the prefix. */ if (!(flags & GTOP_IGNORECASE) && *pattern == '^' && *(p = pattern + 1) && !isregexchar(*p)) { int i = 0; while (*p && !isregexchar(*p) && i < IDENTLEN) prefix[i++] = *p++; prefix[i] = '\0'; key = prefix; dbflags |= DBOP_PREFIX; } else { key = NULL; } } else { key = pattern; preg = NULL; } /* * If GTOP_PATH is set, at first, we collect all path names in a pool and * sort them. gtags_first() and gtags_next() returns one of the pool. */ if (gtop->flags & GTOP_PATH) { struct sh_entry *entry; char *p; const char *cp; unsigned long i; gtop->path_hash = strhash_open(HASHBUCKETS); /* * Pool path names. * * fid path name * +-------------------------- * |100 ./aaa/a.c * |105 ./aaa/b.c * ... */ for (tagline = dbop_first(gtop->dbop, key, preg, dbflags); tagline != NULL; tagline = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); /* extract file id */ p = locatestring(tagline, " ", MATCH_FIRST); if (p == NULL) die("Illegal tag record. '%s'\n", tagline); *p = '\0'; entry = strhash_assign(gtop->path_hash, tagline, 1); /* new entry: get path name and set. */ if (entry->value == NULL) { cp = gpath_fid2path(tagline, NULL); if (cp == NULL) die("GPATH is corrupted.(file id '%s' not found)", tagline); entry->value = strhash_strdup(gtop->path_hash, cp, 0); } } /* * Sort path names. * * fid path name path_array (sort) * +-------------------------- +---+ * |100 ./aaa/a.c <-------* | * |105 ./aaa/b.c <-------* | * ... ... */ gtop->path_array = (char **)check_malloc(gtop->path_hash->entries * sizeof(char *)); i = 0; for (entry = strhash_first(gtop->path_hash); entry != NULL; entry = strhash_next(gtop->path_hash)) gtop->path_array[i++] = entry->value; if (i != gtop->path_hash->entries) die("Something is wrong. 'i = %lu, entries = %lu'" , i, gtop->path_hash->entries); if (!(gtop->flags & GTOP_NOSORT)) qsort(gtop->path_array, gtop->path_hash->entries, sizeof(char *), compare_path); gtop->path_count = gtop->path_hash->entries; gtop->path_index = 0; if (gtop->path_index >= gtop->path_count) return NULL; gtop->gtp.path = gtop->path_array[gtop->path_index++]; return >op->gtp; } else if (gtop->flags & GTOP_KEY) { for (gtop->gtp.tag = dbop_first(gtop->dbop, key, preg, dbflags); gtop->gtp.tag != NULL; gtop->gtp.tag = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); break; } return gtop->gtp.tag ? >op->gtp : NULL; } else { if (gtop->vb == NULL) gtop->vb = varray_open(sizeof(GTP), 200); else varray_reset(gtop->vb); if (gtop->segment_pool == NULL) gtop->segment_pool = pool_open(); else pool_reset(gtop->segment_pool); if (gtop->path_hash == NULL) gtop->path_hash = strhash_open(HASHBUCKETS); else strhash_reset(gtop->path_hash); tagline = dbop_first(gtop->dbop, key, preg, dbflags); if (tagline == NULL) return NULL; /* * Dbop_next() wil read the same record again. */ dbop_unread(gtop->dbop); /* * Read a tag segment with sorting. */ segment_read(gtop); return >op->gtp_array[gtop->gtp_index++]; } }
/* * prepare_skip: prepare skipping files. * * go) skip regular expression for skip files. * go) listarry[] skip list. * go) list_count count of skip list. */ static void prepare_skip(void) { char *skiplist; STRBUF *reg = strbuf_open(0); int reg_count = 0; char *p, *q; int flags = REG_EXTENDED|REG_NEWLINE; /* * load icase_path option. */ if (getconfb("icase_path")) flags |= REG_ICASE; #if defined(_WIN32) || defined(__DJGPP__) flags |= REG_ICASE; #endif /* * initialize common data. */ if (!list) list = strbuf_open(0); else strbuf_reset(list); list_count = 0; if (listarray) (void)free(listarray); listarray = (char **)0; /* * load skip data. */ if (!getconfs("skip", reg)) { strbuf_close(reg); return; } skiplist = check_strdup(strbuf_value(reg)); trim(skiplist); strbuf_reset(reg); /* * construct regular expression. */ strbuf_putc(reg, '('); /* ) */ /* skip files which start with '.' e.g. .cvsignore */ strbuf_puts(reg, "/\\.[^/]+$|"); strbuf_puts(reg, "/\\.[^/]+/|"); for (p = skiplist; p; ) { char *skipf = p; if ((p = locatestring(p, ",", MATCH_FIRST)) != NULL) *p++ = 0; if (*skipf == '/') { list_count++; strbuf_puts0(list, skipf); } else { reg_count++; strbuf_putc(reg, '/'); for (q = skipf; *q; q++) { if (isregexchar(*q)) strbuf_putc(reg, '\\'); strbuf_putc(reg, *q); } if (*(q - 1) != '/') strbuf_putc(reg, '$'); if (p) strbuf_putc(reg, '|'); } } strbuf_unputc(reg, '|'); strbuf_putc(reg, ')'); if (reg_count > 0) { int retval; /* * compile regular expression. */ skip = &skip_area; retval = regcomp(skip, strbuf_value(reg), flags); #ifdef DEBUG if (debug) fprintf(stderr, "skip regex: %s\n", strbuf_value(reg)); #endif if (retval != 0) die("cannot compile regular expression."); } else { skip = (regex_t *)0; } if (list_count > 0) { int i; listarray = (char **)check_malloc(sizeof(char *) * list_count); p = strbuf_value(list); #ifdef DEBUG if (debug) fprintf(stderr, "skip list: "); #endif for (i = 0; i < list_count; i++) { #ifdef DEBUG if (debug) { fprintf(stderr, "%s", p); if (i + 1 < list_count) fputc(',', stderr); } #endif listarray[i] = p; p += strlen(p) + 1; } #ifdef DEBUG if (debug) fputc('\n', stderr); #endif } strbuf_close(reg); free(skiplist); }
/** * makefileindex: make file index. * * @param[in] file output file name * @param[out] a_files top level file index */ int makefileindex(const char *file, STRBUF *a_files) { STATIC_STRBUF(sb); FILE *filesop; int flags = REG_EXTENDED; /* * Basedir is a directory to which we are paying attention on each * occasion. It starts with ".", grows and shrink according to the * progress of processing. It isn't copied each every recursive call * not to waste the stack. */ char basedir[MAXPATHLEN]; /* * Initialize data. */ indexlink = (Fflag) ? "../files" : "../mains"; src_count = 0; gp = gfind_open(dbpath, NULL, other_files ? GPATH_BOTH : GPATH_SOURCE); /* * for collecting include files. */ if (w32) flags |= REG_ICASE; strbuf_clear(sb); strbuf_puts(sb, "\\.("); { const char *p = include_file_suffixes; int c; while ((c = (unsigned char)*p++) != '\0') { if (isregexchar(c)) strbuf_putc(sb, '\\'); else if (c == ',') c = '|'; strbuf_putc(sb, c); } } strbuf_puts(sb, ")$"); if (regcomp(&is_include_file, strbuf_value(sb), flags) != 0) die("cannot compile regular expression '%s'.", strbuf_value(sb)); /* * Write to files.html. */ if ((filesop = fopen(makepath(distpath, file, NULL), "w")) == NULL) die("cannot open file '%s'.", file); fputs_nl(gen_page_index_begin(title_file_index, jscode), filesop); fputs_nl(body_begin, filesop); fputs(header_begin, filesop); fputs(gen_href_begin(NULL, "files", normal_suffix, NULL), filesop); fputs(title_file_index, filesop); fputs(gen_href_end(), filesop); fputs_nl(header_end, filesop); if (tree_view) { fputs_nl(tree_control, filesop); fputs_nl(tree_loading, filesop); if (tree_view_type) { fprintf(filesop, tree_begin_using, tree_view_type); fputc('\n', filesop); } else { fputs_nl(tree_begin, filesop); } } else if (table_flist) fputs_nl(flist_begin, filesop); else if (!no_order_list) fputs_nl(list_begin, filesop); FILEMAP = NULL; if (filemap_file) { if (!(FILEMAP = fopen(makepath(distpath, "FILEMAP", NULL), "w"))) die("cannot open '%s'.", makepath(distpath, "FILEMAP", NULL)); } /* * print whole directory tree. */ files = a_files; strcpy(basedir, "."); (void)print_directory(0, basedir); if (tree_view) strbuf_puts(files, tree_end); if (filemap_file) fclose(FILEMAP); gfind_close(gp); regfree(&is_include_file); fputs(strbuf_value(files), filesop); if (tree_view) fputs_nl(tree_end, filesop); else if (table_flist) fputs_nl(flist_end, filesop); else if (!no_order_list) fputs_nl(list_end, filesop); fputs_nl(body_end, filesop); fputs_nl(gen_page_end(), filesop); fclose(filesop); html_count++; return src_count; }