Revise calling sequences for grok_bslash_[xo]
authorKarl Williamson <public@khwilliamson.com>
Mon, 7 Jan 2013 03:25:24 +0000 (20:25 -0700)
committerKarl Williamson <public@khwilliamson.com>
Fri, 11 Jan 2013 18:50:35 +0000 (11:50 -0700)
By passing the address of the parse pointer, the functions can advance
it, eliminating a parameter to the function, and simplifying the code in
the caller.

dquote_static.c
embed.fnc
embed.h
proto.h
regcomp.c
toke.c

index 5cc890b..fa8e354 100644 (file)
@@ -85,31 +85,30 @@ S_grok_bslash_c(pTHX_ const char source, const bool utf8, const bool output_warn
 }
 
 STATIC bool
-S_grok_bslash_o(pTHX_ const char *s,
-                        UV *uv,
-                        STRLEN *len,
-                        const char** error_msg,
-                        const bool output_warning)
+S_grok_bslash_o(pTHX_ char **s, UV *uv, const char** error_msg,
+                      const bool output_warning)
 {
 
 /*  Documentation to be supplied when interface nailed down finally
  *  This returns FALSE if there is an error which the caller need not recover
  *  from; , otherwise TRUE.  In either case the caller should look at *len
  *  On input:
- *     s   points to a string that begins with 'o', and the previous character
- *         was a backslash.
+ *     s   is the address of a pointer to a NULL terminated string that begins
+ *         with 'o', and the previous character was a backslash.  At exit, *s
+ *         will be advanced to the byte just after those absorbed by this
+ *         function.  Hence the caller can continue parsing from there.  In
+ *         the case of an error, this routine has generally positioned *s to
+ *         point just to the right of the first bad spot, so that a message
+ *         that has a "<--" to mark the spot will be correctly positioned.
  *     uv  points to a UV that will hold the output value, valid only if the
  *         return from the function is TRUE
- *     len on success will point to the next character in the string past the
- *                    end of this construct.
- *         on failure, it will point to the failure
  *      error_msg is a pointer that will be set to an internal buffer giving an
  *         error message upon failure (the return is FALSE).  Untouched if
  *         function succeeds
  *     output_warning says whether to output any warning messages, or suppress
  *         them
  */
-    const char* e;
+    char* e;
     STRLEN numbers_len;
     I32 flags = PERL_SCAN_ALLOW_UNDERSCORES
                | PERL_SCAN_DISALLOW_PREFIX
@@ -120,75 +119,74 @@ S_grok_bslash_o(pTHX_ const char *s,
     PERL_ARGS_ASSERT_GROK_BSLASH_O;
 
 
-    assert(*s == 'o');
-    s++;
+    assert(**s == 'o');
+    (*s)++;
 
-    if (*s != '{') {
-       *len = 1;       /* Move past the o */
+    if (**s != '{') {
        *error_msg = "Missing braces on \\o{}";
        return FALSE;
     }
 
-    e = strchr(s, '}');
+    e = strchr(*s, '}');
     if (!e) {
-       *len = 2;       /* Move past the o{ */
-       *error_msg = "Missing right brace on \\o{";
+        (*s)++;  /* Move past the '{' */
+        *error_msg = "Missing right brace on \\o{";
        return FALSE;
     }
 
-    /* Return past the '}' no matter what is inside the braces */
-    *len = e - s + 2;  /* 2 = 1 for the 'o' + 1 for the '}' */
-
-    s++;    /* Point to first digit */
-
-    numbers_len = e - s;
+    (*s)++;    /* Point to expected first digit (could be first byte of utf8
+                  sequence if not a digit) */
+    numbers_len = e - *s;
     if (numbers_len == 0) {
+        (*s)++;    /* Move past the } */
        *error_msg = "Number with no digits";
        return FALSE;
     }
 
-    *uv = grok_oct(s, &numbers_len, &flags, NULL);
+    *uv = grok_oct(*s, &numbers_len, &flags, NULL);
     /* Note that if has non-octal, will ignore everything starting with that up
      * to the '}' */
 
-    if (output_warning && numbers_len != (STRLEN) (e - s)) {
+    if (output_warning && numbers_len != (STRLEN) (e - *s)) {
        Perl_ck_warner(aTHX_ packWARN(WARN_DIGIT),
        /* diag_listed_as: Non-octal character '%c'.  Resolved as "%s" */
                       "Non-octal character '%c'.  Resolved as \"\\o{%.*s}\"",
-                      *(s + numbers_len),
+                      *(*s + numbers_len),
                       (int) numbers_len,
-                      s);
+                      *s);
     }
 
+    /* Return past the '}' */
+    *s = e + 1;
+
     return TRUE;
 }
 
 PERL_STATIC_INLINE bool
-S_grok_bslash_x(pTHX_ const char *s,
-                        UV *uv,
-                        STRLEN *len,
-                        const char** error_msg,
-                        const bool output_warning)
+S_grok_bslash_x(pTHX_ char **s, UV *uv, const char** error_msg,
+                      const bool output_warning)
 {
 
 /*  Documentation to be supplied when interface nailed down finally
  *  This returns FALSE if there is an error which the caller need not recover
  *  from; , otherwise TRUE.  In either case the caller should look at *len
  *  On input:
- *     s   points to a string that begins with 'x', and the previous character
- *         was a backslash.
+ *     s   is the address of a pointer to a NULL terminated string that begins
+ *         with 'x', and the previous character was a backslash.  At exit, *s
+ *         will be advanced to the byte just after those absorbed by this
+ *         function.  Hence the caller can continue parsing from there.  In
+ *         the case of an error, this routine has generally positioned *s to
+ *         point just to the right of the first bad spot, so that a message
+ *         that has a "<--" to mark the spot will be correctly positioned.
  *     uv  points to a UV that will hold the output value, valid only if the
  *         return from the function is TRUE
- *     len on success will point to the next character in the string past the
- *                    end of this construct.
- *         on failure, it will point to the failure
  *      error_msg is a pointer that will be set to an internal buffer giving an
  *         error message upon failure (the return is FALSE).  Untouched if
  *         function succeeds
  *     output_warning says whether to output any warning messages, or suppress
  *         them
  */
-    const char* e;
+    char* e;
     STRLEN numbers_len;
     I32 flags = PERL_SCAN_ALLOW_UNDERSCORES
                | PERL_SCAN_DISALLOW_PREFIX;
@@ -197,20 +195,20 @@ S_grok_bslash_x(pTHX_ const char *s,
 
     PERL_UNUSED_ARG(output_warning);
 
-    assert(*s == 'x');
-    s++;
+    assert(**s == 'x');
+    (*s)++;
 
-    if (*s != '{') {
-       I32 flags = PERL_SCAN_DISALLOW_PREFIX;
-       *len = 2;
-       *uv = grok_hex(s, len, &flags, NULL);
-       (*len)++;
+    if (**s != '{') {
+       I32 flags = PERL_SCAN_DISALLOW_PREFIX;
+       STRLEN len = 2;
+       *uv = grok_hex(*s, &len, &flags, NULL);
+       *s += len;
        return TRUE;
     }
 
-    e = strchr(s, '}');
+    e = strchr(*s, '}');
     if (!e) {
-       *len = 2;       /* Move past the 'x{' */
+        (*s)++;  /* Move past the '{' */
         /* XXX The corresponding message above for \o is just '\\o{'; other
          * messages for other constructs include the '}', so are inconsistent.
          */
@@ -218,16 +216,16 @@ S_grok_bslash_x(pTHX_ const char *s,
        return FALSE;
     }
 
-    /* Return past the '}' no matter what is inside the braces */
-    *len = e - s + 2;  /* 2 = 1 for the 'x' + 1 for the '}' */
-
-    s++;    /* Point to first digit */
-
-    numbers_len = e - s;
-    *uv = grok_hex(s, &numbers_len, &flags, NULL);
+    (*s)++;    /* Point to expected first digit (could be first byte of utf8
+                  sequence if not a digit) */
+    numbers_len = e - *s;
+    *uv = grok_hex(*s, &numbers_len, &flags, NULL);
     /* Note that if has non-hex, will ignore everything starting with that up
      * to the '}' */
 
+    /* Return past the '}' */
+    *s = e + 1;
+
     return TRUE;
 }
 
index 0bdbd93..02ce9b2 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -736,8 +736,12 @@ ApdR       |I32    |looks_like_number|NN SV *const sv
 Apd    |UV     |grok_bin       |NN const char* start|NN STRLEN* len_p|NN I32* flags|NULLOK NV *result
 #if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_TOKE_C)
 EMsR   |char   |grok_bslash_c  |const char source|const bool utf8|const bool output_warning
-EMsR   |bool   |grok_bslash_o  |NN const char* s|NN UV* uv|NN STRLEN* len|NN const char** error_msg|const bool output_warning
-EMiR   |bool   |grok_bslash_x  |NN const char* s|NN UV* uv|NN STRLEN* len|NN const char** error_msg|const bool output_warning
+EMsR   |bool   |grok_bslash_o  |NN char** s|NN UV* uv \
+                               |NN const char** error_msg   \
+                               |const bool output_warning
+EMiR   |bool   |grok_bslash_x  |NN char** s|NN UV* uv \
+                               |NN const char** error_msg   \
+                               |const bool output_warning
 #endif
 Apd    |UV     |grok_hex       |NN const char* start|NN STRLEN* len_p|NN I32* flags|NULLOK NV *result
 Apd    |int    |grok_number    |NN const char *pv|STRLEN len|NULLOK UV *valuep
diff --git a/embed.h b/embed.h
index c0439a6..86d7760 100644 (file)
--- a/embed.h
+++ b/embed.h
 #  endif
 #  if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_TOKE_C)
 #define grok_bslash_c(a,b,c)   S_grok_bslash_c(aTHX_ a,b,c)
-#define grok_bslash_o(a,b,c,d,e)       S_grok_bslash_o(aTHX_ a,b,c,d,e)
-#define grok_bslash_x(a,b,c,d,e)       S_grok_bslash_x(aTHX_ a,b,c,d,e)
+#define grok_bslash_o(a,b,c,d) S_grok_bslash_o(aTHX_ a,b,c,d)
+#define grok_bslash_x(a,b,c,d) S_grok_bslash_x(aTHX_ a,b,c,d)
 #define regcurly(a)            S_regcurly(aTHX_ a)
 #  endif
 #  if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_UTF8_C)
diff --git a/proto.h b/proto.h
index 5f16d65..596f310 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -6756,23 +6756,21 @@ PERL_CALLCONV SV*       Perl__core_swash_init(pTHX_ const char* pkg, const char* name,
 STATIC char    S_grok_bslash_c(pTHX_ const char source, const bool utf8, const bool output_warning)
                        __attribute__warn_unused_result__;
 
-STATIC bool    S_grok_bslash_o(pTHX_ const char* s, UV* uv, STRLEN* len, const char** error_msg, const bool output_warning)
+STATIC bool    S_grok_bslash_o(pTHX_ char** s, UV* uv, const char** error_msg, const bool output_warning)
                        __attribute__warn_unused_result__
                        __attribute__nonnull__(pTHX_1)
                        __attribute__nonnull__(pTHX_2)
-                       __attribute__nonnull__(pTHX_3)
-                       __attribute__nonnull__(pTHX_4);
+                       __attribute__nonnull__(pTHX_3);
 #define PERL_ARGS_ASSERT_GROK_BSLASH_O \
-       assert(s); assert(uv); assert(len); assert(error_msg)
+       assert(s); assert(uv); assert(error_msg)
 
-PERL_STATIC_INLINE bool        S_grok_bslash_x(pTHX_ const char* s, UV* uv, STRLEN* len, const char** error_msg, const bool output_warning)
+PERL_STATIC_INLINE bool        S_grok_bslash_x(pTHX_ char** s, UV* uv, const char** error_msg, const bool output_warning)
                        __attribute__warn_unused_result__
                        __attribute__nonnull__(pTHX_1)
                        __attribute__nonnull__(pTHX_2)
-                       __attribute__nonnull__(pTHX_3)
-                       __attribute__nonnull__(pTHX_4);
+                       __attribute__nonnull__(pTHX_3);
 #define PERL_ARGS_ASSERT_GROK_BSLASH_X \
-       assert(s); assert(uv); assert(len); assert(error_msg)
+       assert(s); assert(uv); assert(error_msg)
 
 PERL_STATIC_INLINE I32 S_regcurly(pTHX_ const char *s)
                        __attribute__warn_unused_result__
index 7382753..c6bd79a 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -10612,16 +10612,13 @@ tryagain:
                        break;
                    case 'o':
                        {
-                           STRLEN brace_len = len;
                            UV result;
                            const char* error_msg;
 
-                           bool valid = grok_bslash_o(p,
+                           bool valid = grok_bslash_o(&p,
                                                       &result,
-                                                      &brace_len,
                                                       &error_msg,
-                                                      1);
-                           p += brace_len;
+                                                      TRUE); /* out warnings */
                            if (! valid) {
                                RExC_parse = p; /* going to die anyway; point
                                                   to exact spot of failure */
@@ -10641,16 +10638,13 @@ tryagain:
                        }
                    case 'x':
                        {
-                           STRLEN brace_len = len;
                            UV result;
                            const char* error_msg;
 
-                           bool valid = grok_bslash_x(p,
+                           bool valid = grok_bslash_x(&p,
                                                       &result,
-                                                      &brace_len,
                                                       &error_msg,
-                                                      1);
-                           p += brace_len;
+                                                      TRUE); /* out warnings */
                            if (! valid) {
                                RExC_parse = p; /* going to die anyway; point
                                                   to exact spot of failure */
@@ -11571,12 +11565,10 @@ parseit:
                RExC_parse--;   /* function expects to be pointed at the 'o' */
                {
                    const char* error_msg;
-                   bool valid = grok_bslash_o(RExC_parse,
+                   bool valid = grok_bslash_o(&RExC_parse,
                                               &value,
-                                              &numlen,
                                               &error_msg,
                                               SIZE_ONLY);
-                   RExC_parse += numlen;
                    if (! valid) {
                        vFAIL(error_msg);
                    }
@@ -11589,12 +11581,10 @@ parseit:
                RExC_parse--;   /* function expects to be pointed at the 'x' */
                {
                    const char* error_msg;
-                   bool valid = grok_bslash_x(RExC_parse,
+                   bool valid = grok_bslash_x(&RExC_parse,
                                               &value,
-                                              &numlen,
                                               &error_msg,
                                               1);
-                   RExC_parse += numlen;
                    if (! valid) {
                        vFAIL(error_msg);
                    }
diff --git a/toke.c b/toke.c
index 419768c..6cf5afc 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -3287,11 +3287,10 @@ S_scan_const(pTHX_ char *start)
            /* eg. \o{24} indicates the octal constant \024 */
            case 'o':
                {
-                   STRLEN len;
                    const char* error;
 
-                   bool valid = grok_bslash_o(s, &uv, &len, &error, 1);
-                   s += len;
+                   bool valid = grok_bslash_o(&s, &uv, &error,
+                                               TRUE); /* Output warning */
                    if (! valid) {
                        yyerror(error);
                        continue;
@@ -3302,11 +3301,10 @@ S_scan_const(pTHX_ char *start)
            /* eg. \x24 indicates the hex constant 0x24 */
            case 'x':
                {
-                   STRLEN len;
                    const char* error;
 
-                   bool valid = grok_bslash_x(s, &uv, &len, &error, 1);
-                   s += len;
+                   bool valid = grok_bslash_x(&s, &uv, &error,
+                                               TRUE); /* Output warning */
                    if (! valid) {
                        yyerror(error);
                        continue;