source: git/src/filename.c @ aadc86e

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

0.90 beta 2

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

  • Property mode set to 100644
File size: 4.2 KB
Line 
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5/* OS dependent filename manipulation routines */
6#include "filename.h"
7#include <string.h>
8
9/* Wrapper for fopen which throws a fatal error if it fails.
10 * Some versions of fopen() are quite happy to open a directory.
11 * We aren't, so catch this case. */
12extern FILE *
13safe_fopen(const char *fnm, const char *mode)
14{
15   FILE *f;
16   if (fDirectory(fnm))
17      fatalerror(/*Filename '%s' refers to directory*/44, fnm);
18
19   f = fopen(fnm, mode);
20   if (!f) fatalerror(mode[0] == 'w' ?
21                      /*Failed to open output file*/47 :
22                      /*Couldn't open data file*/24, fnm);
23   return f;
24}
25
26FILE *
27fopen_not_dir(const char *fnm, const char *mode)
28{
29   if (fDirectory(fnm)) return NULL;
30   return fopen(fnm, mode);
31}
32
33extern char * FAR
34PthFromFnm(const char *fnm)
35{
36   char *pth;
37   const char *lf;
38   int lenpth = 0;
39
40   lf = strrchr(fnm, FNM_SEP_LEV);
41#ifdef FNM_SEP_LEV2
42   if (!lf) lf = strrchr(fnm, FNM_SEP_LEV2);
43#endif
44#ifdef FNM_SEP_DRV
45   if (!lf) lf = strrchr(fnm, FNM_SEP_DRV);
46#endif
47   if (lf) lenpth = lf - fnm + 1;
48
49   pth = osmalloc(lenpth + 1);
50   memcpy(pth, fnm, lenpth);
51   pth[lenpth] = '\0';
52
53   return pth;
54}
55
56extern char * FAR
57LfFromFnm(const char *fnm)
58{
59   char *lf;
60   lf = strrchr(fnm, FNM_SEP_LEV);
61   if (lf != NULL
62#ifdef FNM_SEP_LEV2
63       || (lf = strrchr(fnm, FNM_SEP_LEV2)) != NULL
64#endif
65#ifdef FNM_SEP_DRV
66       || (lf = strrchr(fnm, FNM_SEP_DRV)) != NULL
67#endif
68       ) {
69      return osstrdup(lf + 1);
70   }
71   return osstrdup(fnm);
72}
73
74/* Make fnm from pth and lf, inserting an FNM_SEP_LEV if appropriate */
75extern char * FAR
76UsePth(const char *pth, const char *lf)
77{
78   char *fnm;
79   int len, len_total;
80   bool fAddSep = fFalse;
81
82   len = strlen(pth);
83   len_total = len + strlen(lf) + 1;
84
85   /* if there's a path and it doesn't end in a separator, insert one */
86   if (len && pth[len - 1] != FNM_SEP_LEV) {
87#ifdef FNM_SEP_LEV2
88      if (pth[len - 1] != FNM_SEP_LEV2) {
89#endif
90#ifdef FNM_SEP_DRV
91         if (pth[len - 1] != FNM_SEP_DRV) {
92#endif
93            fAddSep = fTrue;
94            len_total++;
95#ifdef FNM_SEP_DRV
96         }
97#endif
98#ifdef FNM_SEP_LEV2
99      }
100#endif
101   }
102
103   fnm = osmalloc(len_total);
104   strcpy(fnm, pth);
105   if (fAddSep) fnm[len++] = FNM_SEP_LEV;
106   strcpy(fnm + len, lf);
107   return fnm;
108}
109
110/* Add ext to fnm, inserting an FNM_SEP_EXT if appropriate */
111extern char * FAR
112AddExt(const char *fnm, const char *ext)
113{
114   char * fnmNew;
115   int len, len_total;
116#ifdef FNM_SEP_EXT
117   bool fAddSep = fFalse;
118#endif
119
120   len = strlen(fnm);
121   len_total = len + strlen(ext) + 1;
122#ifdef FNM_SEP_EXT
123   if (ext[0] != FNM_SEP_EXT) {
124      fAddSep = fTrue;
125      len_total++;
126   }
127#endif
128
129   fnmNew = osmalloc(len_total);
130   strcpy(fnmNew, fnm);
131#ifdef FNM_SEP_EXT
132   if (fAddSep) fnmNew[len++] = FNM_SEP_EXT;
133#endif
134   strcpy(fnmNew + len, ext);
135   return fnmNew;
136}
137
138/* fopen file, found using pth and fnm
139 * pfnmUsed used to return filename used to open file (ignored if NULL)
140 * or NULL if file didn't open
141 */
142extern FILE FAR *
143fopenWithPthAndExt(const char * pth, const char * fnm, const char * szExt,
144                   const char * szMode, char **pfnmUsed)
145{
146   char *fnmFull = NULL;
147   FILE *fh = NULL;
148   bool fAbs;
149
150   /* if no pth treat fnm as absolute */
151   fAbs = (pth == NULL || *pth == '\0' || fAbsoluteFnm(fnm));
152
153   /* if appropriate, try it without pth */
154   if (fAbs) {
155      fh = fopen_not_dir(fnm, szMode);
156      if (fh) {
157         if (pfnmUsed) fnmFull = osstrdup(fnm);
158      } else {
159         if (szExt && *szExt) {
160            /* we've been given an extension so try using it */
161            fnmFull = AddExt(fnm, szExt);
162            fh = fopen_not_dir(fnmFull, szMode);
163         }
164      }
165   } else {
166      /* try using path given - first of all without the extension */
167      fnmFull = UsePth(pth, fnm);
168      fh = fopen_not_dir(fnmFull, szMode);
169      if (!fh) {
170         if (szExt && *szExt) {
171            /* we've been given an extension so try using it */
172            char *fnmTmp;
173            fnmTmp = fnmFull;
174            fnmFull = AddExt(fnmFull, szExt);
175            osfree(fnmTmp);
176            fh = fopen_not_dir(fnmFull, szMode);
177         }
178      }
179   }
180
181   /* either it opened or didn't. If not, fh == NULL from fopen_not_dir() */
182
183   /* free name if it didn't open or name isn't wanted */
184   if (fh == NULL || pfnmUsed == NULL) osfree(fnmFull);
185   if (pfnmUsed) *pfnmUsed = (fh ? fnmFull : NULL);
186   return fh;
187}
Note: See TracBrowser for help on using the repository browser.