From effcc27f75408c276c2900429af96ce6f2ec9a6d Mon Sep 17 00:00:00 2001 From: Tangles Date: Thu, 13 Feb 2020 23:27:01 +1100 Subject: [PATCH] userprefs - getpref() now calls dgl_format_str() on the 'fallback' value which is recursive. getpref() and dgl_format_str both now return a dynamic string which must be freed. --- dgamelaunch.c | 15 +++++++++++---- dgamelaunch.h | 2 +- dgl-common.c | 6 +++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/dgamelaunch.c b/dgamelaunch.c index f3c83ce..94cf4b9 100644 --- a/dgamelaunch.c +++ b/dgamelaunch.c @@ -404,6 +404,7 @@ bannerstr_substprefs(char *buf, char *bufnew, int buflen) char *dst = bufnew; char *varname = NULL; char *fallback = NULL; + char *gpr = NULL; int isdollar = 0; if (!src) return NULL; while (*src && dst < bufnew + buflen - 1) { @@ -423,7 +424,11 @@ bannerstr_substprefs(char *buf, char *bufnew, int buflen) fallback = src + 1; } else if (*src == '}') { *src = '\0'; - snprintf(dst, bufnew + buflen - dst - 1, "%s", getpref(varname, fallback)); + snprintf(dst, bufnew + buflen - dst - 1, "%s", gpr = getpref(varname, fallback)); + if (gpr) { + free(gpr); + gpr = NULL; + } for (; *dst; dst++); fallback = varname = NULL; } @@ -2243,14 +2248,16 @@ writeprefs () return prefcount; } -const char * +/* getpref allocates memory for the return value. + This must be freed when finished */ +char * getpref(char *key, char *fallback) { struct userpref *cpref; for (cpref = userprefs; cpref; cpref = cpref->npref) if (!strcmp(cpref->name, key)) - return (const char *)cpref->value; - return fallback ? (const char *)fallback : ""; + return strdup(cpref->value); + return fallback ? dgl_format_str(0, me, fallback, NULL) : strdup(""); } int diff --git a/dgamelaunch.h b/dgamelaunch.h index b746074..a4695cb 100644 --- a/dgamelaunch.h +++ b/dgamelaunch.h @@ -361,7 +361,7 @@ extern void graceful_exit(int status); extern int purge_stale_locks(int game); extern int readprefs(void); extern int writeprefs(void); -extern const char *getpref(char *key, char *fallback); +extern char *getpref(char *key, char *fallback); extern int setpref(char *key, char *val); extern int askpref(char *prompt, char *key); /*extern int menuloop(void);*/ diff --git a/dgl-common.c b/dgl-common.c index 426f9ce..868ade2 100644 --- a/dgl-common.c +++ b/dgl-common.c @@ -122,12 +122,15 @@ dgl_find_menu(char *menuname) * %N, %W, %L (char; first character of their lowercase counterparts) * ${varname[:default]} expands to userpref value of varname if defined, else * default if specified. + * + * Now returns a dynamically allocated string which must be freed. */ char * dgl_format_str(int game, struct dg_user *me, char *str, char *plrname) { char buf[1024]; char *f, *p, *end, *varname = NULL, *fallback = NULL; + char *gpr = NULL; int ispercent = 0; int isbackslash = 0; int isdollar = 0; @@ -147,7 +150,8 @@ dgl_format_str(int game, struct dg_user *me, char *str, char *plrname) } if (*f == '}') { *f = '\0'; - snprintf(p, end + 1 - p, "%s", getpref(varname, fallback)); + snprintf(p, end + 1 - p, "%s", gpr = getpref(varname, fallback)); + if (gpr) free(gpr); for (; *p; p++); varname = fallback = NULL; } -- 2.47.3