| iMatix home page | << | < | > | >> |
SFL Version 2.11 |
#include "sfldir.h" char * resolve_path ( const char *old_path)
Accepts a path consisting of zero or more directory names and optionally a filename plus extension. Removes '.' and '..' if they occur in the path. '..' is resolved by also removing the preceding directory name, if any. Returns a freshly-allocated string containing the resulting path. The caller must free this string using mem_free() when finished with it. The returned path may be empty. Under OS/2 and DOS, treats '\' and '/' both as directory separators. A '..' directory at the start of the path resolves into nothing. If the input path started with '/', the returned path also does, else it does not. For compatibility with DOS-based systems, '...' is treated as '../..', '....' as '../../..', and so on.
{ #if (defined (__UNIX__) || defined (MSDOS_FILESYSTEM) || defined (__VMS__)) char *new_path, /* Newly-allocated path */ *new_ptr, /* Pointer into new_path */ last_char = '/'; /* Start of path counts as delim */ int nbr_dots; /* Size of '..', '...' specifier */ ASSERT (old_path); new_path = mem_strdup (old_path); new_ptr = new_path; while (*old_path) { if (path_delimiter (last_char) && *old_path == '.') { /* Handle one or more dots followed by a path delimiter */ nbr_dots = 0; /* Count number of dots */ while (old_path [nbr_dots] == '.') nbr_dots++; if (path_delimiter (old_path [nbr_dots])) { old_path += nbr_dots; /* Skip past dots */ if (*old_path) old_path++; /* and past / if any */ /* Now backtrack in new path, dropping directories as */ /* many times as needed (0 or more times) */ while (nbr_dots > 1) { if (new_ptr > new_path + 1) { new_ptr--; /* Drop delimiter */ while (new_ptr > new_path) { if (path_delimiter (*(new_ptr - 1))) break; /* and end after delimiter */ new_ptr--; } } else break; /* At start of name - finish */ nbr_dots--; } } else /* Handle '.something' */ last_char = *new_ptr++ = *old_path++; } else last_char = *new_ptr++ = *old_path++; } *new_ptr = '\0'; /* Terminate string nicely */ return (new_path); #else return (mem_strdup (old_path)); /* Path resolution not supported */ #endif }
| << | < | > | >> | Copyright © 1996-2000 iMatix Corporation |