diff --git a/polymer/eduke32/build/include/common.h b/polymer/eduke32/build/include/common.h index e54dde762..beeadf981 100644 --- a/polymer/eduke32/build/include/common.h +++ b/polymer/eduke32/build/include/common.h @@ -62,6 +62,7 @@ void G_LoadGroupsInDir(const char *dirname); void G_DoAutoload(const char *dirname); char *dup_filename(const char *fn); +int32_t maybe_append_ext(char *wbuf, int32_t wbufsiz, const char *fn, const char *ext); // timer defs for profiling function chunks the simple way #define EDUKE32_TMRDEF int32_t t[20], ti=0; const char *tmrstr=__func__; fprintf(stderr,"%s\n",tmrstr); t[ti++]=getticks(); diff --git a/polymer/eduke32/source/common.c b/polymer/eduke32/source/common.c index bd369044b..57fa1dc71 100644 --- a/polymer/eduke32/source/common.c +++ b/polymer/eduke32/source/common.c @@ -315,3 +315,18 @@ char *dup_filename(const char *fn) return Bstrncpyz(buf, fn, BMAX_PATH); } + + +// Copy FN to WBUF and append an extension if it's not there, which is checked +// case-insensitively. +// Returns: 1 if not all characters could be written to WBUF, 0 else. +int32_t maybe_append_ext(char *wbuf, int32_t wbufsiz, const char *fn, const char *ext) +{ + const int32_t slen=Bstrlen(fn), extslen=Bstrlen(ext); + const int32_t haveext = (slen>=extslen && Bstrcasecmp(&fn[slen-extslen], ext)==0); + + Bassert((intptr_t)wbuf != (intptr_t)fn); // no aliasing + + // If 'fn' has no extension suffixed, append one. + return (Bsnprintf(wbuf, wbufsiz, "%s%s", fn, haveext ? "" : ext) >= wbufsiz); +} diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 4032986cc..7c7397d6a 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -8961,17 +8961,10 @@ static void G_CheckCommandLine(int32_t argc, const char **argv) ud.m_coop--; break; case 'd': - { - char *dot; - c++; - Bstrcpy(g_firstDemoFile,c); - dot = Bstrchr(g_firstDemoFile,'.'); - if (!dot && Bstrlen(g_firstDemoFile)+4 < sizeof(g_firstDemoFile)) - Bstrcat(g_firstDemoFile,".edm"); + maybe_append_ext(g_firstDemoFile, sizeof(g_firstDemoFile), c, ".edm"); initprintf("Play demo %s.\n",g_firstDemoFile); break; - } case 'g': c++; if (*c) diff --git a/polymer/eduke32/source/osdcmds.c b/polymer/eduke32/source/osdcmds.c index 56cbb1f3d..a8fd4c194 100644 --- a/polymer/eduke32/source/osdcmds.c +++ b/polymer/eduke32/source/osdcmds.c @@ -167,13 +167,21 @@ static int32_t osdcmd_map(const osdfuncparm_t *parm) int32_t i; char filename[BMAX_PATH]; - if (parm->numparms != 1) + const int32_t wildcardp = parm->numparms==1 && + (Bstrchr(parm->parms[0], '*') != NULL); + + if (parm->numparms != 1 || wildcardp) { CACHE1D_FIND_REC *r; fnlist_t fnlist = FNLIST_INITIALIZER; int32_t maxwidth = 0; - fnlist_getnames(&fnlist, "/", "*.MAP", -1, 0); + if (wildcardp) + maybe_append_ext(filename, sizeof(filename), parm->parms[0], ".map"); + else + Bstrcpy(filename, "*.MAP"); + + fnlist_getnames(&fnlist, "/", filename, -1, 0); for (r=fnlist.findfiles; r; r=r->next) maxwidth = max((unsigned)maxwidth, Bstrlen(r->name)); @@ -211,9 +219,7 @@ static int32_t osdcmd_map(const osdfuncparm_t *parm) } #endif - strcpy(filename,parm->parms[0]); - if (strchr(filename,'.') == 0) - strcat(filename,".map"); + maybe_append_ext(filename, sizeof(filename), parm->parms[0], ".map"); if ((i = kopen4loadfrommod(filename,0)) < 0) {