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 2025-01-12 11:09:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-XS-Parse-Keyword (Old) and /work/SRC/openSUSE:Factory/.perl-XS-Parse-Keyword.new.1881 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-XS-Parse-Keyword" Sun Jan 12 11:09:33 2025 rev:23 rq:1236285 version:0.470.0 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-XS-Parse-Keyword/perl-XS-Parse-Keyword.changes 2024-07-31 13:28:21.865513104 +0200 +++ /work/SRC/openSUSE:Factory/.perl-XS-Parse-Keyword.new.1881/perl-XS-Parse-Keyword.changes 2025-01-12 11:09:48.091683855 +0100 @@ -1,0 +2,23 @@ +Thu Dec 12 16:46:16 UTC 2024 - Tina Müller <timueller+p...@suse.de> + +- updated to 0.470.0 (0.47) + see /usr/share/doc/packages/perl-XS-Parse-Keyword/Changes + + 0.47 2024-11-25 + [BUGFIXES] + * Don't upset gcc 15, by ensuring that function pointer casts fully + specify argument types (RT157196) + 0.46 2024-09-03 + [CHANGES] + * Added `XPK_PREFIXED_TERMEXPR_ENTERLEAVE` + * Use module-specific rather than dist-specific dirs to store + `include/` files + 0.45 2024-08-29 + [CHANGES] + * Refuse to register operators that have neither `.new_op` nor + `.ppadd`, as these will never work + [BUGFIXES] + * Update for perl 5.41.3: `OP_SMARTMATCH` is now removed, so make + that registration conditional (RT155194) + +------------------------------------------------------------------- Old: ---- XS-Parse-Keyword-0.44.tar.gz New: ---- XS-Parse-Keyword-0.47.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-XS-Parse-Keyword.spec ++++++ --- /var/tmp/diff_new_pack.Eo6ofq/_old 2025-01-12 11:09:48.527701745 +0100 +++ /var/tmp/diff_new_pack.Eo6ofq/_new 2025-01-12 11:09:48.527701745 +0100 @@ -18,10 +18,10 @@ %define cpan_name XS-Parse-Keyword Name: perl-XS-Parse-Keyword -Version: 0.440.0 +Version: 0.470.0 Release: 0 -# 0.44 -> normalize -> 0.440.0 -%define cpan_version 0.44 +# 0.47 -> normalize -> 0.470.0 +%define cpan_version 0.47 License: Artistic-1.0 OR GPL-1.0-or-later Summary: XS functions to assist in parsing keyword syntax URL: https://metacpan.org/release/%{cpan_name} ++++++ XS-Parse-Keyword-0.44.tar.gz -> XS-Parse-Keyword-0.47.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/Build.PL new/XS-Parse-Keyword-0.47/Build.PL --- old/XS-Parse-Keyword-0.44/Build.PL 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/Build.PL 2024-11-25 17:42:13.000000000 +0100 @@ -6,7 +6,7 @@ use ExtUtils::CChecker 0.11; use Module::Build::with::XSTests; -my @extra_compiler_flags = qw( -Ishare/include -Ihax ); +my @extra_compiler_flags = qw( -Ishare-keyword/include -Ishare-infix/include -Ihax ); # Perl 5.36 made -std=c99 standard; before then we'll have to request it specially push @extra_compiler_flags, qw( -std=c99 ) if $^V lt v5.36.0; @@ -57,7 +57,10 @@ 'Module::Build' => '0.4004', # test_requires }, share_dir => { - dist => [ 'share' ], + module => { + "XS::Parse::Infix" => [ 'share-infix' ], + "XS::Parse::Keyword" => [ 'share-keyword' ], + }, }, license => 'perl', create_license => 1, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/Changes new/XS-Parse-Keyword-0.47/Changes --- old/XS-Parse-Keyword-0.44/Changes 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/Changes 2024-11-25 17:42:13.000000000 +0100 @@ -1,5 +1,25 @@ Revision history for XS-Parse-Keyword +0.47 2024-11-25 + [BUGFIXES] + * Don't upset gcc 15, by ensuring that function pointer casts fully + specify argument types (RT157196) + +0.46 2024-09-03 + [CHANGES] + * Added `XPK_PREFIXED_TERMEXPR_ENTERLEAVE` + * Use module-specific rather than dist-specific dirs to store + `include/` files + +0.45 2024-08-29 + [CHANGES] + * Refuse to register operators that have neither `.new_op` nor + `.ppadd`, as these will never work + + [BUGFIXES] + * Update for perl 5.41.3: `OP_SMARTMATCH` is now removed, so make + that registration conditional (RT155194) + 0.44 2024-07-19 [BUGFIXES] * `boot_xs_parse_infix()` has to load `XS/Parse/Infix.pm`, the perl diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/MANIFEST new/XS-Parse-Keyword-0.47/MANIFEST --- old/XS-Parse-Keyword-0.44/MANIFEST 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/MANIFEST 2024-11-25 17:42:13.000000000 +0100 @@ -23,8 +23,8 @@ META.json META.yml README -share/include/XSParseInfix.h -share/include/XSParseKeyword.h +share-infix/include/XSParseInfix.h +share-keyword/include/XSParseKeyword.h src/infix.c src/infix.h src/keyword.c diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/META.json new/XS-Parse-Keyword-0.47/META.json --- old/XS-Parse-Keyword-0.44/META.json 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/META.json 2024-11-25 17:42:13.000000000 +0100 @@ -41,19 +41,19 @@ "provides" : { "XS::Parse::Infix" : { "file" : "lib/XS/Parse/Infix.pm", - "version" : "0.44" + "version" : "0.47" }, "XS::Parse::Infix::Builder" : { "file" : "lib/XS/Parse/Infix/Builder.pm", - "version" : "0.44" + "version" : "0.47" }, "XS::Parse::Keyword" : { "file" : "lib/XS/Parse/Keyword.pm", - "version" : "0.44" + "version" : "0.47" }, "XS::Parse::Keyword::Builder" : { "file" : "lib/XS/Parse/Keyword/Builder.pm", - "version" : "0.44" + "version" : "0.47" } }, "release_status" : "stable", @@ -62,6 +62,6 @@ "http://dev.perl.org/licenses/" ] }, - "version" : "0.44", + "version" : "0.47", "x_serialization_backend" : "JSON::PP version 4.16" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/META.yml new/XS-Parse-Keyword-0.47/META.yml --- old/XS-Parse-Keyword-0.44/META.yml 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/META.yml 2024-11-25 17:42:13.000000000 +0100 @@ -19,20 +19,20 @@ provides: XS::Parse::Infix: file: lib/XS/Parse/Infix.pm - version: '0.44' + version: '0.47' XS::Parse::Infix::Builder: file: lib/XS/Parse/Infix/Builder.pm - version: '0.44' + version: '0.47' XS::Parse::Keyword: file: lib/XS/Parse/Keyword.pm - version: '0.44' + version: '0.47' XS::Parse::Keyword::Builder: file: lib/XS/Parse/Keyword/Builder.pm - version: '0.44' + version: '0.47' requires: File::ShareDir: '1.00' perl: '5.014' resources: license: http://dev.perl.org/licenses/ -version: '0.44' +version: '0.47' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/README new/XS-Parse-Keyword-0.47/README --- old/XS-Parse-Keyword-0.44/README 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/README 2024-11-25 17:42:13.000000000 +0100 @@ -155,7 +155,7 @@ parsing step is placed into the args or arg0 parameter to the invoked function, using a struct type consisting of the following fields: - typedef struct + typedef struct { union { OP *op; CV *cv; @@ -365,20 +365,6 @@ 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, XPK_LISTEXPR_OPT atomic, emits op. @@ -392,6 +378,21 @@ Variant of XPK_LISTEXPR which puts the expression in list context. + XPK_PREFIXED_TERMEXPR_ENTERLEAVE, XPK_PREFIXED_LISTEXPR_ENTERLEAVE + + XPK_PREFIXED_TERMEXPR_ENTERLEAVE(pieces ...) + XPK_PREFIXED_LISTEXPR_ENTERLEAVE(pieces ...) + + Variants of XPK_TERMEXPR or XPK_LISTEXPR which expect 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. + + These are 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_IDENT, XPK_IDENT_OPT atomic, can probe, emits sv. @@ -508,10 +509,10 @@ Various versions of the macro are provided, each using a different selection filter to choose certain available infix operators: - XPK_INFIX_RELATION # any relational operator - XPK_INFIX_EQUALITY # an equality operator like `==` or `eq` - XPK_INFIX_MATCH_NOSMART # any sort of "match"-like operator, except smartmatch - XPK_INFIX_MATCH_SMART # XPK_INFIX_MATCH_NOSMART plus smartmatch + XPK_INFIX_RELATION // any relational operator + XPK_INFIX_EQUALITY // an equality operator like `==` or `eq` + XPK_INFIX_MATCH_NOSMART // any sort of "match"-like operator, except smartmatch + XPK_INFIX_MATCH_SMART // XPK_INFIX_MATCH_NOSMART plus smartmatch XPK_LITERAL diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/hax/newOP_CUSTOM.c.inc new/XS-Parse-Keyword-0.47/hax/newOP_CUSTOM.c.inc --- old/XS-Parse-Keyword-0.44/hax/newOP_CUSTOM.c.inc 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/hax/newOP_CUSTOM.c.inc 2024-11-25 17:42:13.000000000 +0100 @@ -7,6 +7,9 @@ #define newOP_CUSTOM(func, flags) S_newOP_CUSTOM(aTHX_ func, flags) #define newUNOP_CUSTOM(func, flags, first) S_newUNOP_CUSTOM(aTHX_ func, flags, first) +#if HAVE_PERL_VERSION(5, 22, 0) +# define newUNOP_AUX_CUSTOM(func, flags, first, aux) S_newUNOP_AUX_CUSTOM(aTHX_ func, flags, first, aux) +#endif #define newSVOP_CUSTOM(func, flags, sv) S_newSVOP_CUSTOM(aTHX_ func, flags, sv) #define newBINOP_CUSTOM(func, flags, first, last) S_newBINOP_CUSTOM(aTHX_ func, flags, first, last) #define newLISTOP_CUSTOM(func, flags, first, last) S_newLISTOP_CUSTOM(aTHX_ func, flags, first, last) @@ -35,6 +38,20 @@ return (OP *)unop; } +#if HAVE_PERL_VERSION(5, 22, 0) +static OP *S_newUNOP_AUX_CUSTOM(pTHX_ OP *(*func)(pTHX), U32 flags, OP *first, UNOP_AUX_item *aux) +{ + UNOP_AUX *unop; +#if HAVE_PERL_VERSION(5,22,0) + unop = (UNOP_AUX *)newUNOP_AUX(OP_CUSTOM, flags, first, aux); +#else + croak("TODO: create newUNOP_AUX_CUSTOM"); +#endif + unop->op_ppaddr = func; + return (OP *)unop; +} +#endif + static OP *S_newSVOP_CUSTOM(pTHX_ OP *(*func)(pTHX), U32 flags, SV *sv) { SVOP *svop; @@ -132,15 +149,3 @@ return o; } - -#if HAVE_PERL_VERSION(5, 22, 0) -# define newUNOP_AUX_CUSTOM(func, flags, first, aux) S_newUNOP_AUX_CUSTOM(aTHX_ func, flags, first, aux) - -static OP *S_newUNOP_AUX_CUSTOM(pTHX_ OP *(*func)(pTHX), U32 flags, OP *first, UNOP_AUX_item *aux) -{ - UNOP_AUX *unop; - unop = (UNOP_AUX *)newUNOP_AUX(OP_CUSTOM, flags, first, aux); - unop->op_ppaddr = func; - return (OP *)unop; -} -#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/lib/XS/Parse/Infix/Builder.pm new/XS-Parse-Keyword-0.47/lib/XS/Parse/Infix/Builder.pm --- old/XS-Parse-Keyword-0.44/lib/XS/Parse/Infix/Builder.pm 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/lib/XS/Parse/Infix/Builder.pm 2024-11-25 17:42:13.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2021 -- leon...@leonerd.org.uk -package XS::Parse::Infix::Builder 0.44; +package XS::Parse::Infix::Builder 0.47; use v5.14; use warnings; @@ -14,6 +14,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + In F<Build.PL>: use XS::Parse::Infix::Builder; @@ -72,7 +74,9 @@ require File::ShareDir; require File::Spec; - return "-I" . File::Spec->catdir( File::ShareDir::dist_dir( "XS-Parse-Keyword" ), "include" ), + require XS::Parse::Infix; + + return "-I" . File::Spec->catdir( File::ShareDir::module_dir( "XS::Parse::Infix" ), "include" ), XS::Parse::Infix::Builder_data->BUILDER_CFLAGS; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/lib/XS/Parse/Infix/Builder_data.pm.PL new/XS-Parse-Keyword-0.47/lib/XS/Parse/Infix/Builder_data.pm.PL --- old/XS-Parse-Keyword-0.44/lib/XS/Parse/Infix/Builder_data.pm.PL 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/lib/XS/Parse/Infix/Builder_data.pm.PL 2024-11-25 17:42:13.000000000 +0100 @@ -23,7 +23,7 @@ =~ s/__BUILDER_CFLAGS__/$quoted_cflags/r ); __DATA__ -package XS::Parse::Infix::Builder_data 0.44; +package XS::Parse::Infix::Builder_data 0.47; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/lib/XS/Parse/Infix.pm new/XS-Parse-Keyword-0.47/lib/XS/Parse/Infix.pm --- old/XS-Parse-Keyword-0.44/lib/XS/Parse/Infix.pm 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/lib/XS/Parse/Infix.pm 2024-11-25 17:42:13.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2021-2024 -- leon...@leonerd.org.uk -package XS::Parse::Infix 0.44; +package XS::Parse::Infix 0.47; use v5.14; use warnings; @@ -60,6 +60,8 @@ =head1 CONSTANTS +=for highlighter language=perl + =head2 HAVE_PL_INFIX_PLUGIN if( XS::Parse::Infix::HAVE_PL_INFIX_PLUGIN ) { ... } @@ -165,6 +167,8 @@ =head1 XS FUNCTIONS +=for highlighter language=c + =head2 boot_xs_parse_infix void boot_xs_parse_infix(double ver); @@ -270,8 +274,12 @@ If set, the operator supports n-way list-associative syntax; written in the form +=for highlighter + OPERAND op OPERAND op OPERAND op ... +=for highlighter language=c + In this case, the custom operator will be a LISTOP rather than a BINOP, and every operand of the entire chain will be stored as a child op of it. The op function will need to know how many operands it is working on. There are two @@ -399,6 +407,8 @@ =head2 The Wrapper Function +=for highlighter language=perl + Additionally, if the C<wrapper_func_name> field is set to a string, this gives the (fully-qualified) name for a function to be generated as part of registering the operator. This newly-generated function will act as a wrapper diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/lib/XS/Parse/Keyword/Builder.pm new/XS-Parse-Keyword-0.47/lib/XS/Parse/Keyword/Builder.pm --- old/XS-Parse-Keyword-0.44/lib/XS/Parse/Keyword/Builder.pm 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/lib/XS/Parse/Keyword/Builder.pm 2024-11-25 17:42:13.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2021 -- leon...@leonerd.org.uk -package XS::Parse::Keyword::Builder 0.44; +package XS::Parse::Keyword::Builder 0.47; use v5.14; use warnings; @@ -14,6 +14,8 @@ =head1 SYNOPSIS +=for highlighter language=perl + In F<Build.PL>: use XS::Parse::Keyword::Builder; @@ -72,7 +74,9 @@ require File::ShareDir; require File::Spec; - return "-I" . File::Spec->catdir( File::ShareDir::dist_dir( "XS-Parse-Keyword" ), "include" ), + require XS::Parse::Keyword; + + return "-I" . File::Spec->catdir( File::ShareDir::module_dir( "XS::Parse::Keyword" ), "include" ), XS::Parse::Keyword::Builder_data->BUILDER_CFLAGS; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/lib/XS/Parse/Keyword/Builder_data.pm.PL new/XS-Parse-Keyword-0.47/lib/XS/Parse/Keyword/Builder_data.pm.PL --- old/XS-Parse-Keyword-0.44/lib/XS/Parse/Keyword/Builder_data.pm.PL 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/lib/XS/Parse/Keyword/Builder_data.pm.PL 2024-11-25 17:42:13.000000000 +0100 @@ -23,7 +23,7 @@ =~ s/__BUILDER_CFLAGS__/$quoted_cflags/r ); __DATA__ -package XS::Parse::Keyword::Builder_data 0.44; +package XS::Parse::Keyword::Builder_data 0.47; use v5.14; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/lib/XS/Parse/Keyword.pm new/XS-Parse-Keyword-0.47/lib/XS/Parse/Keyword.pm --- old/XS-Parse-Keyword-0.44/lib/XS/Parse/Keyword.pm 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/lib/XS/Parse/Keyword.pm 2024-11-25 17:42:13.000000000 +0100 @@ -3,7 +3,7 @@ # # (C) Paul Evans, 2021-2023 -- leon...@leonerd.org.uk -package XS::Parse::Keyword 0.44; +package XS::Parse::Keyword 0.47; use v5.14; use warnings; @@ -32,6 +32,8 @@ =head1 XS FUNCTIONS +=for highlighter language=c + =head2 boot_xs_parse_keyword void boot_xs_parse_keyword(double ver); @@ -172,7 +174,7 @@ parsing step is placed into the I<args> or I<arg0> parameter to the invoked function, using a C<struct> type consisting of the following fields: - typedef struct + typedef struct { union { OP *op; CV *cv; @@ -384,18 +386,6 @@ 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, XPK_LISTEXPR_OPT I<atomic, emits op.> @@ -409,6 +399,20 @@ Variant of C<XPK_LISTEXPR> which puts the expression in list context. +=head2 XPK_PREFIXED_TERMEXPR_ENTERLEAVE, XPK_PREFIXED_LISTEXPR_ENTERLEAVE + + XPK_PREFIXED_TERMEXPR_ENTERLEAVE(pieces ...) + XPK_PREFIXED_LISTEXPR_ENTERLEAVE(pieces ...) + +Variants of C<XPK_TERMEXPR> or C<XPK_LISTEXPR> which expect 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. + +These are 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_IDENT, XPK_IDENT_OPT I<atomic, can probe, emits sv.> @@ -450,9 +454,13 @@ value wrapped in parentheses. Whitespace is B<NOT> permitted between the name and value, as per standard Perl parsing rules. +=for highlighter language=perl + :attrname :attrname(value) +=for highlighter language=c + The I<i> field indicates how many attributes were found. That number of additional arguments are then passed, each containing two SVs in the I<attr.name> and I<attr.value> fields. This number may be zero. @@ -523,10 +531,10 @@ Various versions of the macro are provided, each using a different selection filter to choose certain available infix operators: - XPK_INFIX_RELATION # any relational operator - XPK_INFIX_EQUALITY # an equality operator like `==` or `eq` - XPK_INFIX_MATCH_NOSMART # any sort of "match"-like operator, except smartmatch - XPK_INFIX_MATCH_SMART # XPK_INFIX_MATCH_NOSMART plus smartmatch + XPK_INFIX_RELATION // any relational operator + XPK_INFIX_EQUALITY // an equality operator like `==` or `eq` + XPK_INFIX_MATCH_NOSMART // any sort of "match"-like operator, except smartmatch + XPK_INFIX_MATCH_SMART // XPK_INFIX_MATCH_NOSMART plus smartmatch =head2 XPK_LITERAL diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/share/include/XSParseInfix.h new/XS-Parse-Keyword-0.47/share/include/XSParseInfix.h --- old/XS-Parse-Keyword-0.44/share/include/XSParseInfix.h 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/share/include/XSParseInfix.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,149 +0,0 @@ -#ifndef __XS_PARSE_INFIX_H__ -#define __XS_PARSE_INFIX_H__ - -#define XSPARSEINFIX_ABI_VERSION 2 - -/* Infix operator classifications */ -/* No built-in operators use the _MISC categories, but they are provided for - * custom infix operators to use so they are still found by selections */ -enum XSParseInfixClassification { - XPI_CLS_NONE = 0, - XPI_CLS_PREDICATE, /* any boolean-returning operator */ - XPI_CLS_RELATION, /* ... any predicate that is typewise symmetric */ - XPI_CLS_EQUALITY, /* ... any relation that is true for (x == x) and false otherwise */ - XPI_CLS_SMARTMATCH, /* ... the predicate smartmatch (~~) */ - XPI_CLS_MATCHRE, /* ... the predicate regexp match (=~) */ - XPI_CLS_ISA, /* ... the predicate instance of (isa) */ - XPI_CLS_MATCH_MISC, /* ... any other match-like predicate */ - XPI_CLS_ORDERING, /* cmp or <=> */ - - /* Since the _MISC categories never turn up in selections, put them at high - * index so as to leave space for more */ - XPI_CLS_LOW_MISC = 0x80, /* an operator at low precedence */ - XPI_CLS_LOGICAL_OR_LOW_MISC, - XPI_CLS_LOGICAL_AND_LOW_MISC, - XPI_CLS_ASSIGN_MISC, - XPI_CLS_LOGICAL_OR_MISC, - XPI_CLS_LOGICAL_AND_MISC, - XPI_CLS_ADD_MISC, /* an operator at addition-like precedence */ - XPI_CLS_MUL_MISC, /* an operator at multiplication-like precedence */ - XPI_CLS_POW_MISC, /* an operator at power exponentiation-like precedence */ - XPI_CLS_HIGH_MISC, /* an operator at high precedence */ -}; - -enum XSParseInfixSelection { - XPI_SELECT_ANY, - XPI_SELECT_PREDICATE, /* any predicate */ - XPI_SELECT_RELATION, /* any relation */ - XPI_SELECT_EQUALITY, /* any equality */ - XPI_SELECT_ORDERING, /* any ordering */ - - XPI_SELECT_MATCH_NOSMART, /* any equality or other match operator, including smartmatch */ - XPI_SELECT_MATCH_SMART, /* any equality or other match operator, not including smartmatch */ -}; - -/* flags */ -enum { - XPI_FLAG_LISTASSOC = (1<<0), -}; - -/* lhs_flags, rhs_flags */ -enum { - XPI_OPERAND_TERM_LIST = 6, /* term in list context */ - XPI_OPERAND_LIST = 7, /* list in list context */ - - /* Other bitflags */ - XPI_OPERAND_ONLY_LOOK = (1<<3), -}; - -struct XSParseInfixHooks { - U16 flags; - U8 lhs_flags, rhs_flags; - enum XSParseInfixClassification cls; - - const char *wrapper_func_name; - - /* These two hooks are ANDed together; both must pass, if present */ - const char *permit_hintkey; - bool (*permit) (pTHX_ void *hookdata); - - /* These hooks are alternatives; the first one defined is used */ - OP *(*new_op)(pTHX_ U32 flags, OP *lhs, OP *rhs, SV **parsedata, void *hookdata); - OP *(*ppaddr)(pTHX); /* A pp func used directly in newBINOP_custom() */ - - /* optional */ - void (*parse)(pTHX_ U32 flags, SV **parsedata, void *hookdata); -}; - -struct XSParseInfixInfo { - const char *opname; - OPCODE opcode; - - const struct XSParseInfixHooks *hooks; - void *hookdata; - - enum XSParseInfixClassification cls; -}; - -static bool (*parse_infix_func)(pTHX_ enum XSParseInfixSelection select, struct XSParseInfixInfo **infop); -#define parse_infix(select, infop) S_parse_infix(aTHX_ select, infop) -static bool S_parse_infix(pTHX_ enum XSParseInfixSelection select, struct XSParseInfixInfo **infop) -{ - if(!parse_infix_func) - croak("Must call boot_xs_parse_infix() first"); - - struct XSParseInfixInfo *infocopy; - - return (*parse_infix_func)(aTHX_ select, infop); -} - -static OP *(*xs_parse_infix_new_op_func)(pTHX_ const struct XSParseInfixInfo *info, U32 flags, OP *lhs, OP *rhs); -#define xs_parse_infix_new_op(info, flags, lhs, rhs) S_xs_parse_infix_new_op(aTHX_ info, flags, lhs, rhs) -static OP *S_xs_parse_infix_new_op(pTHX_ const struct XSParseInfixInfo *info, U32 flags, OP *lhs, OP *rhs) -{ - if(!xs_parse_infix_new_op_func) - croak("Must call boot_xs_parse_infix() first"); - - return (*xs_parse_infix_new_op_func)(aTHX_ info, flags, lhs, rhs); -} - -static void (*register_xs_parse_infix_func)(pTHX_ const char *kw, const struct XSParseInfixHooks *hooks, void *hookdata); -#define register_xs_parse_infix(opname, hooks, hookdata) S_register_xs_parse_infix(aTHX_ opname, hooks, hookdata) -static void S_register_xs_parse_infix(pTHX_ const char *opname, const struct XSParseInfixHooks *hooks, void *hookdata) -{ - if(!register_xs_parse_infix_func) - croak("Must call boot_xs_parse_infix() first"); - - return (*register_xs_parse_infix_func)(aTHX_ opname, hooks, hookdata); -} - -#define boot_xs_parse_infix(ver) S_boot_xs_parse_infix(aTHX_ ver) -static void S_boot_xs_parse_infix(pTHX_ double ver) { - SV **svp; - SV *versv = ver ? newSVnv(ver) : NULL; - - load_module(PERL_LOADMOD_NOIMPORT, newSVpvs("XS::Parse::Infix"), versv, NULL); - - svp = hv_fetchs(PL_modglobal, "XS::Parse::Infix/ABIVERSION_MIN", 0); - if(!svp) - croak("XS::Parse::Infix ABI minimum version missing"); - int abi_ver = SvIV(*svp); - if(abi_ver > XSPARSEINFIX_ABI_VERSION) - croak("XS::Parse::Infix ABI version mismatch - library supports >= %d, compiled for %d", - abi_ver, XSPARSEINFIX_ABI_VERSION); - - svp = hv_fetchs(PL_modglobal, "XS::Parse::Infix/ABIVERSION_MAX", 0); - abi_ver = SvIV(*svp); - if(abi_ver < XSPARSEINFIX_ABI_VERSION) - croak("XS::Parse::Infix ABI version mismatch - library supports <= %d, compiled for %d", - abi_ver, XSPARSEINFIX_ABI_VERSION); - - parse_infix_func = INT2PTR(bool (*)(pTHX_ enum XSParseInfixSelection, struct XSParseInfixInfo **), - SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/parse()@2", 0))); - xs_parse_infix_new_op_func = INT2PTR(OP *(*)(pTHX_ const struct XSParseInfixInfo *, U32, OP *, OP *), - SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/new_op()@0", 0))); - register_xs_parse_infix_func = INT2PTR(void (*)(pTHX_ const char *, const struct XSParseInfixHooks *, void *), - SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/register()@2", 0))); -} - -#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/share/include/XSParseKeyword.h new/XS-Parse-Keyword-0.47/share/include/XSParseKeyword.h --- old/XS-Parse-Keyword-0.44/share/include/XSParseKeyword.h 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/share/include/XSParseKeyword.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,318 +0,0 @@ -#ifndef __XS_PARSE_KEYWORD_H__ -#define __XS_PARSE_KEYWORD_H__ - -#define XSPARSEKEYWORD_ABI_VERSION 2 - -struct XSParseKeywordPieceType; -struct XSParseKeywordPieceType { - int type; - union { - char c; /* LITERALCHAR */ - const char *str; /* LITERALSTR */ - const struct XSParseKeywordPieceType *pieces; /* containers */ - void (*callback)(pTHX_ void *hookdata); /* SETUP, ANONSUB PREPARE+START */ - - OP *(*op_wrap_callback)(pTHX_ OP *o, void *hookdata); - } u; -}; - -enum { - XPK_FLAG_EXPR = (1<<0), - XPK_FLAG_STMT = (1<<1), - XPK_FLAG_AUTOSEMI = (1<<2), - XPK_FLAG_BLOCKSCOPE = (1<<3), -}; - -enum { - /* skip zero */ - - /* emits */ - XS_PARSE_KEYWORD_LITERALCHAR = 1, /* nothing */ - XS_PARSE_KEYWORD_LITERALSTR, /* nothing */ - XS_PARSE_KEYWORD_AUTOSEMI, /* nothing */ - XS_PARSE_KEYWORD_WARNING = 0x0e, /* nothing */ - XS_PARSE_KEYWORD_FAILURE, /* nothing */ - - XS_PARSE_KEYWORD_BLOCK = 0x10, /* op */ - XS_PARSE_KEYWORD_ANONSUB, /* cv */ - XS_PARSE_KEYWORD_ARITHEXPR, /* op */ - XS_PARSE_KEYWORD_TERMEXPR, /* op */ - XS_PARSE_KEYWORD_LISTEXPR, /* op */ - /* TODO: XS_PARSE_KEYWORD_FULLEXPR = 0x15 */ - XS_PARSE_KEYWORD_IDENT = 0x16, /* sv */ - XS_PARSE_KEYWORD_PACKAGENAME, /* sv */ - XS_PARSE_KEYWORD_LEXVARNAME, /* sv */ - XS_PARSE_KEYWORD_LEXVAR, /* padix */ - XS_PARSE_KEYWORD_ATTRS, /* i / {attr.name + attr.val} */ - XS_PARSE_KEYWORD_VSTRING, /* sv */ - - XS_PARSE_KEYWORD_INFIX = 0x40, /* infix */ - - XS_PARSE_KEYWORD_INTRO_MY = 0x60, /* emits nothing */ - - 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 */ - XS_PARSE_KEYWORD_TAGGEDCHOICE, /* i, contained */ - XS_PARSE_KEYWORD_SEPARATEDLIST, /* i, contained */ - XS_PARSE_KEYWORD_PARENS = 0xb0, /* contained */ - XS_PARSE_KEYWORD_BRACKETS, /* contained */ - XS_PARSE_KEYWORD_BRACES, /* contained */ - XS_PARSE_KEYWORD_CHEVRONS, /* contained */ -}; - -enum { - XPK_LEXVAR_SCALAR = (1<<0), - XPK_LEXVAR_ARRAY = (1<<1), - XPK_LEXVAR_HASH = (1<<2), - XPK_LEXVAR_ANY = XPK_LEXVAR_SCALAR|XPK_LEXVAR_ARRAY|XPK_LEXVAR_HASH, -}; - -enum { - XPK_TYPEFLAG_OPT = (1<<16), - XPK_TYPEFLAG_SPECIAL = (1<<17), /* on XPK_LITERALSTR: keyword - on XPK_BLOCK: scoped - on XPK_LEXVAR: my */ - - /* 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), - - XPK_TYPEFLAG_ENTERLEAVE = (1<<20), /* wrap ENTER/LEAVE pair around the item */ - - XPK_TYPEFLAG_MAYBEPARENS = (1<<21), /* parens themselves are optional on PARENS */ -}; - -#define XPK_BLOCK_flags(flags) {.type = XS_PARSE_KEYWORD_BLOCK|(flags), .u.pieces = NULL} -#define XPK_BLOCK XPK_BLOCK_flags(0) -#define XPK_BLOCK_VOIDCTX XPK_BLOCK_flags(XPK_TYPEFLAG_SPECIAL|XPK_TYPEFLAG_G_VOID) -#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_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} - -#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) -#define XPK_ARITHEXPR_SCALARCTX XPK_ARITHEXPR_flags(XPK_TYPEFLAG_G_SCALAR) -#define XPK_ARITHEXPR_OPT XPK_ARITHEXPR_flags(XPK_TYPEFLAG_OPT) -#define XPK_ARITHEXPR_VOIDCTX_OPT XPK_ARITHEXPR_flags(XPK_TYPEFLAG_G_VOID|XPK_TYPEFLAG_OPT) -#define XPK_ARITHEXPR_SCALARCTX_OPT XPK_ARITHEXPR_flags(XPK_TYPEFLAG_G_SCALAR|XPK_TYPEFLAG_OPT) - -#define XPK_TERMEXPR_flags(flags) {.type = XS_PARSE_KEYWORD_TERMEXPR|(flags)} -#define XPK_TERMEXPR XPK_TERMEXPR_flags(0) -#define XPK_TERMEXPR_VOIDCTX XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_VOID) -#define XPK_TERMEXPR_SCALARCTX XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_SCALAR) -#define XPK_TERMEXPR_OPT XPK_TERMEXPR_flags(XPK_TYPEFLAG_OPT) -#define XPK_TERMEXPR_VOIDCTX_OPT XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_VOID|XPK_TYPEFLAG_OPT) -#define XPK_TERMEXPR_SCALARCTX_OPT XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_SCALAR|XPK_TYPEFLAG_OPT) - -#define XPK_LISTEXPR_flags(flags) {.type = XS_PARSE_KEYWORD_LISTEXPR|(flags)} -#define XPK_LISTEXPR XPK_LISTEXPR_flags(0) -#define XPK_LISTEXPR_LISTCTX XPK_LISTEXPR_flags(XPK_TYPEFLAG_G_LIST) -#define XPK_LISTEXPR_OPT XPK_LISTEXPR_flags(XPK_TYPEFLAG_OPT) -#define XPK_LISTEXPR_LISTCTX_OPT XPK_LISTEXPR_flags(XPK_TYPEFLAG_G_LIST|XPK_TYPEFLAG_OPT) - -#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 } -#define XPK_PACKAGENAME_OPT {.type = XS_PARSE_KEYWORD_PACKAGENAME|XPK_TYPEFLAG_OPT} - -#define XPK_LEXVARNAME(kind) {.type = XS_PARSE_KEYWORD_LEXVARNAME, .u.c = kind} - -#define XPK_LEXVAR(kind) {.type = XS_PARSE_KEYWORD_LEXVAR, .u.c = kind} -#define XPK_LEXVAR_MY(kind) {.type = XS_PARSE_KEYWORD_LEXVAR|XPK_TYPEFLAG_SPECIAL, .u.c = kind} - -#define XPK_ATTRIBUTES {.type = XS_PARSE_KEYWORD_ATTRS} - -#define XPK_VSTRING {.type = XS_PARSE_KEYWORD_VSTRING} -#define XPK_VSTRING_OPT {.type = XS_PARSE_KEYWORD_VSTRING|XPK_TYPEFLAG_OPT} - -#define XPK_COMMA {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = ','} -#define XPK_COLON {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = ':'} -#define XPK_EQUALS {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = '='} - -#define XPK_LITERAL(s) {.type = XS_PARSE_KEYWORD_LITERALSTR, .u.str = (const char *)s} -#define XPK_STRING(s) XPK_LITERAL(s) -#define XPK_AUTOSEMI {.type = XS_PARSE_KEYWORD_AUTOSEMI} -#define XPK_KEYWORD(s) {.type = XS_PARSE_KEYWORD_LITERALSTR|XPK_TYPEFLAG_SPECIAL, .u.str = (const char *)s} - -#define XPK_INFIX(select) {.type = XS_PARSE_KEYWORD_INFIX, .u.c = select} -#define XPK_INFIX_RELATION XPK_INFIX(XPI_SELECT_RELATION) -#define XPK_INFIX_EQUALITY XPK_INFIX(XPI_SELECT_EQUALITY) -#define XPK_INFIX_MATCH_NOSMART XPK_INFIX(XPI_SELECT_MATCH_NOSMART) -#define XPK_INFIX_MATCH_SMART XPK_INFIX(XPI_SELECT_MATCH_SMART) - -#define XPK_INTRO_MY {.type = XS_PARSE_KEYWORD_INTRO_MY} - -#define XPK_SEQUENCE_pieces(p) {.type = XS_PARSE_KEYWORD_SEQUENCE, .u.pieces = p} -#define XPK_SEQUENCE(...) XPK_SEQUENCE_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) - -/* First piece of these must be something probe-able */ -#define XPK_OPTIONAL_pieces(p) {.type = XS_PARSE_KEYWORD_SEQUENCE|XPK_TYPEFLAG_OPT, .u.pieces = p} -#define XPK_OPTIONAL(...) XPK_OPTIONAL_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) - -#define XPK_REPEATED_pieces(p) {.type = XS_PARSE_KEYWORD_REPEATED, .u.pieces = p} -#define XPK_REPEATED(...) XPK_REPEATED_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) - -/* Every piece must be probeable */ -#define XPK_CHOICE_pieces(p) {.type = XS_PARSE_KEYWORD_CHOICE, .u.pieces = p} -#define XPK_CHOICE(...) XPK_CHOICE_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) - -/* Every piece must be probeable, and followed by XPK_TAG */ -#define XPK_TAGGEDCHOICE_pieces(p) {.type = XS_PARSE_KEYWORD_TAGGEDCHOICE, .u.pieces = p} -#define XPK_TAGGEDCHOICE(...) XPK_TAGGEDCHOICE_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0}, {0} })) -#define XPK_TAG(val) {.type = val} - -#define XPK_COMMALIST(...) \ - {.type = XS_PARSE_KEYWORD_SEPARATEDLIST, .u.pieces = (const struct XSParseKeywordPieceType []){ \ - {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = ','}, __VA_ARGS__, {0}}} - -#define XPK_WARNING_bit(bit,s) {.type = (XS_PARSE_KEYWORD_WARNING|(bit << 24)), .u.str = (const char *)s} -#define XPK_WARNING(s) XPK_WARNING_bit(0,s) -#define XPK_WARNING_AMBIGUOUS(s) XPK_WARNING_bit(WARN_AMBIGUOUS, s) -#define XPK_WARNING_DEPRECATED(s) XPK_WARNING_bit(WARN_DEPRECATED, s) -#define XPK_WARNING_EXPERIMENTAL(s) XPK_WARNING_bit(WARN_EXPERIMENTAL,s) -#define XPK_WARNING_PRECEDENCE(s) XPK_WARNING_bit(WARN_PRECEDENCE, s) -#define XPK_WARNING_SYNTAX(s) XPK_WARNING_bit(WARN_SYNTAX, s) - -#define XPK_FAILURE(s) {.type = XS_PARSE_KEYWORD_FAILURE, .u.str = (const char *)s} - -#define XPK_PARENS_pieces(p) {.type = XS_PARSE_KEYWORD_PARENS, .u.pieces = p} -#define XPK_PARENS(...) XPK_PARENS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) -#define XPK_PARENS_OPT(...) \ - {.type = XS_PARSE_KEYWORD_PARENS|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }} - -#define XPK_ARGS_pieces(p) {.type = XS_PARSE_KEYWORD_PARENS|XPK_TYPEFLAG_MAYBEPARENS, .u.pieces = p} -#define XPK_ARGS(...) XPK_ARGS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) - -#define XPK_BRACKETS_pieces(p) {.type = XS_PARSE_KEYWORD_BRACKETS, .u.pieces = p} -#define XPK_BRACKETS(...) XPK_BRACKETS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) -#define XPK_BRACKETS_OPT(...) \ - {.type = XS_PARSE_KEYWORD_BRACKETS|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }} - -#define XPK_BRACES_pieces(p) {.type = XS_PARSE_KEYWORD_BRACES, .u.pieces = p} -#define XPK_BRACES(...) XPK_BRACES_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) -#define XPK_BRACES_OPT(...) \ - {.type = XS_PARSE_KEYWORD_BRACES|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }} - -#define XPK_CHEVRONS_pieces(p) {.type = XS_PARSE_KEYWORD_CHEVRONS, .u.pieces = p} -#define XPK_CHEVRONS(...) XPK_CHEVRONS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) -#define XPK_CHEVRONS_OPT(...) \ - {.type = XS_PARSE_KEYWORD_CHEVRONS|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }} - -/* back-compat for older names */ -#define XPK_PARENSCOPE_pieces XPK_PARENS_pieces -#define XPK_PARENSCOPE XPK_PARENS -#define XPK_PARENSCOPE_OPT XPK_PARENS_OPT -#define XPK_ARGSCOPE_pieces XPK_ARGS_pieces -#define XPK_ARGSCOPE XPK_ARGS -#define XPK_BRACKETSCOPE_pieces XPK_BRACKETS_pieces -#define XPK_BRACKETSCOPE XPK_BRACKETS -#define XPK_BRACKETSCOPE_OPT XPK_BRACKETS_OPT -#define XPK_BRACESCOPE_pieces XPK_BRACES_pieces -#define XPK_BRACESCOPE XPK_BRACES -#define XPK_BRACESCOPE_OPT XPK_BRACES_OPT -#define XPK_CHEVRONSCOPE_pieces XPK_CHEVRONS_pieces -#define XPK_CHEVRONSCOPE XPK_CHEVRONS -#define XPK_CHEVRONSCOPE_OPT XPK_CHEVRONS_OPT - -/* This type defined in XSParseInfix.h */ -typedef struct XSParseInfixInfo XSParseInfixInfo; - -typedef struct { - union { - OP *op; - CV *cv; - SV *sv; - int i; - struct { SV *name; SV *value; } attr; - PADOFFSET padix; - XSParseInfixInfo *infix; - }; - int line; -} XSParseKeywordPiece; - -struct XSParseKeywordHooks { - U32 flags; - - /* used by build1 */ - struct XSParseKeywordPieceType piece1; - /* alternatively, used by build */ - const struct XSParseKeywordPieceType *pieces; - - /* These two hooks are ANDed together; both must pass, if present */ - const char *permit_hintkey; - bool (*permit) (pTHX_ void *hookdata); - - void (*check)(pTHX_ void *hookdata); - - /* These are alternatives; the first one defined is used */ - int (*parse)(pTHX_ OP **opp, void *hookdata); - int (*build)(pTHX_ OP **out, XSParseKeywordPiece *args[], size_t nargs, void *hookdata); - int (*build1)(pTHX_ OP **out, XSParseKeywordPiece *arg0, void *hookdata); -}; - -static void (*register_xs_parse_keyword_func)(pTHX_ const char *kwname, const struct XSParseKeywordHooks *hooks, void *hookdata); -#define register_xs_parse_keyword(kwname, hooks, hookdata) S_register_xs_parse_keyword(aTHX_ kwname, hooks, hookdata) -static void S_register_xs_parse_keyword(pTHX_ const char *kwname, const struct XSParseKeywordHooks *hooks, void *hookdata) -{ - if(!register_xs_parse_keyword_func) - croak("Must call boot_xs_parse_keyword() first"); - - (*register_xs_parse_keyword_func)(aTHX_ kwname, hooks, hookdata); -} - -#define boot_xs_parse_keyword(ver) S_boot_xs_parse_keyword(aTHX_ ver) -static void S_boot_xs_parse_keyword(pTHX_ double ver) { - SV **svp; - SV *versv = ver ? newSVnv(ver) : NULL; - - load_module(PERL_LOADMOD_NOIMPORT, newSVpvs("XS::Parse::Keyword"), versv, NULL); - - svp = hv_fetchs(PL_modglobal, "XS::Parse::Keyword/ABIVERSION_MIN", 0); - if(!svp) - croak("XS::Parse::Keyword ABI minimum version missing"); - int abi_ver = SvIV(*svp); - if(abi_ver > XSPARSEKEYWORD_ABI_VERSION) - croak("XS::Parse::Keyword ABI version mismatch - library supports >= %d, compiled for %d", - abi_ver, XSPARSEKEYWORD_ABI_VERSION); - - svp = hv_fetchs(PL_modglobal, "XS::Parse::Keyword/ABIVERSION_MAX", 0); - abi_ver = SvIV(*svp); - if(abi_ver < XSPARSEKEYWORD_ABI_VERSION) - croak("XS::Parse::Keyword ABI version mismatch - library supports <= %d, compiled for %d", - abi_ver, XSPARSEKEYWORD_ABI_VERSION); - - register_xs_parse_keyword_func = INT2PTR(void (*)(pTHX_ const char *, const struct XSParseKeywordHooks *, void *), - SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Keyword/register()@2", 0))); -} - -#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/share-infix/include/XSParseInfix.h new/XS-Parse-Keyword-0.47/share-infix/include/XSParseInfix.h --- old/XS-Parse-Keyword-0.44/share-infix/include/XSParseInfix.h 1970-01-01 01:00:00.000000000 +0100 +++ new/XS-Parse-Keyword-0.47/share-infix/include/XSParseInfix.h 2024-11-25 17:42:13.000000000 +0100 @@ -0,0 +1,149 @@ +#ifndef __XS_PARSE_INFIX_H__ +#define __XS_PARSE_INFIX_H__ + +#define XSPARSEINFIX_ABI_VERSION 2 + +/* Infix operator classifications */ +/* No built-in operators use the _MISC categories, but they are provided for + * custom infix operators to use so they are still found by selections */ +enum XSParseInfixClassification { + XPI_CLS_NONE = 0, + XPI_CLS_PREDICATE, /* any boolean-returning operator */ + XPI_CLS_RELATION, /* ... any predicate that is typewise symmetric */ + XPI_CLS_EQUALITY, /* ... any relation that is true for (x == x) and false otherwise */ + XPI_CLS_SMARTMATCH, /* ... the predicate smartmatch (~~) */ + XPI_CLS_MATCHRE, /* ... the predicate regexp match (=~) */ + XPI_CLS_ISA, /* ... the predicate instance of (isa) */ + XPI_CLS_MATCH_MISC, /* ... any other match-like predicate */ + XPI_CLS_ORDERING, /* cmp or <=> */ + + /* Since the _MISC categories never turn up in selections, put them at high + * index so as to leave space for more */ + XPI_CLS_LOW_MISC = 0x80, /* an operator at low precedence */ + XPI_CLS_LOGICAL_OR_LOW_MISC, + XPI_CLS_LOGICAL_AND_LOW_MISC, + XPI_CLS_ASSIGN_MISC, + XPI_CLS_LOGICAL_OR_MISC, + XPI_CLS_LOGICAL_AND_MISC, + XPI_CLS_ADD_MISC, /* an operator at addition-like precedence */ + XPI_CLS_MUL_MISC, /* an operator at multiplication-like precedence */ + XPI_CLS_POW_MISC, /* an operator at power exponentiation-like precedence */ + XPI_CLS_HIGH_MISC, /* an operator at high precedence */ +}; + +enum XSParseInfixSelection { + XPI_SELECT_ANY, + XPI_SELECT_PREDICATE, /* any predicate */ + XPI_SELECT_RELATION, /* any relation */ + XPI_SELECT_EQUALITY, /* any equality */ + XPI_SELECT_ORDERING, /* any ordering */ + + XPI_SELECT_MATCH_NOSMART, /* any equality or other match operator, including smartmatch */ + XPI_SELECT_MATCH_SMART, /* any equality or other match operator, not including smartmatch */ +}; + +/* flags */ +enum { + XPI_FLAG_LISTASSOC = (1<<0), +}; + +/* lhs_flags, rhs_flags */ +enum { + XPI_OPERAND_TERM_LIST = 6, /* term in list context */ + XPI_OPERAND_LIST = 7, /* list in list context */ + + /* Other bitflags */ + XPI_OPERAND_ONLY_LOOK = (1<<3), +}; + +struct XSParseInfixHooks { + U16 flags; + U8 lhs_flags, rhs_flags; + enum XSParseInfixClassification cls; + + const char *wrapper_func_name; + + /* These two hooks are ANDed together; both must pass, if present */ + const char *permit_hintkey; + bool (*permit) (pTHX_ void *hookdata); + + /* These hooks are alternatives; the first one defined is used */ + OP *(*new_op)(pTHX_ U32 flags, OP *lhs, OP *rhs, SV **parsedata, void *hookdata); + OP *(*ppaddr)(pTHX); /* A pp func used directly in newBINOP_custom() */ + + /* optional */ + void (*parse)(pTHX_ U32 flags, SV **parsedata, void *hookdata); +}; + +struct XSParseInfixInfo { + const char *opname; + OPCODE opcode; + + const struct XSParseInfixHooks *hooks; + void *hookdata; + + enum XSParseInfixClassification cls; +}; + +static bool (*parse_infix_func)(pTHX_ enum XSParseInfixSelection select, struct XSParseInfixInfo **infop); +#define parse_infix(select, infop) S_parse_infix(aTHX_ select, infop) +static bool S_parse_infix(pTHX_ enum XSParseInfixSelection select, struct XSParseInfixInfo **infop) +{ + if(!parse_infix_func) + croak("Must call boot_xs_parse_infix() first"); + + struct XSParseInfixInfo *infocopy; + + return (*parse_infix_func)(aTHX_ select, infop); +} + +static OP *(*xs_parse_infix_new_op_func)(pTHX_ const struct XSParseInfixInfo *info, U32 flags, OP *lhs, OP *rhs); +#define xs_parse_infix_new_op(info, flags, lhs, rhs) S_xs_parse_infix_new_op(aTHX_ info, flags, lhs, rhs) +static OP *S_xs_parse_infix_new_op(pTHX_ const struct XSParseInfixInfo *info, U32 flags, OP *lhs, OP *rhs) +{ + if(!xs_parse_infix_new_op_func) + croak("Must call boot_xs_parse_infix() first"); + + return (*xs_parse_infix_new_op_func)(aTHX_ info, flags, lhs, rhs); +} + +static void (*register_xs_parse_infix_func)(pTHX_ const char *kw, const struct XSParseInfixHooks *hooks, void *hookdata); +#define register_xs_parse_infix(opname, hooks, hookdata) S_register_xs_parse_infix(aTHX_ opname, hooks, hookdata) +static void S_register_xs_parse_infix(pTHX_ const char *opname, const struct XSParseInfixHooks *hooks, void *hookdata) +{ + if(!register_xs_parse_infix_func) + croak("Must call boot_xs_parse_infix() first"); + + return (*register_xs_parse_infix_func)(aTHX_ opname, hooks, hookdata); +} + +#define boot_xs_parse_infix(ver) S_boot_xs_parse_infix(aTHX_ ver) +static void S_boot_xs_parse_infix(pTHX_ double ver) { + SV **svp; + SV *versv = ver ? newSVnv(ver) : NULL; + + load_module(PERL_LOADMOD_NOIMPORT, newSVpvs("XS::Parse::Infix"), versv, NULL); + + svp = hv_fetchs(PL_modglobal, "XS::Parse::Infix/ABIVERSION_MIN", 0); + if(!svp) + croak("XS::Parse::Infix ABI minimum version missing"); + int abi_ver = SvIV(*svp); + if(abi_ver > XSPARSEINFIX_ABI_VERSION) + croak("XS::Parse::Infix ABI version mismatch - library supports >= %d, compiled for %d", + abi_ver, XSPARSEINFIX_ABI_VERSION); + + svp = hv_fetchs(PL_modglobal, "XS::Parse::Infix/ABIVERSION_MAX", 0); + abi_ver = SvIV(*svp); + if(abi_ver < XSPARSEINFIX_ABI_VERSION) + croak("XS::Parse::Infix ABI version mismatch - library supports <= %d, compiled for %d", + abi_ver, XSPARSEINFIX_ABI_VERSION); + + parse_infix_func = INT2PTR(bool (*)(pTHX_ enum XSParseInfixSelection, struct XSParseInfixInfo **), + SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/parse()@2", 0))); + xs_parse_infix_new_op_func = INT2PTR(OP *(*)(pTHX_ const struct XSParseInfixInfo *, U32, OP *, OP *), + SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/new_op()@0", 0))); + register_xs_parse_infix_func = INT2PTR(void (*)(pTHX_ const char *, const struct XSParseInfixHooks *, void *), + SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/register()@2", 0))); +} + +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/share-keyword/include/XSParseKeyword.h new/XS-Parse-Keyword-0.47/share-keyword/include/XSParseKeyword.h --- old/XS-Parse-Keyword-0.44/share-keyword/include/XSParseKeyword.h 1970-01-01 01:00:00.000000000 +0100 +++ new/XS-Parse-Keyword-0.47/share-keyword/include/XSParseKeyword.h 2024-11-25 17:42:13.000000000 +0100 @@ -0,0 +1,319 @@ +#ifndef __XS_PARSE_KEYWORD_H__ +#define __XS_PARSE_KEYWORD_H__ + +#define XSPARSEKEYWORD_ABI_VERSION 2 + +struct XSParseKeywordPieceType; +struct XSParseKeywordPieceType { + int type; + union { + char c; /* LITERALCHAR */ + const char *str; /* LITERALSTR */ + const struct XSParseKeywordPieceType *pieces; /* containers */ + void (*callback)(pTHX_ void *hookdata); /* SETUP, ANONSUB PREPARE+START */ + + OP *(*op_wrap_callback)(pTHX_ OP *o, void *hookdata); + } u; +}; + +enum { + XPK_FLAG_EXPR = (1<<0), + XPK_FLAG_STMT = (1<<1), + XPK_FLAG_AUTOSEMI = (1<<2), + XPK_FLAG_BLOCKSCOPE = (1<<3), +}; + +enum { + /* skip zero */ + + /* emits */ + XS_PARSE_KEYWORD_LITERALCHAR = 1, /* nothing */ + XS_PARSE_KEYWORD_LITERALSTR, /* nothing */ + XS_PARSE_KEYWORD_AUTOSEMI, /* nothing */ + XS_PARSE_KEYWORD_WARNING = 0x0e, /* nothing */ + XS_PARSE_KEYWORD_FAILURE, /* nothing */ + + XS_PARSE_KEYWORD_BLOCK = 0x10, /* op */ + XS_PARSE_KEYWORD_ANONSUB, /* cv */ + XS_PARSE_KEYWORD_ARITHEXPR, /* op */ + XS_PARSE_KEYWORD_TERMEXPR, /* op */ + XS_PARSE_KEYWORD_LISTEXPR, /* op */ + /* TODO: XS_PARSE_KEYWORD_FULLEXPR = 0x15 */ + XS_PARSE_KEYWORD_IDENT = 0x16, /* sv */ + XS_PARSE_KEYWORD_PACKAGENAME, /* sv */ + XS_PARSE_KEYWORD_LEXVARNAME, /* sv */ + XS_PARSE_KEYWORD_LEXVAR, /* padix */ + XS_PARSE_KEYWORD_ATTRS, /* i / {attr.name + attr.val} */ + XS_PARSE_KEYWORD_VSTRING, /* sv */ + + XS_PARSE_KEYWORD_INFIX = 0x40, /* infix */ + + XS_PARSE_KEYWORD_INTRO_MY = 0x60, /* emits nothing */ + + 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 */ + XS_PARSE_KEYWORD_TAGGEDCHOICE, /* i, contained */ + XS_PARSE_KEYWORD_SEPARATEDLIST, /* i, contained */ + XS_PARSE_KEYWORD_PARENS = 0xb0, /* contained */ + XS_PARSE_KEYWORD_BRACKETS, /* contained */ + XS_PARSE_KEYWORD_BRACES, /* contained */ + XS_PARSE_KEYWORD_CHEVRONS, /* contained */ +}; + +enum { + XPK_LEXVAR_SCALAR = (1<<0), + XPK_LEXVAR_ARRAY = (1<<1), + XPK_LEXVAR_HASH = (1<<2), + XPK_LEXVAR_ANY = XPK_LEXVAR_SCALAR|XPK_LEXVAR_ARRAY|XPK_LEXVAR_HASH, +}; + +enum { + XPK_TYPEFLAG_OPT = (1<<16), + XPK_TYPEFLAG_SPECIAL = (1<<17), /* on XPK_LITERALSTR: keyword + on XPK_BLOCK: scoped + on XPK_LEXVAR: my */ + + /* 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), + + XPK_TYPEFLAG_ENTERLEAVE = (1<<20), /* wrap ENTER/LEAVE pair around the item */ + + XPK_TYPEFLAG_MAYBEPARENS = (1<<21), /* parens themselves are optional on PARENS */ +}; + +#define XPK_PREFIXED(typecode,...) \ + {.type = typecode, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }} + +#define XPK_BLOCK_flags(flags) {.type = XS_PARSE_KEYWORD_BLOCK|(flags), .u.pieces = NULL} +#define XPK_BLOCK XPK_BLOCK_flags(0) +#define XPK_BLOCK_VOIDCTX XPK_BLOCK_flags(XPK_TYPEFLAG_SPECIAL|XPK_TYPEFLAG_G_VOID) +#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(...) XPK_PREFIXED(XS_PARSE_KEYWORD_BLOCK, __VA_ARGS__) +#define XPK_PREFIXED_BLOCK_ENTERLEAVE(...) XPK_PREFIXED(XS_PARSE_KEYWORD_BLOCK|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} + +#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) +#define XPK_ARITHEXPR_SCALARCTX XPK_ARITHEXPR_flags(XPK_TYPEFLAG_G_SCALAR) +#define XPK_ARITHEXPR_OPT XPK_ARITHEXPR_flags(XPK_TYPEFLAG_OPT) +#define XPK_ARITHEXPR_VOIDCTX_OPT XPK_ARITHEXPR_flags(XPK_TYPEFLAG_G_VOID|XPK_TYPEFLAG_OPT) +#define XPK_ARITHEXPR_SCALARCTX_OPT XPK_ARITHEXPR_flags(XPK_TYPEFLAG_G_SCALAR|XPK_TYPEFLAG_OPT) + +#define XPK_TERMEXPR_flags(flags) {.type = XS_PARSE_KEYWORD_TERMEXPR|(flags)} +#define XPK_TERMEXPR XPK_TERMEXPR_flags(0) +#define XPK_TERMEXPR_VOIDCTX XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_VOID) +#define XPK_TERMEXPR_SCALARCTX XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_SCALAR) +#define XPK_TERMEXPR_OPT XPK_TERMEXPR_flags(XPK_TYPEFLAG_OPT) +#define XPK_TERMEXPR_VOIDCTX_OPT XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_VOID|XPK_TYPEFLAG_OPT) +#define XPK_TERMEXPR_SCALARCTX_OPT XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_SCALAR|XPK_TYPEFLAG_OPT) + +#define XPK_PREFIXED_TERMEXPR_ENTERLEAVE(...) XPK_PREFIXED(XS_PARSE_KEYWORD_TERMEXPR|XPK_TYPEFLAG_ENTERLEAVE, __VA_ARGS__) + +#define XPK_LISTEXPR_flags(flags) {.type = XS_PARSE_KEYWORD_LISTEXPR|(flags)} +#define XPK_LISTEXPR XPK_LISTEXPR_flags(0) +#define XPK_LISTEXPR_LISTCTX XPK_LISTEXPR_flags(XPK_TYPEFLAG_G_LIST) +#define XPK_LISTEXPR_OPT XPK_LISTEXPR_flags(XPK_TYPEFLAG_OPT) +#define XPK_LISTEXPR_LISTCTX_OPT XPK_LISTEXPR_flags(XPK_TYPEFLAG_G_LIST|XPK_TYPEFLAG_OPT) + +#define XPK_PREFIXED_LISTEXPR_ENTERLEAVE(...) XPK_PREFIXED(XS_PARSE_KEYWORD_LISTEXPR|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 } +#define XPK_PACKAGENAME_OPT {.type = XS_PARSE_KEYWORD_PACKAGENAME|XPK_TYPEFLAG_OPT} + +#define XPK_LEXVARNAME(kind) {.type = XS_PARSE_KEYWORD_LEXVARNAME, .u.c = kind} + +#define XPK_LEXVAR(kind) {.type = XS_PARSE_KEYWORD_LEXVAR, .u.c = kind} +#define XPK_LEXVAR_MY(kind) {.type = XS_PARSE_KEYWORD_LEXVAR|XPK_TYPEFLAG_SPECIAL, .u.c = kind} + +#define XPK_ATTRIBUTES {.type = XS_PARSE_KEYWORD_ATTRS} + +#define XPK_VSTRING {.type = XS_PARSE_KEYWORD_VSTRING} +#define XPK_VSTRING_OPT {.type = XS_PARSE_KEYWORD_VSTRING|XPK_TYPEFLAG_OPT} + +#define XPK_COMMA {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = ','} +#define XPK_COLON {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = ':'} +#define XPK_EQUALS {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = '='} + +#define XPK_LITERAL(s) {.type = XS_PARSE_KEYWORD_LITERALSTR, .u.str = (const char *)s} +#define XPK_STRING(s) XPK_LITERAL(s) +#define XPK_AUTOSEMI {.type = XS_PARSE_KEYWORD_AUTOSEMI} +#define XPK_KEYWORD(s) {.type = XS_PARSE_KEYWORD_LITERALSTR|XPK_TYPEFLAG_SPECIAL, .u.str = (const char *)s} + +#define XPK_INFIX(select) {.type = XS_PARSE_KEYWORD_INFIX, .u.c = select} +#define XPK_INFIX_RELATION XPK_INFIX(XPI_SELECT_RELATION) +#define XPK_INFIX_EQUALITY XPK_INFIX(XPI_SELECT_EQUALITY) +#define XPK_INFIX_MATCH_NOSMART XPK_INFIX(XPI_SELECT_MATCH_NOSMART) +#define XPK_INFIX_MATCH_SMART XPK_INFIX(XPI_SELECT_MATCH_SMART) + +#define XPK_INTRO_MY {.type = XS_PARSE_KEYWORD_INTRO_MY} + +#define XPK_SEQUENCE_pieces(p) {.type = XS_PARSE_KEYWORD_SEQUENCE, .u.pieces = p} +#define XPK_SEQUENCE(...) XPK_SEQUENCE_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) + +/* First piece of these must be something probe-able */ +#define XPK_OPTIONAL_pieces(p) {.type = XS_PARSE_KEYWORD_SEQUENCE|XPK_TYPEFLAG_OPT, .u.pieces = p} +#define XPK_OPTIONAL(...) XPK_OPTIONAL_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) + +#define XPK_REPEATED_pieces(p) {.type = XS_PARSE_KEYWORD_REPEATED, .u.pieces = p} +#define XPK_REPEATED(...) XPK_REPEATED_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) + +/* Every piece must be probeable */ +#define XPK_CHOICE_pieces(p) {.type = XS_PARSE_KEYWORD_CHOICE, .u.pieces = p} +#define XPK_CHOICE(...) XPK_CHOICE_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) + +/* Every piece must be probeable, and followed by XPK_TAG */ +#define XPK_TAGGEDCHOICE_pieces(p) {.type = XS_PARSE_KEYWORD_TAGGEDCHOICE, .u.pieces = p} +#define XPK_TAGGEDCHOICE(...) XPK_TAGGEDCHOICE_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0}, {0} })) +#define XPK_TAG(val) {.type = val} + +#define XPK_COMMALIST(...) \ + {.type = XS_PARSE_KEYWORD_SEPARATEDLIST, .u.pieces = (const struct XSParseKeywordPieceType []){ \ + {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = ','}, __VA_ARGS__, {0}}} + +#define XPK_WARNING_bit(bit,s) {.type = (XS_PARSE_KEYWORD_WARNING|(bit << 24)), .u.str = (const char *)s} +#define XPK_WARNING(s) XPK_WARNING_bit(0,s) +#define XPK_WARNING_AMBIGUOUS(s) XPK_WARNING_bit(WARN_AMBIGUOUS, s) +#define XPK_WARNING_DEPRECATED(s) XPK_WARNING_bit(WARN_DEPRECATED, s) +#define XPK_WARNING_EXPERIMENTAL(s) XPK_WARNING_bit(WARN_EXPERIMENTAL,s) +#define XPK_WARNING_PRECEDENCE(s) XPK_WARNING_bit(WARN_PRECEDENCE, s) +#define XPK_WARNING_SYNTAX(s) XPK_WARNING_bit(WARN_SYNTAX, s) + +#define XPK_FAILURE(s) {.type = XS_PARSE_KEYWORD_FAILURE, .u.str = (const char *)s} + +#define XPK_PARENS_pieces(p) {.type = XS_PARSE_KEYWORD_PARENS, .u.pieces = p} +#define XPK_PARENS(...) XPK_PARENS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) +#define XPK_PARENS_OPT(...) \ + {.type = XS_PARSE_KEYWORD_PARENS|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }} + +#define XPK_ARGS_pieces(p) {.type = XS_PARSE_KEYWORD_PARENS|XPK_TYPEFLAG_MAYBEPARENS, .u.pieces = p} +#define XPK_ARGS(...) XPK_ARGS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) + +#define XPK_BRACKETS_pieces(p) {.type = XS_PARSE_KEYWORD_BRACKETS, .u.pieces = p} +#define XPK_BRACKETS(...) XPK_BRACKETS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) +#define XPK_BRACKETS_OPT(...) \ + {.type = XS_PARSE_KEYWORD_BRACKETS|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }} + +#define XPK_BRACES_pieces(p) {.type = XS_PARSE_KEYWORD_BRACES, .u.pieces = p} +#define XPK_BRACES(...) XPK_BRACES_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) +#define XPK_BRACES_OPT(...) \ + {.type = XS_PARSE_KEYWORD_BRACES|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }} + +#define XPK_CHEVRONS_pieces(p) {.type = XS_PARSE_KEYWORD_CHEVRONS, .u.pieces = p} +#define XPK_CHEVRONS(...) XPK_CHEVRONS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} })) +#define XPK_CHEVRONS_OPT(...) \ + {.type = XS_PARSE_KEYWORD_CHEVRONS|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }} + +/* back-compat for older names */ +#define XPK_PARENSCOPE_pieces XPK_PARENS_pieces +#define XPK_PARENSCOPE XPK_PARENS +#define XPK_PARENSCOPE_OPT XPK_PARENS_OPT +#define XPK_ARGSCOPE_pieces XPK_ARGS_pieces +#define XPK_ARGSCOPE XPK_ARGS +#define XPK_BRACKETSCOPE_pieces XPK_BRACKETS_pieces +#define XPK_BRACKETSCOPE XPK_BRACKETS +#define XPK_BRACKETSCOPE_OPT XPK_BRACKETS_OPT +#define XPK_BRACESCOPE_pieces XPK_BRACES_pieces +#define XPK_BRACESCOPE XPK_BRACES +#define XPK_BRACESCOPE_OPT XPK_BRACES_OPT +#define XPK_CHEVRONSCOPE_pieces XPK_CHEVRONS_pieces +#define XPK_CHEVRONSCOPE XPK_CHEVRONS +#define XPK_CHEVRONSCOPE_OPT XPK_CHEVRONS_OPT + +/* This type defined in XSParseInfix.h */ +typedef struct XSParseInfixInfo XSParseInfixInfo; + +typedef struct { + union { + OP *op; + CV *cv; + SV *sv; + int i; + struct { SV *name; SV *value; } attr; + PADOFFSET padix; + XSParseInfixInfo *infix; + }; + int line; +} XSParseKeywordPiece; + +struct XSParseKeywordHooks { + U32 flags; + + /* used by build1 */ + struct XSParseKeywordPieceType piece1; + /* alternatively, used by build */ + const struct XSParseKeywordPieceType *pieces; + + /* These two hooks are ANDed together; both must pass, if present */ + const char *permit_hintkey; + bool (*permit) (pTHX_ void *hookdata); + + void (*check)(pTHX_ void *hookdata); + + /* These are alternatives; the first one defined is used */ + int (*parse)(pTHX_ OP **opp, void *hookdata); + int (*build)(pTHX_ OP **out, XSParseKeywordPiece *args[], size_t nargs, void *hookdata); + int (*build1)(pTHX_ OP **out, XSParseKeywordPiece *arg0, void *hookdata); +}; + +static void (*register_xs_parse_keyword_func)(pTHX_ const char *kwname, const struct XSParseKeywordHooks *hooks, void *hookdata); +#define register_xs_parse_keyword(kwname, hooks, hookdata) S_register_xs_parse_keyword(aTHX_ kwname, hooks, hookdata) +static void S_register_xs_parse_keyword(pTHX_ const char *kwname, const struct XSParseKeywordHooks *hooks, void *hookdata) +{ + if(!register_xs_parse_keyword_func) + croak("Must call boot_xs_parse_keyword() first"); + + (*register_xs_parse_keyword_func)(aTHX_ kwname, hooks, hookdata); +} + +#define boot_xs_parse_keyword(ver) S_boot_xs_parse_keyword(aTHX_ ver) +static void S_boot_xs_parse_keyword(pTHX_ double ver) { + SV **svp; + SV *versv = ver ? newSVnv(ver) : NULL; + + load_module(PERL_LOADMOD_NOIMPORT, newSVpvs("XS::Parse::Keyword"), versv, NULL); + + svp = hv_fetchs(PL_modglobal, "XS::Parse::Keyword/ABIVERSION_MIN", 0); + if(!svp) + croak("XS::Parse::Keyword ABI minimum version missing"); + int abi_ver = SvIV(*svp); + if(abi_ver > XSPARSEKEYWORD_ABI_VERSION) + croak("XS::Parse::Keyword ABI version mismatch - library supports >= %d, compiled for %d", + abi_ver, XSPARSEKEYWORD_ABI_VERSION); + + svp = hv_fetchs(PL_modglobal, "XS::Parse::Keyword/ABIVERSION_MAX", 0); + abi_ver = SvIV(*svp); + if(abi_ver < XSPARSEKEYWORD_ABI_VERSION) + croak("XS::Parse::Keyword ABI version mismatch - library supports <= %d, compiled for %d", + abi_ver, XSPARSEKEYWORD_ABI_VERSION); + + register_xs_parse_keyword_func = INT2PTR(void (*)(pTHX_ const char *, const struct XSParseKeywordHooks *, void *), + SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Keyword/register()@2", 0))); +} + +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/src/infix.c new/XS-Parse-Keyword-0.47/src/infix.c --- old/XS-Parse-Keyword-0.44/src/infix.c 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/src/infix.c 2024-11-25 17:42:13.000000000 +0100 @@ -176,6 +176,8 @@ return (*hd.hooks->new_op)(aTHX_ flags, lhs, rhs, parsedata, hd.data); } + assert(hd.hooks->ppaddr); + OP *ret; if(hd.hooks->flags & XPI_FLAG_LISTASSOC) { OP *listop = lhs; @@ -1114,6 +1116,9 @@ } #endif + if(!hooks->new_op && !hooks->ppaddr) + croak("Cannot register third-party infix operator without at least one of .new_op or .ppaddr"); + struct Registration *reg; Newx(reg, 1, struct Registration); @@ -1217,7 +1222,9 @@ reg_builtin(aTHX_ "<=>", XPI_CLS_ORDERING, OP_NCMP); /* other predicates */ +#ifdef OP_SMARTMATCH /* removed in perl 5.41.3 */ reg_builtin(aTHX_ "~~", XPI_CLS_SMARTMATCH, OP_SMARTMATCH); +#endif reg_builtin(aTHX_ "=~", XPI_CLS_MATCHRE, OP_MATCH); /* TODO: !~ */ #ifdef HAVE_OP_ISA diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/XS-Parse-Keyword-0.44/src/keyword.c new/XS-Parse-Keyword-0.47/src/keyword.c --- old/XS-Parse-Keyword-0.44/src/keyword.c 2024-07-19 14:26:26.000000000 +0200 +++ new/XS-Parse-Keyword-0.47/src/keyword.c 2024-11-25 17:42:13.000000000 +0100 @@ -510,6 +510,7 @@ case XS_PARSE_KEYWORD_ARITHEXPR: case XS_PARSE_KEYWORD_TERMEXPR: + case XS_PARSE_KEYWORD_LISTEXPR: { if(is_enterleave) ENTER; @@ -526,7 +527,7 @@ /* TODO: This auto-parens behaviour ought to be tuneable, depend on how * many args, open at i=0 and close at i=MAX, etc... */ - if(lex_peek_unichar(0) == '(') { + if(type != XS_PARSE_KEYWORD_LISTEXPR && lex_peek_unichar(0) == '(') { /* consume a fullexpr and stop at the close paren */ lex_read_unichar(0); @@ -551,6 +552,9 @@ case XS_PARSE_KEYWORD_TERMEXPR: THISARG.op = parse_termexpr(optflag); break; + case XS_PARSE_KEYWORD_LISTEXPR: + THISARG.op = parse_listexpr(optflag); + break; } CHECK_PARSEFAIL; } @@ -566,16 +570,6 @@ return; } - case XS_PARSE_KEYWORD_LISTEXPR: - THISARG.op = parse_listexpr(optflag); - CHECK_PARSEFAIL; - - if(want && THISARG.op) - THISARG.op = op_contextualize(THISARG.op, want); - - (*argidx)++; - return; - case XS_PARSE_KEYWORD_IDENT: THISARG.sv = lex_scan_ident(); if(!THISARG.sv && !is_optional) @@ -892,7 +886,7 @@ else if(reg->apiver < 2) { /* version 1 ->build1 used to take a struct directly, not a pointer thereto */ int (*v1_build1)(pTHX_ OP **out, XSParseKeywordPiece_v1 arg0, void *hookdata) = - (int (*)())hooks->build1; + (int (*)(pTHX_ OP **, XSParseKeywordPiece_v1, void *))hooks->build1; XSParseKeywordPiece_v1 arg0_v1; Copy(args + 0, &arg0_v1, 1, XSParseKeywordPiece_v1); ret = (*v1_build1)(aTHX_ op, arg0_v1, reg->hookdata);