source: git/src/filename.c @ d2eae80

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 d2eae80 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
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
[a420b49]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);
[9af1d7a9]31}
32
[a420b49]33extern char * FAR
34PthFromFnm(const char *fnm)
35{
[9af1d7a9]36   char *pth;
37   const char *lf;
38   int lenpth = 0;
39
[a420b49]40   lf = strrchr(fnm, FNM_SEP_LEV);
[9af1d7a9]41#ifdef FNM_SEP_LEV2
[a420b49]42   if (!lf) lf = strrchr(fnm, FNM_SEP_LEV2);
[9af1d7a9]43#endif
44#ifdef FNM_SEP_DRV
[a420b49]45   if (!lf) lf = strrchr(fnm, FNM_SEP_DRV);
[9af1d7a9]46#endif
47   if (lf) lenpth = lf - fnm + 1;
48
[a420b49]49   pth = osmalloc(lenpth + 1);
50   memcpy(pth, fnm, lenpth);
[9af1d7a9]51   pth[lenpth] = '\0';
52
53   return pth;
54}
55
[a420b49]56extern char * FAR
57LfFromFnm(const char *fnm)
58{
[9af1d7a9]59   char *lf;
[a420b49]60   lf = strrchr(fnm, FNM_SEP_LEV);
61   if (lf != NULL
[9af1d7a9]62#ifdef FNM_SEP_LEV2
[a420b49]63       || (lf = strrchr(fnm, FNM_SEP_LEV2)) != NULL
[9af1d7a9]64#endif
65#ifdef FNM_SEP_DRV
[a420b49]66       || (lf = strrchr(fnm, FNM_SEP_DRV)) != NULL
[9af1d7a9]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 */
[a420b49]75extern char * FAR
76UsePth(const char *pth, const char *lf)
77{
[9af1d7a9]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 */
[a420b49]86   if (len && pth[len - 1] != FNM_SEP_LEV) {
[9af1d7a9]87#ifdef FNM_SEP_LEV2
[a420b49]88      if (pth[len - 1] != FNM_SEP_LEV2) {
[9af1d7a9]89#endif
90#ifdef FNM_SEP_DRV
[a420b49]91         if (pth[len - 1] != FNM_SEP_DRV) {
[9af1d7a9]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);
[a420b49]104   strcpy(fnm, pth);
[9af1d7a9]105   if (fAddSep) fnm[len++] = FNM_SEP_LEV;
[a420b49]106   strcpy(fnm + len, lf);
[9af1d7a9]107   return fnm;
108}
109
110/* Add ext to fnm, inserting an FNM_SEP_EXT if appropriate */
[a420b49]111extern char * FAR
112AddExt(const char *fnm, const char *ext)
113{
[9af1d7a9]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);
[a420b49]130   strcpy(fnmNew, fnm);
[9af1d7a9]131#ifdef FNM_SEP_EXT
132   if (fAddSep) fnmNew[len++] = FNM_SEP_EXT;
133#endif
[a420b49]134   strcpy(fnmNew + len, ext);
[9af1d7a9]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 */
[a420b49]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         }
[9af1d7a9]164      }
[a420b49]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         }
[9af1d7a9]178      }
[a420b49]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;
[9af1d7a9]187}
Note: See TracBrowser for help on using the repository browser.