Don't invoke the const callback for a keyword followed by a fat comma.
Florian Ragwitz [Thu, 13 Aug 2009 21:21:29 +0000 (23:21 +0200)]
Declare.xs
stolen_chunk_of_toke.c

index 500e9d7..0474261 100644 (file)
@@ -220,7 +220,7 @@ int dd_toke_scan_str(pTHX_ int offset) {
 
 int dd_toke_skipspace(pTHX_ int offset) {
   char* base_s = SvPVX(PL_linestr) + offset;
-  char* s = skipspace(base_s);
+  char* s = skipspace_force(base_s);
   return s - base_s;
 }
 
@@ -381,10 +381,37 @@ STATIC OP *dd_ck_const(pTHX_ OP *o, void *user_data) {
       break;
   }
 
-  if (strnEQ (PL_bufptr, "->", 2)) {
+  if (strnEQ(PL_bufptr, "->", 2)) {
     return o;
   }
 
+  {
+    char buf[256];
+    STRLEN len;
+    char *s = PL_bufptr;
+    STRLEN old_offset = PL_bufptr - SvPVX(PL_linestr);
+
+    s = scan_word(s, buf, sizeof buf, FALSE, &len);
+    if (strnEQ(buf, name, len)) {
+      char *d;
+      SV *inject = newSVpv("", 0);
+      sv_catpvn(inject, SvPV_nolen(PL_linestr), PL_bufptr - SvPVX(PL_linestr));
+      sv_catpvn(inject, buf, len);
+
+      d = peekspace(s);
+      sv_catpvn(inject, s, d - s);
+
+      if ((PL_bufend - d) >= 2 && strnEQ(d, "=>", 2)) {
+        return o;
+      }
+
+      sv_catpv(inject, d);
+      dd_set_linestr(aTHX_ SvPV_nolen(inject));
+      PL_bufptr = SvPVX(PL_linestr) + old_offset;
+      SvREFCNT_dec (inject);
+    }
+  }
+
   dd_linestr_callback(aTHX_ "const", name);
 
   return o;
index a15c9a1..e231264 100644 (file)
@@ -19,7 +19,9 @@
 
 /* the following #defines are stolen from assorted headers, not toke.c (mst) */
 
-#define skipspace(a)            S_skipspace(aTHX_ a)
+#define skipspace(a)            S_skipspace(aTHX_ a, 0)
+#define peekspace(a)            S_skipspace(aTHX_ a, 1)
+#define skipspace_force(a)      S_skipspace(aTHX_ a, 2)
 #define incline(a)              S_incline(aTHX_ a)
 #define filter_gets(a,b,c)      S_filter_gets(aTHX_ a,b,c)
 #define scan_str(a,b,c)         S_scan_str(aTHX_ a,b,c)
@@ -27,7 +29,7 @@
 #define scan_ident(a,b,c,d,e)   S_scan_ident(aTHX_ a,b,c,d,e)
 
 STATIC void     S_incline(pTHX_ char *s);
-STATIC char*    S_skipspace(pTHX_ char *s);
+STATIC char*    S_skipspace(pTHX_ char *s, int incline);
 STATIC char *   S_filter_gets(pTHX_ SV *sv, PerlIO *fp, STRLEN append);
 STATIC char*    S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims);
 STATIC char*    S_scan_word(pTHX_ char *s, char *dest, STRLEN destlen, int allow_package, STRLEN *slp);
@@ -270,7 +272,7 @@ S_filter_gets(pTHX_ register SV *sv, register PerlIO *fp, STRLEN append)
  */
 
 STATIC char *
-S_skipspace(pTHX_ register char *s)
+S_skipspace(pTHX_ register char *s, int incline)
 {
     if (PL_lex_formbrack && PL_lex_brackets <= PL_lex_formbrack) {
        while (s < PL_bufend && SPACE_OR_TAB(*s))
@@ -282,7 +284,7 @@ S_skipspace(pTHX_ register char *s)
        SSize_t oldprevlen, oldoldprevlen;
        SSize_t oldloplen = 0, oldunilen = 0;
        while (s < PL_bufend && isSPACE(*s)) {
-           if (*s++ == '\n' && PL_in_eval && !PL_rsfp)
+           if (*s++ == '\n' && ((incline == 2) || PL_in_eval && !PL_rsfp && !incline))
                incline(s);
        }
 
@@ -292,13 +294,21 @@ S_skipspace(pTHX_ register char *s)
                s++;
            if (s < PL_bufend) {
                s++;
-               if (PL_in_eval && !PL_rsfp) {
+               if (PL_in_eval && !PL_rsfp && !incline) {
                    incline(s);
                    continue;
                }
            }
        }
 
+       /* also skip leading whitespace on the beginning of a line before deciding
+        * whether or not to recharge the linestr. --rafl
+        */
+       while (s < PL_bufend && isSPACE(*s)) {
+               if (*s++ == '\n' && PL_in_eval && !PL_rsfp && !incline)
+                       incline(s);
+       }
+
        /* only continue to recharge the buffer if we're at the end
         * of the buffer, we're not reading from a source filter, and
         * we're in normal lexing mode
@@ -368,7 +378,8 @@ S_skipspace(pTHX_ register char *s)
            PL_last_uni = s + oldunilen;
        if (PL_last_lop)
            PL_last_lop = s + oldloplen;
-       incline(s);
+       if (!incline)
+               incline(s);
 
        /* debugger active and we're not compiling the debugger code,
         * so store the line into the debugger's array of lines