root/libutil/gpathop.c(148.html)

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gpath_open
  2. gpath_put
  3. gpath_path2fid
  4. gpath_fid2path
  5. gpath_delete
  6. gpath_nextkey
  7. gpath_close
  8. gfind_open
  9. gfind_read
  10. gfind_close

/*
 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2005, 2006
 *      Tama Communications Corporation
 *
 * This file is part of GNU GLOBAL.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifdef HAVE_CONFIG_H #include <config.h> #endif #include <assert.h> #ifdef STDC_HEADERS #include <stdlib.h> #endif #ifdef HAVE_STRING_H #include <string.h> #else #include <strings.h> #endif #include "checkalloc.h" #include "die.h" #include "dbop.h" #include "gtagsop.h" #include "makepath.h" #include "gpathop.h" #include "strbuf.h" #include "strlimcpy.h" static DBOP *dbop; static int _nextkey; static int _mode; static int opened; static int created; /* * GPATH format version * * 1. Gtags(1) bury version number in GPATH. * 2. Global(1) pick up the version number from GPATH. If the number * is not acceptable version number then global give up work any more * and display error message. * 3. If version number is not found then it assumes version 1. * 4. GPATH version is independent with the other tag files. * * [History of format version] * * GLOBAL-4.8.7 no idea about format version. * GLOBAL-5.0 understand format version. * support format version 2. * * - Format version 1 * * GPATH has only source files. * * key data * -------------------- * ./aaa.c\0 11\0 * * - Format version 2 * * GPATH has not only source files but also other files like README. * You can distinguish them by the flag following data value. * At present, the flag value is only 'o'(other files). * * key data * -------------------- * ./aaa.c\0 11\0 * ./README\0 12\0o\0 <=== 'o' means other files. */
static int support_version = 2; /* acceptable format version */
static int create_version = 2; /* format version of newly created tag file */
/* * 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; } /* * gpath_put: put path name * * i) path path name * i) type path type * GPATH_SOURCE: source file * GPATH_OTHER: other file */
void gpath_put(const char *path, int type) { char fid[32]; STATIC_STRBUF(sb); assert(opened > 0); if (_mode == 1 && created) return; if (dbop_get(dbop, path) != NULL) return; /* * generate new file id for the path. */
snprintf(fid, sizeof(fid), "%d", _nextkey++); /* * path => fid mapping. */
strbuf_clear(sb); strbuf_puts0(sb, fid); if (type == GPATH_OTHER) strbuf_puts0(sb, "o"); dbop_put_withlen(dbop, path, strbuf_value(sb), strbuf_getlen(sb)); /* * fid => path mapping. */
strbuf_clear(sb); strbuf_puts0(sb, path); if (type == GPATH_OTHER) strbuf_puts0(sb, "o"); dbop_put_withlen(dbop, fid, strbuf_value(sb), strbuf_getlen(sb)); } /* * gpath_path2fid: convert path into id * * i) path path name * o) type path type * GPATH_SOURCE: source file * GPATH_OTHER: other file * r) file id */
const char * gpath_path2fid(const char *path, int *type) { const char *fid = dbop_get(dbop, path); assert(opened > 0); if (fid && type) { const char *flag = dbop_getflag(dbop); *type = (*flag == 'o') ? GPATH_OTHER : GPATH_SOURCE; } return fid; } /* * gpath_fid2path: convert id into path * * i) fid file id * o) type path type * GPATH_SOURCE: source file * GPATH_OTHER: other file * r) path name */
const char * gpath_fid2path(const char *fid, int *type) { const char *path = dbop_get(dbop, fid); assert(opened > 0); if (path && type) { const char *flag = dbop_getflag(dbop); *type = (*flag == 'o') ? GPATH_OTHER : GPATH_SOURCE; } return path; } /* * gpath_delete: delete specified path record * * i) path path name */
void gpath_delete(const char *path) { const char *fid; assert(opened > 0); assert(_mode == 2); assert(path[0] == '.' && path[1] == '/'); fid = dbop_get(dbop, path); if (fid == NULL) return; dbop_delete(dbop, fid); dbop_delete(dbop, path); } /* * gpath_nextkey: return next key * * r) next id */
int gpath_nextkey(void) { assert(_mode != 1); return _nextkey; } /* * gpath_close: close gpath tag file */
void gpath_close(void) { char fid[32]; assert(opened > 0); if (--opened > 0) return; if (_mode == 1 && created) { dbop_close(dbop); return; } if (_mode == 1 || _mode == 2) { snprintf(fid, sizeof(fid), "%d", _nextkey); dbop_update(dbop, NEXTKEY, fid); } dbop_close(dbop); if (_mode == 1) created = 1; } /* * gfind iterator using GPATH. * * gfind_xxx() does almost same with find_xxx() but much faster, * because gfind_xxx() use GPATH (file index). * If GPATH exist then you should use this. */
/* * gfind_open: start iterator using GPATH. * * i) dbpath dbpath * i) local local prefix * if NULL specified, it assumes "./"; * i) target GPATH_SOURCE: only source file * GPATH_OTHER: only other file * GPATH_BOTH: source file + other file * r) GFIND structure */
GFIND * gfind_open(const char *dbpath, const char *local, int target) { GFIND *gfind = (GFIND *)check_calloc(sizeof(GFIND), 1); gfind->dbop = dbop_open(makepath(dbpath, dbname(GPATH), NULL), 0, 0, 0); if (gfind->dbop == NULL) die("GPATH not found."); gfind->path = NULL; gfind->prefix = check_strdup(local ? local : "./"); gfind->first = 1; gfind->eod = 0; gfind->target = target; gfind->type = GPATH_SOURCE; gfind->version = dbop_getversion(gfind->dbop); if (gfind->version > support_version) die("GPATH seems new format. Please install the latest GLOBAL."); else if (gfind->version < support_version) die("GPATH seems older format. Please remake tag files."); return gfind; } /* * gfind_read: read path using GPATH. * * i) gfind GFIND structure * r) path */
const char * gfind_read(GFIND *gfind) { const char *flag; gfind->type = GPATH_SOURCE; if (gfind->eod) return NULL; for (;;) { if (gfind->first) { gfind->first = 0; gfind->path = dbop_first(gfind->dbop, gfind->prefix, NULL, DBOP_KEY | DBOP_PREFIX); } else { gfind->path = dbop_next(gfind->dbop); } if (gfind->path == NULL) { gfind->eod = 1; break; } /* * if gfind->target == 0, return only source files. * *flag == 'o' means 'other files' like README. */
flag = dbop_getflag(gfind->dbop); gfind->type = (*flag == 'o') ? GPATH_OTHER : GPATH_SOURCE; if (gfind->type & gfind->target) break; } return gfind->path; } /* * gfind_close: close iterator. */
void gfind_close(GFIND *gfind) { dbop_close(gfind->dbop); free((void *)gfind->prefix); free(gfind); }

/* [<][>][^][v][top][bottom][index][help] */