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; }
/* Expand all special constructs in a path, and include only the actually existing directories in the result. */ string kpse_path_expand P1C(const_string, path) { string ret; string xpath; string elt; unsigned len; /* Initialise ret to the empty string. */ ret = (string)xmalloc (1); *ret = 0; len = 0; /* Expand variables and braces first. */ xpath = kpse_brace_expand (path); /* Now expand each of the path elements, printing the results */ for (elt = kpse_path_element (xpath); elt; elt = kpse_path_element (NULL)) { str_llist_type *dirs; /* Skip and ignore magic leading chars. */ if (*elt == '!' && *(elt + 1) == '!') elt += 2; /* Search the disk for all dirs in the component specified. Be faster to check the database, but this is more reliable. */ dirs = kpse_element_dirs (elt); if (dirs && *dirs) { str_llist_elt_type *dir; for (dir = *dirs; dir; dir = STR_LLIST_NEXT (*dir)) { string thedir = STR_LLIST (*dir); unsigned dirlen = strlen (thedir); string save_ret = ret; /* We need to retain trailing slash if that's the root directory. * On unix, "/" is root dir, "" often taken to be current dir. * On windows, "C:/" is root dir of drive C, and "C:" is current * on drive C. There's no need to look at other cases, like UNC * names. */ if (dirlen == 1 || (dirlen == 3 && NAME_BEGINS_WITH_DEVICE (thedir) && IS_DIR_SEP (thedir[2]))) { ret = concat3 (ret, thedir, ENV_SEP_STRING); len += dirlen + 1; ret[len - 1] = ENV_SEP; } else { ret = concat (ret, thedir); len += dirlen; ret [len - 1] = ENV_SEP; } free (save_ret); } } } /* Get rid of trailing ':', if any. */ if (len != 0) ret[len - 1] = 0; return ret; }
/* * Derived from BSD basename */ char *basename(char *str, const char *suffix){ char *p; int len = 0; const char *t; char *base; printf("basename of %s = ", str); #ifdef KPATHSEA for (p = base = (NAME_BEGINS_WITH_DEVICE(str) ? str+2 : str); *p; p++) { #else for (p = base = str; *p; p++) { #endif /* if (*p++ == DIRSEP) { base = p; len = 0; } */ if (IS_DIR_SEP(*p)) { base = p+1; len = 0; } else len++; } printf("%s\n", base); if (suffix != NULL) { for (t = suffix; *t; ++t); do { len--; t--; p--; if (*t != *p) break; if (t == suffix) { char *bn; if (len == 0) return NULL; bn = malloc(len+1); if (bn == NULL) fatal("Out of memory\n"); strncpy(bn, base, len); *(bn+len) = '\0'; /* RA */ return bn; } } while (p > base); } return base; } /* * Return true if name can be the name of a PostScript resource * (no extension and no absolute pathname). */ int ps_resource(const char *name) { if (strchr(name, '.')) return 0 ; #ifdef KPATHSEA if (kpse_absolute_p(name, true)) return 0; #else if (strchr(name, DIRSEP)) return 0 ; #endif return 1; }
/* ** Search the URL and determine whether it is a relative or absolute URL. ** We check to see if there is a ":" before any "/", "?", and "#". If this ** is the case then we say it is absolute. Otherwise it is relative. */ BOOL HTURL_isAbsolute (const char * url) { /* Given the context, we can't let windvi believe that c:/foo.dvi is an absolute url ... */ if (NAME_BEGINS_WITH_DEVICE(url)) return NO; if (url) { const char * ptr = url; while (*ptr) { if (*ptr == ':') return YES; if (*ptr == '/' || *ptr == '?' || *ptr == '#') break; ptr ++; } } return NO; }
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; }
static string remove_dots P1C(string, dir) { #ifdef AMIGA return dir; #else string c; unsigned len; string ret = (string) ""; /* We always reassign. */ for (c = kpse_filename_component (dir); c; c = kpse_filename_component (NULL)) { if (STREQ (c, ".")) { /* If leading ., replace with cwd. Else ignore. */ if (*ret == 0) { ret = xgetcwd (); } } else if (STREQ (c, "..")) { /* If leading .., start with xdirname (cwd). Else remove last component from ret, if any. */ if (*ret == 0) { string dot = xgetcwd (); ret = xdirname (dot); free (dot); } else { unsigned last; for (last = strlen (ret); last > (NAME_BEGINS_WITH_DEVICE (ret) ? 2 : 0); last--) { if (IS_DIR_SEP (ret[last - 1])) { /* If we have `/../', that's the same as `/'. */ if (last > 1) { ret[last - 1] = 0; } break; } } } } else { /* Not . or ..; just append. Include a directory separator unless our string already ends with one. This also changes all directory separators into the canonical DIR_SEP_STRING. */ string temp; len = strlen (ret); temp = concat3 (ret, ((len > 0 && ret[len - 1] == DIR_SEP) || (NAME_BEGINS_WITH_DEVICE (c) && *ret == 0)) ? "" : DIR_SEP_STRING, c); if (*ret) free (ret); ret = temp; } } /* Remove a trailing /, just in case it snuck in. */ len = strlen (ret); if (len > 0 && ret[len - 1] == DIR_SEP) { ret[len - 1] = 0; } return ret; #endif /* not AMIGA */ }
search P3C(char *, path, char *, file, char *, mode) { register char *nam ; /* index into fname */ register FILE *fd ; /* file desc of file */ char fname[MAXPATHLEN] ; /* to store file name */ static char *home = 0 ; /* home is where the heart is */ int len = strlen(file) ; int tryz = 0 ; if (len>=3 && ((file[len-2] == '.' && file[len-1] == 'Z') || (file[len-3] == '.' && file[len-2] == 'g' && file[len-1] == 'z')) && (path==figpath || path==pictpath || path==headerpath)) tryz = file[len-1] ; to_close = USE_FCLOSE ; #ifdef MVSXA char fname_safe[256]; register int i, firstext, lastext, lastchar; #endif #ifdef VMCMS /* IBM: VM/CMS - we don't have paths or dirsep's but we strip off filename if there is a Unix path dirsep */ register char *lastdirsep ; lastdirsep = strrchr(file, '/') ; if ( NULL != lastdirsep ) file = lastdirsep + 1 ; if ((fd=fopen(file,mode)) != NULL) { return(fd) ; } else { return(NULL) ; } #else if (*file == DIRSEP || NAME_BEGINS_WITH_DEVICE(file)) { /* if full path name */ if ((fd=fopen(file,mode)) != NULL) { strcpy(realnameoffile, file) ; if (tryz) { char *cmd = mymalloc(strlen(file) + 20) ; strcpy(cmd, (tryz=='z' ? "gzip -d <" : "compress -d <")) ; strcat(cmd, file) ; fclose(fd) ; fd = popen(cmd, "r") ; to_close = USE_PCLOSE ; free(cmd) ; } return(fd) ; } else return(NULL) ; } #endif /* IBM: VM/CMS */ #if defined MSDOS || defined OS2 || defined(ATARIST) || defined(WIN32) if ( isalpha(file[0]) && file[1]==':' ) { /* if full path name */ if ((fd=fopen(file,mode)) != NULL) { strcpy(realnameoffile, file) ; return(fd) ; } else return(NULL) ; } if (*file == '/') {/* if full path name with unix DIRSEP less drive code */ if ((fd=fopen(file,mode)) != NULL) { strcpy(realnameoffile, file) ; return(fd) ; } else return(NULL) ; } #endif do { /* copy the current directory into fname */ nam = fname; /* copy till PATHSEP */ if (*path == '~') { char *p = nam ; path++ ; while (*path && *path != PATHSEP && *path != DIRSEP) *p++ = *path++ ; *p = 0 ; if (*nam == 0) { if (home == 0) { if (0 != (home = getenv("HOME"))) home = newstring(home) ; else home = "." ; } strcpy(fname, home) ; } else { #if defined MSDOS || defined OS2 error("! ~username in path???") ; #else #ifdef WIN32 /* FIXME: at least under NT, it should be possible to retrieve the HOME DIR for a given user */ error("! ~username in path???") ; #else #ifdef VMS error("! ~username in path???") ; #else #ifdef ATARIST error("! ~username in path???") ; #else #ifdef VMCMS /* IBM: VM/CMS */ error("! ~username in path???") ; #else #ifdef MVSXA /* IBM: MVS/XA */ error("! ~username in path???") ; #else #ifdef __THINK__ error("! ~username in path???") ; #else struct passwd *pw = getpwnam(fname) ; if (pw) strcpy(fname, pw->pw_dir) ; else error("no such user") ; #endif #endif /* IBM: VM/CMS */ #endif #endif #endif #endif #endif } nam = fname + strlen(fname) ; } while (*path != PATHSEP && *path) *nam++ = *path++; *nam = 0 ; #ifndef VMS #ifndef __THINK__ if (nam == fname) *nam++ = '.'; /* null component is current dir */ if (*file != '\0') { if ((nam != fname) && *(nam-1) != DIRSEP) /* GNW 1992.07.09 */ *nam++ = DIRSEP; /* add separator */ (void)strcpy(nam,file); /* tack the file on */ } else *nam = '\0' ; #else (void)strcpy(nam,file); /* tack the file on */ #endif #else (void)strcpy(nam,file); /* tack the file on */ #endif #ifdef MVSXA nam = fname; if (strchr(nam,'=') != NULL) { (void) strcpy(fname_safe,fname); /* save fname */ firstext = strchr(nam, '=') - nam + 2; lastext = strrchr(nam, '.') - nam + 1; lastchar = strlen(nam) - 1; (void) strcpy(fname,"dd:"); /* initialize fname */ nam=&fname[3]; for (i=lastext; i<=lastchar; i++) *nam++ = fname_safe[i] ; *nam++ = '(' ; for (i=firstext; i<lastext-1; i++) *nam++ = fname_safe[i] ; *nam++ = ')' ; *nam++ = 0 ; } else { if (fname[0] == '/') { fname[0] = '\''; strcat(&fname[strlen(fname)],"\'"); } if (fname[0] == '.') fname[0] = ' '; if (fname[1] == '.') fname[1] = ' '; } #endif /* belated check -- bah! */ if ((nam - fname) + strlen(file) + 1 > MAXPATHLEN) error("! overran allocated storage in search()"); #ifdef DEBUG if (dd(D_PATHS)) (void)fprintf(stderr,"search: Trying to open %s\n", fname) ; #endif if ((fd=fopen(fname,mode)) != NULL) { strcpy(realnameoffile, fname) ; if (tryz) { char *cmd = mymalloc(strlen(file) + 20) ; strcpy(cmd, (tryz=='z' ? "gzip -d <" : "compress -d <")) ; strcat(cmd, file) ; fclose(fd) ; fd = popen(cmd, "r") ; to_close = USE_PCLOSE ; } return(fd); } /* skip over PATHSEP and try again */ } while (*(path++)); return(NULL); } /* end search */