source: git/src/filename.c @ e05bdb8

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 e05bdb8 was ce5b43c, checked in by Olly Betts <olly@…>, 26 years ago

fettled function names

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

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