From 418953e0e6162ff29691357a91d08f36809fe495 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 4 Dec 2023 14:20:07 -0500 Subject: [PATCH] symbol parsing improvement This gets rid of a FIXME and K4056 internal bug report. Allow the comma to be quoted as follows: SYMBOLS=S_ice:\, or SYMBOLS=S_ice:',' Disclaimer: The use of the comma on the map could conflict with future use of that currently unused symbol for other intended purposes. --- src/options.c | 2 ++ src/symbols.c | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/options.c b/src/options.c index e8d758d95..94971838c 100644 --- a/src/options.c +++ b/src/options.c @@ -6491,6 +6491,8 @@ escapes(const char *cp, /* might be 'tp', updating in place */ case 'r': cval = '\r'; break; + case ',': + cval = ','; default: cval = *cp; } diff --git a/src/symbols.c b/src/symbols.c index 8e3456c87..3d201ad7f 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -764,25 +764,43 @@ boolean parsesymbols(register char *opts, int which_set) { int val; - char *op, *symname, *strval; + unsigned i; + char *symname, *strval, *ch = opts, + *first_unquoted_comma = 0, *first_unquoted_colon = 0; const struct symparse *symp; boolean is_glyph = FALSE; - /* - * FIXME: - * The parsing here (and next) yields incorrect results for - * "S_sample=','" or "S_sample=':'". - */ + /* are there any commas or colons that aren't quoted? */ + for (i = 0; i < strlen(opts); ++i) { + char *prech, *postch; - if ((op = strchr(opts, ',')) != 0) { - *op++ = '\0'; - if (!parsesymbols(op, which_set)) + ch++; /* we never want to match on the first char, so this is ok */ + prech = ch - 1; + postch = ch + 1; + if (*ch == ',') { + if (*prech == '\'' && *postch == '\'') + continue; + if (*prech == '\\') + continue; + } + if (*ch == ':') { + if (*prech == '\'' && *postch == '\'') + continue; + } + if (*ch == ',' && !first_unquoted_comma) + first_unquoted_comma = ch; + if (*ch == ':' && !first_unquoted_colon) + first_unquoted_colon = ch; + } + if (first_unquoted_comma != 0) { + *first_unquoted_comma++ = '\0'; + if (!parsesymbols(first_unquoted_comma, which_set)) return FALSE; } /* S_sample:string */ symname = opts; - strval = strchr(opts, ':'); + strval = first_unquoted_colon; if (!strval) strval = strchr(opts, '='); if (!strval)