]> skyeroc.xyz Git - dgamelaunch/commitdiff
userprefs - getpref, setptref, variable expansion in TYPE_VALUE fields in config
authorTangles <andyrthomson@gmail.com>
Wed, 22 Jan 2020 12:06:51 +0000 (23:06 +1100)
committerTangles <andyrthomson@gmail.com>
Wed, 22 Jan 2020 12:06:51 +0000 (23:06 +1100)
config.l
dgamelaunch.c
dgamelaunch.h
dgl-common.c

index 81a188cb4fec0a44b80e5a54d1b5cd550c6f9711..7d5d6deb6556cf5a17ada496ea8669ac1a7f2bf9 100644 (file)
--- 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; }
index 9c381c80edb5b37a9d832553980574be6499392b..ef9b0f6d3d266815f431bd7b089b517ebe4b649f 100644 (file)
@@ -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
index a45cd85d392169db252b66065e13734d4cb25295..a00d8a6a8f66f3118d7a7bdca038c03ad1c2f086 100644 (file)
@@ -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
index f81bddafe5b9522859a2065d6c5f9daa31851779..0033622474b5c4e00b8c5fbb22e21ea050a07fb6 100644 (file)
@@ -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();