src/path.c

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

FUNCTIONS

This source file includes following functions.
  1. vf_path_core_subst_ext
  2. vf_path_base
  3. vf_path_base_core
  4. vf_path_absolute
  5. vf_path_terminated_by_delim
  6. vf_path_terminated_by_2delims
  7. vf_path_del_terminating_2delims
  8. vf_path_cons_path
  9. vf_path_cons_path2
  10. cons_path
  11. vf_path_concat
  12. vf_path_file_read_ok
  13. vf_path_directory_read_ok
  14. vf_path_runtime_dir
  15. vf_path_find_runtime_file
  16. vf_path_runtime_file2

   1 /*
   2  * path.c  --- path string functions
   3  *
   4  */
   5 /*
   6  * Copyright (C) 1996-1999  Hirotsugu Kakugawa. 
   7  * All rights reserved.
   8  *
   9  * This file is part of the VFlib Library.  This library is free
  10  * software; you can redistribute it and/or modify it under the terms of
  11  * the GNU Library General Public License as published by the Free
  12  * Software Foundation; either version 2 of the License, or (at your
  13  * option) any later version.  This library is distributed in the hope
  14  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
  15  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  16  * PURPOSE.  See the GNU Library General Public License for more details.
  17  * You should have received a copy of the GNU Library General Public
  18  * License along with this library; if not, write to the Free Software
  19  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20  */
  21 
  22 #include "config.h"
  23 #include <stdio.h>
  24 #include <stdlib.h>
  25 #include <ctype.h>
  26 #ifdef HAVE_UNISTD_H
  27 #  include <unistd.h>
  28 #endif
  29 #if HAVE_STRING_H
  30 # include <string.h>
  31 #endif
  32 #if HAVE_STRINGS_H
  33 # include <strings.h>
  34 #endif
  35 #include <sys/types.h>
  36 #include <sys/param.h>
  37 #if HAVE_SYS_STAT_H
  38 #  ifdef __linux__
  39 #    define __USE_BSD
  40 #  endif
  41 #  include <sys/stat.h>
  42 #endif
  43 
  44 #include "VFlib-3_6.h"
  45 #include "VFsys.h"
  46 #include "path.h"
  47 #include "vflpaths.h"
  48 #include "consts.h"
  49 #include "str.h"
  50 
  51 
  52 Private int   cons_path(char *path, int n, char *dir, char *file, char *ext);
  53 Private char *vf_path_runtime_file2(char *root, char *subdir, char *file,
  54                                     char *envname);
  55 
  56 
  57 
  58 Glocal char*
  59 vf_path_core_subst_ext(char *f, char *ext) 
     /* [<][>][^][v][top][bottom][index][help] */
  60      /* "/opt/font/cmr10.300pk" & "vf" => "cmr10.vf" */
  61      /* IMPORTANT: CALLER MUST RELEASE RETURNED DATA OBJECT */
  62 {
  63   char  *b, *p, *e;
  64 
  65   if ((f == NULL) || (ext == NULL))
  66     return NULL;
  67 
  68   if ((b = vf_path_base(f)) == NULL){
  69     vf_error = VF_ERR_NO_MEMORY;
  70     return NULL;
  71   }
  72   if ((p = (char*)malloc(strlen(b) + 1 + strlen(ext) + 1)) == NULL){
  73     vf_error = VF_ERR_NO_MEMORY;
  74     return NULL;
  75   }
  76   strcpy(p, b);
  77   vf_free(b);
  78 
  79   if ((e = vf_index(p, '.')) != NULL)
  80     *e = '\0';
  81   if (*ext != '.')
  82     strcat(p, ".");
  83   strcat(p, ext);
  84 
  85   return p;
  86 }
  87 
  88 
  89 Glocal char*
  90 vf_path_base(char *f)   
     /* [<][>][^][v][top][bottom][index][help] */
  91      /* "/opt/font/cmr10.300pk" => "cmr10.300pk" */
  92      /* IMPORTANT: CALLER MUST RELEASE RETURNED DATA OBJECT */
  93 {
  94   char  *s, *b;
  95   int   dl; 
  96 
  97   dl = strlen(vf_directory_delimiter);
  98   b = f;
  99   for (s = f; *s != '\0'; s++){
 100     if (strncmp(s, vf_directory_delimiter, dl) == 0)
 101       b = &s[dl];
 102   }
 103   return vf_strdup(b); 
 104 }
 105 
 106 
 107 Glocal char*
 108 vf_path_base_core(char *f)
     /* [<][>][^][v][top][bottom][index][help] */
 109      /* "/opt/font/cmr10.300pk" => "cmr10" */
 110      /* IMPORTANT: CALLER MUST RELEASE RETURNED DATA OBJECT */
 111 {
 112   char  *p, *core;
 113 
 114   if ((core = vf_path_base(f)) == NULL)
 115     return NULL;
 116   if ((p = vf_index(core, '.')) != NULL)
 117     *p = '\0';
 118   return core;
 119 }
 120 
 121 
 122 
 123 
 124 Glocal int
 125 vf_path_absolute(char *f)
     /* [<][>][^][v][top][bottom][index][help] */
 126 {
 127   if (strncmp(f, vf_directory_delimiter,
 128               strlen(vf_directory_delimiter)) == 0){
 129     return TRUE;
 130   }
 131 
 132 #ifdef MSDOS
 133   if ((strlen(f) >= 3) 
 134       && isalpha(f[0]) && (f[1] == ':') 
 135       && ((f[2] == '/') || (f[2] == '\\'))){
 136     return TRUE;
 137   }
 138 #endif /*MSDOS*/
 139 
 140   return FALSE;
 141 }
 142 
 143 Glocal int
 144 vf_path_terminated_by_delim(char *f)
     /* [<][>][^][v][top][bottom][index][help] */
 145 {
 146   int   dlen, index;
 147 
 148   dlen = strlen(vf_directory_delimiter);
 149 
 150   if ((index = strlen(f) - dlen) < 0)
 151     return FALSE;
 152   if (strcmp(&f[index], vf_directory_delimiter) != 0)
 153     return FALSE;
 154 
 155   return TRUE;  
 156 }
 157 
 158 Glocal int
 159 vf_path_terminated_by_2delims(char *f)
     /* [<][>][^][v][top][bottom][index][help] */
 160 {
 161   int   dlen, index;
 162 
 163   dlen = strlen(vf_directory_delimiter);
 164 
 165   if ((index = strlen(f) - 2*dlen) < 0)
 166     return FALSE;
 167   if (strncmp(&f[index],      vf_directory_delimiter, dlen) != 0)
 168     return FALSE;
 169   if (strncmp(&f[index+dlen], vf_directory_delimiter, dlen) != 0)
 170     return FALSE;
 171 
 172   return TRUE;  
 173 }
 174 
 175 Glocal void
 176 vf_path_del_terminating_2delims(char *f)
     /* [<][>][^][v][top][bottom][index][help] */
 177 {
 178   int   dlen;
 179 
 180   if (vf_path_terminated_by_2delims(f) == TRUE){
 181     dlen = strlen(vf_directory_delimiter);
 182     f[strlen(f)-2*dlen] = '\0';
 183   }
 184 }
 185 
 186 Glocal int
 187 vf_path_cons_path(char *path, int n, char *dir, char *file)
     /* [<][>][^][v][top][bottom][index][help] */
 188 {
 189   return cons_path(path, n, dir, file, NULL);
 190 }
 191 
 192 Glocal int
 193 vf_path_cons_path2(char *path, int n, char *dir, char *file, char *ext)
     /* [<][>][^][v][top][bottom][index][help] */
 194 {
 195   return cons_path(path, n, dir, file, ext);
 196 }
 197 
 198 Private int
 199 cons_path(char *path, int n, char *dir, char *file, char *ext)
     /* [<][>][^][v][top][bottom][index][help] */
 200 {
 201   int  r;
 202 
 203   r = n;
 204   if (vf_path_absolute(file)){
 205     strncpy(path, file, n);
 206     if ((r -= strlen(file)) < 0)
 207       return -1;
 208     if (ext != NULL)
 209       strncat(path, ext, r);
 210     return 0;
 211   } else {
 212     strncpy(path, dir, r);
 213     if ((r -= strlen(dir)) < 0)
 214       return -1;
 215     if (vf_path_terminated_by_2delims(path) == TRUE)
 216       vf_path_del_terminating_2delims(path);
 217     strncat(path, vf_directory_delimiter, r);
 218     if ((r -= strlen(vf_directory_delimiter)) < 0)
 219       return -1;
 220     strncat(path, file, r);
 221     if ((r -= strlen(file)) < 0)
 222       return -1;
 223     if (ext != NULL)
 224       strncat(path, ext, r);
 225   }
 226 
 227   return 0;
 228 }
 229 
 230 Glocal int
 231 vf_path_concat(char *path, int n, char *f)
     /* [<][>][^][v][top][bottom][index][help] */
 232 {
 233   if (vf_path_terminated_by_2delims(path) == TRUE)
 234     vf_path_del_terminating_2delims(path);
 235   strncat(path, vf_directory_delimiter, n);
 236   strncat(path, f, n - strlen(path));
 237 
 238   return 0;
 239 }
 240 
 241 
 242 
 243 
 244 Glocal int
 245 vf_path_file_read_ok(char *f)
     /* [<][>][^][v][top][bottom][index][help] */
 246 {
 247 #if HAVE_SYS_STAT_H
 248   struct stat  st;
 249 
 250   if (stat(f, &st) < 0)
 251     return FALSE;
 252   if ((st.st_mode & S_IFMT) != S_IFREG)
 253     return FALSE;
 254 #endif
 255 
 256   if (access(f, R_OK) < 0)
 257     return FALSE;
 258 
 259   return TRUE;
 260 }
 261 
 262 Glocal int
 263 vf_path_directory_read_ok(char *f)
     /* [<][>][^][v][top][bottom][index][help] */
 264 {
 265 #if HAVE_SYS_STAT_H
 266   struct stat  st;
 267 
 268   if (stat(f, &st) < 0)
 269     return FALSE;
 270   if ((st.st_mode & S_IFMT) != S_IFDIR)
 271     return FALSE;
 272 #endif
 273 
 274   if (access(f, R_OK) < 0)
 275     return FALSE;
 276 
 277   return TRUE;
 278 }
 279 
 280 
 281 Glocal char*
 282 vf_path_runtime_dir(char *subdir, char *envname)
     /* [<][>][^][v][top][bottom][index][help] */
 283      /* return a absolute directory name of SUBDIR under the default 
 284         runtime dir. Runtime dir can be overridden by ""
 285         It can be overridden by an env var ENVNAME if 
 286         it is defined. */
 287      /* IMPORTANT: CALLER MUST RELEASE RETURNED DATA OBJECT */
 288 {
 289   char  *root, *dir, *s;
 290   int    sd_len, dir_len;
 291 
 292   if ((root = getenv(VF_ENV_DIR_RUNTIME_LIB)) == NULL)
 293     root = DIR_RUNTIME_LIB;
 294 
 295   if ((envname != NULL) && ((s = getenv(envname)) != NULL)){
 296     root = s;
 297     subdir = NULL;
 298   }
 299 
 300   if (subdir == NULL)
 301     sd_len = 0;
 302   else
 303     sd_len = strlen(subdir);
 304   dir_len = strlen(root) + strlen(vf_directory_delimiter) + sd_len + 4;
 305   ALLOCN_IF_ERR(dir, char, dir_len){
 306     return NULL;
 307   }
 308 
 309   if ((subdir == NULL) || (strcmp(subdir, "") == 0)){
 310     strncpy(dir, root, dir_len);
 311   } else {
 312     vf_path_cons_path(dir, dir_len, root, subdir);
 313   }
 314 
 315   return  dir;
 316 }
 317 
 318 Glocal char*
 319 vf_path_find_runtime_file(char *subdir, char *file, char *envname)
     /* [<][>][^][v][top][bottom][index][help] */
 320      /* return a absolute directory name of SUBDIR under the default 
 321         runtime dir. Runtime dir can be overridden by ""
 322         It can be overridden by an env var ENVNAME if 
 323         it is defined. */
 324      /* IMPORTANT: CALLER MUST RELEASE RETURNED DATA OBJECT */
 325 {
 326   char *root, *p;
 327 
 328   if ((root = getenv(VF_ENV_DIR_RUNTIME_SITE_LIB)) == NULL)
 329     root = DIR_RUNTIME_SITE_LIB;
 330   p = vf_path_runtime_file2(root, subdir, file, envname);
 331   if (p != NULL)
 332     return p;
 333 
 334   if ((root = getenv(VF_ENV_DIR_RUNTIME_LIB)) == NULL)
 335     root = DIR_RUNTIME_LIB;
 336   p = vf_path_runtime_file2(root, subdir, file, envname);
 337   return p;
 338 }
 339 
 340 Private char*
 341 vf_path_runtime_file2(char *root, char *subdir, char *file, char *envname)
     /* [<][>][^][v][top][bottom][index][help] */
 342 {
 343   char  *dir, *s;
 344   int    sd_len, dir_len;
 345 
 346   if ((envname != NULL) && ((s = getenv(envname)) != NULL)){
 347     root = s;
 348     subdir = NULL;
 349   }
 350 
 351   if (subdir == NULL)
 352     sd_len = 0;
 353   else
 354     sd_len = strlen(subdir);
 355   dir_len = strlen(root) + sd_len + strlen(file) 
 356             + 2 * strlen(vf_directory_delimiter) + 8;
 357   ALLOCN_IF_ERR(dir, char, dir_len){
 358     return NULL;
 359   }
 360 
 361   if ((subdir == NULL) || (strcmp(subdir, "") == 0)){
 362     vf_path_cons_path(dir, dir_len, root, file);
 363   } else {
 364     vf_path_cons_path(dir, dir_len, root, subdir);
 365     vf_path_concat(dir, dir_len, file);
 366   }
 367   if (vf_path_file_read_ok(dir) == FALSE){
 368     vf_free(dir);
 369     dir = NULL;
 370   }
 371 
 372   return  dir;
 373 }
 374 
 375 
 376 /*EOF*/

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