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 2022-12-14 14:10:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-XS-Parse-Keyword (Old)
and /work/SRC/openSUSE:Factory/.perl-XS-Parse-Keyword.new.1835 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-XS-Parse-Keyword"
Wed Dec 14 14:10:54 2022 rev:10 rq:1042728 version:0.30
Changes:
--------
---
/work/SRC/openSUSE:Factory/perl-XS-Parse-Keyword/perl-XS-Parse-Keyword.changes
2022-11-09 12:56:40.200089005 +0100
+++
/work/SRC/openSUSE:Factory/.perl-XS-Parse-Keyword.new.1835/perl-XS-Parse-Keyword.changes
2022-12-14 14:11:08.391536946 +0100
@@ -1,0 +2,29 @@
+Sun Dec 4 03:10:55 UTC 2022 - Tina Müller <[email protected]>
+
+- updated to 0.30
+ see /usr/share/doc/packages/perl-XS-Parse-Keyword/Changes
+
+ 0.30 2022-12-03
+ [CHANGES]
+ * Added XPK_STAGED_ANONSUB; inspired a bit by XS::Parse::Sublike for
+ customising the parsing of anonmethod
+ 0.29 2022-12-01
+ [CHANGES]
+ * Added XPK_PREFIXED_TERMEXPR_ENTERLEAVE
+ [BUGFIXES]
+ * Don't try to call `SvPVX()` on a `newSV(0)` because -DDEBUGGING
+ perls get upset (RT145278)
+ * Remember to `break` out of switch block cases when testing for
+ `KEYWORD_PLUGIN_*` return values
+ 0.28 2022-11-25
+ [CHANGES]
+ * Include a XSParseInfixClassification field in the XSParseInfixInfo
+ structure
+ * Do not permit mixed identifier/non characters in the names of
+ registered infix operators
+ * No longer supports XSParseInfix ABI version 0
+ [BUGFIXES]
+ * When parsing an infix operator name, make sure not to be confused
+ by additional identifier characters immediately after it
+
+-------------------------------------------------------------------
Old:
----
XS-Parse-Keyword-0.27.tar.gz
New:
----
XS-Parse-Keyword-0.30.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ perl-XS-Parse-Keyword.spec ++++++
--- /var/tmp/diff_new_pack.pwRy9C/_old 2022-12-14 14:11:09.027540218 +0100
+++ /var/tmp/diff_new_pack.pwRy9C/_new 2022-12-14 14:11:09.031540238 +0100
@@ -18,7 +18,7 @@
%define cpan_name XS-Parse-Keyword
Name: perl-XS-Parse-Keyword
-Version: 0.27
+Version: 0.30
Release: 0
License: Artistic-1.0 OR GPL-1.0-or-later
Summary: XS functions to assist in parsing keyword syntax
++++++ XS-Parse-Keyword-0.27.tar.gz -> XS-Parse-Keyword-0.30.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/Changes
new/XS-Parse-Keyword-0.30/Changes
--- old/XS-Parse-Keyword-0.27/Changes 2022-10-31 23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/Changes 2022-12-03 15:51:44.000000000 +0100
@@ -1,5 +1,32 @@
Revision history for XS-Parse-Keyword
+0.30 2022-12-03
+ [CHANGES]
+ * Added XPK_STAGED_ANONSUB; inspired a bit by XS::Parse::Sublike for
+ customising the parsing of anonmethod
+
+0.29 2022-12-01
+ [CHANGES]
+ * Added XPK_PREFIXED_TERMEXPR_ENTERLEAVE
+
+ [BUGFIXES]
+ * Don't try to call `SvPVX()` on a `newSV(0)` because -DDEBUGGING
+ perls get upset (RT145278)
+ * Remember to `break` out of switch block cases when testing for
+ `KEYWORD_PLUGIN_*` return values
+
+0.28 2022-11-25
+ [CHANGES]
+ * Include a XSParseInfixClassification field in the XSParseInfixInfo
+ structure
+ * Do not permit mixed identifier/non characters in the names of
+ registered infix operators
+ * No longer supports XSParseInfix ABI version 0
+
+ [BUGFIXES]
+ * When parsing an infix operator name, make sure not to be confused
+ by additional identifier characters immediately after it
+
0.27 2022-10-31
[CHANGES]
* Updates to XS::Parse::Infix for latest `infix-plugin` perl5 branch
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/META.json
new/XS-Parse-Keyword-0.30/META.json
--- old/XS-Parse-Keyword-0.27/META.json 2022-10-31 23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/META.json 2022-12-03 15:51:44.000000000 +0100
@@ -40,19 +40,19 @@
"provides" : {
"XS::Parse::Infix" : {
"file" : "lib/XS/Parse/Infix.pm",
- "version" : "0.27"
+ "version" : "0.30"
},
"XS::Parse::Infix::Builder" : {
"file" : "lib/XS/Parse/Infix/Builder.pm",
- "version" : "0.27"
+ "version" : "0.30"
},
"XS::Parse::Keyword" : {
"file" : "lib/XS/Parse/Keyword.pm",
- "version" : "0.27"
+ "version" : "0.30"
},
"XS::Parse::Keyword::Builder" : {
"file" : "lib/XS/Parse/Keyword/Builder.pm",
- "version" : "0.27"
+ "version" : "0.30"
}
},
"release_status" : "stable",
@@ -61,6 +61,6 @@
"http://dev.perl.org/licenses/"
]
},
- "version" : "0.27",
- "x_serialization_backend" : "JSON::PP version 4.06"
+ "version" : "0.30",
+ "x_serialization_backend" : "JSON::PP version 4.07"
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/META.yml
new/XS-Parse-Keyword-0.30/META.yml
--- old/XS-Parse-Keyword-0.27/META.yml 2022-10-31 23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/META.yml 2022-12-03 15:51:44.000000000 +0100
@@ -19,19 +19,19 @@
provides:
XS::Parse::Infix:
file: lib/XS/Parse/Infix.pm
- version: '0.27'
+ version: '0.30'
XS::Parse::Infix::Builder:
file: lib/XS/Parse/Infix/Builder.pm
- version: '0.27'
+ version: '0.30'
XS::Parse::Keyword:
file: lib/XS/Parse/Keyword.pm
- version: '0.27'
+ version: '0.30'
XS::Parse::Keyword::Builder:
file: lib/XS/Parse/Keyword/Builder.pm
- version: '0.27'
+ version: '0.30'
requires:
perl: '5.014'
resources:
license: http://dev.perl.org/licenses/
-version: '0.27'
+version: '0.30'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/README
new/XS-Parse-Keyword-0.30/README
--- old/XS-Parse-Keyword-0.27/README 2022-10-31 23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/README 2022-12-03 15:51:44.000000000 +0100
@@ -260,12 +260,67 @@
XPK_ANONSUB
- atomic, emits op.
+ atomic, emits cv.
A brace-delimited block of code is expected, and assembled into the
body of a new anonymous subroutine. This will be passed as a protosub
CV in the cv field.
+ XPK_STAGED_ANONSUB
+
+ XPK_STAGED_ANONSUB(stages ...)
+
+ structural, emits cv.
+
+ A variant of XPK_ANONSUB which accepts additional function pointers to
+ be invoked at various points during parsing and compilation. These can
+ be used to interrupt the normal parsing in a manner similar to
+ XS::Parse::Sublike, though currently somewhat less flexibly.
+
+ The stages list may contain elements of the following types. Not every
+ stage must be present, but any that are present must be in the
+ following order. Multiple copies of each stage are permitted; they are
+ invoked in the written order, with parser code happening inbetween.
+
+ XPK_ANONSUB_PREPARE
+
+ XPK_ANONSUB_PREPARE(&callback)
+
+ atomic, emits nothing.
+
+ Invokes the callback before start_subparse().
+
+ XPK_ANONSUB_START
+
+ XPK_ANONSUB_START(&callback)
+
+ atomic, emits nothing.
+
+ Invokes the callback after block_start() but before parsing the
+ actual block contents.
+
+ XPK_ANONSUB_END
+
+ OP *op_wrapper_callback(pTHX_ OP *o, void *hookdata);
+
+ XPK_ANONSUB_END(&op_wrapper_callback)
+
+ atomic, emits nothing.
+
+ Invokes the callback after parsing the block contents but before
+ calling block_end(). The callback may modify the optree if required
+ and return a new one.
+
+ XPK_ANONSUB_WRAP
+
+ XPK_ANONSUB_WRAP(&op_wrapper_callback)
+
+ atomic, emits nothing.
+
+ Invokes the callback after block_end() but before passing the optree
+ to newATTRSUB(). The callback may modify the optree if required and
+ return a new one.
+
XPK_ARITHEXPR
atomic, emits op.
@@ -294,6 +349,20 @@
Variants of XPK_TERMEXPR which puts the expression in void or scalar
context.
+ XPK_PREFIXED_TERMEXPR_ENTERLEAVE
+
+ XPK_PREFIXED_TERMEXPR_ENTERLEAVE(pieces ...)
+
+ A variant of XPK_TERMEXPR which expects a sequence pieces first before
+ it parses a term expression, similar to how
+ XPK_PREFIXED_BLOCK_ENTERLEAVE works. The entire operation is wrapped in
+ an ENTER/LEAVE pair.
+
+ This is intended just for use of XPK_SETUP pieces as prefixes. Any
+ other pieces which actually parse real input are likely to cause
+ overly-complex, subtle, or outright ambiguous grammars, and should be
+ avoided.
+
XPK_LISTEXPR
atomic, emits op.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/XSParseInfix.h
new/XS-Parse-Keyword-0.30/XSParseInfix.h
--- old/XS-Parse-Keyword-0.27/XSParseInfix.h 2022-10-31 23:09:16.000000000
+0100
+++ new/XS-Parse-Keyword-0.30/XSParseInfix.h 2022-12-03 15:51:44.000000000
+0100
@@ -71,6 +71,8 @@
const struct XSParseInfixHooks *hooks;
void *hookdata;
+
+ enum XSParseInfixClassification cls;
};
static bool (*parse_infix_func)(pTHX_ enum XSParseInfixSelection select,
struct XSParseInfixInfo **infop);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/XSParseKeyword.h
new/XS-Parse-Keyword-0.30/XSParseKeyword.h
--- old/XS-Parse-Keyword-0.27/XSParseKeyword.h 2022-10-31 23:09:16.000000000
+0100
+++ new/XS-Parse-Keyword-0.30/XSParseKeyword.h 2022-12-03 15:51:44.000000000
+0100
@@ -7,10 +7,12 @@
struct XSParseKeywordPieceType {
int type;
union {
- char c; /* LITERALCHAR */
- const char *str; /* LITERALSTR */
+ char c; /* LITERALCHAR */
+ const char *str; /* LITERALSTR */
const struct XSParseKeywordPieceType *pieces; /* SCOPEs */
- void (*callback)(pTHX_ void *hookdata); /*
SETUP */
+ void (*callback)(pTHX_ void *hookdata); /* SETUP, ANONSUB
PREPARE+START */
+
+ OP *(*op_wrap_callback)(pTHX_ OP *o, void *hookdata);
} u;
};
@@ -46,6 +48,11 @@
XS_PARSE_KEYWORD_SETUP = 0x70, /* invokes callback, emits nothing */
+ XS_PARSE_KEYWORD_ANONSUB_PREPARE, /* invokes callback, emits nothing */
+ XS_PARSE_KEYWORD_ANONSUB_START, /* invokes callback, emits nothing */
+ XS_PARSE_KEYWORD_ANONSUB_END, /* invokes op_wrap_callback, emits
nothing */
+ XS_PARSE_KEYWORD_ANONSUB_WRAP, /* invokes op_wrap_callback, emits
nothing */
+
XS_PARSE_KEYWORD_SEQUENCE = 0x80, /* contained */
XS_PARSE_KEYWORD_REPEATED, /* i, contained */
XS_PARSE_KEYWORD_CHOICE, /* i, contained */
@@ -95,6 +102,14 @@
#define XPK_ANONSUB {.type = XS_PARSE_KEYWORD_ANONSUB}
+#define XPK_ANONSUB_PREPARE(func) {.type = XS_PARSE_KEYWORD_ANONSUB_PREPARE,
.u.callback = func}
+#define XPK_ANONSUB_START(func) {.type = XS_PARSE_KEYWORD_ANONSUB_START,
.u.callback = func}
+#define XPK_ANONSUB_END(func) {.type = XS_PARSE_KEYWORD_ANONSUB_END,
.u.op_wrap_callback = func}
+#define XPK_ANONSUB_WRAP(func) {.type = XS_PARSE_KEYWORD_ANONSUB_WRAP,
.u.op_wrap_callback = func}
+
+#define XPK_STAGED_ANONSUB(...) \
+ {.type = XS_PARSE_KEYWORD_ANONSUB, .u.pieces = (const struct
XSParseKeywordPieceType []){ __VA_ARGS__, {0} }}
+
#define XPK_ARITHEXPR_flags(flags) {.type = XS_PARSE_KEYWORD_ARITHEXPR|(flags)}
#define XPK_ARITHEXPR XPK_ARITHEXPR_flags(0)
#define XPK_ARITHEXPR_VOIDCTX XPK_ARITHEXPR_flags(XPK_TYPEFLAG_G_VOID)
@@ -107,6 +122,10 @@
#define XPK_LISTEXPR XPK_LISTEXPR_flags(0)
#define XPK_LISTEXPR_LISTCTX XPK_LISTEXPR_flags(XPK_TYPEFLAG_G_LIST)
+#define XPK_PREFIXED_TERMEXPR_flags(flags,...) \
+ {.type = XS_PARSE_KEYWORD_TERMEXPR|(flags), .u.pieces = (const struct
XSParseKeywordPieceType []){ __VA_ARGS__, {0} }}
+#define XPK_PREFIXED_TERMEXPR_ENTERLEAVE(...)
XPK_PREFIXED_TERMEXPR_flags(XPK_TYPEFLAG_ENTERLEAVE, __VA_ARGS__)
+
#define XPK_IDENT {.type = XS_PARSE_KEYWORD_IDENT
}
#define XPK_IDENT_OPT {.type = XS_PARSE_KEYWORD_IDENT
|XPK_TYPEFLAG_OPT}
#define XPK_PACKAGENAME {.type = XS_PARSE_KEYWORD_PACKAGENAME
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix/Builder.pm
new/XS-Parse-Keyword-0.30/lib/XS/Parse/Infix/Builder.pm
--- old/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix/Builder.pm 2022-10-31
23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/lib/XS/Parse/Infix/Builder.pm 2022-12-03
15:51:44.000000000 +0100
@@ -3,7 +3,7 @@
#
# (C) Paul Evans, 2021 -- [email protected]
-package XS::Parse::Infix::Builder 0.27;
+package XS::Parse::Infix::Builder 0.30;
use v5.14;
use warnings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix/Builder_data.pm.PL
new/XS-Parse-Keyword-0.30/lib/XS/Parse/Infix/Builder_data.pm.PL
--- old/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix/Builder_data.pm.PL
2022-10-31 23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/lib/XS/Parse/Infix/Builder_data.pm.PL
2022-12-03 15:51:44.000000000 +0100
@@ -28,7 +28,7 @@
<$in_h> } );
__DATA__
-package XS::Parse::Infix::Builder_data 0.27;
+package XS::Parse::Infix::Builder_data 0.30;
use v5.14;
use warnings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix.pm
new/XS-Parse-Keyword-0.30/lib/XS/Parse/Infix.pm
--- old/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix.pm 2022-10-31
23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/lib/XS/Parse/Infix.pm 2022-12-03
15:51:44.000000000 +0100
@@ -3,7 +3,7 @@
#
# (C) Paul Evans, 2021-2022 -- [email protected]
-package XS::Parse::Infix 0.27;
+package XS::Parse::Infix 0.30;
use v5.14;
use warnings;
@@ -72,6 +72,8 @@
bool parse_infix(enum XSParseInfixSelection select, struct XSParseInfixInfo
**infop);
+I<Since version 0.27.>
+
This function attempts to parse syntax for an infix operator from the current
parser position. If it is successful, it fills in the variable pointed to by
I<infop> with a pointer to the actual information structure and returns
@@ -109,6 +111,8 @@
struct XSParseInfixHooks *hooks;
void *hookdata;
+
+ enum XSParseInfixClassification cls; /* since version 0.28 */
};
If the operator name contains any non-ASCII characters they are presumed to be
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword/Builder.pm
new/XS-Parse-Keyword-0.30/lib/XS/Parse/Keyword/Builder.pm
--- old/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword/Builder.pm 2022-10-31
23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/lib/XS/Parse/Keyword/Builder.pm 2022-12-03
15:51:44.000000000 +0100
@@ -3,7 +3,7 @@
#
# (C) Paul Evans, 2021 -- [email protected]
-package XS::Parse::Keyword::Builder 0.27;
+package XS::Parse::Keyword::Builder 0.30;
use v5.14;
use warnings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword/Builder_data.pm.PL
new/XS-Parse-Keyword-0.30/lib/XS/Parse/Keyword/Builder_data.pm.PL
--- old/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword/Builder_data.pm.PL
2022-10-31 23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/lib/XS/Parse/Keyword/Builder_data.pm.PL
2022-12-03 15:51:44.000000000 +0100
@@ -28,7 +28,7 @@
<$in_h> } );
__DATA__
-package XS::Parse::Keyword::Builder_data 0.27;
+package XS::Parse::Keyword::Builder_data 0.30;
use v5.14;
use warnings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword.pm
new/XS-Parse-Keyword-0.30/lib/XS/Parse/Keyword.pm
--- old/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword.pm 2022-10-31
23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/lib/XS/Parse/Keyword.pm 2022-12-03
15:51:44.000000000 +0100
@@ -3,7 +3,7 @@
#
# (C) Paul Evans, 2021-2022 -- [email protected]
-package XS::Parse::Keyword 0.27;
+package XS::Parse::Keyword 0.30;
use v5.14;
use warnings;
@@ -277,12 +277,71 @@
=head2 XPK_ANONSUB
-I<atomic, emits op.>
+I<atomic, emits cv.>
A brace-delimited block of code is expected, and assembled into the body of a
new anonymous subroutine. This will be passed as a protosub CV in the I<cv>
field.
+=head2 XPK_STAGED_ANONSUB
+
+ XPK_STAGED_ANONSUB(stages ...)
+
+I<structural, emits cv.>
+
+A variant of C<XPK_ANONSUB> which accepts additional function pointers to be
+invoked at various points during parsing and compilation. These can be used to
+interrupt the normal parsing in a manner similar to L<XS::Parse::Sublike>,
+though currently somewhat less flexibly.
+
+The I<stages> list may contain elements of the following types. Not every
+stage must be present, but any that are present must be in the following
+order. Multiple copies of each stage are permitted; they are invoked in the
+written order, with parser code happening inbetween.
+
+=over 4
+
+=item XPK_ANONSUB_PREPARE
+
+ XPK_ANONSUB_PREPARE(&callback)
+
+I<atomic, emits nothing.>
+
+Invokes the callback before C<start_subparse()>.
+
+=item XPK_ANONSUB_START
+
+ XPK_ANONSUB_START(&callback)
+
+I<atomic, emits nothing.>
+
+Invokes the callback after C<block_start()> but before parsing the actual
+block contents.
+
+=item XPK_ANONSUB_END
+
+ OP *op_wrapper_callback(pTHX_ OP *o, void *hookdata);
+
+ XPK_ANONSUB_END(&op_wrapper_callback)
+
+I<atomic, emits nothing.>
+
+Invokes the callback after parsing the block contents but before calling
+C<block_end()>. The callback may modify the optree if required and return a
+new one.
+
+=item XPK_ANONSUB_WRAP
+
+ XPK_ANONSUB_WRAP(&op_wrapper_callback)
+
+I<atomic, emits nothing.>
+
+Invokes the callback after C<block_end()> but before passing the optree to
+C<newATTRSUB()>. The callback may modify the optree if required and return a
+new one.
+
+=back
+
=head2 XPK_ARITHEXPR
I<atomic, emits op.>
@@ -309,6 +368,18 @@
Variants of C<XPK_TERMEXPR> which puts the expression in void or scalar
context.
+=head2 XPK_PREFIXED_TERMEXPR_ENTERLEAVE
+
+ XPK_PREFIXED_TERMEXPR_ENTERLEAVE(pieces ...)
+
+A variant of C<XPK_TERMEXPR> which expects a sequence pieces first before it
+parses a term expression, similar to how C<XPK_PREFIXED_BLOCK_ENTERLEAVE>
+works. The entire operation is wrapped in an C<ENTER>/C<LEAVE> pair.
+
+This is intended just for use of C<XPK_SETUP> pieces as prefixes. Any other
+pieces which actually parse real input are likely to cause overly-complex,
+subtle, or outright ambiguous grammars, and should be avoided.
+
=head2 XPK_LISTEXPR
I<atomic, emits op.>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword.xs
new/XS-Parse-Keyword-0.30/lib/XS/Parse/Keyword.xs
--- old/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword.xs 2022-10-31
23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/lib/XS/Parse/Keyword.xs 2022-12-03
15:51:44.000000000 +0100
@@ -16,39 +16,6 @@
#include "keyword.h"
#include "infix.h"
-/* v0 hooks lacked wrapper_func_name */
-struct XSParseInfixHooks_v0 {
- U32 flags;
- enum XSParseInfixClassification cls;
-
- const char *permit_hintkey;
- bool (*permit) (pTHX_ void *hookdata);
-
- OP *(*new_op)(pTHX_ U32 flags, OP *lhs, OP *rhs, void *hookdata);
- OP *(*ppaddr)(pTHX);
-};
-
-static void XSParseInfix_register_v0(pTHX_ const char *opname, const struct
XSParseInfixHooks_v0 *hooks_v0, void *hookdata)
-{
- warn("XSParseInfix ABI version 0 is deprecated and will soon be removed");
-
- struct XSParseInfixHooks *hooks;
- Newx(hooks, 1, struct XSParseInfixHooks);
-
- hooks->flags = hooks_v0->flags | (1<<15); /* NO_PARSEDATA */
- hooks->cls = hooks_v0->cls;
-
- hooks->wrapper_func_name = NULL;
-
- hooks->permit_hintkey = hooks_v0->permit_hintkey;
- hooks->permit = hooks_v0->permit;
- hooks->new_op = (OP *(*)(pTHX_ U32, OP *, OP *, SV **, void
*))hooks_v0->new_op;
- hooks->ppaddr = hooks_v0->ppaddr;
- hooks->parse = NULL;
-
- XSParseInfix_register(aTHX_ opname, hooks, hookdata);
-}
-
/* v1 hooks.newop did not pass parsedata */
struct XSParseInfixHooks_v1 {
U16 flags;
@@ -108,12 +75,11 @@
XSParseKeyword_boot(aTHX);
- sv_setiv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/ABIVERSION_MIN", 1), 0);
+ sv_setiv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/ABIVERSION_MIN", 1), 1);
sv_setiv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/ABIVERSION_MAX", 1),
XSPARSEINFIX_ABI_VERSION);
sv_setuv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/parse()@2", 1),
PTR2UV(&XSParseInfix_parse));
sv_setuv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/new_op()@0", 1),
PTR2UV(&XSParseInfix_new_op));
- sv_setuv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/register()@0", 1),
PTR2UV(&XSParseInfix_register_v0));
sv_setuv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/register()@1", 1),
PTR2UV(&XSParseInfix_register_v1));
sv_setuv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/register()@2", 1),
PTR2UV(&XSParseInfix_register));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/src/infix.c
new/XS-Parse-Keyword-0.30/src/infix.c
--- old/XS-Parse-Keyword-0.27/src/infix.c 2022-10-31 23:09:16.000000000
+0100
+++ new/XS-Parse-Keyword-0.30/src/infix.c 2022-12-03 15:51:44.000000000
+0100
@@ -136,13 +136,13 @@
struct XSParseInfixInfo info;
STRLEN oplen;
- enum XSParseInfixClassification cls;
struct HooksAndData hd;
STRLEN permit_hintkey_len;
int opname_is_WIDE : 1;
+ int opname_is_ident : 1;
};
static struct Registration *registrations;
@@ -345,8 +345,11 @@
continue;
if(!strnEQ(buf, reg->info.opname, reg->oplen))
continue;
-
- if(!(selection & (1 << reg->cls)))
+ /* If the operator name is an identifer then we don't want to capture a
+ * longer identifier from the incoming source of which this is just a
+ * prefix
+ */
+ if(reg->opname_is_ident && isIDCONT_utf8_safe(buf + reg->oplen,
PL_parser->bufend))
continue;
if(reg->hd.hooks && reg->hd.hooks->permit_hintkey &&
@@ -357,6 +360,12 @@
!(*reg->hd.hooks->permit)(aTHX_ reg->hd.data))
continue;
+ /* At this point we're committed to this being the best match of operator.
+ * Is it selected by the filter?
+ */
+ if(!(selection & (1 << reg->info.cls)))
+ return FALSE;
+
*infop = ®->info;
lex_read_to(PL_parser->bufptr + reg->oplen);
@@ -636,9 +645,9 @@
reg->info.opname = savepv(opname);
reg->info.opcode = opcode;
reg->info.hooks = NULL;
+ reg->info.cls = cls;
reg->oplen = strlen(opname);
- reg->cls = cls;
reg->hd.hooks = NULL;
reg->hd.data = NULL;
@@ -653,6 +662,27 @@
void XSParseInfix_register(pTHX_ const char *opname, const struct
XSParseInfixHooks *hooks, void *hookdata)
{
+ STRLEN oplen = strlen(opname);
+ const char *opname_end = opname + oplen;
+ bool opname_is_ident = isIDFIRST_utf8_safe(opname, opname_end);
+
+ {
+ const char *s = opname;
+ s += UTF8SKIP(s);
+
+ while(s < opname_end) {
+ if(opname_is_ident) {
+ if(!isIDCONT_utf8_safe(s, opname_end))
+ croak("Infix operator name that starts with an identifier may not
have non-identifier characters in it");
+ }
+ else {
+ if(isIDFIRST_utf8_safe(s, opname_end))
+ croak("Infix operator name that does not start with an identifer may
not have identifier characters in it");
+ }
+ s += UTF8SKIP(s);
+ }
+ }
+
switch(hooks->flags) {
case (1<<15):
/* undocumented internal flag to indicate v1-compatible ->new_op hook
function */
@@ -730,9 +760,10 @@
reg->info.opcode = OP_CUSTOM;
reg->info.hooks = hooks;
reg->info.hookdata = hookdata;
+ reg->info.cls = hooks->cls;
- reg->oplen = strlen(opname);
- reg->cls = hooks->cls;
+ reg->oplen = oplen;
+ reg->opname_is_ident = opname_is_ident;
reg->hd.hooks = hooks;
reg->hd.data = hookdata;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/src/keyword.c
new/XS-Parse-Keyword-0.30/src/keyword.c
--- old/XS-Parse-Keyword-0.27/src/keyword.c 2022-10-31 23:09:16.000000000
+0100
+++ new/XS-Parse-Keyword-0.30/src/keyword.c 2022-12-03 15:51:44.000000000
+0100
@@ -342,15 +342,36 @@
croak("TODO: probe_piece on type=%d\n", type);
}
+static void parse_prefix_pieces(pTHX_ SV *argsv, size_t *argidx, const struct
XSParseKeywordPieceType *pieces, void *hookdata)
+{
+ 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++;
+ }
+
+ intro_my(); /* in case any of the pieces was XPK_LEXVAR_MY */
+}
+
static void parse_piece(pTHX_ SV *argsv, size_t *argidx, const struct
XSParseKeywordPieceType *piece, void *hookdata)
{
int argi = *argidx;
- if(argi >= (SvLEN(argsv) / sizeof(XSParseKeywordPiece)))
- SvGROW(argsv, SvLEN(argsv) * 2);
+#define CHECK_GROW_ARGSV \
+ do { \
+ if(argi >= (SvLEN(argsv) / sizeof(XSParseKeywordPiece))) \
+ SvGROW(argsv, SvLEN(argsv) * 2); \
+ } while(0)
#define THISARG ((XSParseKeywordPiece *)SvPVX(argsv))[argi]
+ CHECK_GROW_ARGSV;
+
THISARG.line =
#if HAVE_PERL_VERSION(5, 20, 0)
/* on perl 5.20 onwards, CopLINE(PL_curcop) is only set at runtime; during
@@ -399,27 +420,11 @@
I32 save_ix = block_start(1);
if(piece->u.pieces) {
- /* The prefix 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++;
- }
+ parse_prefix_pieces(aTHX_ argsv, argidx, piece->u.pieces, hookdata);
if(*argidx > argi) {
argi = *argidx;
-
- if(argi >= (SvLEN(argsv) / sizeof(XSParseKeywordPiece)))
- SvGROW(argsv, SvLEN(argsv) * 2);
-
- intro_my(); /* in case any of the pieces was XPK_LEXVAR_MY */
+ CHECK_GROW_ARGSV;
}
}
@@ -448,16 +453,39 @@
case XS_PARSE_KEYWORD_ANONSUB:
{
+ const struct XSParseKeywordPieceType *stages = piece->u.pieces;
+
+ while(stages && stages->type == XS_PARSE_KEYWORD_ANONSUB_PREPARE) {
+ (*stages->u.callback)(aTHX_ hookdata);
+ stages++;
+ }
+
I32 floor_ix = start_subparse(FALSE, CVf_ANON);
SAVEFREESV(PL_compcv);
I32 save_ix = block_start(0);
+
+ while(stages && stages->type == XS_PARSE_KEYWORD_ANONSUB_START) {
+ (*stages->u.callback)(aTHX_ hookdata);
+ stages++;
+ }
+
OP *body = parse_block(0);
CHECK_PARSEFAIL;
+ while(stages && stages->type == XS_PARSE_KEYWORD_ANONSUB_END) {
+ body = (*stages->u.op_wrap_callback)(aTHX_ body, hookdata);
+ stages++;
+ }
+
SvREFCNT_inc(PL_compcv);
body = block_end(save_ix, body);
+ while(stages && stages->type == XS_PARSE_KEYWORD_ANONSUB_WRAP) {
+ body = (*stages->u.op_wrap_callback)(aTHX_ body, hookdata);
+ stages++;
+ }
+
THISARG.cv = newATTRSUB(floor_ix, NULL, NULL, NULL, body);
(*argidx)++;
return;
@@ -465,6 +493,19 @@
case XS_PARSE_KEYWORD_ARITHEXPR:
case XS_PARSE_KEYWORD_TERMEXPR:
+ {
+ if(is_enterleave)
+ ENTER;
+
+ if(piece->u.pieces) {
+ parse_prefix_pieces(aTHX_ argsv, argidx, piece->u.pieces, hookdata);
+
+ if(*argidx > argi) {
+ argi = *argidx;
+ CHECK_GROW_ARGSV;
+ }
+ }
+
/* TODO: This auto-parens behaviour ought to be tuneable, depend on how
* many args, open at i=0 and close at i=MAX, etc...
*/
@@ -495,7 +536,12 @@
THISARG.op = op_contextualize(THISARG.op, want);
(*argidx)++;
+
+ if(is_enterleave)
+ LEAVE;
+
return;
+ }
case XS_PARSE_KEYWORD_LISTEXPR:
THISARG.op = parse_listexpr(0);
@@ -787,9 +833,13 @@
if(hooks->build) {
/* build function takes an array of pointers to piece structs, so we can
* add new fields to the end of them without breaking back-compat. */
- SV *ptrssv = newSV(argidx * sizeof(XSParseKeywordPiece *));
- XSParseKeywordPiece **argptrs = (XSParseKeywordPiece **)SvPVX(ptrssv);
- SAVEFREESV(ptrssv);
+ XSParseKeywordPiece **argptrs = NULL;
+ if(argidx) {
+ SV *ptrssv = newSV(argidx * sizeof(XSParseKeywordPiece *));
+ SAVEFREESV(ptrssv);
+
+ argptrs = (XSParseKeywordPiece **)SvPVX(ptrssv);
+ }
int i;
for(i = 0; i < argidx; i++)
@@ -813,11 +863,13 @@
if(ret && (ret != KEYWORD_PLUGIN_EXPR))
yycroakf("Expected parse function for '%s' keyword to return
KEYWORD_PLUGIN_EXPR but it did not",
reg->kwname);
+ break;
case XPK_FLAG_STMT:
if(ret && (ret != KEYWORD_PLUGIN_STMT))
yycroakf("Expected parse function for '%s' keyword to return
KEYWORD_PLUGIN_STMT but it did not",
reg->kwname);
+ break;
}
return ret;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/t/32pieces-anonsub.t
new/XS-Parse-Keyword-0.30/t/32pieces-anonsub.t
--- old/XS-Parse-Keyword-0.27/t/32pieces-anonsub.t 2022-10-31
23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/t/32pieces-anonsub.t 2022-12-03
15:51:44.000000000 +0100
@@ -16,4 +16,13 @@
is( $ret->(), "sub value", 'result of invoking' );
}
+{
+ my $ret = piecestagedanonsub { return "$VAR, world" };
+
+ is( ref $ret, "CODE", 'result of piecestagedanonsub is CODE reference' );
+ is( $ret->(), "Hello, world", 'result of invoking' );
+
+ is( $::STAGES, "PREPARE,START,END,WRAP", 'All ANONSUB stages were invoked'
);
+}
+
done_testing;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/t/33pieces-termexpr.t
new/XS-Parse-Keyword-0.30/t/33pieces-termexpr.t
--- old/XS-Parse-Keyword-0.27/t/33pieces-termexpr.t 2022-10-31
23:09:16.000000000 +0100
+++ new/XS-Parse-Keyword-0.30/t/33pieces-termexpr.t 2022-12-03
15:51:44.000000000 +0100
@@ -35,4 +35,9 @@
is( $ret, "(x)y", 'termexpr treats (PARENS) as entire expression' );
}
+{
+ $ret = pieceprefixedtermexpr_VAR $VAR . ", world!";
+ is( $ret, "(Hello, world!)", 'result of pieceprefixedtermexpr_VAR' );
+}
+
done_testing;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.27/t/pieces.xs
new/XS-Parse-Keyword-0.30/t/pieces.xs
--- old/XS-Parse-Keyword-0.27/t/pieces.xs 2022-10-31 23:09:16.000000000
+0100
+++ new/XS-Parse-Keyword-0.30/t/pieces.xs 2022-12-03 15:51:44.000000000
+0100
@@ -134,6 +134,40 @@
sv_setpvs(PAD_SVl(padix), "Hello");
}
+static void callback_catpv_stages(pTHX_ const char *pv)
+{
+ SV *sv = get_sv("main::STAGES", GV_ADD);
+ if(!SvPOK(sv))
+ sv_setpvs(sv, "");
+
+ if(SvCUR(sv))
+ sv_catpvs(sv, ",");
+
+ sv_catpv(sv, pv);
+}
+
+static void callback_PREPARE(pTHX_ void *hookdata)
+{
+ callback_catpv_stages(aTHX_ "PREPARE");
+}
+
+static void callback_START(pTHX_ void *hookdata)
+{
+ callback_catpv_stages(aTHX_ "START");
+}
+
+static OP *callback_END(pTHX_ OP *o, void *hookdata)
+{
+ callback_catpv_stages(aTHX_ "END");
+ return o;
+}
+
+static OP *callback_WRAP(pTHX_ OP *o, void *hookdata)
+{
+ callback_catpv_stages(aTHX_ "WRAP");
+ return o;
+}
+
static const struct XSParseKeywordHooks hooks_block = {
.permit_hintkey = hintkey,
@@ -177,6 +211,19 @@
.build1 = &build_anonsub,
};
+static const struct XSParseKeywordHooks hooks_stagedanonsub = {
+ .permit_hintkey = hintkey,
+
+ .piece1 = XPK_STAGED_ANONSUB(
+ XPK_ANONSUB_PREPARE(&callback_PREPARE),
+ XPK_ANONSUB_START(&callback_START),
+ XPK_ANONSUB_START(&setup_block_VAR),
+ XPK_ANONSUB_END(&callback_END),
+ XPK_ANONSUB_WRAP(&callback_WRAP)
+ ),
+ .build1 = &build_anonsub,
+};
+
static const struct XSParseKeywordHooks hooks_arithexpr = {
.permit_hintkey = hintkey,
@@ -191,6 +238,13 @@
.build1 = &build_expr,
};
+static const struct XSParseKeywordHooks hooks_prefixedtermexpr_VAR = {
+ .permit_hintkey = hintkey,
+
+ .piece1 = XPK_PREFIXED_TERMEXPR_ENTERLEAVE( XPK_SETUP(&setup_block_VAR) ),
+ .build1 = &build_expr,
+};
+
static const struct XSParseKeywordHooks hooks_listexpr = {
.permit_hintkey = hintkey,
@@ -312,10 +366,15 @@
register_xs_parse_keyword("pieceprefixedblock_VAR",
&hooks_prefixedblock_VAR, "$VAR");
register_xs_parse_keyword("pieceanonsub", &hooks_anonsub, NULL);
+
+ register_xs_parse_keyword("piecestagedanonsub", &hooks_stagedanonsub,
"$VAR");
+
register_xs_parse_keyword("piecearithexpr", &hooks_arithexpr, NULL);
register_xs_parse_keyword("piecetermexpr", &hooks_termexpr, NULL);
register_xs_parse_keyword("piecelistexpr", &hooks_listexpr, NULL);
+ register_xs_parse_keyword("pieceprefixedtermexpr_VAR",
&hooks_prefixedtermexpr_VAR, "$VAR");
+
register_xs_parse_keyword("pieceident", &hooks_ident, NULL);
register_xs_parse_keyword("pieceident_opt", &hooks_ident_opt, NULL);
register_xs_parse_keyword("piecepkg", &hooks_packagename, NULL);