This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Initial devel changes.
[perl5.git] / toke.c
diff --git a/toke.c b/toke.c
index 54c0919..1318208 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -276,7 +276,7 @@ void *f;
 
     if (rsfp == stdin)
        clearerr(rsfp);
-    else if (rsfp != fp)
+    else if (rsfp && (rsfp != fp))
        fclose(rsfp);
     rsfp = fp;
 }
@@ -1485,8 +1485,9 @@ yylex()
                    if (*d++ == '-') {
                        while (d = moreswitches(d)) ;
                        if (perldb && !oldpdb ||
-                           minus_n && !oldn ||
-                           minus_p && !oldp)
+                           ( minus_n || minus_p ) && !(oldn || oldp) )
+                             /* if we have already added "LINE: while (<>) {",
+                                we must not do it again */
                        {
                            sv_setpv(linestr, "");
                            oldoldbufptr = oldbufptr = s = SvPVX(linestr);
@@ -1877,6 +1878,24 @@ yylex()
        if (expect == XSTATE && isALPHA(tmp) &&
                (s == SvPVX(linestr)+1 || s[-2] == '\n') )
        {
+           if (in_eval && !rsfp) {
+               d = bufend;
+               while (s < d) {
+                   if (*s++ == '\n') {
+                       incline(s);
+                       if (strnEQ(s,"=cut",4)) {
+                           s = strchr(s,'\n');
+                           if (s)
+                               s++;
+                           else
+                               s = d;
+                           incline(s);
+                           goto retry;
+                       }
+                   }
+               }
+               goto retry;
+           }
            s = bufend;
            doextract = TRUE;
            goto retry;
@@ -2297,10 +2316,9 @@ yylex()
        if (tmp < 0) {                  /* second-class keyword? */
            GV* gv;
            if (expect != XOPERATOR &&
-             (*s != ':' || s[1] != ':') &&
-             (gv = gv_fetchpv(tokenbuf,FALSE, SVt_PVCV)) &&
-             (GvFLAGS(gv) & GVf_IMPORTED) &&
-             GvCV(gv))
+               (*s != ':' || s[1] != ':') &&
+               (gv = gv_fetchpv(tokenbuf, FALSE, SVt_PVCV)) &&
+               GvIMPORTED_CV(gv))
            {
                tmp = 0;
            }
@@ -2415,8 +2433,8 @@ yylex()
 
                if (gv && GvCV(gv)) {
                    CV* cv = GvCV(gv);
-                   nextval[nexttoke].opval = yylval.opval;
                    if (*s == '(') {
+                       nextval[nexttoke].opval = yylval.opval;
                        expect = XTERM;
                        force_next(WORD);
                        yylval.ival = 0;
@@ -2427,6 +2445,9 @@ yylex()
                                tokenbuf, tokenbuf);
                    last_lop = oldbufptr;
                    last_lop_op = OP_ENTERSUB;
+                   /* Resolve to GV now. */
+                   op_free(yylval.opval);
+                   yylval.opval = newCVREF(0, newGVOP(OP_GV, 0, gv));
                    /* Is there a prototype? */
                    if (SvPOK(cv)) {
                        STRLEN len;
@@ -2440,6 +2461,7 @@ yylex()
                            PREBLOCK(LSTOPSUB);
                        }
                    }
+                   nextval[nexttoke].opval = yylval.opval;
                    expect = XTERM;
                    force_next(WORD);
                    TOKEN(NOAMP);
@@ -2492,14 +2514,14 @@ yylex()
            GV *gv;
 
            /*SUPPRESS 560*/
-           if (!in_eval || tokenbuf[2] == 'D') {
+           if (rsfp && (!in_eval || tokenbuf[2] == 'D')) {
                char dname[256];
                char *pname = "main";
                if (tokenbuf[2] == 'D')
                    pname = HvNAME(curstash ? curstash : defstash);
                sprintf(dname,"%s::DATA", pname);
                gv = gv_fetchpv(dname,TRUE, SVt_PVIO);
-               SvMULTI_on(gv);
+               GvMULTI_on(gv);
                if (!GvIO(gv))
                    GvIOp(gv) = newIO();
                IoIFP(GvIOp(gv)) = rsfp;
@@ -2524,6 +2546,7 @@ yylex()
        case KEY_DESTROY:
        case KEY_BEGIN:
        case KEY_END:
+       case KEY_RESTART:
            if (expect == XSTATE) {
                s = bufptr;
                goto really_sub;
@@ -2909,6 +2932,17 @@ yylex()
        case KEY_my:
            in_my = TRUE;
            yylval.ival = 1;
+           s = skipspace(s);
+           if (isIDFIRST(*s)) {
+               s = scan_word(s, tokenbuf, TRUE, &len);
+               in_my_stash = gv_stashpv(tokenbuf, FALSE);
+               if (!in_my_stash) {
+                   char tmpbuf[1024];
+                   bufptr = s;
+                   sprintf(tmpbuf, "No such class %.1000s", tokenbuf);
+                   yyerror(tmpbuf);
+               }
+           }
            OPERATOR(LOCAL);
 
        case KEY_next:
@@ -3794,6 +3828,9 @@ I32 len;
        }
        else if (strEQ(d,"quotemeta"))          return -KEY_quotemeta;
        break;
+    case 'R':
+       if (strEQ(d,"RESTART"))                 return KEY_RESTART;
+       break;
     case 'r':
        switch (len) {
        case 3:
@@ -4975,5 +5012,6 @@ char *s;
        croak("%s has too many errors.\n",
        SvPVX(GvSV(curcop->cop_filegv)));
     in_my = 0;
+    in_my_stash = Nullhv;
     return 0;
 }