/* * gpath_open: open gpath tag file * * i) dbpath GTAGSDBPATH * i) mode 0: read only * 1: create * 2: modify * r) 0: normal * -1: error */ int gpath_open(const char *dbpath, int mode) { if (opened > 0) { if (mode != _mode) die("duplicate open with different mode."); opened++; return 0; } /* * We create GPATH just first time. */ _mode = mode; if (mode == 1 && created) mode = 0; dbop = dbop_open(makepath(dbpath, dbname(GPATH), NULL), mode, 0644, 0); if (dbop == NULL) return -1; if (mode == 1) { dbop_putversion(dbop, create_version); _nextkey = 1; } else { int format_version; const char *path = dbop_get(dbop, NEXTKEY); if (path == NULL) die("nextkey not found in GPATH."); _nextkey = atoi(path); format_version = dbop_getversion(dbop); if (format_version > support_version) die("GPATH seems new format. Please install the latest GLOBAL."); else if (format_version < support_version) die("GPATH seems older format. Please remake tag files."); } opened++; return 0; }
/** * gtags_open: open global tag. * * @param[in] dbpath dbpath directory * @param[in] root root directory (needed when compact format) * @param[in] db #GTAGS, #GRTAGS, #GSYMS * @param[in] mode #GTAGS_READ: read only <br> * #GTAGS_CREATE: create tag <br> * #GTAGS_MODIFY: modify tag * @param[in] flags #GTAGS_COMPACT: compact format * @return #GTOP structure * * @note when error occurred, @NAME{gtags_open()} doesn't return. */ GTOP * gtags_open(const char *dbpath, const char *root, int db, int mode, int flags) { GTOP *gtop; char tagfile[MAXPATHLEN]; int dbmode; gtop = (GTOP *)check_calloc(sizeof(GTOP), 1); gtop->db = db; gtop->mode = mode; gtop->openflags = flags; /* * Open tag file allowing duplicate records. */ switch (gtop->mode) { case GTAGS_READ: dbmode = 0; break; case GTAGS_CREATE: dbmode = 1; break; case GTAGS_MODIFY: dbmode = 2; break; default: assert(0); } /* * GRTAGS and GSYMS are virtual tag file. They are included in a real GRTAGS file. * In fact, GSYMS doesn't exist now. * * GRTAGS: tags which belongs to GRTAGS, and are defined in GTAGS. * GSYMS: tags which belongs to GRTAGS, and is not defined in GTAGS. */ strlimcpy(tagfile, makepath(dbpath, dbname(db == GSYMS ? GRTAGS : db), NULL), sizeof(tagfile)); gtop->dbop = dbop_open(tagfile, dbmode, 0644, DBOP_DUP|DBOP_SORTED_WRITE); if (gtop->dbop == NULL) { if (dbmode == 1) die("cannot make %s.", dbname(db)); die("%s not found.", dbname(db)); } if (gtop->mode == GTAGS_READ && db != GTAGS) { const char *gtags = makepath(dbpath, dbname(GTAGS), NULL); int format_version; gtop->gtags = dbop_open(gtags, 0, 0, 0); if (gtop->gtags == NULL) die("GTAGS not found."); format_version = dbop_getversion(gtop->dbop); if (format_version > upper_bound_version) die("%s seems new format. Please install the latest GLOBAL.", gtags); else if (format_version < lower_bound_version) die("%s seems older format. Please remake tag files.", gtags); } if (gtop->mode == GTAGS_CREATE) { /* * Decide format. */ gtop->format = 0; gtop->format_version = new_format_version; /* * GRTAGS and GSYSM always use compact format. * GTAGS uses compact format only when the -c option specified. */ if (gtop->db == GRTAGS || gtop->db == GSYMS || gtop->openflags & GTAGS_COMPACT) { gtop->format |= GTAGS_COMPACT; gtop->format |= GTAGS_COMPLINE; } else { /* standard format */ gtop->format |= GTAGS_COMPRESS; } gtop->format |= GTAGS_COMPNAME; if (gtop->format & GTAGS_COMPACT) dbop_putoption(gtop->dbop, COMPACTKEY, NULL); if (gtop->format & GTAGS_COMPRESS) { dbop_putoption(gtop->dbop, COMPRESSKEY, DEFAULT_ABBREVIATION); abbrev_open(DEFAULT_ABBREVIATION); } if (gtop->format & GTAGS_COMPLINE) dbop_putoption(gtop->dbop, COMPLINEKEY, NULL); if (gtop->format & GTAGS_COMPNAME) dbop_putoption(gtop->dbop, COMPNAMEKEY, NULL); dbop_putversion(gtop->dbop, gtop->format_version); } else { /* * recognize format version of GTAGS. 'format version record' * is saved as a META record in GTAGS and GRTAGS. * if 'format version record' is not found, it's assumed * version 1. */ const char *p; /* * check format version. */ gtop->format_version = dbop_getversion(gtop->dbop); if (gtop->format_version > upper_bound_version) die("%s seems new format. Please install the latest GLOBAL.", tagfile); else if (gtop->format_version < lower_bound_version) die("%s seems older format. Please remake tag files.", tagfile); gtop->format = 0; if (dbop_getoption(gtop->dbop, COMPACTKEY) != NULL) gtop->format |= GTAGS_COMPACT; if ((p = dbop_getoption(gtop->dbop, COMPRESSKEY)) != NULL) { abbrev_open(p); gtop->format |= GTAGS_COMPRESS; } if (dbop_getoption(gtop->dbop, COMPLINEKEY) != NULL) gtop->format |= GTAGS_COMPLINE; if (dbop_getoption(gtop->dbop, COMPNAMEKEY) != NULL) gtop->format |= GTAGS_COMPNAME; } if (gpath_open(dbpath, dbmode) < 0) { if (dbmode == 1) die("cannot create GPATH."); else die("GPATH not found."); } if (gtop->mode != GTAGS_READ) gtop->sb = strbuf_open(0); /* This buffer is used for working area. */ /* * Stuff for compact format. */ if (gtop->format & GTAGS_COMPACT) { assert(root != NULL); strlimcpy(gtop->root, root, sizeof(gtop->root)); if (gtop->mode != GTAGS_READ) gtop->path_hash = strhash_open(HASHBUCKETS); } return gtop; }