Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package perl-XS-Parse-Keyword for openSUSE:Factory checked in at 2021-10-23 00:51:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-XS-Parse-Keyword (Old) and /work/SRC/openSUSE:Factory/.perl-XS-Parse-Keyword.new.1890 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-XS-Parse-Keyword" Sat Oct 23 00:51:32 2021 rev:4 rq:926939 version:0.21 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-XS-Parse-Keyword/perl-XS-Parse-Keyword.changes 2021-09-30 23:44:47.668565496 +0200 +++ /work/SRC/openSUSE:Factory/.perl-XS-Parse-Keyword.new.1890/perl-XS-Parse-Keyword.changes 2021-10-23 00:52:16.209155625 +0200 @@ -1,0 +2,15 @@ +Wed Oct 13 03:07:09 UTC 2021 - Tina M??ller <timueller+p...@suse.de> + +- updated to 0.21 + see /usr/share/doc/packages/perl-XS-Parse-Keyword/Changes + + 0.20 2021-10-11 + [BUGFIXES] + * Fix for perl 5.20 - cannot use assert() as an expression + + 0.19 2021-10-05 + [CHANGES] + * Defined XPK_PREFIXED_BLOCK_ENTERLEAVE and XPK_SETUP for customizing + the parser context around blocks + +------------------------------------------------------------------- Old: ---- XS-Parse-Keyword-0.18.tar.gz New: ---- XS-Parse-Keyword-0.21.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-XS-Parse-Keyword.spec ++++++ --- /var/tmp/diff_new_pack.Ev604b/_old 2021-10-23 00:52:16.701155842 +0200 +++ /var/tmp/diff_new_pack.Ev604b/_new 2021-10-23 00:52:16.705155844 +0200 @@ -18,7 +18,7 @@ %define cpan_name XS-Parse-Keyword Name: perl-XS-Parse-Keyword -Version: 0.18 +Version: 0.21 Release: 0 Summary: XS functions to assist in parsing keyword syntax License: Artistic-1.0 OR GPL-1.0-or-later ++++++ XS-Parse-Keyword-0.18.tar.gz -> XS-Parse-Keyword-0.21.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/Changes new/XS-Parse-Keyword-0.21/Changes --- old/XS-Parse-Keyword-0.18/Changes 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/Changes 2021-10-12 10:55:54.000000000 +0200 @@ -1,5 +1,14 @@ Revision history for XS-Parse-Keyword +0.20 2021-10-11 + [BUGFIXES] + * Fix for perl 5.20 - cannot use assert() as an expression + +0.19 2021-10-05 + [CHANGES] + * Defined XPK_PREFIXED_BLOCK_ENTERLEAVE and XPK_SETUP for customizing + the parser context around blocks + 0.18 2021-09-28 [CHANGES] * Define the XPI_OPERAND_ONLY_LOOK flag diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/MANIFEST new/XS-Parse-Keyword-0.21/MANIFEST --- old/XS-Parse-Keyword-0.18/MANIFEST 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/MANIFEST 2021-10-12 10:55:54.000000000 +0200 @@ -1,10 +1,11 @@ Build.PL Changes +hax/force_list_keeping_pushmark.c.inc hax/lexer-additions.c.inc hax/make_argcheck_aux.c.inc hax/make_argcheck_ops.c.inc hax/newOP_CUSTOM.c.inc -hax/op_sibling.c.inc +hax/op_sibling_splice.c.inc hax/perl-backcompat.c.inc hax/wrap_keyword_plugin.c.inc inc/Module/Build/with/XSTests.pm diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/META.json new/XS-Parse-Keyword-0.21/META.json --- old/XS-Parse-Keyword-0.18/META.json 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/META.json 2021-10-12 10:55:54.000000000 +0200 @@ -39,19 +39,19 @@ "provides" : { "XS::Parse::Infix" : { "file" : "lib/XS/Parse/Infix.pm", - "version" : "0.18" + "version" : "0.21" }, "XS::Parse::Infix::Builder" : { "file" : "lib/XS/Parse/Infix/Builder.pm", - "version" : "0.18" + "version" : "0.21" }, "XS::Parse::Keyword" : { "file" : "lib/XS/Parse/Keyword.pm", - "version" : "0.18" + "version" : "0.21" }, "XS::Parse::Keyword::Builder" : { "file" : "lib/XS/Parse/Keyword/Builder.pm", - "version" : "0.18" + "version" : "0.21" } }, "release_status" : "stable", @@ -60,6 +60,6 @@ "http://dev.perl.org/licenses/" ] }, - "version" : "0.18", + "version" : "0.21", "x_serialization_backend" : "JSON::PP version 4.05" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/META.yml new/XS-Parse-Keyword-0.21/META.yml --- old/XS-Parse-Keyword-0.18/META.yml 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/META.yml 2021-10-12 10:55:54.000000000 +0200 @@ -18,19 +18,19 @@ provides: XS::Parse::Infix: file: lib/XS/Parse/Infix.pm - version: '0.18' + version: '0.21' XS::Parse::Infix::Builder: file: lib/XS/Parse/Infix/Builder.pm - version: '0.18' + version: '0.21' XS::Parse::Keyword: file: lib/XS/Parse/Keyword.pm - version: '0.18' + version: '0.21' XS::Parse::Keyword::Builder: file: lib/XS/Parse/Keyword/Builder.pm - version: '0.18' + version: '0.21' requires: perl: '5.014' resources: license: http://dev.perl.org/licenses/ -version: '0.18' +version: '0.21' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/README new/XS-Parse-Keyword-0.21/README --- old/XS-Parse-Keyword-0.18/README 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/README 2021-10-12 10:55:54.000000000 +0200 @@ -232,6 +232,32 @@ pieces, before the block itself is parsed, ensuring any new lexical variables are now visible. + In addition, the following extra piece types are recognised here: + + XPK_SETUP + + void setup(pTHX_ void *hookdata); + + XPK_SETUP(&setup) + + atomic, emits nothing. + + This piece type runs a function given by pointer. Typically this + function may be used to introduce new lexical state into the parser, + or in some other way have some side-effect on the parsing context of + the block to be parsed. + + XPK_PREFIXED_BLOCK_ENTERLEAVE + + A variant of XPK_PREFIXED_BLOCK which additionally wraps the entire + parsing operation, including the block_start(), block_end() and any + calls to XPK_SETUP functions, within a ENTER/LEAVE pair. + + This should not make a difference to the standard parser pieces + provided here, but may be useful behaviour for the code in the setup + function, especially if it wishes to modify parser state and use the + savestack to ensure it is restored again when parsing has finished. + XPK_ANONSUB atomic, emits op. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/XSParseKeyword.h new/XS-Parse-Keyword-0.21/XSParseKeyword.h --- old/XS-Parse-Keyword-0.18/XSParseKeyword.h 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/XSParseKeyword.h 2021-10-12 10:55:54.000000000 +0200 @@ -10,6 +10,7 @@ char c; /* LITERALCHAR */ const char *str; /* LITERALSTR */ const struct XSParseKeywordPieceType *pieces; /* SCOPEs */ + void (*callback)(pTHX_ void *hookdata); /* SETUP */ } u; }; @@ -42,6 +43,8 @@ XS_PARSE_KEYWORD_INFIX = 0x40, /* infix */ + XS_PARSE_KEYWORD_SETUP = 0x70, /* invokes callback, emits nothing */ + XS_PARSE_KEYWORD_SEQUENCE = 0x80, /* contained */ XS_PARSE_KEYWORD_REPEATED, /* i, contained */ XS_PARSE_KEYWORD_CHOICE, /* i, contained */ @@ -65,10 +68,12 @@ XPK_TYPEFLAG_SPECIAL = (1<<17), /* on XPK_BLOCK: scoped on XPK_LEXVAR: my */ - /* These three are shifted versions of perl's G_VOID, G_SCALAR, G_ARRAY */ + /* These three are shifted versions of perl's G_VOID, G_SCALAR, G_LIST */ XPK_TYPEFLAG_G_VOID = (1<<18), XPK_TYPEFLAG_G_SCALAR = (2<<18), - XPK_TYPEFLAG_G_LIST = (3<<18), /* yes it's called LIST, not ARRAY */ + XPK_TYPEFLAG_G_LIST = (3<<18), + + XPK_TYPEFLAG_ENTERLEAVE = (1<<20), /* wrap ENTER/LEAVE pair around the item */ }; #define XPK_BLOCK_flags(flags) {.type = XS_PARSE_KEYWORD_BLOCK|(flags), .u.pieces = NULL} @@ -77,8 +82,12 @@ #define XPK_BLOCK_SCALARCTX XPK_BLOCK_flags(XPK_TYPEFLAG_SPECIAL|XPK_TYPEFLAG_G_SCALAR) #define XPK_BLOCK_LISTCTX XPK_BLOCK_flags(XPK_TYPEFLAG_SPECIAL|XPK_TYPEFLAG_G_LIST) -#define XPK_PREFIXED_BLOCK(...) \ - {.type = XS_PARSE_KEYWORD_BLOCK, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }} +#define XPK_PREFIXED_BLOCK_flags(flags,...) \ + {.type = XS_PARSE_KEYWORD_BLOCK|flags, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }} +#define XPK_PREFIXED_BLOCK(...) XPK_PREFIXED_BLOCK_flags(0, __VA_ARGS__) +#define XPK_PREFIXED_BLOCK_ENTERLEAVE(...) XPK_PREFIXED_BLOCK_flags(XPK_TYPEFLAG_ENTERLEAVE, __VA_ARGS__) + +#define XPK_SETUP(setup) {.type = XS_PARSE_KEYWORD_SETUP, .u.callback = setup} #define XPK_ANONSUB {.type = XS_PARSE_KEYWORD_ANONSUB} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/hax/force_list_keeping_pushmark.c.inc new/XS-Parse-Keyword-0.21/hax/force_list_keeping_pushmark.c.inc --- old/XS-Parse-Keyword-0.18/hax/force_list_keeping_pushmark.c.inc 1970-01-01 01:00:00.000000000 +0100 +++ new/XS-Parse-Keyword-0.21/hax/force_list_keeping_pushmark.c.inc 2021-10-12 10:55:55.000000000 +0200 @@ -0,0 +1,25 @@ +/* vi: set ft=c : */ + +#include "op_sibling_splice.c.inc" + +/* force_list_keeping_pushmark nulls out the OP_LIST itself but preserves + * the OP_PUSHMARK inside it. This is essential or else op_contextualize() + * will null out both of them and we lose the mark + */ +/* copypasta from core's op.c */ +#define force_list_keeping_pushmark(o) S_force_list_keeping_pushmark(aTHX_ o) +static OP *S_force_list_keeping_pushmark(pTHX_ OP *o) +{ + if(!o || o->op_type != OP_LIST) { + OP *rest = NULL; + if(o) { + rest = OpSIBLING(o); + OpLASTSIB_set(o, NULL); + } + o = newLISTOP(OP_LIST, 0, o, NULL); + if(rest) + op_sibling_splice(o, cLISTOPo->op_last, 0, rest); + } + op_null(o); + return op_contextualize(o, G_LIST); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/hax/op_sibling.c.inc new/XS-Parse-Keyword-0.21/hax/op_sibling.c.inc --- old/XS-Parse-Keyword-0.18/hax/op_sibling.c.inc 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/hax/op_sibling.c.inc 1970-01-01 01:00:00.000000000 +0100 @@ -1,57 +0,0 @@ -/* vi: set ft=c : */ - -#ifndef OpSIBLING -# define OpSIBLING(op) ((op)->op_sibling) -#endif - -#ifndef OpMORESIB_set -# define OpMORESIB_set(op,sib) ((op)->op_sibling = (sib)) -#endif - -#ifndef OpLASTSIB_set - /* older perls don't need to store this at all */ -# define OpLASTSIB_set(op,parent) -#endif - -#ifndef op_sibling_splice -# define op_sibling_splice(parent, start, del_count, insert) S_op_sibling_splice(aTHX_ parent, start, del_count, insert) -static OP *S_op_sibling_splice(pTHX_ OP *parent, OP *start, int del_count, OP *insert) -{ - OP *deleted = NULL; - - if(!insert && !del_count) - return NULL; - - OP **prevp; - if(start) - prevp = &(start->op_sibling); - else - prevp = &(cLISTOPx(parent)->op_first); - - OP *after = *prevp; - - if(del_count) { - croak("Back-compat op_sibling_splice with del_count != 0 not yet implemented"); - /* THIS IS AS YET UNTESTED - deleted = *prevp; - OP *o = deleted; - while(del_count > 1) - o = o->op_sibling, del_count--; - after = o->op_sibling; - o->op_sibling = NULL; - */ - } - - if(insert) { - *prevp = insert; - OP *o = insert; - while(o->op_sibling) - o = o->op_sibling; - o->op_sibling = after; - } - else - *prevp = after; - - return deleted; -} -#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/hax/op_sibling_splice.c.inc new/XS-Parse-Keyword-0.21/hax/op_sibling_splice.c.inc --- old/XS-Parse-Keyword-0.18/hax/op_sibling_splice.c.inc 1970-01-01 01:00:00.000000000 +0100 +++ new/XS-Parse-Keyword-0.21/hax/op_sibling_splice.c.inc 2021-10-12 10:55:55.000000000 +0200 @@ -0,0 +1,44 @@ +/* vi: set ft=c : */ + +#ifndef op_sibling_splice +# define op_sibling_splice(parent, start, del_count, insert) S_op_sibling_splice(aTHX_ parent, start, del_count, insert) +static OP *S_op_sibling_splice(pTHX_ OP *parent, OP *start, int del_count, OP *insert) +{ + OP *deleted = NULL; + + if(!insert && !del_count) + return NULL; + + OP **prevp; + if(start) + prevp = &(start->op_sibling); + else + prevp = &(cLISTOPx(parent)->op_first); + + OP *after = *prevp; + + if(del_count) { + croak("Back-compat op_sibling_splice with del_count != 0 not yet implemented"); + /* THIS IS AS YET UNTESTED + deleted = *prevp; + OP *o = deleted; + while(del_count > 1) + o = o->op_sibling, del_count--; + after = o->op_sibling; + o->op_sibling = NULL; + */ + } + + if(insert) { + *prevp = insert; + OP *o = insert; + while(o->op_sibling) + o = o->op_sibling; + o->op_sibling = after; + } + else + *prevp = after; + + return deleted; +} +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/hax/perl-backcompat.c.inc new/XS-Parse-Keyword-0.21/hax/perl-backcompat.c.inc --- old/XS-Parse-Keyword-0.18/hax/perl-backcompat.c.inc 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/hax/perl-backcompat.c.inc 2021-10-12 10:55:55.000000000 +0200 @@ -11,6 +11,10 @@ # define SvTRUE_NN(sv) SvTRUE(sv) #endif +#ifndef G_LIST +# define G_LIST G_ARRAY +#endif + #if !HAVE_PERL_VERSION(5, 18, 0) typedef AV PADNAMELIST; # define PadlistARRAY(pl) ((PAD **)AvARRAY(pl)) @@ -61,6 +65,19 @@ # define OLDSAVEIX(cx) (PL_scopestack[cx->blk_oldscopesp-1]) #endif +#ifndef OpSIBLING +# define OpSIBLING(op) ((op)->op_sibling) +#endif + +#ifndef OpMORESIB_set +# define OpMORESIB_set(op,sib) ((op)->op_sibling = (sib)) +#endif + +#ifndef OpLASTSIB_set + /* older perls don't need to store this at all */ +# define OpLASTSIB_set(op,parent) +#endif + #ifndef op_convert_list # define op_convert_list(type, flags, o) S_op_convert_list(aTHX_ type, flags, o) static OP *S_op_convert_list(pTHX_ I32 type, I32 flags, OP *o) @@ -106,7 +123,7 @@ /* On Perl 5.14 this had a different name */ #ifndef pad_add_name_pvn #define pad_add_name_pvn(name, len, flags, typestash, ourstash) MY_pad_add_name(aTHX_ name, len, flags, typestash, ourstash) -PADOFFSET MY_pad_add_name(pTHX_ const char *name, STRLEN len, U32 flags, HV *typestash, HV *ourstash) +static PADOFFSET MY_pad_add_name(pTHX_ const char *name, STRLEN len, U32 flags, HV *typestash, HV *ourstash) { /* perl 5.14's Perl_pad_add_name requires a NUL-terminated name */ SV *namesv = sv_2mortal(newSVpvn(name, len)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/lib/XS/Parse/Infix/Builder.pm new/XS-Parse-Keyword-0.21/lib/XS/Parse/Infix/Builder.pm --- old/XS-Parse-Keyword-0.18/lib/XS/Parse/Infix/Builder.pm 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/lib/XS/Parse/Infix/Builder.pm 2021-10-12 10:55:55.000000000 +0200 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2021 -- leon...@leonerd.org.uk -package XS::Parse::Infix::Builder 0.18; +package XS::Parse::Infix::Builder 0.21; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/lib/XS/Parse/Infix/Builder_data.pm.PL new/XS-Parse-Keyword-0.21/lib/XS/Parse/Infix/Builder_data.pm.PL --- old/XS-Parse-Keyword-0.18/lib/XS/Parse/Infix/Builder_data.pm.PL 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/lib/XS/Parse/Infix/Builder_data.pm.PL 2021-10-12 10:55:55.000000000 +0200 @@ -28,7 +28,7 @@ <$in_h> } ); __DATA__ -package XS::Parse::Infix::Builder_data 0.18; +package XS::Parse::Infix::Builder_data 0.21; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/lib/XS/Parse/Infix.pm new/XS-Parse-Keyword-0.21/lib/XS/Parse/Infix.pm --- old/XS-Parse-Keyword-0.18/lib/XS/Parse/Infix.pm 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/lib/XS/Parse/Infix.pm 2021-10-12 10:55:55.000000000 +0200 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2021 -- leon...@leonerd.org.uk -package XS::Parse::Infix 0.18; +package XS::Parse::Infix 0.21; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/lib/XS/Parse/Keyword/Builder.pm new/XS-Parse-Keyword-0.21/lib/XS/Parse/Keyword/Builder.pm --- old/XS-Parse-Keyword-0.18/lib/XS/Parse/Keyword/Builder.pm 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/lib/XS/Parse/Keyword/Builder.pm 2021-10-12 10:55:55.000000000 +0200 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2021 -- leon...@leonerd.org.uk -package XS::Parse::Keyword::Builder 0.18; +package XS::Parse::Keyword::Builder 0.21; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/lib/XS/Parse/Keyword/Builder_data.pm.PL new/XS-Parse-Keyword-0.21/lib/XS/Parse/Keyword/Builder_data.pm.PL --- old/XS-Parse-Keyword-0.18/lib/XS/Parse/Keyword/Builder_data.pm.PL 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/lib/XS/Parse/Keyword/Builder_data.pm.PL 2021-10-12 10:55:55.000000000 +0200 @@ -28,7 +28,7 @@ <$in_h> } ); __DATA__ -package XS::Parse::Keyword::Builder_data 0.18; +package XS::Parse::Keyword::Builder_data 0.21; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/lib/XS/Parse/Keyword.pm new/XS-Parse-Keyword-0.21/lib/XS/Parse/Keyword.pm --- old/XS-Parse-Keyword-0.18/lib/XS/Parse/Keyword.pm 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/lib/XS/Parse/Keyword.pm 2021-10-12 10:55:55.000000000 +0200 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2021 -- leon...@leonerd.org.uk -package XS::Parse::Keyword 0.18; +package XS::Parse::Keyword 0.21; use v5.14; use warnings; @@ -246,6 +246,35 @@ before the block itself is parsed, ensuring any new lexical variables are now visible. +In addition, the following extra piece types are recognised here: + +=over 4 + +=item XPK_SETUP + + void setup(pTHX_ void *hookdata); + + XPK_SETUP(&setup) + +I<atomic, emits nothing.> + +This piece type runs a function given by pointer. Typically this function may +be used to introduce new lexical state into the parser, or in some other way +have some side-effect on the parsing context of the block to be parsed. + +=back + +=head2 XPK_PREFIXED_BLOCK_ENTERLEAVE + +A variant of C<XPK_PREFIXED_BLOCK> which additionally wraps the entire parsing +operation, including the C<block_start()>, C<block_end()> and any calls to +C<XPK_SETUP> functions, within a C<ENTER>/C<LEAVE> pair. + +This should not make a difference to the standard parser pieces provided here, +but may be useful behaviour for the code in the setup function, especially if +it wishes to modify parser state and use the savestack to ensure it is +restored again when parsing has finished. + =head2 XPK_ANONSUB I<atomic, emits op.> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/src/infix.c new/XS-Parse-Keyword-0.21/src/infix.c --- old/XS-Parse-Keyword-0.18/src/infix.c 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/src/infix.c 2021-10-12 10:55:55.000000000 +0200 @@ -12,18 +12,18 @@ #include "infix.h" -#define HAVE_PERL_VERSION(R, V, S) \ - (PERL_REVISION > (R) || (PERL_REVISION == (R) && (PERL_VERSION > (V) || (PERL_VERSION == (V) && (PERL_SUBVERSION >= (S)))))) +#include "perl-backcompat.c.inc" +#include "force_list_keeping_pushmark.c.inc" #include "make_argcheck_ops.c.inc" #include "newOP_CUSTOM.c.inc" -#include "op_sibling.c.inc" +#include "op_sibling_splice.c.inc" #if HAVE_PERL_VERSION(5,32,0) # define HAVE_OP_ISA #endif -#if HAVE_PERL_VERSION(5,20,0) +#if HAVE_PERL_VERSION(5,22,0) /* assert() can be used as an expression */ # define HAVE_ASSERT_AS_EXPRESSION #endif @@ -39,10 +39,6 @@ # define block_end(a,b) Perl_block_end(aTHX_ a,b) #endif -#ifndef G_LIST -# define G_LIST G_ARRAY -#endif - #ifndef XS_INTERNAL /* copypasta from perl-v5.16.0/XSUB.h */ # if defined(__CYGWIN__) && defined(USE_DYNAMIC_LOADING) @@ -134,28 +130,6 @@ return ret; } -/* force_list_keeping_pushmark nulls out the OP_LIST itself but preserves - * the OP_PUSHMARK inside it. This is essential or else op_contextualize() - * will null out both of them and we lose the mark - */ -/* copypasta from core's op.c */ -#define force_list_keeping_pushmark(o) S_force_list(aTHX_ o) -static OP *S_force_list(pTHX_ OP *o) -{ - if(!o || o->op_type != OP_LIST) { - OP *rest = NULL; - if(o) { - rest = OpSIBLING(o); - OpLASTSIB_set(o, NULL); - } - o = newLISTOP(OP_LIST, 0, o, NULL); - if(rest) - op_sibling_splice(o, cLISTOPo->op_last, 0, rest); - } - op_null(o); - return op_contextualize(o, G_LIST); -} - static bool op_extract_onerefgen(OP *o, OP **kidp) { OP *first; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/src/keyword.c new/XS-Parse-Keyword-0.21/src/keyword.c --- old/XS-Parse-Keyword-0.18/src/keyword.c 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/src/keyword.c 2021-10-12 10:55:55.000000000 +0200 @@ -135,11 +135,11 @@ }; } XSParseKeywordPiece_v1; -static bool probe_piece(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *piece); -static void parse_piece(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *piece); -static void parse_pieces(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *pieces); +static bool probe_piece(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *piece, void *hookdata); +static void parse_piece(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *piece, void *hookdata); +static void parse_pieces(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *pieces, void *hookdata); -static bool probe_piece(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *piece) +static bool probe_piece(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *piece, void *hookdata) { int argi = *argidx; @@ -186,7 +186,7 @@ if(lex_peek_unichar(0) != '{') return FALSE; - parse_piece(aTHX_ argsv, argidx, piece); + parse_piece(aTHX_ argsv, argidx, piece, hookdata); return TRUE; case XS_PARSE_KEYWORD_IDENT: @@ -219,12 +219,19 @@ return TRUE; } + case XS_PARSE_KEYWORD_SETUP: + croak("ARGH probe_piece() should never see XS_PARSE_KEYWORD_SETUP!"); + case XS_PARSE_KEYWORD_SEQUENCE: - if(!probe_piece(aTHX_ argsv, argidx, piece->u.pieces + 0)) + { + const struct XSParseKeywordPieceType *pieces = piece->u.pieces; + + if(!probe_piece(aTHX_ argsv, argidx, pieces++, hookdata)) return FALSE; - parse_pieces(aTHX_ argsv, argidx, piece->u.pieces + 1); + parse_pieces(aTHX_ argsv, argidx, pieces, hookdata); return TRUE; + } case XS_PARSE_KEYWORD_CHOICE: { @@ -232,7 +239,7 @@ THISARG.i = 0; (*argidx)++; /* tentative */ while(choices->type) { - if(probe_piece(aTHX_ argsv, argidx, choices + 0)) { + if(probe_piece(aTHX_ argsv, argidx, choices + 0, hookdata)) { return TRUE; } choices++; @@ -247,7 +254,7 @@ const struct XSParseKeywordPieceType *choices = piece->u.pieces; (*argidx)++; /* tentative */ while(choices->type) { - if(probe_piece(aTHX_ argsv, argidx, choices + 0)) { + if(probe_piece(aTHX_ argsv, argidx, choices + 0, hookdata)) { THISARG.i = choices[1].type; return TRUE; } @@ -261,23 +268,23 @@ { const struct XSParseKeywordPieceType *pieces = piece->u.pieces; (*argidx)++; /* tentative */ - if(!probe_piece(aTHX_ argsv, argidx, pieces + 1)) { + if(!probe_piece(aTHX_ argsv, argidx, pieces + 1, hookdata)) { (*argidx)--; return FALSE; } /* we're now committed */ THISARG.i = 1; if(pieces[2].type) - parse_pieces(aTHX_ argsv, argidx, pieces + 2); + parse_pieces(aTHX_ argsv, argidx, pieces + 2, hookdata); - if(!probe_piece(aTHX_ argsv, argidx, pieces + 0)) + if(!probe_piece(aTHX_ argsv, argidx, pieces + 0, hookdata)) return TRUE; while(1) { - parse_pieces(aTHX_ argsv, argidx, pieces + 1); + parse_pieces(aTHX_ argsv, argidx, pieces + 1, hookdata); THISARG.i++; - if(!probe_piece(aTHX_ argsv, argidx, pieces + 0)) + if(!probe_piece(aTHX_ argsv, argidx, pieces + 0, hookdata)) break; } return TRUE; @@ -287,35 +294,35 @@ if(lex_peek_unichar(0) != '(') return FALSE; - parse_piece(aTHX_ argsv, argidx, piece); + parse_piece(aTHX_ argsv, argidx, piece, hookdata); return TRUE; case XS_PARSE_KEYWORD_BRACKETSCOPE: if(lex_peek_unichar(0) != '[') return FALSE; - parse_piece(aTHX_ argsv, argidx, piece); + parse_piece(aTHX_ argsv, argidx, piece, hookdata); return TRUE; case XS_PARSE_KEYWORD_BRACESCOPE: if(lex_peek_unichar(0) != '{') return FALSE; - parse_piece(aTHX_ argsv, argidx, piece); + parse_piece(aTHX_ argsv, argidx, piece, hookdata); return TRUE; case XS_PARSE_KEYWORD_CHEVRONSCOPE: if(lex_peek_unichar(0) != '<') return FALSE; - parse_piece(aTHX_ argsv, argidx, piece); + parse_piece(aTHX_ argsv, argidx, piece, hookdata); return TRUE; } croak("TODO: probe_piece on type=%d\n", type); } -static void parse_piece(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *piece) +static void parse_piece(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *piece, void *hookdata) { int argi = *argidx; @@ -336,10 +343,11 @@ bool is_special = !!(piece->type & XPK_TYPEFLAG_SPECIAL); U8 want = 0; switch(piece->type & (3 << 18)) { - case XPK_TYPEFLAG_G_VOID: want = G_VOID; break; + case XPK_TYPEFLAG_G_VOID: want = G_VOID; break; case XPK_TYPEFLAG_G_SCALAR: want = G_SCALAR; break; - case XPK_TYPEFLAG_G_LIST: want = G_ARRAY; break; + case XPK_TYPEFLAG_G_LIST: want = G_LIST; break; } + bool is_enterleave = !!(piece->type & XPK_TYPEFLAG_ENTERLEAVE); U32 type = piece->type & 0xFFFF; @@ -361,11 +369,25 @@ case XS_PARSE_KEYWORD_BLOCK: { + if(is_enterleave) + ENTER; + I32 save_ix = block_start(1); if(piece->u.pieces) { /* The prefix pieces */ - parse_pieces(aTHX_ argsv, argidx, piece->u.pieces); + const struct XSParseKeywordPieceType *pieces = piece->u.pieces; + + while(pieces->type) { + if(pieces->type == XS_PARSE_KEYWORD_SETUP) + (pieces->u.callback)(aTHX_ hookdata); + else { + parse_piece(aTHX_ argsv, argidx, pieces, hookdata); + lex_read_space(0); + } + + pieces++; + } if(*argidx > argi) { argi = *argidx; @@ -393,6 +415,10 @@ THISARG.op = op_contextualize(THISARG.op, want); (*argidx)++; + + if(is_enterleave) + LEAVE; + return; } @@ -552,6 +578,9 @@ return; } + case XS_PARSE_KEYWORD_SETUP: + croak("ARGH parse_piece() should never see XS_PARSE_KEYWORD_SETUP!"); + case XS_PARSE_KEYWORD_SEQUENCE: { const struct XSParseKeywordPieceType *pieces = piece->u.pieces; @@ -559,28 +588,28 @@ if(is_optional) { THISARG.i = 0; (*argidx)++; - if(!probe_piece(aTHX_ argsv, argidx, pieces)) + if(!probe_piece(aTHX_ argsv, argidx, pieces, hookdata)) return; THISARG.i++; pieces++; } - parse_pieces(aTHX_ argsv, argidx, pieces); + parse_pieces(aTHX_ argsv, argidx, pieces, hookdata); return; } case XS_PARSE_KEYWORD_REPEATED: THISARG.i = 0; (*argidx)++; - while(probe_piece(aTHX_ argsv, argidx, piece->u.pieces + 0)) { + while(probe_piece(aTHX_ argsv, argidx, piece->u.pieces + 0, hookdata)) { THISARG.i++; - parse_pieces(aTHX_ argsv, argidx, piece->u.pieces + 1); + parse_pieces(aTHX_ argsv, argidx, piece->u.pieces + 1, hookdata); } return; case XS_PARSE_KEYWORD_CHOICE: case XS_PARSE_KEYWORD_TAGGEDCHOICE: - if(!probe_piece(aTHX_ argsv, argidx, piece)) { + if(!probe_piece(aTHX_ argsv, argidx, piece, hookdata)) { THISARG.i = -1; (*argidx)++; } @@ -590,10 +619,10 @@ THISARG.i = 0; (*argidx)++; while(1) { - parse_pieces(aTHX_ argsv, argidx, piece->u.pieces + 1); + parse_pieces(aTHX_ argsv, argidx, piece->u.pieces + 1, hookdata); THISARG.i++; - if(!probe_piece(aTHX_ argsv, argidx, piece->u.pieces + 0)) + if(!probe_piece(aTHX_ argsv, argidx, piece->u.pieces + 0, hookdata)) break; } return; @@ -609,7 +638,7 @@ lex_expect_unichar('('); lex_read_space(0); - parse_pieces(aTHX_ argsv, argidx, piece->u.pieces); + parse_pieces(aTHX_ argsv, argidx, piece->u.pieces, hookdata); lex_expect_unichar(')'); @@ -626,7 +655,7 @@ lex_expect_unichar('['); lex_read_space(0); - parse_pieces(aTHX_ argsv, argidx, piece->u.pieces); + parse_pieces(aTHX_ argsv, argidx, piece->u.pieces, hookdata); lex_expect_unichar(']'); @@ -643,7 +672,7 @@ lex_expect_unichar('{'); lex_read_space(0); - parse_pieces(aTHX_ argsv, argidx, piece->u.pieces); + parse_pieces(aTHX_ argsv, argidx, piece->u.pieces, hookdata); lex_expect_unichar('}'); @@ -660,7 +689,7 @@ lex_expect_unichar('<'); lex_read_space(0); - parse_pieces(aTHX_ argsv, argidx, piece->u.pieces); + parse_pieces(aTHX_ argsv, argidx, piece->u.pieces, hookdata); lex_expect_unichar('>'); @@ -670,11 +699,11 @@ croak("TODO: parse_piece on type=%d\n", type); } -static void parse_pieces(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *pieces) +static void parse_pieces(pTHX_ SV *argsv, size_t *argidx, const struct XSParseKeywordPieceType *pieces, void *hookdata) { size_t idx; for(idx = 0; pieces[idx].type; idx++) { - parse_piece(aTHX_ argsv, argidx, pieces + idx); + parse_piece(aTHX_ argsv, argidx, pieces + idx, hookdata); lex_read_space(0); } } @@ -695,9 +724,9 @@ size_t argidx = 0; if(hooks->build) - parse_pieces(aTHX_ argsv, &argidx, hooks->pieces); + parse_pieces(aTHX_ argsv, &argidx, hooks->pieces, reg->hookdata); else - parse_piece(aTHX_ argsv, &argidx, &hooks->piece1); + parse_piece(aTHX_ argsv, &argidx, &hooks->piece1, reg->hookdata); if(hooks->flags & XPK_FLAG_AUTOSEMI) { lex_read_space(0); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/t/31pieces-block.t new/XS-Parse-Keyword-0.21/t/31pieces-block.t --- old/XS-Parse-Keyword-0.18/t/31pieces-block.t 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/t/31pieces-block.t 2021-10-12 10:55:55.000000000 +0200 @@ -30,4 +30,9 @@ is( $ret, 123+456, 'result of pieceprefixedblock' ); } +{ + my $ret = pieceprefixedblock_VAR { "$VAR, world!" }; + is( $ret, "(Hello, world!)", 'result of pieceprefixedblock_VAR' ); +} + done_testing; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.18/t/pieces.xs new/XS-Parse-Keyword-0.21/t/pieces.xs --- old/XS-Parse-Keyword-0.18/t/pieces.xs 2021-09-29 01:43:31.000000000 +0200 +++ new/XS-Parse-Keyword-0.21/t/pieces.xs 2021-10-12 10:55:55.000000000 +0200 @@ -124,6 +124,15 @@ return KEYWORD_PLUGIN_EXPR; } +static void setup_block_VAR(pTHX_ void *hookdata) +{ + char *varname = hookdata; + PADOFFSET padix = pad_add_name_pvn(varname, strlen(varname), 0, NULL, NULL); + intro_my(); + + sv_setpvs(PAD_SVl(padix), "Hello"); +} + static const struct XSParseKeywordHooks hooks_block = { .permit_hintkey = hintkey, @@ -153,6 +162,13 @@ .build = &build_prefixedblock, }; +static const struct XSParseKeywordHooks hooks_prefixedblock_VAR = { + .permit_hintkey = hintkey, + + .piece1 = XPK_PREFIXED_BLOCK( XPK_SETUP(&setup_block_VAR) ), + .build1 = &build_expr, +}; + static const struct XSParseKeywordHooks hooks_anonsub = { .permit_hintkey = hintkey, @@ -271,6 +287,7 @@ register_xs_parse_keyword("pieceblock_list", &hooks_block_list, NULL); register_xs_parse_keyword("pieceprefixedblock", &hooks_prefixedblock, NULL); + register_xs_parse_keyword("pieceprefixedblock_VAR", &hooks_prefixedblock_VAR, "$VAR"); register_xs_parse_keyword("pieceanonsub", &hooks_anonsub, NULL); register_xs_parse_keyword("piecetermexpr", &hooks_termexpr, NULL);