diff --git a/include/extern.h b/include/extern.h index d61dcfac3..65d2026a5 100644 --- a/include/extern.h +++ b/include/extern.h @@ -868,6 +868,7 @@ extern void makerogueghost(void); /* ### files.c ### */ +extern const char *nh_basename(const char *, boolean); #if !defined(CROSSCOMPILE) || defined(CROSSCOMPILE_TARGET) extern int l_get_config_errors(lua_State *); #endif @@ -3210,7 +3211,7 @@ extern int vms_creat(const char *, unsigned int); extern int vms_open(const char *, int, unsigned int); extern boolean same_dir(const char *, const char *); extern int c__translate(int); -extern char *vms_basename(const char *); +extern char *vms_basename(const char *, boolean); /* ### vmsmail.c ### */ diff --git a/include/vmsconf.h b/include/vmsconf.h index b07b2f1f3..1ab86b3c5 100644 --- a/include/vmsconf.h +++ b/include/vmsconf.h @@ -335,7 +335,7 @@ typedef int32_t off_t; extern void vms_exit(int); extern int vms_open(const char *, int, unsigned); extern FILE *vms_fopen(const char *, const char *); -char *vms_basename(const char *); /* vmsfiles.c */ +char *vms_basename(const char *, boolean); /* vmsfiles.c */ #endif /* VMSCONF_H */ #endif /* VMS */ diff --git a/src/files.c b/src/files.c index 650e288bc..54d26fed3 100644 --- a/src/files.c +++ b/src/files.c @@ -232,6 +232,40 @@ static boolean copy_bytes(int, int); #endif static NHFILE *viable_nhfile(NHFILE *); +/* return a file's name without its path and optionally trailing 'type' */ +const char * +nh_basename(const char *fname, boolean keep_suffix) +{ +#ifndef VMS + static char basebuf[80]; + const char *p; + + if ((p = strrchr(fname, '/')) != 0) + fname = p + 1; +#if defined(WIN32) || defined(MSDOS) + if ((p = strrchr(fname, '\\')) != 0) + fname = p + 1; +#endif + if ((p = strrchr(fname, '.')) != 0 && !keep_suffix) { + size_t ln = (size_t) (p - fname); + /* note that without path, name should be reasonable length; + it is expected to refer to a source file name or run-time + configuration file name and those aren't arbitrarily long; + if "name" part of "name.suffix" is too long for 'basebuf[]', + just return that as-is without stripping off ".suffix" */ + + if (ln < sizeof basebuf) { + strncpy(basebuf, fname, ln); + basebuf[ln] = '\0'; + fname = basebuf; + } + } +#else /* VMS */ + fname = vms_basename(fname, keep_suffix); +#endif + return fname; +} + /* * fname_encode() * @@ -4437,18 +4471,8 @@ debugcore(const char *filename, boolean wildcards) if (!debugfiles || !*debugfiles) return FALSE; -/* strip filename's path if present */ -#ifdef UNIX - if ((p = strrchr(filename, '/')) != 0) - filename = p + 1; -#endif -#ifdef VMS - filename = vms_basename(filename); - /* vms_basename strips off 'type' suffix as well as path and version; - we want to put suffix back (".c" assumed); since it always returns - a pointer to a static buffer, we can safely modify its result */ - Strcat((char *) filename, ".c"); -#endif + /* strip filename's path if present */ + filename = nh_basename(filename, TRUE); /* * Wildcard match will only work if there's a single pattern (which diff --git a/sys/vms/vmsfiles.c b/sys/vms/vmsfiles.c index 9088a9d9c..e2ae8d657 100644 --- a/sys/vms/vmsfiles.c +++ b/sys/vms/vmsfiles.c @@ -305,10 +305,10 @@ static char base_name[NAM$C_MAXRSS + 1]; /* return a copy of the 'base' portion of a filename */ char * -vms_basename(const char *name) +vms_basename(const char *name, boolean keep_suffix) { unsigned len; - char *base, *base_p; + char *base, *base_p, *xtra_p; register const char *name_p; /* skip directory/path */ @@ -323,10 +323,14 @@ vms_basename(const char *name) if (!*name) name = "."; /* this should never happen */ - /* find extension/version and derive length of basename */ - if ((name_p = strchr(name, '.')) == 0 || name_p == name) - name_p = strchr(name, ';'); - len = (name_p && name_p > name) ? name_p - name : strlen(name); + /* find extension/version and derive length of basename; + for 'keep_suffix', this won't be accurate if version number is + present and delimited by dot instead of semi-colon, but normal + usage is for DEBUGFILES and that uses compiler supplied name */ + name_p = strrchr(name, ';'); + if (!keep_suffix && (xtra_p = strrchr(name, '.')) != 0) + name_p = xtra_p; + len = (name_p && name_p > name) ? name_p - name : (unsigned) strlen(name); /* return a lowercase copy of the name in a private static buffer */ base = strncpy(base_name, name, len);