fix config file path
[AROS.git] / compiler / clib / __upath.c
bloba67e9f9f097aa5280da1e522d55d877dace4ec86
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: utility internal function __path_u2a()
6 Lang: english
7 */
9 #include "__arosc_privdata.h"
11 #include <string.h>
12 #include <stdlib.h>
13 #include <errno.h>
15 static const char *__path_devstuff_u2a(const char *path);
16 static void __path_normalstuff_u2a(const char *path, char *buf);
18 /*****************************************************************************
20 NAME */
21 #include "__upath.h"
24 const char *__path_u2a(
26 /* SYNOPSIS */
27 const char *upath)
29 /* FUNCTION
30 Translates an unix-style path into an AmigaDOS one.
32 INPUTS
33 upath - Unix-style path to translate into an AmigaDOS-style equivalent.
35 RESULT
36 A pointer to a string containing the AmigaDOS-style path, or NULL in
37 case of error.
39 The pointer is valid only until next call to this function, so if
40 you need to call this function recursively, you must save the string
41 pointed to by the pointer before calling this function again.
43 NOTES
44 This function is for private usage by system code. Do not use it
45 elsewhere.
47 INTERNALS
49 SEE ALSO
51 ******************************************************************************/
53 struct aroscbase *aroscbase = __aros_getbase_aroscbase();
54 const char *newpath;
56 /* Does the path really need to be converted? */
57 if (!aroscbase->acb_doupath)
58 return upath;
60 /* Safety check. */
61 if (upath == NULL)
63 errno = EFAULT;
64 return NULL;
67 /* Some scripts (config.guess) try to access /.attbin
68 which is MacOS-specific thing. Block it. */
69 if (!strncmp(upath, "/.attbin", 8))
71 errno = ENOENT;
72 return NULL;
76 First see whether the path is in the /dev/#? form and,
77 if so, if it's handled internally
79 newpath = __path_devstuff_u2a(upath);
80 if (!newpath)
82 /* Else, convert it normally */
83 newpath = realloc_nocopy(aroscbase->acb_apathbuf, strlen(upath) + 1);
85 if (newpath == NULL)
87 errno = ENOMEM;
88 return NULL;
91 aroscbase->acb_apathbuf = (char *)newpath;
92 __path_normalstuff_u2a(upath, aroscbase->acb_apathbuf);
95 return newpath;
98 /*****************************************************************************
100 NAME */
101 #include "__upath.h"
104 const char *__path_a2u(
106 /* SYNOPSIS */
107 const char *apath)
109 /* FUNCTION
110 Translates an AmigaDOS-style path into an unix one.
112 INPUTS
113 apath - AmigaDOS-style path to translate into an unix-style equivalent.
115 RESULT
116 A pointer to a string containing the unix-style path, or NULL in
117 case of error.
119 The pointer is valid only until next call to this function, so if
120 you need to call this function recursively, you must save the string
121 pointed to by the pointer before calling this function again.
123 NOTES
124 This function is for private usage by system code. Do not use it
125 elsewhere.
127 INTERNALS
129 SEE ALSO
131 ******************************************************************************/
133 struct aroscbase *aroscbase = __aros_getbase_aroscbase();
134 const char *old_apath = apath;
135 char ch, *upath, *old_upath;
136 size_t size = 0;
137 int run;
138 register enum
140 S_START0,
141 S_START1,
142 S_START,
143 S_VOLUME,
144 S_PARENT,
145 S_SLASH
146 } state;
148 /* Safety check. */
149 if (apath == NULL)
151 errno = EFAULT;
152 return NULL;
155 if (!aroscbase->acb_doupath)
156 return apath;
158 while ((ch = *apath++))
160 if (ch == '/')
161 size += 3;
162 else
163 size += 1;
166 if (size == 0)
167 return "";
169 old_upath = realloc_nocopy(aroscbase->acb_apathbuf, 1 + size + 1);
170 if (old_upath == NULL)
172 errno = ENOMEM;
173 return NULL;
176 aroscbase->acb_apathbuf = old_upath;
177 upath = ++old_upath;
178 apath = old_apath;
180 run = 1;
181 state = S_START0;
182 while (run)
184 register char ch = apath[0];
186 switch (state)
188 case S_START0:
189 if (ch == '/')
190 state = S_PARENT;
191 else
193 state = S_START1;
194 continue;
197 break;
199 case S_START1:
200 if (ch == ':')
201 state = S_VOLUME;
202 else
203 case S_START:
204 if (ch == '/')
205 state = S_SLASH;
206 else
207 if (ch == '\0')
208 run = 0;
209 else
210 upath++[0] = ch;
212 break;
214 case S_VOLUME:
215 (--old_upath)[0] = '/';
216 state = S_SLASH;
217 continue;
219 break;
221 case S_SLASH:
222 upath++[0] = '/';
224 if (ch == '/')
225 state = S_PARENT;
226 else
228 state = S_START;
229 continue;
232 break;
234 case S_PARENT:
235 upath[0] = '.'; upath[1] = '.'; upath[2] = '/'; upath += 3;
237 if (ch != '/')
239 state = S_START;
240 continue;
243 break;
246 upath[0] = '\0';
247 apath++;
250 upath[0] = '\0';
251 return old_upath;
255 static const char *__path_devstuff_u2a(const char *path)
258 Translate the various /dev/#? most used files into the AROS equivalent.
259 Use a tree-like handmade search to speed things up
262 if (path[0] == '/' && path[1] == 'd' && path[2] == 'e' && path[3] == 'v')
264 if (path[4] == '/')
266 if (path[5] == 'n' && path[6] == 'u' && path[7] == 'l' && path[8] == 'l' && path[9] == '\0')
267 return "NIL:";
268 else
269 if (path[5] == 'z' && path[6] == 'e' && path[7] == 'r' && path[8] == 'o' && path[9] == '\0')
270 return "ZERO:";
271 else
272 if (path[5] == 's' && path[6] == 't' && path[7] == 'd')
274 if (path[8] == 'i' && path[9] == 'n' && path[10] == '\0')
275 return "IN:";
276 else
277 if (path[8] == 'o' && path[9] == 'u' && path[10] == 't' && path[11] == '\0')
278 return "OUT:";
279 else
280 if (path[8] == 'e' && path[9] == 'r' && path[10] == 'r' && path[11] == '\0')
281 return "ERR:";
283 else
284 if (path[5] == '\0')
285 return "DEV:";
287 else
288 if (path[4] == '\0')
289 return "DEV:";
292 return NULL;
295 static void __path_normalstuff_u2a(const char *path, char *buf)
297 register char dir_sep = '\0';
298 register int makevol = 0;
299 register enum
301 S_START0,
302 S_START,
303 S_DOT1,
304 S_DOT2,
305 S_SLASH,
306 } state = S_START0;
308 int run = 1;
310 while (path[0] == '/')
312 path++;
313 makevol = 1;
316 while (run)
318 register char ch = path[0];
320 switch (state)
322 case S_START0:
323 if (ch == '.')
324 state = S_DOT1;
325 else
327 state = S_START;
328 continue;
330 break;
331 case S_START:
332 if (ch == '/')
334 dir_sep = '/';
335 state = S_SLASH;
337 else
338 if (ch == ':')
340 dir_sep = ':';
341 state = S_SLASH;
343 else
344 if (ch == '\0')
345 run = 0;
346 else
347 buf++[0] = ch;
349 break;
351 case S_DOT1:
352 if (ch == '\0')
353 run = 0;
354 else
355 if (ch == '.')
356 state = S_DOT2;
357 else
358 if (ch == '/')
360 dir_sep = '\0';
361 state = S_SLASH;
363 else
365 buf[0] = '.';
366 buf[1] = ch;
367 buf += 2;
368 state = S_START;
371 break;
373 case S_DOT2:
374 if (ch == '/' || ch == '\0')
376 dir_sep = '/';
377 state = S_SLASH;
378 continue;
380 else
382 buf[0] = '.';
383 buf[1] = '.';
384 buf[2] = ch;
385 buf += 3;
386 state = S_START;
389 break;
391 case S_SLASH:
392 if (ch != '/')
394 if (makevol)
396 makevol = 0;
397 dir_sep = ':';
400 if (dir_sep != '\0')
401 buf++[0] = dir_sep;
403 state = S_START0;
405 continue;
408 break;
411 path++;
414 if (makevol)
415 buf++[0] = ':';
417 buf[0] = '\0';