source: git/src/filename.c @ 0a603b6

RELEASE/1.0RELEASE/1.1RELEASE/1.2debug-cidebug-ci-sanitisersfaster-cavernloglog-selectstereostereo-2025walls-datawalls-data-hanging-as-warningwarn-only-for-hanging-survey
Last change on this file since 0a603b6 was 6ba8d69, checked in by Olly Betts <olly@…>, 26 years ago

minor

git-svn-id: file:///home/survex-svn/survex/trunk@173 4b37db11-9a0c-4f06-9ece-9ab7cdaee568

  • Property mode set to 100644
File size: 5.3 KB
RevLine 
[6ba8d69]1/* OS dependent filename manipulation routines */
2
[a420b49]3#ifdef HAVE_CONFIG_H
4# include <config.h>
5#endif
6
[9af1d7a9]7#include "filename.h"
8#include <string.h>
9
[ce5b43c]10/* FIXME: finish sorting out safe_fopen vs fopenWithPthAndExt... */
11
[a420b49]12/* Wrapper for fopen which throws a fatal error if it fails.
13 * Some versions of fopen() are quite happy to open a directory.
14 * We aren't, so catch this case. */
15extern FILE *
16safe_fopen(const char *fnm, const char *mode)
17{
18   FILE *f;
19   if (fDirectory(fnm))
20      fatalerror(/*Filename '%s' refers to directory*/44, fnm);
21
22   f = fopen(fnm, mode);
23   if (!f) fatalerror(mode[0] == 'w' ?
24                      /*Failed to open output file*/47 :
25                      /*Couldn't open data file*/24, fnm);
26   return f;
27}
28
[ce5b43c]29extern FILE *
30safe_fopen_with_ext(const char *fnm, const char *ext, const char *mode)
31{
32   FILE *f;
33   char *p;
34   p = add_ext(fnm, ext);
35   f = safe_fopen(p, mode);
36   osfree(p);
37   return f;
38}
39
40static FILE *
[a420b49]41fopen_not_dir(const char *fnm, const char *mode)
42{
43   if (fDirectory(fnm)) return NULL;
44   return fopen(fnm, mode);
[9af1d7a9]45}
46
[a420b49]47extern char * FAR
[ce5b43c]48path_from_fnm(const char *fnm)
[a420b49]49{
[9af1d7a9]50   char *pth;
51   const char *lf;
52   int lenpth = 0;
53
[a420b49]54   lf = strrchr(fnm, FNM_SEP_LEV);
[9af1d7a9]55#ifdef FNM_SEP_LEV2
[a420b49]56   if (!lf) lf = strrchr(fnm, FNM_SEP_LEV2);
[9af1d7a9]57#endif
58#ifdef FNM_SEP_DRV
[a420b49]59   if (!lf) lf = strrchr(fnm, FNM_SEP_DRV);
[9af1d7a9]60#endif
61   if (lf) lenpth = lf - fnm + 1;
62
[a420b49]63   pth = osmalloc(lenpth + 1);
64   memcpy(pth, fnm, lenpth);
[9af1d7a9]65   pth[lenpth] = '\0';
66
67   return pth;
68}
69
[ce5b43c]70extern char *
71base_from_fnm(const char *fnm)
72{
73   char *p;
74   
75   p = strrchr(fnm, FNM_SEP_EXT);
76   /* Trim off any leaf extension, but dirs can have extensions too */
77   if (p && !strrchr(p, FNM_SEP_LEV)
78#ifdef FNM_SEP_LEV2
79       && !strrchr(p, FNM_SEP_LEV2)
80#endif
81       ) {
82      size_t len = p - fnm;
83
84      p = osmalloc(len + 1);
85      memcpy(p, fnm, len);
86      p[len] = '\0';
87      return p;
88   }
89
90   return osstrdup(fnm);
91}
92
93extern char *
94baseleaf_from_fnm(const char *fnm)
95{
96   const char *p;
97   char *q;
98   size_t len;
99   
100   p = fnm;
101   q = strrchr(p, FNM_SEP_LEV);
102   if (q) p = q + 1;
103#ifdef FNM_SEP_LEV2
104   q = strrchr(p, FNM_SEP_LEV2);
105   if (q) p = q + 1;
106#endif
107   
108   q = strrchr(p, FNM_SEP_EXT);
109   if (q) len = q - p; else len = strlen(p);
110
111   q = osmalloc(len + 1);
112   memcpy(q, p, len);
113   q[len] = '\0';
114   return q;
115}
116
[a420b49]117extern char * FAR
[ce5b43c]118leaf_from_fnm(const char *fnm)
[a420b49]119{
[9af1d7a9]120   char *lf;
[a420b49]121   lf = strrchr(fnm, FNM_SEP_LEV);
122   if (lf != NULL
[9af1d7a9]123#ifdef FNM_SEP_LEV2
[a420b49]124       || (lf = strrchr(fnm, FNM_SEP_LEV2)) != NULL
[9af1d7a9]125#endif
126#ifdef FNM_SEP_DRV
[a420b49]127       || (lf = strrchr(fnm, FNM_SEP_DRV)) != NULL
[9af1d7a9]128#endif
129       ) {
130      return osstrdup(lf + 1);
131   }
132   return osstrdup(fnm);
133}
134
135/* Make fnm from pth and lf, inserting an FNM_SEP_LEV if appropriate */
[a420b49]136extern char * FAR
[ce5b43c]137use_path(const char *pth, const char *lf)
[a420b49]138{
[9af1d7a9]139   char *fnm;
140   int len, len_total;
141   bool fAddSep = fFalse;
142
143   len = strlen(pth);
144   len_total = len + strlen(lf) + 1;
145
146   /* if there's a path and it doesn't end in a separator, insert one */
[a420b49]147   if (len && pth[len - 1] != FNM_SEP_LEV) {
[9af1d7a9]148#ifdef FNM_SEP_LEV2
[a420b49]149      if (pth[len - 1] != FNM_SEP_LEV2) {
[9af1d7a9]150#endif
151#ifdef FNM_SEP_DRV
[a420b49]152         if (pth[len - 1] != FNM_SEP_DRV) {
[9af1d7a9]153#endif
154            fAddSep = fTrue;
155            len_total++;
156#ifdef FNM_SEP_DRV
157         }
158#endif
159#ifdef FNM_SEP_LEV2
160      }
161#endif
162   }
163
164   fnm = osmalloc(len_total);
[a420b49]165   strcpy(fnm, pth);
[9af1d7a9]166   if (fAddSep) fnm[len++] = FNM_SEP_LEV;
[a420b49]167   strcpy(fnm + len, lf);
[9af1d7a9]168   return fnm;
169}
170
171/* Add ext to fnm, inserting an FNM_SEP_EXT if appropriate */
[a420b49]172extern char * FAR
[ce5b43c]173add_ext(const char *fnm, const char *ext)
[a420b49]174{
[9af1d7a9]175   char * fnmNew;
176   int len, len_total;
177#ifdef FNM_SEP_EXT
178   bool fAddSep = fFalse;
179#endif
180
181   len = strlen(fnm);
182   len_total = len + strlen(ext) + 1;
183#ifdef FNM_SEP_EXT
184   if (ext[0] != FNM_SEP_EXT) {
185      fAddSep = fTrue;
186      len_total++;
187   }
188#endif
189
190   fnmNew = osmalloc(len_total);
[a420b49]191   strcpy(fnmNew, fnm);
[9af1d7a9]192#ifdef FNM_SEP_EXT
193   if (fAddSep) fnmNew[len++] = FNM_SEP_EXT;
194#endif
[a420b49]195   strcpy(fnmNew + len, ext);
[9af1d7a9]196   return fnmNew;
197}
198
199/* fopen file, found using pth and fnm
200 * pfnmUsed used to return filename used to open file (ignored if NULL)
201 * or NULL if file didn't open
202 */
[a420b49]203extern FILE FAR *
204fopenWithPthAndExt(const char * pth, const char * fnm, const char * szExt,
205                   const char * szMode, char **pfnmUsed)
206{
207   char *fnmFull = NULL;
208   FILE *fh = NULL;
209   bool fAbs;
210
211   /* if no pth treat fnm as absolute */
212   fAbs = (pth == NULL || *pth == '\0' || fAbsoluteFnm(fnm));
213
214   /* if appropriate, try it without pth */
215   if (fAbs) {
216      fh = fopen_not_dir(fnm, szMode);
217      if (fh) {
218         if (pfnmUsed) fnmFull = osstrdup(fnm);
219      } else {
220         if (szExt && *szExt) {
221            /* we've been given an extension so try using it */
[ce5b43c]222            fnmFull = add_ext(fnm, szExt);
[a420b49]223            fh = fopen_not_dir(fnmFull, szMode);
224         }
[9af1d7a9]225      }
[a420b49]226   } else {
227      /* try using path given - first of all without the extension */
[ce5b43c]228      fnmFull = use_path(pth, fnm);
[a420b49]229      fh = fopen_not_dir(fnmFull, szMode);
230      if (!fh) {
231         if (szExt && *szExt) {
232            /* we've been given an extension so try using it */
233            char *fnmTmp;
234            fnmTmp = fnmFull;
[ce5b43c]235            fnmFull = add_ext(fnmFull, szExt);
[a420b49]236            osfree(fnmTmp);
237            fh = fopen_not_dir(fnmFull, szMode);
238         }
[9af1d7a9]239      }
[a420b49]240   }
241
242   /* either it opened or didn't. If not, fh == NULL from fopen_not_dir() */
243
244   /* free name if it didn't open or name isn't wanted */
245   if (fh == NULL || pfnmUsed == NULL) osfree(fnmFull);
246   if (pfnmUsed) *pfnmUsed = (fh ? fnmFull : NULL);
247   return fh;
[9af1d7a9]248}
Note: See TracBrowser for help on using the repository browser.