/* * Copyright (c) 1997, 1998, 1999, 2000, 2002 * 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 . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #ifdef STDC_HEADERS #include #endif #ifdef HAVE_STRING_H #include #else #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "gparam.h" #include "die.h" #include "getdbpath.h" #include "gtagsop.h" #include "makepath.h" #include "path.h" #include "strlimcpy.h" #include "test.h" static const char *makeobjdirprefix; /* obj partition */ static const char *makeobjdir; /* obj directory */ /* * setupvariables: load variables regard to BSD OBJ directory. */ static void setupvariables(int verbose) { const char *p; if ((p = getenv("MAKEOBJDIRPREFIX")) != NULL) { makeobjdirprefix = p; if (verbose) fprintf(stderr, "MAKEOBJDIRPREFIX is set to '%s'.\n", p); } else { makeobjdirprefix = "/usr/obj"; } if ((p = getenv("MAKEOBJDIR")) != NULL) { makeobjdir = p; if (verbose) fprintf(stderr, "MAKEOBJDIR is set to '%s'.\n", p); } else { makeobjdir = "obj"; } } /* * gtagsexist: test whether GTAGS's existence. * * i) candidate candidate root directory * o) dbpath directory which GTAGS exist * i) size size of dbpath buffer * i) verbose verbose mode 1: on, 0: off * r) 0: not found, 1: found * * Gtagsexist locate GTAGS file in "$candidate/", "$candidate/obj/" and * "/usr/obj/$candidate/" in this order by default. * This behavior is same with BSD make(1)'s one. */ int gtagsexist(const char *candidate, char *dbpath, int size, int verbose) { char path[MAXPATHLEN+1]; /* * setup makeobjdir and makeobjdirprefix (only first time). */ if (makeobjdir == NULL) setupvariables(verbose); snprintf(path, sizeof(path), "%s/%s", candidate, dbname(GTAGS)); if (verbose) fprintf(stderr, "checking %s\n", path); if (test("fr", path)) { if (verbose) fprintf(stderr, "GTAGS found at '%s'.\n", path); snprintf(dbpath, size, "%s", candidate); return 1; } snprintf(path, sizeof(path), "%s/%s/%s", candidate, makeobjdir, dbname(GTAGS)); if (verbose) fprintf(stderr, "checking %s\n", path); if (test("fr", path)) { if (verbose) fprintf(stderr, "GTAGS found at '%s'.\n", path); snprintf(dbpath, size, "%s/%s", candidate, makeobjdir); return 1; } #if !defined(_WIN32) && !defined(__DJGPP__) snprintf(path, sizeof(path), "%s%s/%s", makeobjdirprefix, candidate, dbname(GTAGS)); if (verbose) fprintf(stderr, "checking %s\n", path); if (test("fr", path)) { if (verbose) fprintf(stderr, "GTAGS found at '%s'.\n", path); snprintf(dbpath, size, "%s%s", makeobjdirprefix, candidate); return 1; } #endif return 0; } /* * getdbpath: get dbpath directory * * o) cwd current directory * o) root root of source tree * o) dbpath directory which GTAGS exist * i) verbose verbose mode 1: on, 0: off * * root and dbpath assumed as * char cwd[MAXPATHLEN+1]; * char root[MAXPATHLEN+1]; * char dbpath[MAXPATHLEN+1]; * * At first, getdbpath locate GTAGS file in the current directory. * If not found, it move up to the parent directory and locate GTAGS again. * It repeat above behavior until GTAGS file is found or reach the system's * root directory '/'. If reached to '/' then getdbpath print "GTAGS not found." * and exit. */ void getdbpath(char *cwd, char *root, char *dbpath, int verbose) { struct stat sb; char *p; if (!getcwd(cwd, MAXPATHLEN)) die("cannot get current directory."); canonpath(cwd); if ((p = getenv("GTAGSROOT")) != NULL) { if (verbose) fprintf(stderr, "GTAGSROOT is set to '%s'.\n", p); if (!isabspath(p)) die("GTAGSROOT must be an absolute path."); if (stat(p, &sb) || !S_ISDIR(sb.st_mode)) die("directory '%s' not found.", p); if (realpath(p, root) == NULL) die("cannot get real path of '%s'.", p); /* * GTAGSDBPATH is meaningful only when GTAGSROOT exist. */ if ((p = getenv("GTAGSDBPATH")) != NULL) { if (verbose) fprintf(stderr, "GTAGSDBPATH is set to '%s'.\n", p); if (!isabspath(p)) die("GTAGSDBPATH must be an absolute path."); if (stat(p, &sb) || !S_ISDIR(sb.st_mode)) die("directory '%s' not found.", p); strlimcpy(dbpath, getenv("GTAGSDBPATH"), MAXPATHLEN); } else { if (!gtagsexist(root, dbpath, MAXPATHLEN, verbose)) die_with_code(3, "GTAGS not found."); } } else { if (verbose && getenv("GTAGSDBPATH")) fprintf(stderr, "warning: GTAGSDBPATH is ignored because GTAGSROOT is not set.\n"); /* * start from current directory to '/' directory. */ strlimcpy(root, cwd, MAXPATHLEN); p = root + strlen(root); while (!gtagsexist(root, dbpath, MAXPATHLEN, verbose)) { while (*--p != '/' && p > root) ; *p = 0; if (root == p) /* reached root directory */ break; } if (*root == 0) die_with_code(3, "GTAGS not found."); /* * If file 'GTAGSROOT' found without environment variable * GTAGSDBPATH, use the value of it as GTAGSROOT. */ do { FILE *fp; STRBUF *sb; const char *s, *path; path = makepath(root, "GTAGSROOT", NULL); if (!test("fr", path)) { break; } fp = fopen(path, "r"); if (fp == NULL) { if (verbose) fprintf(stderr, "'%s' ignored because it cannot be opened.\n", path); break; } sb = strbuf_open(0); s = strbuf_fgets(sb, fp, STRBUF_NOCRLF); if (!test("d", s)) { if (verbose) fprintf(stderr, "'%s' ignored because it doesn't include existent directory name.\n", path); } else { if (verbose) fprintf(stderr, "GTAGSROOT found at '%s'.\n", path); if (*s != '/') { char buf[MAXPATHLEN+1]; s = realpath(makepath(root, s, NULL), buf); } strlimcpy(root, s, MAXPATHLEN); } fclose(fp); strbuf_close(sb); break; } while (0); } }