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);

Reply via email to