/////////////////////////////////////////// // level_rigthmost(bp *b, i64 d) /////////////////////////////////////////// i64 level_rigthmost(bp *b, i64 d) { i64 t; if (d < 1) return -1; if (d == 1) return 0; t = bwd_excess(b,b->n-1,d)+1; return find_open(b,t); }
/////////////////////////////////////////// // prev_sibling(bp *b,i64 s) // returns the previous sibling of parent(s) // -1 if s is the first child ////////////////////////////////////////// i64 prev_sibling(bp *b, i64 s) { i64 t; if (s < 0) { printf("prev_sibling: error s=%d\n",(int)s); } if (s == 0) return -1; if (inspect(b,s-1) == OP) return -1; t = find_open(b,s-1); return t; }
/* * createtags: create tags file * * i) dbpath dbpath directory * i) root root directory of source tree */ void createtags(const char *dbpath, const char *root) { STATISTICS_TIME *tim; STRBUF *sb = strbuf_open(0); struct put_func_data data; int openflags, flags, seqno; const char *path; tim = statistics_time_start("Time of creating %s and %s.", dbname(GTAGS), dbname(GRTAGS)); if (vflag) fprintf(stderr, "[%s] Creating '%s' and '%s'.\n", now(), dbname(GTAGS), dbname(GRTAGS)); openflags = cflag ? GTAGS_COMPACT : 0; data.gtop[GTAGS] = gtags_open(dbpath, root, GTAGS, GTAGS_CREATE, openflags); data.gtop[GTAGS]->flags = 0; if (extractmethod) data.gtop[GTAGS]->flags |= GTAGS_EXTRACTMETHOD; data.gtop[GRTAGS] = gtags_open(dbpath, root, GRTAGS, GTAGS_CREATE, openflags); data.gtop[GRTAGS]->flags = data.gtop[GTAGS]->flags; flags = 0; if (debug) flags |= PARSER_DEBUG; if (wflag) flags |= PARSER_WARNING; /* * Add tags to GTAGS and GRTAGS. */ if (file_list) find_open_filelist(file_list, root); else find_open(NULL); seqno = 0; while ((path = find_read()) != NULL) { if (*path == ' ') { path++; if (!test("b", path)) gpath_put(path, GPATH_OTHER); continue; } gpath_put(path, GPATH_SOURCE); data.fid = gpath_path2fid(path, NULL); if (data.fid == NULL) die("GPATH is corrupted.('%s' not found)", path); seqno++; if (vflag) fprintf(stderr, " [%d] extracting tags of %s\n", seqno, path + 2); if (debug) fprintf(stderr, "[%s]\n", path + 2); parse_file(path, flags, put_syms, &data); gtags_flush(data.gtop[GTAGS], data.fid); gtags_flush(data.gtop[GRTAGS], data.fid); } total = seqno; parser_exit(); find_close(); statistics_time_end(tim); tim = statistics_time_start("Time of flushing B-tree cache"); gtags_close(data.gtop[GTAGS]); gtags_close(data.gtop[GRTAGS]); statistics_time_end(tim); strbuf_reset(sb); if (getconfs("GTAGS_extra", sb)) { tim = statistics_time_start("Time of executing GTAGS_extra command"); if (system(strbuf_value(sb))) fprintf(stderr, "GTAGS_extra command failed: %s\n", strbuf_value(sb)); statistics_time_end(tim); } strbuf_reset(sb); if (getconfs("GRTAGS_extra", sb)) { tim = statistics_time_start("Time of executing GRTAGS_extra command"); if (system(strbuf_value(sb))) fprintf(stderr, "GRTAGS_extra command failed: %s\n", strbuf_value(sb)); statistics_time_end(tim); } strbuf_close(sb); }
/* * incremental: incremental update * * i) dbpath dbpath directory * i) root root directory of source tree * r) 0: not updated, 1: updated */ int incremental(const char *dbpath, const char *root) { STATISTICS_TIME *tim; struct stat statp; STRBUF *addlist = strbuf_open(0); STRBUF *deletelist = strbuf_open(0); STRBUF *addlist_other = strbuf_open(0); IDSET *deleteset, *findset; int updated = 0; const char *path; unsigned int id, limit; tim = statistics_time_start("Time of inspecting %s and %s.", dbname(GTAGS), dbname(GRTAGS)); if (vflag) { fprintf(stderr, " Tag found in '%s'.\n", dbpath); fprintf(stderr, " Incremental updating.\n"); } /* * get modified time of GTAGS. */ path = makepath(dbpath, dbname(GTAGS), NULL); if (gpath_open(dbpath, 0) < 0) die("GPATH not found."); /* * deleteset: * The list of the path name which should be deleted from GPATH. * findset: * The list of the path name which exists in the current project. * A project is limited by the --file option. */ deleteset = idset_open(gpath_nextkey()); findset = idset_open(gpath_nextkey()); total = 0; /* * Make add list and delete list for update. */ if (single_update) { int type; const char *fid = gpath_path2fid(single_update, &type); /* * The --single-update=file supports only updating. * If it is new file, this option is ignored, and the processing is * automatically switched to the normal procedure. */ if (fid == NULL) { if (vflag) fprintf(stderr, " --single-update option ignored, because '%s' is new file.\n", single_update); goto normal_update; } /* * If type != GPATH_SOURCE then we have nothing to do, and you will see * a message 'Global databases are up to date.'. */ if (type == GPATH_SOURCE) { strbuf_puts0(addlist, single_update); idset_add(deleteset, atoi(fid)); total++; } } else { normal_update: if (file_list) find_open_filelist(file_list, root); else find_open(NULL); while ((path = find_read()) != NULL) { const char *fid; int n_fid = 0; int other = 0; /* a blank at the head of path means 'NOT SOURCE'. */ if (*path == ' ') { if (test("b", ++path)) continue; other = 1; } if (stat(path, &statp) < 0) die("stat failed '%s'.", path); fid = gpath_path2fid(path, NULL); if (fid) { n_fid = atoi(fid); idset_add(findset, n_fid); } if (other) { if (fid == NULL) strbuf_puts0(addlist_other, path); } else { if (fid == NULL) { strbuf_puts0(addlist, path); total++; } else if (gpath_mtime(NULL, fid) < statp.st_mtime) { if (uflag) { printf("%s\n", path); } else { strbuf_puts0(addlist, path); total++; idset_add(deleteset, n_fid); } } } } find_close(); /* * make delete list. */ if (remove_lost) { limit = gpath_nextkey(); } else { limit = 0; } for (id = 1; id < limit; id++) { char fid[MAXFIDLEN]; int type; snprintf(fid, sizeof(fid), "%d", id); /* * This is a hole of GPATH. The hole increases if the deletion * and the addition are repeated. */ if ((path = gpath_fid2path(fid, &type)) == NULL) continue; /* * The file which does not exist in the findset is treated * assuming that it does not exist in the file system. */ if (type == GPATH_OTHER) { if (!idset_contains(findset, id) || !test("f", path) || test("b", path)) strbuf_puts0(deletelist, path); } else { if (!idset_contains(findset, id) || !test("f", path)) { strbuf_puts0(deletelist, path); idset_add(deleteset, id); } } } } gpath_close(); statistics_time_end(tim); /* * execute updating. */ if ((!idset_empty(deleteset) || strbuf_getlen(addlist) > 0) || (strbuf_getlen(deletelist) + strbuf_getlen(addlist_other) > 0)) { int db; updated = 1; tim = statistics_time_start("Time of updating %s and %s.", dbname(GTAGS), dbname(GRTAGS)); if (!idset_empty(deleteset) || strbuf_getlen(addlist) > 0) updatetags(dbpath, root, deleteset, addlist); if (strbuf_getlen(deletelist) + strbuf_getlen(addlist_other) > 0) { const char *start, *end, *p; if (vflag) fprintf(stderr, "[%s] Updating '%s'.\n", now(), dbname(GPATH)); gpath_open(dbpath, 2); if (strbuf_getlen(deletelist) > 0) { start = strbuf_value(deletelist); end = start + strbuf_getlen(deletelist); for (p = start; p < end; p += strlen(p) + 1) gpath_delete(p); } if (strbuf_getlen(addlist_other) > 0) { start = strbuf_value(addlist_other); end = start + strbuf_getlen(addlist_other); for (p = start; p < end; p += strlen(p) + 1) gpath_put(p, GPATH_OTHER); } gpath_close(); } /* * Update modification time of tag files * because they may have no definitions. */ for (db = GTAGS; db < GTAGLIM; db++) utime(makepath(dbpath, dbname(db), NULL), NULL); statistics_time_end(tim); } if (vflag) { if (updated) fprintf(stderr, " Global databases have been modified.\n"); else fprintf(stderr, " Global databases are up to date.\n"); fprintf(stderr, "[%s] Done.\n", now()); } strbuf_close(addlist); strbuf_close(deletelist); strbuf_close(addlist_other); idset_close(deleteset); idset_close(findset); return updated; }
/////////////////////////////////////////// // level_prev(bp *b, i64 d) /////////////////////////////////////////// i64 level_prev(bp *b,i64 s) { i64 t; t = find_open(b,bwd_excess(b,s,0)+1); return t; }