X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=Declare.xs;h=83ebc1d0062d68f46f396e2221f9258b2f9b02fd;hb=hook_parser;hp=17a0cd306ca6e2db2e05e2ce8dd1ea9865880041;hpb=04a8a223b0a8ab54b0b1cc648c2abe24036ea7b0;p=p5sagit%2FDevel-Declare.git diff --git a/Declare.xs b/Declare.xs index 17a0cd3..83ebc1d 100644 --- a/Declare.xs +++ b/Declare.xs @@ -1,8 +1,7 @@ -#define PERL_CORE -#define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" +#include "hook_op_check.h" #undef printf #include "stolen_chunk_of_toke.c" #include @@ -12,23 +11,7 @@ # define Newx(v,n,t) New(0,v,n,t) #endif /* !Newx */ -#if 1 -#define DD_HAS_TRAITS -#endif - -#if 0 -#define DD_DEBUG -#endif - -#define DD_HANDLE_NAME 1 -#define DD_HANDLE_PROTO 2 -#define DD_HANDLE_PACKAGE 8 - -#ifdef DD_DEBUG -#define DD_DEBUG_S printf("Buffer: %s\n", s); -#else -#define DD_DEBUG_S -#endif +static int dd_debug = 0; #define LEX_NORMAL 10 #define LEX_INTERPNORMAL 9 @@ -37,6 +20,22 @@ static int in_declare = 0; +/* in 5.10, PL_parser will be NULL if we aren't parsing, and PL_lex_stuff + is a lookup into it - so if anything else we can use to tell, so we + need to be a bit more careful if PL_parser exists */ + +#define DD_AM_LEXING_CHECK (PL_lex_state == LEX_NORMAL || PL_lex_state == LEX_INTERPNORMAL) + +#if defined(PL_parser) || defined(PERL_5_9_PLUS) +#define DD_HAVE_PARSER PL_parser +#define DD_HAVE_LEX_STUFF (PL_parser && PL_lex_stuff) +#define DD_AM_LEXING (PL_parser && DD_AM_LEXING_CHECK) +#else +#define DD_HAVE_PARSER 1 +#define DD_HAVE_LEX_STUFF PL_lex_stuff +#define DD_AM_LEXING DD_AM_LEXING_CHECK +#endif + /* thing that decides whether we're dealing with a declarator */ int dd_is_declarator(pTHX_ char* name) { @@ -53,6 +52,9 @@ int dd_is_declarator(pTHX_ char* name) { /* $declarators{$current_package_name} */ + if (!HvNAME(PL_curstash)) + return -1; + is_declarator_pack_ref = hv_fetch(is_declarator, HvNAME(PL_curstash), strlen(HvNAME(PL_curstash)), FALSE); @@ -82,10 +84,10 @@ int dd_is_declarator(pTHX_ char* name) { /* callback thingy */ -void dd_linestr_callback (pTHX_ char* type, char* name, char* s) { +void dd_linestr_callback (pTHX_ char* type, char* name) { char* linestr = SvPVX(PL_linestr); - int offset = s - linestr; + int offset = PL_bufptr - linestr; dSP; @@ -104,32 +106,13 @@ void dd_linestr_callback (pTHX_ char* type, char* name, char* s) { LEAVE; } -char* dd_get_linestr(pTHX) { - return SvPVX(PL_linestr); -} - -void dd_set_linestr(pTHX_ char* new_value) { - int new_len = strlen(new_value); - char* old_linestr = SvPVX(PL_linestr); - - SvGROW(PL_linestr, strlen(new_value)); - - if (SvPVX(PL_linestr) != old_linestr) - Perl_croak(aTHX_ "forced to realloc PL_linestr for line %s, bailing out before we crash harder", SvPVX(PL_linestr)); - - memcpy(SvPVX(PL_linestr), new_value, new_len+1); - - SvCUR_set(PL_linestr, new_len); - - PL_bufend = SvPVX(PL_linestr) + new_len; -} - char* dd_get_lex_stuff(pTHX) { - return SvPVX(PL_lex_stuff); + return (DD_HAVE_LEX_STUFF ? SvPVX(PL_lex_stuff) : ""); } -char* dd_clear_lex_stuff(pTHX) { - PL_lex_stuff = Nullsv; +void dd_clear_lex_stuff(pTHX) { + if (DD_HAVE_PARSER) + PL_lex_stuff = (SV*)NULL; } char* dd_get_curstash_name(pTHX) { @@ -178,42 +161,38 @@ int dd_toke_skipspace(pTHX_ int offset) { /* replacement PL_check rv2cv entry */ -STATIC OP *(*dd_old_ck_rv2cv)(pTHX_ OP *op); - -STATIC OP *dd_ck_rv2cv(pTHX_ OP *o) { +STATIC OP *dd_ck_rv2cv(pTHX_ OP *o, void *user_data) { OP* kid; - char* s; - char* save_s; - char tmpbuf[sizeof PL_tokenbuf]; - char found_name[sizeof PL_tokenbuf]; - char* found_proto = NULL, *found_traits = NULL; - STRLEN len = 0; int dd_flags; - char* cb_args[6]; - dSP; /* define stack pointer for later call stuff */ - char* retstr; - STRLEN n_a; /* for POPpx */ - - o = dd_old_ck_rv2cv(aTHX_ o); /* let the original do its job */ if (in_declare) { - cb_args[0] = NULL; -#ifdef DD_DEBUG - printf("Deconstructing declare\n"); - printf("PL_bufptr: %s\n", PL_bufptr); - printf("bufend at: %i\n", PL_bufend - PL_bufptr); - printf("linestr: %s\n", SvPVX(PL_linestr)); - printf("linestr len: %i\n", PL_bufend - SvPVX(PL_linestr)); -#endif - call_argv("Devel::Declare::done_declare", G_VOID|G_DISCARD, cb_args); - in_declare--; -#ifdef DD_DEBUG - printf("PL_bufptr: %s\n", PL_bufptr); - printf("bufend at: %i\n", PL_bufend - PL_bufptr); - printf("linestr: %s\n", SvPVX(PL_linestr)); - printf("linestr len: %i\n", PL_bufend - SvPVX(PL_linestr)); - printf("actual len: %i\n", strlen(PL_bufptr)); -#endif + if (dd_debug) { + printf("Deconstructing declare\n"); + printf("PL_bufptr: %s\n", PL_bufptr); + printf("bufend at: %i\n", PL_bufend - PL_bufptr); + printf("linestr: %s\n", SvPVX(PL_linestr)); + printf("linestr len: %i\n", PL_bufend - SvPVX(PL_linestr)); + } + + dSP; + + ENTER; + SAVETMPS; + + PUSHMARK(SP); + + call_pv("Devel::Declare::done_declare", G_VOID|G_DISCARD); + + FREETMPS; + LEAVE; + + if (dd_debug) { + printf("PL_bufptr: %s\n", PL_bufptr); + printf("bufend at: %i\n", PL_bufend - PL_bufptr); + printf("linestr: %s\n", SvPVX(PL_linestr)); + printf("linestr len: %i\n", PL_bufend - SvPVX(PL_linestr)); + printf("actual len: %i\n", strlen(PL_bufptr)); + } return o; } @@ -222,49 +201,37 @@ STATIC OP *dd_ck_rv2cv(pTHX_ OP *o) { if (kid->op_type != OP_GV) /* not a GV so ignore */ return o; - if (PL_lex_state != LEX_NORMAL && PL_lex_state != LEX_INTERPNORMAL) + if (!DD_AM_LEXING) return o; /* not lexing? */ - /* I was doing this, but the CONST wrap can't so it didn't gain anything - stash = GvSTASH(kGVOP_gv); */ - -#ifdef DD_DEBUG - printf("Checking GV %s -> %s\n", HvNAME(GvSTASH(kGVOP_gv)), GvNAME(kGVOP_gv)); -#endif + if (dd_debug) { + printf("Checking GV %s -> %s\n", HvNAME(GvSTASH(kGVOP_gv)), GvNAME(kGVOP_gv)); + } dd_flags = dd_is_declarator(aTHX_ GvNAME(kGVOP_gv)); if (dd_flags == -1) return o; -#ifdef DD_DEBUG - printf("dd_flags are: %i\n", dd_flags); -#endif - - s = PL_bufptr; /* copy the current buffer pointer */ - - DD_DEBUG_S - -#ifdef DD_DEBUG - printf("PL_tokenbuf: %s\n", PL_tokenbuf); -#endif + if (dd_debug) { + printf("dd_flags are: %i\n", dd_flags); + printf("PL_tokenbuf: %s\n", PL_tokenbuf); + } - dd_linestr_callback(aTHX_ "rv2cv", GvNAME(kGVOP_gv), s); + dd_linestr_callback(aTHX_ "rv2cv", GvNAME(kGVOP_gv)); return o; } -STATIC OP *(*dd_old_ck_entereval)(pTHX_ OP *op); - OP* dd_pp_entereval(pTHX) { dSP; dPOPss; STRLEN len; const char* s; if (SvPOK(sv)) { -#ifdef DD_DEBUG - printf("mangling eval sv\n"); -#endif + if (dd_debug) { + printf("mangling eval sv\n"); + } if (SvREADONLY(sv)) sv = sv_2mortal(newSVsv(sv)); s = SvPVX(sv); @@ -280,8 +247,7 @@ OP* dd_pp_entereval(pTHX) { return PL_ppaddr[OP_ENTEREVAL](aTHX); } -STATIC OP *dd_ck_entereval(pTHX_ OP *o) { - o = dd_old_ck_entereval(aTHX_ o); /* let the original do its job */ +STATIC OP *dd_ck_entereval(pTHX_ OP *o, void *user_data) { if (o->op_ppaddr == PL_ppaddr[OP_ENTEREVAL]) o->op_ppaddr = dd_pp_entereval; return o; @@ -295,14 +261,15 @@ static I32 dd_filter_realloc(pTHX_ int idx, SV *sv, int maxlen) return count; } -STATIC OP *(*dd_old_ck_const)(pTHX_ OP*op); - -STATIC OP *dd_ck_const(pTHX_ OP *o) { +STATIC OP *dd_ck_const(pTHX_ OP *o, void *user_data) { int dd_flags; - char* s; char* name; - o = dd_old_ck_const(aTHX_ o); /* let the original do its job */ + /* if this is set, we just grabbed a delimited string or something, + not a bareword, so NO TOUCHY */ + + if (DD_HAVE_LEX_STUFF) + return o; /* don't try and look this up if it's not a string const */ if (!SvPOK(cSVOPo->op_sv)) @@ -315,9 +282,7 @@ STATIC OP *dd_ck_const(pTHX_ OP *o) { if (dd_flags == -1) return o; - s = PL_bufptr; - - dd_linestr_callback(aTHX_ "const", name, s); + dd_linestr_callback(aTHX_ "const", name); return o; } @@ -332,28 +297,13 @@ void setup() CODE: if (!initialized++) { - dd_old_ck_rv2cv = PL_check[OP_RV2CV]; - PL_check[OP_RV2CV] = dd_ck_rv2cv; - dd_old_ck_entereval = PL_check[OP_ENTEREVAL]; - PL_check[OP_ENTEREVAL] = dd_ck_entereval; - dd_old_ck_const = PL_check[OP_CONST]; - PL_check[OP_CONST] = dd_ck_const; + hook_op_check(OP_RV2CV, dd_ck_rv2cv, NULL); + hook_op_check(OP_ENTEREVAL, dd_ck_entereval, NULL); + hook_op_check(OP_CONST, dd_ck_const, NULL); } filter_add(dd_filter_realloc, NULL); char* -get_linestr() - CODE: - RETVAL = dd_get_linestr(aTHX); - OUTPUT: - RETVAL - -void -set_linestr(char* new_value) - CODE: - dd_set_linestr(aTHX_ new_value); - -char* get_lex_stuff() CODE: RETVAL = dd_get_lex_stuff(aTHX); @@ -411,3 +361,8 @@ void set_in_declare(int value) CODE: in_declare = value; + +BOOT: + if (getenv ("DD_DEBUG")) { + dd_debug = 1; + }