]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
debugger/custom event calculator updates.
authorToni Wilen <twilen@winuae.net>
Mon, 8 May 2023 17:19:03 +0000 (20:19 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 8 May 2023 17:19:03 +0000 (20:19 +0300)
calc.cpp
cfgfile.cpp
debug.cpp
include/calc.h
inputdevice.cpp

index 2f1224d968d2f4c3dd5ba7c1571c91ad6ddd84cc..eaa10fd958ee42059c750b360968f4dc2a938dab 100644 (file)
--- a/calc.cpp
+++ b/calc.cpp
@@ -32,7 +32,8 @@
 #define MAX_VALUES 32
 #define IOBUFFERS 256
 
-static double parsedvalues[MAX_VALUES];
+static double parsedvaluesd[MAX_VALUES];
+static TCHAR *parsedvaluess[MAX_VALUES];
 
 // operators
 // precedence   operators       associativity
@@ -50,8 +51,12 @@ static int op_preced(const TCHAR c)
             return 3;
         case '+': case '-':
             return 2;
-        case '=': case '@': case '>': case '<':
+        case '=': case '@': case '@' | 0x80: case '>': case '<': case '>' | 0x80: case '<' | 0x80:
             return 1;
+        case ':':
+            return -1;
+        case '?':
+            return -2;
     }
     return 0;
 }
@@ -64,7 +69,7 @@ static bool op_left_assoc(const TCHAR c)
         case '|': case '&': case '^':
             return true;
         // right to left
-        case '=': case '!': case '@': case '>': case '<':
+        case '=': case '!': case '@': case '@' | 0x80: case '>': case '<': case '>' | 0x80: case '<' | 0x80:
             return false;
     }
     return false;
@@ -73,10 +78,13 @@ static bool op_left_assoc(const TCHAR c)
 static unsigned int op_arg_count(const TCHAR c)
 {
     switch(c)  {
-        case '*': case '/': case '%': case '+': case '-': case '=': case '@': case '<': case '>':
-        case '|': case '&': case '^':
+        case '?':
+            return 3;
+        case '*': case '/': case '%': case '+': case '-': case '=': case '@': case '@' | 0x80: case '<': case '>':
+        case '|': case '&': case '^': case '<' | 0x80: case '>' | 0x80:
             return 2;
         case '!':
+        case ':':
             return 1;
         default:
             return c - 'A';
@@ -84,7 +92,9 @@ static unsigned int op_arg_count(const TCHAR c)
     return 0;
 }
  
-#define is_operator(c)  (c == '+' || c == '-' || c == '/' || c == '*' || c == '!' || c == '%' || c == '=' || c == '|' || c == '&' || c == '^' || c == '@' || c == '>' || c == '<')
+#define is_operator(c)  (c == '+' || c == '-' || c == '/' || c == '*' || c == '!' || c == '%' || c == '=' || \
+                         c == '|' || c == '&' || c == '^' || c == '@' || c == ('@' | 0x80) || c == '>' || c == '<' || c == ('>' | 0x80) || c == ('<' | 0x80) || \
+                         c == '?' || c == ':')
 #define is_function(c)  (c >= 'A' && c <= 'Z')
 #define is_ident(c)     ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z'))
  
@@ -227,63 +237,205 @@ struct calcstack
 {
        TCHAR *s;
        double val;
+    TCHAR *vals;
 };
 
-static double docalcx(TCHAR op, double v1, double v2)
+static double stacktoval(struct calcstack *st)
+{
+    if (st->s) {
+        if (_tcslen(st->s) == 1 && st->s[0] >= 'a' && st->s[0] <= 'z')
+            return parsedvaluesd[st->s[0] - 'a'];
+        return _tstof(st->s);
+    } else {
+        return st->val;
+    }
+}
+
+static bool isstackstring(struct calcstack *st)
+{
+    if (st->vals && st->vals[0]) {
+        return true;
+    }
+    if (st->s) {
+        if (_tcslen(st->s) == 1 && st->s[0] >= 'a' && st->s[0] <= 'z') {
+            TCHAR *s = parsedvaluess[st->s[0] - 'a'];
+            if (s) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+static TCHAR *stacktostring(struct calcstack *st)
+{
+    if (st->s) {
+        if (_tcslen(st->s) == 1 && st->s[0] >= 'a' && st->s[0] <= 'z') {
+            TCHAR *s = parsedvaluess[st->s[0] - 'a'];
+            if (s) {
+                st->vals = my_strdup(s);
+                xfree(st->s);
+                st->s = NULL;
+                return st->vals;
+            }
+            double v = parsedvaluesd[st->s[0] - 'a'];
+            TCHAR tmp[256];
+            _stprintf(tmp, _T("%d"), (int)v);
+            st->vals = my_strdup(tmp);
+            xfree(st->s);
+            st->s = NULL;
+            return st->vals;
+        }
+    }
+    if (!st->vals || !st->vals[0]) {
+        TCHAR tmp[256];
+        _stprintf(tmp, _T("%d"), (int)st->val);
+        xfree(st->vals);
+        st->vals = my_strdup(tmp);
+    }
+    return st->vals;
+}
+
+
+static TCHAR *docalcxs(TCHAR op, TCHAR *v1, TCHAR *v2, double *voutp)
 {
+    TCHAR tmp[MAX_DPATH];
+    tmp[0] = 0;
+
+    switch(op)
+    {
+    case '+':
+        _tcscpy(tmp, v1);
+        _tcscat(tmp, v2);
+        break;
+    case '@':
+        if (!_tcsicmp(v1, v2)) {
+            *voutp = 1;
+            return my_strdup(_T(""));
+        } else {
+            *voutp = 0;
+            return my_strdup(_T(""));
+        }
+        break;
+    case '@' | 0x80:
+        if (!_tcsicmp(v1, v2)) {
+            *voutp = 0;
+            return my_strdup(_T(""));
+        } else {
+            *voutp = 1;
+            return my_strdup(_T(""));
+        }
+        break;
+    case ':':
+        _tcscpy(tmp, v1);
+        break;
+    default:
+        return NULL;
+    }
+    return my_strdup(tmp);
+}
+
+static bool docalcx(TCHAR op, double v1, double v2, double *valp)
+{
+    double v = 0;
        switch (op)
        {
                case '-':
-               return v1 - v2;
+               v = v1 - v2;
+        break;
                case '+':
-               return v1 + v2;
-               case '*':
-               return v1 * v2;
-               case '/':
-               return v1 / v2;
-               case '\\':
-               return (int)v1 % (int)v2;
+               v =  v1 + v2;
+        break;
+        case '*':
+               v = v1 * v2;
+        break;
+        case '/':
+               v = v1 / v2;
+        break;
+        case '\\':
+               v =  (int)v1 % (int)v2;
+        break;
         case '|':
-        return (int)v1 | (int)v2;
+        v =  (int)v1 | (int)v2;
+        break;
         case '&':
-        return (int)v1 & (int)v2;
+        v =  (int)v1 & (int)v2;
+        break;
         case '^':
-        return (int)v1 ^ (int)v2;
+        v =  (int)v1 ^ (int)v2;
+        break;
         case '@':
-        return (int)v1 == (int)v2;
+        v = (int)v1 == (int)v2;
+        break;
+        case '@' | 0x80:
+        v =  (int)v1 != (int)v2;
+        break;
         case '>':
-        return (int)v1 > (int)v2;
+        v = (int)v1 > (int)v2;
+        break;
         case '<':
-        return (int)v1 < (int)v2;
-       }
-       return 0;
-}
-
-static double stacktoval(struct calcstack *st)
-{
-       if (st->s) {
-               if (_tcslen(st->s) == 1 && st->s[0] >= 'a' && st->s[0] <= 'z')
-                       return parsedvalues[st->s[0] - 'a'];
-               return _tstof (st->s);
-       } else {
-               return st->val;
-       }
+        v =  (int)v1 < (int)v2;
+        break;
+        case '<' | 0x80:
+        if ((uae_u32)v2 < 32) {
+            v = (uae_u32)v1 << (uae_u32)v2;
+        }
+        break;
+        case '>' | 0x80:
+        if ((uae_u32)v2 < 32) {
+            v = (uae_u32)v1 >> (uae_u32)v2;
+        }
+        break;
+        case ':':
+        v = v1;
+        break;
+        default:
+        return false;
+    }
+    *valp = v;
+       return true;
 }
 
-static double docalc2(TCHAR op, struct calcstack *sv1, struct calcstack *sv2)
+static bool docalc2(TCHAR op, struct calcstack *sv1, struct calcstack *sv2, double *valp, TCHAR *sp)
 {
-       double v1, v2;
-
-       v1 = stacktoval(sv1);
-       v2 = stacktoval(sv2);
-       return docalcx (op, v1, v2);
+    *sp = NULL;
+    *valp = 0;
+    if (isstackstring(sv1) || isstackstring(sv2)) {
+        TCHAR *v1 = stacktostring(sv1);
+        TCHAR *v2 = stacktostring(sv2);
+        double vout = 0;
+        TCHAR *s = docalcxs(op, v1, v2, &vout);
+        if (!s) {
+            return false;
+        }
+        _tcscpy(sp, s);
+        xfree(s);
+        if (vout) {
+            *valp = vout;
+        }
+        return true;
+    } else {
+       double v1 = stacktoval(sv1);
+           double v2 = stacktoval(sv2);
+           return docalcx(op, v1, v2, valp);
+    }
 }
-static double docalc1(TCHAR op, struct calcstack *sv1, double v2)
+static bool docalc1(TCHAR op, struct calcstack *sv1, double v2, double *valp, TCHAR *sp)
 {
-       double v1;
-
-       v1 = stacktoval(sv1);
-       return docalcx (op, v1, v2);
+    if (isstackstring(sv1)) {
+        TCHAR *v1 = stacktostring(sv1);
+        double vout;
+        TCHAR *s = docalcxs(op, v1, _T(""), &vout);
+        if (!s) {
+            return false;
+        }
+        _tcscpy(sp, s);
+        xfree(s);
+        return true;
+    } else {
+           double v1 = stacktoval(sv1);
+           return docalcx(op, v1, v2, valp);
+    }
 }
 
 #if CALC_DEBUG
@@ -305,16 +457,20 @@ static TCHAR *chartostack(TCHAR c)
        return s;
 }
 
-static bool execution_order(const TCHAR *input, double *outval)
+static struct calcstack stack[STACK_SIZE] = { 0 };
+
+static bool execution_order(const TCHAR *input, double *outval, TCHAR *outstring, int maxlen)
 {
     const TCHAR *strpos = input, *strend = input + _tcslen(input);
     TCHAR c, res[4];
     unsigned int sl = 0, rn = 0;
-       struct calcstack stack[STACK_SIZE] = { { 0 } }, *sc, *sc2;
+       struct calcstack *sc, *sc2;
        double val = 0;
-       int i;
+    TCHAR vals[MAX_DPATH];
+    int i;
        bool ok = false;
 
+    vals[0] = 0;
        // While there are input tokens left
     while(strpos < strend)  {
 
@@ -361,20 +517,37 @@ static bool execution_order(const TCHAR *input, double *outval)
                                 if(nargs == 1) {
                                         sc = &stack[sl - 1];
                                         sl--;
-                                                                               val = docalc1 (c, sc, val);
+                                                                               docalc1 (c, sc, val, &val, vals);
                                                                                calc_log ((_T("%c %s = %f;\n"), c, stacktostr(sc), val));
                                }
-                                else   {
+                                else if (nargs == 2) {
                                         sc = &stack[sl - 2];
                                         calc_log ((_T("%s %c "), stacktostr(sc), c));
                                         sc2 = &stack[sl - 1];
-                                                                               val = docalc2 (c, sc, sc2);
-                                         sl--;sl--;
+                                                                               docalc2 (c, sc, sc2, &val, vals);
+                                        sl--;sl--;
                                         calc_log ((_T("%s = %f;\n"), stacktostr(sc2), val));
+                               } else if (nargs == 3) {
+                                        // ternary
+                                        sc = &stack[sl - 3];
+                                        if (sc->val != 0) {
+                                            sc2 = &stack[sl - 2];
+                                        } else {
+                                            sc2 = &stack[sl - 1];
+                                        }
+                                        sl--;sl--;sl--;
+                                        if (isstackstring(sc2)) {
+                                            TCHAR *c = stacktostring(sc2);
+                                            _tcscpy(vals, c);
+                                            xfree(c);
+                                        }
+                                        val = stacktoval(sc2);
                                }
                         }
                         // Push the returned results, if any, back onto the stack.
                                                stack[sl].val = val;
+                        xfree(stack[sl].vals);
+                        stack[sl].vals = my_strdup(vals);
                                                stack[sl].s = NULL;
             ++sl;
         }
@@ -388,6 +561,12 @@ static bool execution_order(const TCHAR *input, double *outval)
                                calc_log ((_T("result = %f\n"), val));
                                if (outval)
                                        *outval = val;
+                if (outstring) {
+                    if (vals && _tcslen(vals) >= maxlen) {
+                        vals[maxlen] = 0;
+                    }
+                    _tcscpy(outstring, vals ? vals : _T(""));
+                }
                                ok = true;
                }
                for (i = 0; i < STACK_SIZE; i++)
@@ -433,12 +612,41 @@ static bool parse_values(const TCHAR *ins, TCHAR *out)
                        in[2] = ' ';
                        in[3] = ' ';
                        in[4] = ' ';
-               }
+               } else if (in[0] == '>' && in[1] == '>') {
+            in[0] = '>' | 0x80;
+            in[1] = ' ';
+        } else if (in[0] == '<' && in[1] == '<') {
+            in[0] = '<' | 0x80;
+            in[1] = ' ';
+        } else if (in[0] == '"' || in[0] == '\'') {
+            TCHAR *quoted = in;
+            TCHAR quotec = *in;
+            *in++ = 0;
+            if (ident >= MAX_VALUES)
+                return false;
+            *p++ = ident + 'a';
+            while (*in != 0 && *in != quotec) {
+                in++;
+            }
+            if (*in != quotec) {
+                return false;
+            }
+            *in = 0;
+            parsedvaluess[ident++] = my_strdup(quoted + 1);
+            while (quoted <= in) {
+                *quoted++ = ' ';
+            }
+            continue;
+        }
         if (*in == '=' && *(in + 1) == '=') {
             *in = '@';
             *(in + 1) = ' ';
         }
-               if (_istdigit (*in)) {
+        if (*in == '!' && *(in + 1) == '=') {
+            *in = '@' | 0x80;
+            *(in + 1) = ' ';
+        }
+        if (_istdigit (*in)) {
                        if (ident >= MAX_VALUES)
                                return false;
                        if (op > 1 && (in[-1] == '-' || in[-1] == '+')) {
@@ -450,7 +658,7 @@ static bool parse_values(const TCHAR *ins, TCHAR *out)
                                in++;
                        tmp = *in;
                        *in = 0;
-                       parsedvalues[ident++] = _tstof (instart);
+                       parsedvaluesd[ident++] = _tstof (instart);
                        *in = tmp;
                        op = 0;
                } else {
@@ -463,21 +671,43 @@ static bool parse_values(const TCHAR *ins, TCHAR *out)
        return true;
 }
 
-bool calc(const TCHAR *input, double *outval)
+int calc(const TCHAR *input, double *outval, TCHAR *outstring, int maxlen)
 {
     TCHAR output[IOBUFFERS], output2[IOBUFFERS];
+    int ret = -1;
     calc_log ((_T("IN: '%s'\n"), input));
+    if (outval) {
+        *outval = 0;
+    }
+    if (outstring) {
+        outstring[0] = 0;
+    }
        if (parse_values(input, output2)) {
                if(shunting_yard(output2, output))    {
                        calc_log ((_T("RPN OUT: %s\n"), output));
-                       if(!execution_order(output, outval)) {
+                       if(!execution_order(output, outval, outstring, maxlen)) {
                                calc_log ((_T("PARSE ERROR!\n")));
                        } else {
-                               return true;
+                if (outstring && outstring[0]) {
+                    ret = -1;
+                } else {
+                    ret = 1;
+                }
                        }
                }
     }
-    return false;
+    for (int i = 0; i < MAX_VALUES; i++) {
+        xfree(parsedvaluess[i]);
+        parsedvaluesd[i] = 0;
+        parsedvaluess[i] = NULL;
+    }
+    for (int i = 0; i < STACK_SIZE; i++) {
+        struct calcstack *s = &stack[i];
+        xfree(s->vals);
+        xfree(s->s);
+        memset(s, 0, sizeof(struct calcstack));
+    }
+    return ret;
 }
 
 bool iscalcformula (const TCHAR *formula)
index 1a8e2b1638ab5e8b22e70157958c49bb050dfcaa..11ebde0c94783531aa5d618c2c37fdddbaddfc48 100644 (file)
@@ -6649,11 +6649,12 @@ static int getconfigstoreline (const TCHAR *option, TCHAR *value);
 
 static void calcformula (struct uae_prefs *prefs, TCHAR *in)
 {
-       TCHAR out[MAX_DPATH], configvalue[CONFIG_BLEN];
+       TCHAR out[MAX_DPATH], configvalue[CONFIG_BLEN], tmp[MAX_DPATH];
        TCHAR *p = out;
        double val;
        int cnt1, cnt2;
        static bool updatestore;
+       int escaped, quoted;
 
        if (_tcslen (in) < 2 || in[0] != '[' || in[_tcslen (in) - 1] != ']')
                return;
@@ -6663,9 +6664,18 @@ static void calcformula (struct uae_prefs *prefs, TCHAR *in)
        if (!configstore)
                return;
        cnt1 = cnt2 = 0;
+       escaped = 0;
+       quoted = 0;
        for (int i = 1; i < _tcslen (in) - 1; i++) {
                TCHAR c = _totupper (in[i]);
-               if (c >= 'A' && c <='Z') {
+               if (c == '\\') {
+                       escaped = 1;
+               } else if (c == '\'') {
+                       quoted = escaped + 1;
+                       escaped = 0;
+                       cnt2++;
+                       *p++ = c;
+               } else if (c >= 'A' && c <='Z') {
                        TCHAR *start = &in[i];
                        while (_istalnum (c) || c == '_' || c == '.') {
                                i++;
@@ -6674,16 +6684,22 @@ static void calcformula (struct uae_prefs *prefs, TCHAR *in)
                        TCHAR store = in[i];
                        in[i] = 0;
                        //write_log (_T("'%s'\n"), start);
-                       if (!getconfigstoreline (start, configvalue))
-                               return;
-                       _tcscpy (p, configvalue);
+                       if ((quoted == 0 || quoted == 2) && getconfigstoreline (start, configvalue)) {
+                               _tcscpy(p, configvalue);
+                       } else {
+                               _tcscpy(p, start);
+                       }
                        p += _tcslen (p);
                        in[i] = store;
                        i--;
                        cnt1++;
+                       escaped = 0;
+                       quoted = 0;
                } else {
                        cnt2++;
-                       *p ++= c;
+                       *p++= c;
+                       escaped = 0;
+                       quoted = 0;
                }
        }
        *p = 0;
@@ -6695,13 +6711,16 @@ static void calcformula (struct uae_prefs *prefs, TCHAR *in)
                updatestore = true;
                return;
        }
-       if (calc (out, &val)) {
+       int v = calc(out, &val, tmp, sizeof(tmp) / sizeof(TCHAR));
+       if (v > 0) {
                if (val - (int)val != 0.0f)
                        _stprintf (in, _T("%f"), val);
                else
                        _stprintf (in, _T("%d"), (int)val);
                updatestore = true;
-               return;
+       } else if (v < 0) {
+               _tcscpy(in, tmp);
+               updatestore = true;
        }
 }
 
index afe157d8f5e2e1b6214d8ac6647c384ab3887d13..e1f07a060190f4c08dcd1d7868fc00ffe75ddfb0 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -750,12 +750,26 @@ static int readregx(TCHAR **c, uae_u32 *valp)
        return 1;
 }
 
+static bool checkisneg(TCHAR **c)
+{
+       TCHAR nc = peekchar(c);
+       if (nc == '-') {
+               (*c)++;
+               return true;
+       } else if (nc == '+') {
+               (*c)++;
+       }
+       return false;
+}
+
 static bool readbinx (TCHAR **c, uae_u32 *valp)
 {
        uae_u32 val = 0;
        bool first = true;
+       bool negative = false;
 
        ignore_ws (c);
+       negative = checkisneg(c);
        for (;;) {
                TCHAR nc = **c;
                if (nc != '1' && nc != '0') {
@@ -769,7 +783,7 @@ static bool readbinx (TCHAR **c, uae_u32 *valp)
                if (nc == '1')
                        val |= 1;
        }
-       *valp = val;
+       *valp = val * (negative ? -1 : 1);
        return true;
 }
 
@@ -777,9 +791,11 @@ static bool readhexx (TCHAR **c, uae_u32 *valp)
 {
        uae_u32 val = 0;
        TCHAR nc;
+       bool negative = false;
 
-       ignore_ws (c);
-       if (!isxdigit (peekchar (c)))
+       ignore_ws(c);
+       negative = checkisneg(c);
+       if (!isxdigit(peekchar(c)))
                return false;
        while (isxdigit (nc = **c)) {
                (*c)++;
@@ -791,7 +807,7 @@ static bool readhexx (TCHAR **c, uae_u32 *valp)
                        val += nc - 'A' + 10;
                }
        }
-       *valp = val;
+       *valp = val * (negative ? -1 : 1);
        return true;
 }
 
@@ -802,8 +818,7 @@ static bool readintx (TCHAR **c, uae_u32 *valp)
        int negative = 0;
 
        ignore_ws (c);
-       if (**c == '-')
-               negative = 1, (*c)++;
+       negative = checkisneg(c);
        if (!isdigit (peekchar (c)))
                return false;
        while (isdigit (nc = **c)) {
@@ -896,14 +911,8 @@ static int checkvaltype (TCHAR **cp, uae_u32 *val, int *size, TCHAR def)
        for (;;) {
                uae_u32 v;
                if (!checkvaltype2 (cp, &v, def)) {
-                       if (isoperator(cp) || gotop) {
-                               for (;;) {
-                                       *p = readchar(cp);
-                                       if (*p == 0) {
-                                               goto docalc;
-                                       }
-                                       p++;
-                               }
+                       if (isoperator(cp) || gotop || **cp == '\"' || **cp == '\'') {
+                               goto docalc;
                        }
                        return 0;
                }
@@ -911,11 +920,13 @@ static int checkvaltype (TCHAR **cp, uae_u32 *val, int *size, TCHAR def)
                // stupid but works!
                _stprintf(p, _T("%u"), v);
                p += _tcslen (p);
+               *p = 0;
                if (peekchar (cp) == '.') {
                        readchar (cp);
                        if (size)
                                *size = readsize (v, cp);
                }
+               ignore_ws(cp);
                if (!isoperator (cp))
                        break;
                gotop = true;
@@ -936,7 +947,13 @@ static int checkvaltype (TCHAR **cp, uae_u32 *val, int *size, TCHAR def)
                return 1;
        }
 docalc:
-       if (calc (form, &out)) {
+       while (more_params2(cp)) {
+               *p++ = readchar(cp);
+       }
+       *p = 0;
+       TCHAR tmp[MAX_DPATH];
+       int v = calc(form, &out, tmp, sizeof(tmp) / sizeof(TCHAR));
+       if (v > 0) {
                *val = (uae_u32)out;
                if (size && *size == 0) {
                        uae_s32 v = (uae_s32)(*val);
@@ -949,6 +966,8 @@ docalc:
                        }
                }
                return 1;
+       } else if (v < 0) {
+               console_out_f(_T("String returned: '%s'\n"), tmp);
        }
        return 0;
 }
index 33ae11a25d4b84c6a98d2f7828224402cd17ff3a..80bb19881e31186039e63c3632e5f9bed6478c8f 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "uae/types.h"
 
-extern bool calc(const TCHAR *input, double *outval);
-extern bool iscalcformula (const TCHAR *formula);
+extern int calc(const TCHAR *input, double *outval, TCHAR *outstring, int maxlen);
+extern bool iscalcformula(const TCHAR *formula);
 
 #endif /* UAE_CALC_H */
index 63f050e82380f8a7252e08c62e2baec5772b30b3..d3b6d79f97ff30933dfdfa404cb339b359dd6dbf 100644 (file)
@@ -1535,8 +1535,20 @@ static const struct inputevent *readevent (const TCHAR *name, TCHAR **customp)
        if (_tcslen (name) > 2 && name[0] == '\'') {
                name++;
                const TCHAR *end = name;
-               while (*end && *end != '\'')
+               bool equote = false;
+               while (*end) {
+                       if (*end == '\"') {
+                               if (!equote) {
+                                       equote = 1;
+                               } else {
+                                       equote = 0;
+                               }
+                       }
+                       if (!equote && *end == '\'') {
+                               break;
+                       }
                        end++;
+               }
                if (!customp || *end == 0)
                        return NULL;
                TCHAR *custom = my_strdup (name);