source: git/src/filename.c @ a922586

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 a922586 was 89231c4, checked in by Olly Betts <olly@…>, 25 years ago

Updated GPL info (now has correct address for FSF)

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

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