[win32] fix extra LEAVE when require fails
[p5sagit/p5-mst-13.2.git] / toke.c
diff --git a/toke.c b/toke.c
index b92edd3..640ab67 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -49,6 +49,8 @@ static int uni _((I32 f, char *s));
 #endif
 static char * filter_gets _((SV *sv, PerlIO *fp, STRLEN append));
 static void restore_rsfp _((void *f));
+static void restore_expect _((void *e));
+static void restore_lex_expect _((void *e));
 
 static char ident_too_long[] = "Identifier too long";
 
@@ -187,7 +189,7 @@ missingterm(char *s)
     char q;
     if (s) {
        char *nl = strrchr(s,'\n');
-       if (nl)
+       if (nl) 
            *nl = '\0';
     }
     else if (multi_close < 32 || multi_close == 127) {
@@ -219,6 +221,19 @@ depcom(void)
     deprecate("comma-less variable list");
 }
 
+#ifdef WIN32
+
+static I32
+win32_textfilter(int idx, SV *sv, int maxlen)
+{
+ I32 count = FILTER_READ(idx+1, sv, maxlen);
+ if (count > 0 && !maxlen)
+  win32_strip_return(sv);
+ return count;
+}
+#endif
+
+
 void
 lex_start(SV *line)
 {
@@ -244,6 +259,11 @@ lex_start(SV *line)
     SAVEPPTR(lex_brackstack);
     SAVEPPTR(lex_casestack);
     SAVEDESTRUCTOR(restore_rsfp, rsfp);
+    SAVESPTR(lex_stuff);
+    SAVEI32(lex_defer);
+    SAVESPTR(lex_repl);
+    SAVEDESTRUCTOR(restore_expect, tokenbuf + expect); /* encode as pointer */
+    SAVEDESTRUCTOR(restore_lex_expect, tokenbuf + expect);
 
     lex_state = LEX_NORMAL;
     lex_defer = 0;
@@ -258,11 +278,7 @@ lex_start(SV *line)
     *lex_casestack = '\0';
     lex_dojoin = 0;
     lex_starts = 0;
-    if (lex_stuff)
-       SvREFCNT_dec(lex_stuff);
     lex_stuff = Nullsv;
-    if (lex_repl)
-       SvREFCNT_dec(lex_repl);
     lex_repl = Nullsv;
     lex_inpat = 0;
     lex_inwhat = 0;
@@ -302,6 +318,22 @@ restore_rsfp(void *f)
 }
 
 static void
+restore_expect(e)
+void *e;
+{
+    /* a safe way to store a small integer in a pointer */
+    expect = (expectation)((char *)e - tokenbuf);
+}
+
+static void
+restore_lex_expect(e)
+void *e;
+{
+    /* a safe way to store a small integer in a pointer */
+    lex_expect = (expectation)((char *)e - tokenbuf);
+}
+
+static void
 incline(char *s)
 {
     dTHR;
@@ -376,7 +408,7 @@ skipspace(register char *s)
            oldoldbufptr = oldbufptr = bufptr = s = linestart = SvPVX(linestr);
            bufend = SvPVX(linestr) + SvCUR(linestr);
            if (preprocess && !in_eval)
-               (void)my_pclose(rsfp);
+               (void)PerlProc_pclose(rsfp);
            else if ((PerlIO*)rsfp == PerlIO_stdin())
                PerlIO_clearerr(rsfp);
            else
@@ -487,7 +519,7 @@ force_next(I32 type)
 }
 
 static char *
-force_word(register char *start, int token, int check_keyword, int allow_pack, int allow_tick)
+force_word(register char *start, int token, int check_keyword, int allow_pack, int allow_initial_tick)
 {
     register char *s;
     STRLEN len;
@@ -496,7 +528,7 @@ force_word(register char *start, int token, int check_keyword, int allow_pack, i
     s = start;
     if (isIDFIRST(*s) ||
        (allow_pack && *s == ':') ||
-       (allow_tick && *s == '\'') )
+       (allow_initial_tick && *s == '\'') )
     {
        s = scan_word(s, tokenbuf, sizeof tokenbuf, allow_pack, &len);
        if (check_keyword && keyword(tokenbuf, len))
@@ -640,7 +672,7 @@ static I32
 sublex_push(void)
 {
     dTHR;
-    push_scope();
+    ENTER;
 
     lex_state = sublex_info.super_state;
     SAVEI32(lex_dojoin);
@@ -726,7 +758,7 @@ sublex_done(void)
        return ',';
     }
     else {
-       pop_scope();
+       LEAVE;
        bufend = SvPVX(linestr);
        bufend += SvCUR(linestr);
        expect = XOPERATOR;
@@ -770,9 +802,31 @@ scan_const(char *start)
                s++;
            }
        }
-       else if (*s == '(' && lex_inpat && s[1] == '?' && s[2] == '#') {
-           while (s < send && *s != ')')
-               *d++ = *s++;
+       else if (*s == '(' && lex_inpat && s[1] == '?') {
+           if (s[2] == '#') {
+               while (s < send && *s != ')')
+                   *d++ = *s++;
+           } else if (s[2] == '{') {   /* This should march regcomp.c */
+               I32 count = 1;
+               char *regparse = s + 3;
+               char c;
+
+               while (count && (c = *regparse)) {
+                   if (c == '\\' && regparse[1])
+                       regparse++;
+                   else if (c == '{') 
+                       count++;
+                   else if (c == '}') 
+                       count--;
+                   regparse++;
+               }
+               if (*regparse == ')')
+                   regparse++;
+               else
+                   yyerror("Sequence (?{...}) not terminated or not {}-balanced");
+               while (s < regparse && *s != ')')
+                   *d++ = *s++;
+           }
        }
        else if (*s == '#' && lex_inpat &&
          ((PMOP*)lex_inpat)->op_pmflags & PMf_EXTENDED) {
@@ -784,7 +838,7 @@ scan_const(char *start)
        else if (*s == '$') {
            if (!lex_inpat)     /* not a regexp, so $ must be var */
                break;
-           if (s + 1 < send && !strchr(")| \n\t", s[1]))
+           if (s + 1 < send && !strchr("()| \n\t", s[1]))
                break;          /* in regexp, $ might be tail anchor */
        }
        if (*s == '\\' && s+1 < send) {
@@ -1010,9 +1064,18 @@ intuit_method(char *start, GV *gv)
     GV* indirgv;
 
     if (gv) {
+       CV *cv;
        if (GvIO(gv))
            return 0;
-       if (!GvCVu(gv))
+       if ((cv = GvCVu(gv))) {
+           char *proto = SvPVX(cv);
+           if (proto) {
+               if (*proto == ';')
+                   proto++;
+               if (*proto == '*')
+                   return 0;
+           }
+       } else
            gv = 0;
     }
     s = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len);
@@ -1051,10 +1114,11 @@ static char*
 incl_perldb(void)
 {
     if (perldb) {
-       char *pdb = getenv("PERL5DB");
+       char *pdb = PerlEnv_getenv("PERL5DB");
 
        if (pdb)
            return pdb;
+       SETERRNO(0,SS$_NORMAL);
        return "BEGIN { require 'perl5db.pl' }";
     }
     return "";
@@ -1088,7 +1152,7 @@ filter_add(filter_t funcp, SV *datasv)
     if (!rsfp_filters)
        rsfp_filters = newAV();
     if (!datasv)
-       datasv = newSV(0);
+       datasv = NEWSV(255,0);
     if (!SvUPGRADE(datasv, SVt_PVIO))
         die("Can't upgrade filter_add data to SVt_PVIO");
     IoDIRP(datasv) = (DIR*)funcp; /* stash funcp into spare field */
@@ -1106,12 +1170,11 @@ filter_del(filter_t funcp)
 {
     if (filter_debug)
        warn("filter_del func %p", funcp);
-    if (!rsfp_filters || AvFILL(rsfp_filters)<0)
+    if (!rsfp_filters || AvFILLp(rsfp_filters)<0)
        return;
     /* if filter is on top of stack (usual case) just pop it off */
-    if (IoDIRP(FILTER_DATA(0)) == (void*)funcp){
-       /* sv_free(av_pop(rsfp_filters)); */
-       sv_free(av_shift(rsfp_filters));
+    if (IoDIRP(FILTER_DATA(AvFILLp(rsfp_filters))) == (void*)funcp){
+       sv_free(av_pop(rsfp_filters));
 
         return;
     }
@@ -1132,7 +1195,7 @@ filter_read(int idx, SV *buf_sv, int maxlen)
 
     if (!rsfp_filters)
        return -1;
-    if (idx > AvFILL(rsfp_filters)){       /* Any more filters?        */
+    if (idx > AvFILLp(rsfp_filters)){       /* Any more filters?       */
        /* Provide a default input filter to make life easy.    */
        /* Note that we append to the line. This is handy.      */
        if (filter_debug)
@@ -1159,6 +1222,7 @@ filter_read(int idx, SV *buf_sv, int maxlen)
                else
                    return 0 ;          /* end of file */
            }
+
        }
        return SvCUR(buf_sv);
     }
@@ -1179,9 +1243,15 @@ filter_read(int idx, SV *buf_sv, int maxlen)
     return (*funcp)(idx, buf_sv, maxlen);
 }
 
+
 static char *
-filter_gets(register SV *sv, register FILE *fp, STRLEN append)
+filter_gets(register SV *sv, register PerlIO *fp, STRLEN append)
 {
+#ifdef WIN32FILTER
+    if (!rsfp_filters) {
+       filter_add(win32_textfilter,NULL);
+    }
+#endif
     if (rsfp_filters) {
 
        if (!append)
@@ -1193,7 +1263,6 @@ filter_gets(register SV *sv, register FILE *fp, STRLEN append)
     }
     else 
         return (sv_gets(sv, fp, append));
-    
 }
 
 
@@ -1212,6 +1281,8 @@ yylex(void)
     register char *d;
     register I32 tmp;
     STRLEN len;
+    GV *gv = Nullgv;
+    GV **gvp = 0;
 
     if (pending_ident) {
        char pit = pending_ident;
@@ -1227,12 +1298,12 @@ yylex(void)
 
        if (!strchr(tokenbuf,':')) {
 #ifdef USE_THREADS
-           /* Check for single character per-thread magicals */
+           /* Check for single character per-thread SVs */
            if (tokenbuf[0] == '$' && tokenbuf[2] == '\0'
-               && !isALPHA(tokenbuf[1]) /* Rule out obvious non-magicals */
-               && (tmp = find_thread_magical(&tokenbuf[1])) != NOT_IN_PAD)
+               && !isALPHA(tokenbuf[1]) /* Rule out obvious non-threadsvs */
+               && (tmp = find_threadsv(&tokenbuf[1])) != NOT_IN_PAD)
            {
-               yylval.opval = newOP(OP_SPECIFIC, 0);
+               yylval.opval = newOP(OP_THREADSV, 0);
                yylval.opval->op_targ = tmp;
                return PRIVATEREF;
            }
@@ -1373,8 +1444,8 @@ yylex(void)
            nextval[nexttoke].ival = 0;
            force_next(',');
 #ifdef USE_THREADS
-           nextval[nexttoke].opval = newOP(OP_SPECIFIC, 0);
-           nextval[nexttoke].opval->op_targ = find_thread_magical("\"");
+           nextval[nexttoke].opval = newOP(OP_THREADSV, 0);
+           nextval[nexttoke].opval->op_targ = find_threadsv("\"");
            force_next(PRIVATEREF);
 #else
            force_ident("\"", '$');
@@ -1482,7 +1553,7 @@ yylex(void)
            if (SvCUR(linestr))
                sv_catpv(linestr,";");
            if (preambleav){
-               while(AvFILL(preambleav) >= 0) {
+               while(AvFILLp(preambleav) >= 0) {
                    SV *tmpsv = av_shift(preambleav);
                    sv_catsv(linestr, tmpsv);
                    sv_catpv(linestr, ";");
@@ -1539,7 +1610,7 @@ yylex(void)
              fake_eof:
                if (rsfp) {
                    if (preprocess && !in_eval)
-                       (void)my_pclose(rsfp);
+                       (void)PerlProc_pclose(rsfp);
                    else if ((PerlIO *)rsfp == PerlIO_stdin())
                        PerlIO_clearerr(rsfp);
                    else
@@ -1724,9 +1795,11 @@ yylex(void)
        }
        goto retry;
     case '\r':
+#ifndef WIN32CHEAT
        warn("Illegal character \\%03o (carriage return)", '\r');
        croak(
       "(Maybe you didn't strip carriage returns after a network transfer?)\n");
+#endif
     case ' ': case '\t': case '\f': case 013:
        s++;
        goto retry;
@@ -1991,8 +2064,13 @@ yylex(void)
                else
                    lex_brackstack[lex_brackets++] = XOPERATOR;
                s = skipspace(s);
-               if (*s == '}')
+               if (*s == '}') {
+                   if (expect == XSTATE) {
+                       lex_brackstack[lex_brackets-1] = XSTATE;
+                       break;
+                   }
                    OPERATOR(HASHBRACK);
+               }
                /* This hack serves to disambiguate a pair of curlies
                 * as being a block or an anon hash.  Normally, expectation
                 * determines that, but in cases where we're not in a
@@ -2389,7 +2467,11 @@ yylex(void)
     case '/':                  /* may either be division or pattern */
     case '?':                  /* may either be conditional or pattern */
        if (expect != XOPERATOR) {
-           check_uni();
+           /* Disable warning on "study /blah/" */
+           if (oldoldbufptr == last_uni 
+               && (*last_uni != 's' || s - last_uni < 5 
+                   || memNE(last_uni, "study", 5) || isALNUM(last_uni[5])))
+               check_uni();
            s = scan_pat(s);
            TERM(sublex_start());
        }
@@ -2520,7 +2602,10 @@ yylex(void)
     case 'y': case 'Y':
     case 'z': case 'Z':
 
-      keylookup:
+      keylookup: {
+       gv = Nullgv;
+       gvp = 0;
+
        bufptr = s;
        s = scan_word(s, tokenbuf, sizeof tokenbuf, FALSE, &len);
 
@@ -2562,16 +2647,24 @@ yylex(void)
        }
 
        if (tmp < 0) {                  /* second-class keyword? */
-           GV* gv;
-           if (expect != XOPERATOR &&
-               (*s != ':' || s[1] != ':') &&
-               (gv = gv_fetchpv(tokenbuf, FALSE, SVt_PVCV)) &&
-               GvIMPORTED_CV(gv))
+           if (expect != XOPERATOR && (*s != ':' || s[1] != ':') &&
+               (((gv = gv_fetchpv(tokenbuf, FALSE, SVt_PVCV)) &&
+                 GvCVu(gv) && GvIMPORTED_CV(gv)) ||
+                ((gvp = (GV**)hv_fetch(globalstash,tokenbuf,len,FALSE)) &&
+                 (gv = *gvp) != (GV*)&sv_undef &&
+                 GvCVu(gv) && GvIMPORTED_CV(gv))))
            {
-               tmp = 0;
+               tmp = 0;                /* overridden by importation */
+           }
+           else if (gv && !gvp
+                    && -tmp==KEY_lock  /* XXX generalizable kludge */
+                    && !hv_fetch(GvHVn(incgv), "Thread.pm", 9, FALSE))
+           {
+               tmp = 0;                /* any sub overrides "weak" keyword */
+           }
+           else {
+               tmp = -tmp; gv = Nullgv; gvp = 0;
            }
-           else
-               tmp = -tmp;
        }
 
       reserved_word:
@@ -2579,7 +2672,6 @@ yylex(void)
 
        default:                        /* not a keyword */
          just_a_word: {
-               GV *gv;
                SV *sv;
                char lastchar = (bufptr == oldoldbufptr ? 0 : bufptr[-1]);
 
@@ -2604,12 +2696,19 @@ yylex(void)
 
                /* Look for a subroutine with this name in current package. */
 
-               gv = gv_fetchpv(tokenbuf,FALSE, SVt_PVCV);
+               if (gvp) {
+                   sv = newSVpv("CORE::GLOBAL::",14);
+                   sv_catpv(sv,tokenbuf);
+               }
+               else
+                   sv = newSVpv(tokenbuf,0);
+               if (!gv)
+                   gv = gv_fetchpv(tokenbuf,FALSE, SVt_PVCV);
 
                /* Presume this is going to be a bareword of some sort. */
 
                CLINE;
-               yylval.opval = (OP*)newSVOP(OP_CONST, 0, newSVpv(tokenbuf,0));
+               yylval.opval = (OP*)newSVOP(OP_CONST, 0, sv);
                yylval.opval->op_private = OPpCONST_BARE;
 
                /* See if it's the indirect object for a list operator. */
@@ -3499,7 +3598,7 @@ yylex(void)
            if (*s == ';' || *s == ')')         /* probably a close */
                croak("sort is now a reserved word");
            expect = XTERM;
-           s = force_word(s,WORD,TRUE,TRUE,TRUE);
+           s = force_word(s,WORD,TRUE,TRUE,FALSE);
            LOP(OP_SORT,XREF);
 
        case KEY_split:
@@ -3745,7 +3844,7 @@ yylex(void)
            s = scan_trans(s);
            TERM(sublex_start());
        }
-    }
+    }}
 }
 
 I32
@@ -4659,46 +4758,6 @@ scan_subst(char *start)
     return s;
 }
 
-void
-hoistmust(register PMOP *pm)
-{
-    dTHR;
-    if (!pm->op_pmshort && pm->op_pmregexp->regstart &&
-       (!pm->op_pmregexp->regmust || pm->op_pmregexp->reganch & ROPT_ANCH)
-       ) {
-       if (!(pm->op_pmregexp->reganch & ROPT_ANCH))
-           pm->op_pmflags |= PMf_SCANFIRST;
-       pm->op_pmshort = SvREFCNT_inc(pm->op_pmregexp->regstart);
-       pm->op_pmslen = SvCUR(pm->op_pmshort);
-    }
-    else if (pm->op_pmregexp->regmust) {/* is there a better short-circuit? */
-       if (pm->op_pmshort &&
-         sv_eq(pm->op_pmshort,pm->op_pmregexp->regmust))
-       {
-           if (pm->op_pmflags & PMf_SCANFIRST) {
-               SvREFCNT_dec(pm->op_pmshort);
-               pm->op_pmshort = Nullsv;
-           }
-           else {
-               SvREFCNT_dec(pm->op_pmregexp->regmust);
-               pm->op_pmregexp->regmust = Nullsv;
-               return;
-           }
-       }
-       /* promote the better string */
-       if ((!pm->op_pmshort &&
-            !(pm->op_pmregexp->reganch & ROPT_ANCH_GPOS)) ||
-           ((pm->op_pmflags & PMf_SCANFIRST) &&
-            (SvCUR(pm->op_pmshort) < SvCUR(pm->op_pmregexp->regmust)))) {
-           SvREFCNT_dec(pm->op_pmshort);               /* ok if null */
-           pm->op_pmshort = pm->op_pmregexp->regmust;
-           pm->op_pmslen = SvCUR(pm->op_pmshort);
-           pm->op_pmregexp->regmust = Nullsv;
-           pm->op_pmflags |= PMf_SCANFIRST;
-       }
-    }
-}
-
 static char *
 scan_trans(char *start)
 {
@@ -4832,6 +4891,8 @@ scan_heredoc(register char *s)
        }
        sv_setpvn(tmpstr,d+1,s-d);
        s += len - 1;
+       curcop->cop_line++;     /* the preceding stmt passes a newline */
+
        sv_catpvn(herewas,s,bufend-s);
        sv_setsv(linestr,herewas);
        oldoldbufptr = oldbufptr = bufptr = s = linestart = SvPVX(linestr);
@@ -5370,7 +5431,7 @@ yyerror(char *s)
     if (in_eval & 2)
        warn("%_", msg);
     else if (in_eval)
-       sv_catsv(errsv, msg);
+       sv_catsv(ERRSV, msg);
     else
        PerlIO_write(PerlIO_stderr(), SvPVX(msg), SvCUR(msg));
     if (++error_count >= 10)
@@ -5380,3 +5441,4 @@ yyerror(char *s)
     return 0;
 }
 
+