static enum parser_error parse_prefs_expr(struct parser *p) { struct prefs_data *d = parser_priv(p); const char *v; char *str; char *expr; char f; assert(d != NULL); /* XXX this can be avoided with a rewrite of process_pref_file_expr */ str = expr = string_make(parser_getstr(p, "expr")); /* Parse the expr */ v = process_pref_file_expr(&expr, &f); /* Set flag */ d->bypass = streq(v, "0"); string_free(str); return PARSE_ERROR_NONE; }
/* * Helper function for "process_pref_file()" * * Input: * v: output buffer array * f: final character * * Output: * result */ static const char *process_pref_file_expr(char **sp, char *fp) { const char *v; char *b; char *s; char f = ' '; /* Initial */ s = (*sp); /* Skip spaces */ while (isspace((unsigned char) *s)) s++; /* Save start */ b = s; /* Default */ v = "?o?o?"; /* Analyze */ if (*s == '[') { const char *p; const char *t; /* Skip [ */ s++; /* First */ t = process_pref_file_expr(&s, &f); /* Oops */ if (!*t) { /* Nothing */ } /* Function: IOR */ else if (streq(t, "IOR")) { v = "0"; while (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); if (*t && !streq(t, "0")) v = "1"; } } /* Function: AND */ else if (streq(t, "AND")) { v = "1"; while (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); if (*t && streq(t, "0")) v = "0"; } } /* Function: NOT */ else if (streq(t, "NOT")) { v = "1"; while (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); if (*t && !streq(t, "0")) v = "0"; } } /* Function: EQU */ else if (streq(t, "EQU")) { v = "1"; if (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); } while (*s && (f != ']')) { p = t; t = process_pref_file_expr(&s, &f); if (*t && !streq(p, t)) v = "0"; } } /* Function: LEQ */ else if (streq(t, "LEQ")) { v = "1"; if (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); } while (*s && (f != ']')) { p = t; t = process_pref_file_expr(&s, &f); if (*t && (strcmp(p, t) >= 0)) v = "0"; } } /* Function: GEQ */ else if (streq(t, "GEQ")) { v = "1"; if (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); } while (*s && (f != ']')) { p = t; t = process_pref_file_expr(&s, &f); if (*t && (strcmp(p, t) <= 0)) v = "0"; } } /* Oops */ else { while (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); } } /* Verify ending */ if (f != ']') v = "?x?x?"; /* Extract final and Terminate */ if ((f = *s) != '\0') *s++ = '\0'; } /* Other */ else { /* Accept all printables except spaces and brackets */ while (isprint((unsigned char) *s) && !strchr(" []", *s)) ++s; /* Extract final and Terminate */ if ((f = *s) != '\0') *s++ = '\0'; /* Variable */ if (*b == '$') { if (streq(b + 1, "SYS")) v = ANGBAND_SYS; else if (streq(b + 1, "GRAF")) v = ANGBAND_GRAF; else if (streq(b + 1, "RACE")) v = rp_ptr->name; else if (streq(b + 1, "CLASS")) v = cp_ptr->name; else if (streq(b + 1, "PLAYER")) v = player_safe_name(p_ptr, TRUE); else if (streq(b + 1, "GENDER")) v = sp_ptr->title; } /* Constant */ else { v = b; } } /* Save */ (*fp) = f; (*sp) = s; return v; }
/* * Open the "user pref file" and parse it. */ static errr process_pref_file_aux(cptr name) { FILE *fp; char buf[1024]; char old[1024]; int line = -1; errr err = 0; bool bypass = FALSE; /* Open the file */ fp = my_fopen(name, "r"); /* No such file */ if (!fp) return (-1); /* Process the file */ while (0 == my_fgets(fp, buf, sizeof(buf))) { /* Count lines */ line++; /* Skip "empty" lines */ if (!buf[0]) continue; /* Skip "blank" lines */ if (isspace((unsigned char)buf[0])) continue; /* Skip comments */ if (buf[0] == '#') continue; /* Save a copy */ my_strcpy(old, buf, sizeof(old)); /* Process "?:<expr>" */ if ((buf[0] == '?') && (buf[1] == ':')) { char f; cptr v; char *s; /* Start */ s = buf + 2; /* Parse the expr */ v = process_pref_file_expr(&s, &f); /* Set flag */ bypass = (streq(v, "0") ? TRUE : FALSE); /* Continue */ continue; } /* Apply conditionals */ if (bypass) continue; /* Process "%:<file>" */ if (buf[0] == '%') { /* Process that file if allowed */ (void)process_pref_file(buf + 2); /* Continue */ continue; } /* Process the line */ err = process_pref_file_command(buf); /* Oops */ if (err) break; } /* Error */ if (err) { /* Print error message */ /* ToDo: Add better error messages */ msg_format("Error %d in line %d of file '%s'.", err, line, name); msg_format("Parsing '%s'", old); message_flush(); } /* Close the file */ my_fclose(fp); /* Result */ return (err); }
/** * Helper function for "process_pref_file()" * * Input: * v: output buffer array * f: final character * * Output: * result */ static const char *process_pref_file_expr(char **sp, char *fp) { const char *v; char *b; char *s; char f = ' '; /* Initial */ s = (*sp); /* Skip spaces */ while (isspace((unsigned char)*s)) s++; /* Save start */ b = s; /* Default */ v = "?o?o?"; /* Either the string starts with a [ or it doesn't */ if (*s == '[') { const char *p; const char *t; /* Skip [ */ s++; /* First */ t = process_pref_file_expr(&s, &f); /* Check all the different types of connective */ if (!*t) { /* Nothing */ } else if (streq(t, "IOR")) { v = "0"; while (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); if (*t && !streq(t, "0")) v = "1"; } } else if (streq(t, "AND")) { v = "1"; while (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); if (*t && streq(t, "0")) v = "0"; } } else if (streq(t, "NOT")) { v = "1"; while (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); if (*t && !streq(t, "0")) v = "0"; } } else if (streq(t, "EQU")) { v = "1"; if (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); } while (*s && (f != ']')) { p = t; t = process_pref_file_expr(&s, &f); if (*t && !streq(p, t)) v = "0"; } } else if (streq(t, "LEQ")) { v = "1"; if (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); } while (*s && (f != ']')) { p = t; t = process_pref_file_expr(&s, &f); if (*t && (strcmp(p, t) >= 0)) v = "0"; } } else if (streq(t, "GEQ")) { v = "1"; if (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); } while (*s && (f != ']')) { p = t; t = process_pref_file_expr(&s, &f); if (*t && (strcmp(p, t) <= 0)) v = "0"; } } else { while (*s && (f != ']')) { t = process_pref_file_expr(&s, &f); } } /* Verify ending */ if (f != ']') v = "?x?x?"; /* Extract final and Terminate */ if ((f = *s) != '\0') *s++ = '\0'; } else { /* Accept all printables except spaces and brackets */ while (isprint((unsigned char)*s) && !strchr(" []", *s)) ++s; /* Extract final and Terminate */ if ((f = *s) != '\0') *s++ = '\0'; /* Variables start with $, otherwise it's a constant */ if (*b == '$') { if (streq(b+1, "SYS")) v = ANGBAND_SYS; else if (streq(b+1, "RACE")) v = player->race->name; else if (streq(b+1, "CLASS")) v = player->class->name; else if (streq(b+1, "PLAYER")) v = player_safe_name(player, true); } else {
/* * Helper function for "process_pref_file()" * * Input: * v: output buffer array * f: final character * * Output: * result */ static cptr process_pref_file_expr(char **sp, char *fp) { cptr v; char *b; char *s; char b1 = '['; char b2 = ']'; char f = ' '; /* Initial */ s = (*sp); /* Skip spaces */ while (isspace((unsigned char)*s)) s++; /* Save start */ b = s; /* Default */ v = "?o?o?"; /* Analyze */ if (*s == b1) { const char *p; const char *t; /* Skip b1 */ s++; /* First */ t = process_pref_file_expr(&s, &f); /* Oops */ if (!*t) { /* Nothing */ } /* Function: IOR */ else if (streq(t, "IOR")) { v = "0"; while (*s && (f != b2)) { t = process_pref_file_expr(&s, &f); if (*t && !streq(t, "0")) v = "1"; } } /* Function: AND */ else if (streq(t, "AND")) { v = "1"; while (*s && (f != b2)) { t = process_pref_file_expr(&s, &f); if (*t && streq(t, "0")) v = "0"; } } /* Function: NOT */ else if (streq(t, "NOT")) { v = "1"; while (*s && (f != b2)) { t = process_pref_file_expr(&s, &f); if (*t && !streq(t, "0")) v = "0"; } } /* Function: EQU */ else if (streq(t, "EQU")) { v = "1"; if (*s && (f != b2)) { t = process_pref_file_expr(&s, &f); } while (*s && (f != b2)) { p = t; t = process_pref_file_expr(&s, &f); if (*t && !streq(p, t)) v = "0"; } } /* Function: LEQ */ else if (streq(t, "LEQ")) { v = "1"; if (*s && (f != b2)) { t = process_pref_file_expr(&s, &f); } while (*s && (f != b2)) { p = t; t = process_pref_file_expr(&s, &f); if (*t && (strcmp(p, t) >= 0)) v = "0"; } } /* Function: GEQ */ else if (streq(t, "GEQ")) { v = "1"; if (*s && (f != b2)) { t = process_pref_file_expr(&s, &f); } while (*s && (f != b2)) { p = t; t = process_pref_file_expr(&s, &f); if (*t && (strcmp(p, t) <= 0)) v = "0"; } } /* Oops */ else { while (*s && (f != b2)) { t = process_pref_file_expr(&s, &f); } } /* Verify ending */ if (f != b2) v = "?x?x?"; /* Extract final and Terminate */ if ((f = *s) != '\0') *s++ = '\0'; } /* Other */ else { /* Accept all printables except spaces and brackets */ while (isprint((unsigned char)*s) && !strchr(" []", *s)) ++s; /* Extract final and Terminate */ if ((f = *s) != '\0') *s++ = '\0'; /* Variable */ if (*b == '$') { /* System */ if (streq(b+1, "SYS")) { v = ANGBAND_SYS; } /* Graphics */ else if (streq(b+1, "GRAF")) { v = ANGBAND_GRAF; } #ifndef AVT_HOOKIFY_PREF_VARS /* Race */ else if (streq(b+1, "RACE")) { v = p_name + rp_ptr->name; } /* Class */ else if (streq(b+1, "CLASS")) { v = c_name + cp_ptr->name; } /* Player */ else if (streq(b+1, "PLAYER")) { v = op_ptr->base_name; } #endif /* Game version */ else if (streq(b+1, "VERSION")) { v = VERSION_STRING; } } /* Constant */ else { v = b; } } /* Save */ (*fp) = f; /* Save */ (*sp) = s; /* Result */ return (v); }