root/libutil/getdbpath.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. setupvariables
  2. getobjdir
  3. gtagsexist
  4. setupdbpath
  5. get_dbpath
  6. get_root
  7. get_root_with_slash
  8. get_cwd

   1 /*
   2  * Copyright (c) 1997, 1998, 1999, 2000, 2002, 2008, 2011
   3  *      Tama Communications Corporation
   4  *
   5  * This file is part of GNU GLOBAL.
   6  *
   7  * This program is free software: you can redistribute it and/or modify
   8  * it under the terms of the GNU General Public License as published by
   9  * the Free Software Foundation, either version 3 of the License, or
  10  * (at your option) any later version.
  11  * 
  12  * This program is distributed in the hope that it will be useful,
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  * GNU General Public License for more details.
  16  * 
  17  * You should have received a copy of the GNU General Public License
  18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19  */
  20 
  21 #ifdef HAVE_CONFIG_H
  22 #include <config.h>
  23 #endif
  24 #include <sys/types.h>
  25 #include <sys/stat.h>
  26 #ifdef STDC_HEADERS
  27 #include <stdlib.h>
  28 #endif
  29 #ifdef HAVE_STRING_H
  30 #include <string.h>
  31 #else
  32 #include <strings.h>
  33 #endif
  34 #ifdef HAVE_UNISTD_H
  35 #include <unistd.h>
  36 #endif
  37 
  38 #include "gparam.h"
  39 #include "die.h"
  40 #include "getdbpath.h"
  41 #include "gtagsop.h"
  42 #include "makepath.h"
  43 #include "path.h"
  44 #include "strlimcpy.h"
  45 #include "test.h"
  46 
  47 /**
  48  * define the position of the root slash.
  49  */
  50 #if defined(_WIN32) || defined(__DJGPP__)
  51 #define ROOT 2
  52 #else
  53 #define ROOT 0
  54 #endif
  55 
  56 static const char *makeobjdirprefix;    /**< obj partition              */
  57 static const char *makeobjdir;          /**< obj directory              */
  58 char const *gtags_dbpath_error;         /**< error message */
  59 
  60 /**
  61  * setupvariables: load variables regard to @NAME{BSD} @NAME{OBJ} directory.
  62  */
  63 static void
  64 setupvariables(int verbose)
  65 {
  66         const char *p;
  67 
  68         if ((p = getenv("MAKEOBJDIRPREFIX")) != NULL) {
  69                 makeobjdirprefix = p;
  70                 if (verbose)
  71                         fprintf(stderr, "MAKEOBJDIRPREFIX is set to '%s'.\n", p);
  72         } else {
  73                 makeobjdirprefix = "/usr/obj";
  74         }
  75         if ((p = getenv("MAKEOBJDIR")) != NULL) {
  76                 makeobjdir = p;
  77                 if (verbose)
  78                         fprintf(stderr, "MAKEOBJDIR is set to '%s'.\n", p);
  79         } else {
  80                 makeobjdir = "obj";
  81         }
  82 }
  83 /**
  84  * getobjdir: get objdir if it exists.
  85  *
  86  *      @param[in]      candidate candidate root directory
  87  *      @param[in]      verbose verbose mode 1: on, 0: off
  88  *      @return         objdir(@VAR{NULL}: not found)
  89  */
  90 char *
  91 getobjdir(const char *candidate, int verbose)
  92 {
  93         static char path[MAXPATHLEN];
  94 
  95         /*
  96          * setup makeobjdir and makeobjdirprefix (only first time).
  97          */
  98         if (makeobjdir == NULL)
  99                 setupvariables(0);
 100         snprintf(path, sizeof(path), "%s/%s", candidate, makeobjdir);
 101         if (test("d", path)) {
 102                 if (!test("drw", path))
 103                         die("Found objdir '%s', but you don't have read/write permission for it.", path);
 104                 if (verbose)
 105                         fprintf(stderr, "Using objdir '%s'.\n", path);
 106                 return path;
 107         }
 108 #if !defined(_WIN32) && !defined(__DJGPP__)
 109         if (test("d", makeobjdirprefix)) {
 110                 snprintf(path, sizeof(path), "%s%s", makeobjdirprefix, candidate);
 111                 if (test("d", path)) {
 112                         if (!test("drw", path))
 113                                 die("Found objdir '%s', but you don't have read/write permission for it.", path);
 114                         if (verbose)
 115                                 fprintf(stderr, "Using objdir '%s'.\n", path);
 116                         return path;
 117                 }
 118                 if (makedirectories(makeobjdirprefix, candidate + 1, verbose) < 0)
 119                         die("Found the base for objdir '%s', but you cannot create new directory in it.", path);
 120                 if (verbose)
 121                         fprintf(stderr, "Using objdir '%s'.\n", path);
 122                 return path;
 123         }
 124 #endif
 125         return NULL;
 126 }
 127 /**
 128  * gtagsexist: test whether GTAGS's existence.
 129  *
 130  *      @param[in]      candidate candidate root directory
 131  *      @param[out]     dbpath  directory which @FILE{GTAGS} exist
 132  *      @param[in]      size    size of @a dbpath buffer
 133  *      @param[in]      verbose verbose mode 1: on, 0: off
 134  *      @return         0: not found, 1: found
 135  *
 136  * Gtagsexist locate @FILE{GTAGS} file in @FILE{\$candidate/}, @FILE{\$candidate/obj/} and
 137  * @FILE{/usr/obj/\$candidate/} in this order by default. <br>
 138  * This behavior is same with @NAME{BSD} @XREF{make,1}'s one.
 139  */
 140 int
 141 gtagsexist(const char *candidate, char *dbpath, int size, int verbose)
 142 {
 143         char path[MAXPATHLEN];
 144         const char *candidate_without_slash;
 145 
 146         /*
 147          * setup makeobjdir and makeobjdirprefix (only first time).
 148          */
 149         if (makeobjdir == NULL)
 150                 setupvariables(verbose);
 151 
 152         if (strcmp(candidate, "/") == 0)
 153                 candidate_without_slash = "";
 154         else
 155                 candidate_without_slash = candidate;
 156         snprintf(path, sizeof(path), "%s/%s", candidate_without_slash, dbname(GTAGS));
 157         if (verbose)
 158                 fprintf(stderr, "checking %s\n", path);
 159         if (test("fr", path)) {
 160                 if (verbose)
 161                         fprintf(stderr, "GTAGS found at '%s'.\n", path);
 162                 snprintf(dbpath, size, "%s", candidate);
 163                 return 1;
 164         }
 165         snprintf(path, sizeof(path),
 166                 "%s/%s/%s", candidate_without_slash, makeobjdir, dbname(GTAGS));
 167         if (verbose)
 168                 fprintf(stderr, "checking %s\n", path);
 169         if (test("fr", path)) {
 170                 if (verbose)
 171                         fprintf(stderr, "GTAGS found at '%s'.\n", path);
 172                 snprintf(dbpath, size, "%s/%s", candidate_without_slash, makeobjdir);
 173                 return 1;
 174         }
 175 #if !defined(_WIN32) && !defined(__DJGPP__)
 176         snprintf(path, sizeof(path),
 177                 "%s%s/%s", makeobjdirprefix, candidate_without_slash, dbname(GTAGS));
 178         if (verbose)
 179                 fprintf(stderr, "checking %s\n", path);
 180         if (test("fr", path)) {
 181                 if (verbose)
 182                         fprintf(stderr, "GTAGS found at '%s'.\n", path);
 183                 snprintf(dbpath, size, "%s%s", makeobjdirprefix, candidate_without_slash);
 184                 return 1;
 185         }
 186 #endif
 187         return 0;
 188 }
 189 static char dbpath[MAXPATHLEN];
 190 static char root[MAXPATHLEN];
 191 static char root_with_slash[MAXPATHLEN];
 192 static char cwd[MAXPATHLEN];
 193 /**
 194  * setupdbpath: setup dbpath directory
 195  *
 196  *      @param[in]      verbose verbose mode 1: on, 0: off
 197  *
 198  *      @par Globals used (output):
 199  *              #cwd:   current directory <br>
 200  *              #root:  root of source tree <br>
 201  *              #dbpath: directory which @FILE{GTAGS} exist <br>
 202  *              #gtags_dbpath_error: set if status (return value) \< 0
 203  *
 204  *      @return 0: normal, 0\<: error
 205  */
 206 int
 207 setupdbpath(int verbose)
 208 {
 209         struct stat sb;
 210         char *p;
 211         static char msg[1024];
 212 
 213         if (!getcwd(cwd, MAXPATHLEN)) {
 214                 gtags_dbpath_error = "cannot get current directory.";
 215                 return -1;
 216         }
 217         canonpath(cwd);
 218 
 219         if ((p = getenv("GTAGSROOT")) != NULL) {
 220                 if (verbose)
 221                         fprintf(stderr, "GTAGSROOT is set to '%s'.\n", p);
 222                 if (!isabspath(p)) {
 223                         gtags_dbpath_error = "GTAGSROOT must be an absolute path.";
 224                         return -1;
 225                 }
 226                 if (stat(p, &sb) || !S_ISDIR(sb.st_mode)) {
 227                         snprintf(msg, sizeof(msg), "directory '%s' not found.", p);
 228                         gtags_dbpath_error = msg;
 229                         return -1;
 230                 }
 231                 if (realpath(p, root) == NULL) {
 232                         snprintf(msg, sizeof(msg), "cannot get real path of '%s'.", p);
 233                         gtags_dbpath_error = msg;
 234                         return -1;
 235                 }
 236                 /*
 237                  * GTAGSDBPATH is meaningful only when GTAGSROOT exist.
 238                  */
 239                 if ((p = getenv("GTAGSDBPATH")) != NULL) {
 240                         if (verbose)
 241                                 fprintf(stderr, "GTAGSDBPATH is set to '%s'.\n", p);
 242                         if (!isabspath(p)) {
 243                                 gtags_dbpath_error = "GTAGSDBPATH must be an absolute path.";
 244                                 return -1;
 245                         }
 246                         if (stat(p, &sb) || !S_ISDIR(sb.st_mode)) {
 247                                 snprintf(msg, sizeof(msg), "directory '%s' not found.", p);
 248                                 gtags_dbpath_error = msg;
 249                                 return -1;
 250                         }
 251                         strlimcpy(dbpath, getenv("GTAGSDBPATH"), MAXPATHLEN);
 252                 } else {
 253                         if (!gtagsexist(root, dbpath, MAXPATHLEN, verbose)) {
 254                                 gtags_dbpath_error = "GTAGS not found.";
 255                                 return -3;
 256                         }
 257                 }
 258         } else {
 259                 if (verbose && getenv("GTAGSDBPATH"))
 260                         fprintf(stderr, "warning: GTAGSDBPATH is ignored because GTAGSROOT is not set.\n");
 261                 /*
 262                  * start from current directory to '/' directory.
 263                  */
 264                 strlimcpy(root, cwd, MAXPATHLEN);
 265                 p = root + strlen(root);
 266                 while (!gtagsexist(root, dbpath, MAXPATHLEN, verbose)) {
 267                         if (!strcmp(root+ROOT, "/")) {  /* reached the system's root directory */
 268                                 *(root+ROOT) = '\0';
 269                                 break;
 270                         }
 271                         while (*--p != '/' && p > (root+ROOT))
 272                                 ;
 273                         if (p == (root+ROOT))
 274                                 p++;
 275                         *p = 0;
 276                 }
 277                 if (*(root+ROOT) == 0) {
 278                         gtags_dbpath_error = "GTAGS not found.";
 279                         return -3;
 280                 }
 281                 /*
 282                  * If file 'GTAGSROOT' found without environment variable
 283                  * GTAGSDBPATH, use the value of it as GTAGSROOT.
 284                  */
 285                 do {
 286                         FILE *fp;
 287                         STRBUF *sb;
 288                         const char *s, *path;
 289 
 290                         path = makepath(root, "GTAGSROOT", NULL);
 291                         if (!test("fr", path)) {
 292                                 break;
 293                         }
 294                         fp = fopen(path, "r");
 295                         if (fp == NULL) {
 296                                 if (verbose)
 297                                         fprintf(stderr, "'%s' ignored because it cannot be opened.\n", path);
 298                                 break;
 299                         }
 300                         sb = strbuf_open(0);
 301                         s = strbuf_fgets(sb, fp, STRBUF_NOCRLF);
 302                         if (!test("d", s)) {
 303                                 if (verbose)
 304                                         fprintf(stderr, "'%s' ignored because it doesn't include existent directory name.\n", path);
 305                         } else {
 306                                 char buf[MAXPATHLEN];
 307 
 308                                 if (verbose)
 309                                         fprintf(stderr, "GTAGSROOT found at '%s'.\n", path);
 310                                 if (!isabspath(s))
 311                                         s = realpath(makepath(root, s, NULL), buf);
 312                                 strlimcpy(root, s, MAXPATHLEN);
 313                         }
 314                         fclose(fp);
 315                         strbuf_close(sb);
 316                         break;
 317                 } while (0);
 318         }
 319         if (!strcmp(root+ROOT, "/"))
 320                 strlimcpy(root_with_slash, root, sizeof(root_with_slash));
 321         else
 322                 snprintf(root_with_slash, sizeof(root_with_slash), "%s/", root);
 323         return 0;
 324 }
 325 /**
 326  * @name return saved values.
 327  */
 328 /** @{ */
 329 const char *
 330 get_dbpath(void)
 331 {
 332         return (const char *)dbpath;
 333 }
 334 const char *
 335 get_root(void)
 336 {
 337         return (const char *)root;
 338 }
 339 const char *
 340 get_root_with_slash(void)
 341 {
 342         return (const char *)root_with_slash;
 343 }
 344 const char *
 345 get_cwd(void)
 346 {
 347         return (const char *)cwd;
 348 }
 349 /** @} */

/* [previous][next][first][last][top][bottom][index][help] */