FrontISTR  5.7.0
Large-scale structural analysis program with finit element method
hecmw_path.c
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2019 FrontISTR Commons
3  * This software is released under the MIT License, see LICENSE.txt
4  *****************************************************************************/
5 
6 #include <stdio.h>
7 #include <ctype.h>
8 #include <string.h>
9 #include <errno.h>
10 #include "hecmw_config.h"
11 #include "hecmw_path.h"
12 #include "hecmw_util.h"
13 
14 #ifdef __MINGW32__
15 #define PATH_SEPARATOR '/'
16 #elif __MINGW64__
17 #define PATH_SEPARATOR '/'
18 #elif __CYGWIN__
19 #define PATH_SEPARATOR '/'
20 #elif __WIN32__
21 #define PATH_SEPARATOR '\\'
22 #else
23 #define PATH_SEPARATOR '/'
24 #endif
25 
26 #ifdef __WIN32__
27 #define isslash(c) ((c) == '/' || (c) == '\\')
28 #elif __CYGWIN__
29 #define isslash(c) ((c) == '/' || (c) == '\\')
30 #else
31 #define isslash(c) ((c) == '/')
32 #endif
33 
35 
36 static int has_drive(const char *path) {
37  const char *p = path;
38 
39  if (path == NULL) return 0;
40  if (!*p || !isalpha(*p)) return 0;
41  p++;
42  return (*p == ':');
43 }
44 
45 int HECMW_is_absolute_path(const char *path) {
46  if (path == NULL) return 0;
47 
48 #ifdef __WIN32__
49  if (*path && isslash(*path)) return 1;
50  return has_drive(path);
51 #elif __CYGWIN__
52  if (*path && isslash(*path)) return 1;
53  return has_drive(path);
54 #else
55  return (*path && isslash(*path));
56 #endif
57 }
58 
59 static char *dir_name(const char *path) {
60  const char *p;
61  static char dname[HECMW_FILENAME_LEN + 1];
62 
63  if (path == NULL || strlen(path) == 0) {
64  strcpy(dname, ".");
65  return dname;
66  }
67 
68  p = path + strlen(path) - 1;
69  while (p > path && isslash(*p)) {
70  p--;
71  }
72 
73  while (p > path && !isslash(*p)) {
74  p--;
75  }
76 
77  if (p == path) {
78  sprintf(dname, "%c", isslash(*p) ? PATH_SEPARATOR : '.');
79  return dname;
80  } else {
81  do {
82  p--;
83  } while (p > path && isslash(*p));
84  }
85 
86  if (p - path + 1 > HECMW_FILENAME_LEN) {
87  errno = ENAMETOOLONG;
88  return NULL;
89  }
90  strncpy(dname, path, p - path + 1);
91  dname[p - path + 1] = '\0';
92 
93  return dname;
94 }
95 
96 static char *base_name(const char *path) {
97  const char *sp, *ep;
98  static char bname[HECMW_FILENAME_LEN + 1];
99 
100  if (path == NULL || strlen(path) == 0) {
101  strcpy(bname, ".");
102  return bname;
103  }
104 
105  ep = path + strlen(path) - 1;
106  while (ep > path && isslash(*ep)) {
107  ep--;
108  }
109 
110  if (ep == path && isslash(*ep)) {
111  sprintf(bname, "%c", PATH_SEPARATOR);
112  return bname;
113  }
114 
115  sp = ep;
116  while (sp > path && !isslash(*(sp - 1))) {
117  sp--;
118  }
119 
120  if (ep - sp + 1 > HECMW_FILENAME_LEN) {
121  errno = ENAMETOOLONG;
122  return NULL;
123  }
124  strncpy(bname, sp, ep - sp + 1);
125  bname[ep - sp + 1] = '\0';
126 
127  return bname;
128 }
129 
130 static char *get_bdname(const char *path, int type) {
131  const char *p, *q;
132  static char bname[HECMW_FILENAME_LEN + 1];
133  char drive[10] = "";
134 
135  if (has_drive(path)) {
136  p = path + 2;
137  sprintf(drive, "%.2s", path);
138  } else {
139  p = path;
140  }
141  if (type == 'B') { /* basename */
142  q = base_name(p);
143  } else { /* dirname */
144  q = dir_name(p);
145  }
146  if (q == NULL) return NULL;
147  if (strlen(drive) > 0 && isslash(*q)) {
148  if (strlen(drive) + strlen(q) > HECMW_FILENAME_LEN) {
149  errno = ENAMETOOLONG;
150  return NULL;
151  }
152  sprintf(bname, "%s%s", drive, q);
153  } else {
154  sprintf(bname, "%s", q);
155  }
156  return bname;
157 }
158 
159 char *HECMW_basename(const char *path) {
160  char *bname = get_bdname(path, 'B');
161  if (bname == NULL) {
162  HECMW_set_error(errno, "");
163  }
164  return bname;
165 }
166 
167 char *HECMW_dirname(const char *path) {
168  char *dname = get_bdname(path, 'D');
169  if (dname == NULL) {
170  HECMW_set_error(errno, "");
171  }
172  return dname;
173 }
HECMW_get_path_separator
int HECMW_get_path_separator(void)
Definition: hecmw_path.c:34
hecmw_config.h
PATH_SEPARATOR
#define PATH_SEPARATOR
Definition: hecmw_path.c:23
HECMW_dirname
char * HECMW_dirname(const char *path)
Definition: hecmw_path.c:167
hecmw_path.h
HECMW_basename
char * HECMW_basename(const char *path)
Definition: hecmw_path.c:159
HECMW_is_absolute_path
int HECMW_is_absolute_path(const char *path)
Definition: hecmw_path.c:45
isslash
#define isslash(c)
Definition: hecmw_path.c:31
HECMW_set_error
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:37
NULL
#define NULL
Definition: hecmw_io_nastran.c:30
HECMW_FILENAME_LEN
#define HECMW_FILENAME_LEN
Definition: hecmw_config.h:72
hecmw_util.h