const_string xbasename (const_string name) { const_string base = name; const_string p; if (NAME_BEGINS_WITH_DEVICE(name)) base += 2; else if (IS_UNC_NAME(name)) { unsigned limit; for (limit = 2; name[limit] && !IS_DIR_SEP (name[limit]); limit++) ; if (name[limit++] && name[limit] && !IS_DIR_SEP (name[limit])) { for (; name[limit] && !IS_DIR_SEP (name[limit]); limit++) ; } else /* malformed UNC name, backup */ limit = 0; base += limit; } for (p = base; *p; p++) { if (IS_DIR_SEP(*p)) base = p + 1; #if defined(WIN32) && defined (KPSE_COMPAT_API) else if (IS_KANJI(p)) p++; #endif } return base; }
static int normalize_filename (char *fp, char path_sep) { char *p; int ret, i; /* Always lower-case drive letters a-z, even if the filesystem preserves case in filenames. This is so filenames can be compared by string comparison functions that are case-sensitive. Even case-preserving filesystems do not distinguish case in drive letters. */ if (fp[1] == ':' && *fp >= 'A' && *fp <= 'Z') { *fp += 'a' - 'A'; } /* Remove unneeded double slashes */ ret = (IS_UNC_NAME(fp) ? 2 : NAME_BEGINS_WITH_DEVICE(fp) ? (IS_DIR_SEP(*(fp+2)) ? 3 : 2) : IS_DIR_SEP(*fp) ? 1 : 0); for (i = ret, p = fp+i; IS_DIR_SEP(*p); i++, p++); if (i > ret) { int len = strlen(fp+i); /* remove unneeded slashes, for the sake of win95 */ #if 0 fprintf(stderr, "moving %s to %s\n", fp+ret, fp+i); #endif memmove (fp+ret, fp+i, len+1); } /* conditionnally rewrite to same path_sep, slash preferably */ if (path_sep) { for (p = fp; *p; p++) if (IS_DIR_SEP(*p)) *p = path_sep; } #if 0 fprintf(stderr, "normalize_filename returned (%d) %s\n", ret, fp); #endif return ret; }
unsigned kpathsea_normalize_path (kpathsea kpse, string elt) { unsigned ret; unsigned i; #if defined(WIN32) for (i = 0; elt[i]; i++) { if (elt[i] == '\\') elt[i] = '/'; else if (IS_KANJI(elt + i)) i++; } #endif if (NAME_BEGINS_WITH_DEVICE(elt)) { if (*elt >= 'A' && *elt <= 'Z') *elt += 'a' - 'A'; ret = 2; } else if (IS_UNC_NAME(elt)) { for (ret = 2; elt[ret] && !IS_DIR_SEP_CH(elt[ret]); ret++) ; } else ret = 0; for (i = ret; IS_DIR_SEP_CH(elt[i]); ++i) ; if (i > ret + 1) { #ifdef KPSE_DEBUG if (KPATHSEA_DEBUG_P (KPSE_DEBUG_STAT)) DEBUGF2 ("kpse_normalize_path (%s) => %u\n", elt, ret); #endif /* KPSE_DEBUG */ memmove (elt + ret + 1, elt + i, strlen (elt + i) + 1); } return ret; }
string xdirname (const_string name) { string ret; unsigned limit = 0, loc; #if defined(WIN32) string p; unsigned i, j; #endif /* Ignore a NULL name. */ if (!name) return NULL; if (NAME_BEGINS_WITH_DEVICE(name)) { limit = 2; } else if (IS_UNC_NAME(name)) { for (limit = 2; name[limit] && !IS_DIR_SEP (name[limit]); limit++) #if defined(WIN32) && defined(KPSE_COMPAT_API) if (IS_KANJI(name+limit)) limit++ #endif ; if (name[limit++] && name[limit] && !IS_DIR_SEP (name[limit])) { for (; name[limit] && !IS_DIR_SEP (name[limit]); limit++) #if defined(WIN32) && defined(KPSE_COMPAT_API) if (IS_KANJI(name+limit)) limit++ #endif ; limit--; } else /* malformed UNC name, backup */ limit = 0; } #if defined(WIN32) j = loc = limit; if (j > 2) j++; for (i = j; name[i]; i++) { if (IS_DIR_SEP (name[i])) { j = i; for (i++; IS_DIR_SEP (name[i]); i++) ; loc = i + 1; } #if defined (KPSE_COMPAT_API) else if (IS_KANJI(name+i)) i++; #endif } #else for (loc = strlen (name); loc > limit && !IS_DIR_SEP (name[loc-1]); loc--) ; #endif if (loc == limit) { if (limit == 0) ret = xstrdup ("."); else if (limit == 2) { ret = (string)xmalloc(4); ret[0] = name[0]; ret[1] = name[1]; ret[2] = '.'; ret[3] = '\0'; } else { /* UNC name is "//server/share". */ ret = xstrdup (name); } } else { /* If have ///a, must return /, so don't strip off everything. */ #if defined(WIN32) loc = j; if (loc == limit && IS_DIR_SEP (name[loc])) loc++; #else while (loc > limit+1 && IS_DIR_SEP (name[loc-1])) { loc--; } #endif ret = (string)xmalloc(loc+1); strncpy(ret, name, loc); ret[loc] = '\0'; } #if defined(WIN32) for (p = ret; *p; p++) { if (*p == '\\') *p = '/'; #if defined (KPSE_COMPAT_API) else if (IS_KANJI(p)) p++; #endif } #endif return ret; }