From: Tangles Date: Wed, 22 Jan 2020 12:06:51 +0000 (+1100) Subject: userprefs - getpref, setptref, variable expansion in TYPE_VALUE fields in config X-Git-Tag: v1.6.1-roc-dev~38 X-Git-Url: https://skyeroc.xyz/gitweb/?a=commitdiff_plain;h=955d8973d9b3feb64b482511592dd8c1b9872910;p=dgamelaunch userprefs - getpref, setptref, variable expansion in TYPE_VALUE fields in config --- diff --git a/config.l b/config.l index 81a188c..7d5d6de 100644 --- a/config.l +++ b/config.l @@ -21,6 +21,7 @@ VALUE \"[^"]*\" MALSTRING \"[^\"\n]*\n COMMENT ^[\t ]*#.* WHITE [\t ]* +UPREF \$\{[a-zA-Z][a-zA-Z0-9]*(:{VALUE})?\} %% @@ -47,6 +48,11 @@ WHITE [\t ]* return TYPE_MALSTRING; } +{UPREF} { + yylval.s = strdup(yytext); /* leave as is - we will parse manually at 'run-time'. */ + return TYPE_VALUE; +} + {WHITE} { } {COMMENT} { } @@ -58,6 +64,7 @@ WHITE [\t ]* "}" { return '}'; } "(" { return '('; } ")" { return ')'; } +"$" { return '$'; } "shed_user" { return TYPE_SUSER; } "shed_group" { return TYPE_SGROUP; } "shed_uid" { return TYPE_SUID; } diff --git a/dgamelaunch.c b/dgamelaunch.c index 9c381c8..ef9b0f6 100644 --- a/dgamelaunch.c +++ b/dgamelaunch.c @@ -2201,6 +2201,36 @@ writeprefs () return prefcount; } +const 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 : ""; +} + +int +setpref(char *key, char *val) +{ + struct userpref *cpref; + for (cpref = userprefs; cpref; cpref = cpref->npref) + if (!strcmp(cpref->name, key)) { + free(cpref->value); + cpref->value = strdup(val); + return TRUE; + } + /* prepend to list to avoid ugly double-indirection */ + cpref = (struct userpref *)malloc(sizeof(struct userpref)); + if (!cpref) return FALSE; + cpref->name = strdup(key); + cpref->value = strdup(val); + cpref->npref = userprefs; + userprefs = cpref; + return TRUE; +} + /* ************************************************************* */ int diff --git a/dgamelaunch.h b/dgamelaunch.h index a45cd85..a00d8a6 100644 --- a/dgamelaunch.h +++ b/dgamelaunch.h @@ -357,6 +357,8 @@ 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 int setpref(char *key, char *val); /*extern int menuloop(void);*/ extern void ttyrec_getpty(void); #ifndef HAVE_SETENV diff --git a/dgl-common.c b/dgl-common.c index f81bdda..0033622 100644 --- a/dgl-common.c +++ b/dgl-common.c @@ -119,14 +119,17 @@ dgl_find_menu(char *menuname) * %t == ttyrec file (full path&name) of the last game played. * %w == 'watched' player (string; from 'plrname', or 'me' if 'plrname' is null) * %N, %W, %L (char; first character of their lowercase counterparts) + * ${varname[:default]} expands to userpref value of varname if defined, else + * default if specified. */ char * dgl_format_str(int game, struct dg_user *me, char *str, char *plrname) { static char buf[1024]; - char *f, *p, *end; + char *f, *p, *end, *varname = NULL, *fallback = NULL; int ispercent = 0; int isbackslash = 0; + int isdollar = 0; if (!str) return NULL; @@ -136,7 +139,18 @@ dgl_format_str(int game, struct dg_user *me, char *str, char *plrname) end = buf + sizeof(buf) - 10; while (*f) { - if (ispercent) { + if (varname || fallback) { + if (*f == ':') { + fallback = f+1; + *f = '\0'; + } + if (*f == '}') { + *f = '\0'; + snprintf(p, end + 1 - p, "%s", getpref(varname, fallback)); + for (; *p; p++); + varname = fallback = NULL; + } + } else if (ispercent) { switch (*f) { case 'u': snprintf (p, end + 1 - p, "%d", globalconfig.shed_uid); @@ -231,7 +245,17 @@ dgl_format_str(int game, struct dg_user *me, char *str, char *plrname) ispercent = 1; } else if (*f == '\\') { isbackslash = 1; + } else if (isdollar && *f == '{') { + varname = f+1; + fallback = NULL; + isdollar = 0; + } else if (*f == '$') { + isdollar = 1; } else { + if (isdollar) { /* not part of a variable/pref, so copy the literal $ */ + isdollar = 0; + *p++ = '$'; + } *p = *f; if (p < end) p++; @@ -357,7 +381,7 @@ dgl_exec_cmdqueue_w(struct dg_cmdpart *queue, int game, struct dg_user *me, char case DGLCMD_SETPREFPATH: if (loggedin && p1) { free(userpref_path); - userpref_path = strdup(dgl_format_str(NULL, me, p1, playername)); + userpref_path = strdup(dgl_format_str(-1, me, p1, playername)); } break; case DGLCMD_READPREFS: @@ -811,13 +835,13 @@ populate_games (int xgame, int *l, struct dg_user *me) graceful_exit (int status) { /*FILE *fp; - if (status != 1) - { + if (status != 1) + { fp = fopen ("/crash.log", "a"); char buf[100]; sprintf (buf, "graceful_exit called with status %d", status); fputs (buf, fp); - } + } This doesn't work. Ever. */ endwin();