X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=stolen_chunk_of_toke.c;h=c667eaa77ba2704b3cc69ae93e6b802b7555a47a;hb=b968549dde4c8a36fccca7aca22bcd092242b099;hp=85f714e59d5db573eb0728734f024b857113a8c4;hpb=d6e7537a24f679004f7094f17543c1a340fff6a8;p=p5sagit%2FDevel-Declare.git diff --git a/stolen_chunk_of_toke.c b/stolen_chunk_of_toke.c index 85f714e..c667eaa 100644 --- a/stolen_chunk_of_toke.c +++ b/stolen_chunk_of_toke.c @@ -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); @@ -35,7 +37,6 @@ STATIC char* S_scan_word(pTHX_ char *s, char *dest, STRLEN destlen, int allow #define DPTR2FPTR(t,p) ((t)PTR2nat(p)) /* data pointer to function pointer */ #define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */ #define PTR2nat(p) (PTRV)(p) /* pointer to integer of PTRSIZE */ -#define MEM_WRAP_CHECK_(n,t) MEM_WRAP_CHECK(n,t), /* conditionalise these two because as of 5.9.5 we already get them from the headers (mst) */ @@ -45,6 +46,9 @@ STATIC char* S_scan_word(pTHX_ char *s, char *dest, STRLEN destlen, int allow #ifndef SvPVX_const #define SvPVX_const(sv) ((const char*) (0 + SvPVX(sv))) #endif +#ifndef MEM_WRAP_CHECK_ +#define MEM_WRAP_CHECK_(n,t) MEM_WRAP_CHECK(n,t), +#endif #define SvPV_renew(sv,n) \ STMT_START { SvLEN_set(sv, n); \ @@ -62,6 +66,20 @@ STATIC char* S_scan_word(pTHX_ char *s, char *dest, STRLEN destlen, int allow #define SPACE_OR_TAB(c) ((c)==' '||(c)=='\t') #endif +/* + * Normally, during compile time, PL_curcop == &PL_compiling is true. However, + * Devel::Declare makes the interpreter call back to perl during compile time, + * which temporarily enters runtime. Then perl space calls various functions + * from this file, which are designed to work during compile time. They all + * happen to operate on PL_curcop, not PL_compiling. That doesn't make a + * difference in the core, but it does for Devel::Declare, which operates at + * runtime, but still wants to mangle the things that are about to be compiled. + * That's why we define our own PL_curcop and make it point to PL_compiling + * here. + */ +#undef PL_curcop +#define PL_curcop (&PL_compiling) + #define CLINE (PL_copline = (CopLINE(PL_curcop) < PL_copline ? CopLINE(PL_curcop) : PL_copline)) #define LEX_NORMAL 10 /* normal code (ie not within "...") */ @@ -90,6 +108,20 @@ STATIC char* S_scan_word(pTHX_ char *s, char *dest, STRLEN destlen, int allow #define PERL_5_9_PLUS #endif +#if !defined(PERL_5_9_PLUS) && defined(PERL_IMPLICIT_CONTEXT) +/* These two are not exported from the core on Windows. With 5.9+ + it's not an issue, because they're part of the PL_parser structure, + which is exported. On multiplicity/thread builds we can work + around the lack of export by this formulation, where we provide + a substitute implementation of the unexported accessor functions. + On single-interpreter builds we can't, because access is directly + via symbols that are not exported. */ +# define Perl_Ilinestart_ptr my_Ilinestart_ptr +char **my_Ilinestart_ptr(pTHX) { return &(aTHX->Ilinestart); } +# define Perl_Isublex_info_ptr my_Isublex_info_ptr +static SUBLEXINFO *my_Isublex_info_ptr(pTHX) { return &(aTHX->Isublex_info); } +#endif + #ifdef PERL_5_9_PLUS /* 5.9+ moves a bunch of things to a PL_parser struct so we need to declare the backcompat macros for things to still work (mst) */ @@ -136,12 +168,17 @@ STATIC char* S_scan_word(pTHX_ char *s, char *dest, STRLEN destlen, int allow #define PL_tokenbuf (PL_parser->tokenbuf) #define PL_multi_end (PL_parser->multi_end) #define PL_error_count (PL_parser->error_count) -/* these three are from the non-PERL_MAD path but I don't -think- I need +#define PL_nexttoke (PL_parser->nexttoke) +/* these are from the non-PERL_MAD path but I don't -think- I need the PERL_MAD stuff since my code isn't really populating things (mst) */ -# define PL_nexttoke (PL_parser->nexttoke) +# ifdef PERL_MAD +# define PL_curforce (PL_parser->curforce) +# define PL_lasttoke (PL_parser->lasttoke) +# else # define PL_nexttype (PL_parser->nexttype) # define PL_nextval (PL_parser->nextval) -/* end of backcompat macros form 5.9 toke.c (mst) */ +# endif +/* end of backcompat macros from 5.9 toke.c (mst) */ #endif /* when ccflags include -DDEBUGGING we need this for earlier 5.8 perls */ @@ -149,6 +186,21 @@ STATIC char* S_scan_word(pTHX_ char *s, char *dest, STRLEN destlen, int allow #define SvPV_nolen_const SvPV_nolen #endif +/* Name changed in 5.17; use new name in our code. Apparently we're meant + to use something else instead, but no non-underscored way to achieve + this is apparent. */ + +#ifndef _is_utf8_mark +#define _is_utf8_mark is_utf8_mark +#endif + +/* utf8_to_uvchr_buf() not defined in earlier perls, but less-capable + * substitute is available */ + +#ifndef utf8_to_uvchr_buf +#define utf8_to_uvchr_buf(s, e, lp) ((e), utf8_to_uvchr(s, lp)) +#endif + /* and now we're back to the toke.c stuff again (mst) */ static const char ident_too_long[] = @@ -249,7 +301,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)) @@ -261,7 +313,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); } @@ -271,13 +323,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 @@ -347,19 +407,22 @@ 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 */ if (PERLDB_LINE && PL_curstash != PL_debstash) { - SV * const sv = NEWSV(85,0); - - sv_upgrade(sv, SVt_PVMG); - sv_setpvn(sv,PL_bufptr,PL_bufend-PL_bufptr); - (void)SvIOK_on(sv); - SvIV_set(sv, 0); - av_store(CopFILEAV(PL_curcop),(I32)CopLINE(PL_curcop),sv); + AV *fileav = CopFILEAV(PL_curcop); + if (fileav) { + SV * const sv = NEWSV(85,0); + sv_upgrade(sv, SVt_PVMG); + sv_setpvn(sv,PL_bufptr,PL_bufend-PL_bufptr); + (void)SvIOK_on(sv); + SvIV_set(sv, 0); + av_store(fileav,(I32)CopLINE(PL_curcop),sv); + } } } } @@ -385,7 +448,7 @@ S_scan_word(pTHX_ register char *s, char *dest, STRLEN destlen, int allow_packag } else if (UTF && UTF8_IS_START(*s) && isALNUM_utf8((U8*)s)) { char *t = s + UTF8SKIP(s); - while (UTF8_IS_CONTINUED(*t) && is_utf8_mark((U8*)t)) + while (UTF8_IS_CONTINUED(*t) && _is_utf8_mark((U8*)t)) t += UTF8SKIP(t); if (d + (t - s) > e) Perl_croak(aTHX_ ident_too_long); @@ -581,7 +644,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims) termlen = 1; } else { - termcode = utf8_to_uvchr((U8*)s, &termlen); + termcode = utf8_to_uvchr_buf((U8*)s, PL_bufend, &termlen); Copy(s, termstr, termlen, U8); if (!UTF8_IS_INVARIANT(term)) has_utf8 = TRUE; @@ -783,13 +846,15 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims) /* update debugger info */ if (PERLDB_LINE && PL_curstash != PL_debstash) { - SV *sv = NEWSV(88,0); - - sv_upgrade(sv, SVt_PVMG); - sv_setsv(sv,PL_linestr); - (void)SvIOK_on(sv); - SvIV_set(sv, 0); - av_store(CopFILEAV(PL_curcop), (I32)CopLINE(PL_curcop), sv); + AV *fileav = CopFILEAV(PL_curcop); + if (fileav) { + SV *sv = NEWSV(88,0); + sv_upgrade(sv, SVt_PVMG); + sv_setsv(sv,PL_linestr); + (void)SvIOK_on(sv); + SvIV_set(sv, 0); + av_store(fileav, (I32)CopLINE(PL_curcop), sv); + } } /* having changed the buffer, we must update PL_bufend */ @@ -831,27 +896,6 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims) return s; } -/* - * S_force_next - * When the lexer realizes it knows the next token (for instance, - * it is reordering tokens for the parser) then it can call S_force_next - * to know what token to return the next time the lexer is called. Caller - * will need to set PL_nextval[], and possibly PL_expect to ensure the lexer - * handles the token correctly. - */ - -STATIC void -S_force_next(pTHX_ I32 type) -{ - PL_nexttype[PL_nexttoke] = type; - PL_nexttoke++; - if (PL_lex_state != LEX_KNOWNEXT) { - PL_lex_defer = PL_lex_state; - PL_lex_expect = PL_expect; - PL_lex_state = LEX_KNOWNEXT; - } -} - #define XFAKEBRACK 128 STATIC char * @@ -890,7 +934,7 @@ S_scan_ident(pTHX_ register char *s, register const char *send, char *dest, STRL } else if (UTF && UTF8_IS_START(*s) && isALNUM_utf8((U8*)s)) { char *t = s + UTF8SKIP(s); - while (UTF8_IS_CONTINUED(*t) && is_utf8_mark((U8*)t)) + while (UTF8_IS_CONTINUED(*t) && _is_utf8_mark((U8*)t)) t += UTF8SKIP(t); if (d + (t - s) > e) Perl_croak(aTHX_ ident_too_long); @@ -917,12 +961,10 @@ S_scan_ident(pTHX_ register char *s, register const char *send, char *dest, STRL if (*s == '{') { bracket = s; s++; + } else if (ck_uni) { + /* we always call this with ck_uni == 0, so no need for check_uni() */ + /* check_uni(); */ } - /* we always call this with ck_uni == 0 (rafl) */ - /* - else if (ck_uni) - check_uni(); - */ if (s < send) *d = *s++; d[1] = '\0'; @@ -946,7 +988,7 @@ S_scan_ident(pTHX_ register char *s, register const char *send, char *dest, STRL e = s; while ((e < send && isALNUM_lazy_if(e,UTF)) || *e == ':') { e += UTF8SKIP(e); - while (e < send && UTF8_IS_CONTINUED(*e) && is_utf8_mark((U8*)e)) + while (e < send && UTF8_IS_CONTINUED(*e) && _is_utf8_mark((U8*)e)) e += UTF8SKIP(e); } Copy(s, d, e - s, char);