C API question.
I have a string in an SV, and a quoted regexp object in another SV. I
want to know (as a boolean?) if the string matches the regexp.
Optionally I suppose there might be captures and maybe setting $1 etc..
is good, but if not I don't really mind. It's just a true/false test.
I would have imagined there'd be some sort of API function with a
signature something like
bool regexp_match(SV *rx, SV *s);
but to my observation there doesn't seem to be anything like that.
Stuck for ideas, I went off to read how pp_match does it; being the
actual PP func behind Perl syntax like `$str =~ $pat`. Again I had
somehow expected that it would receive the string and the pattern as
two SVs on the stack and it would just do its thing, so maybe I could
hack it up by pushing my values to the stack and fake-calling the pp
func directly.
But ho-boy was I wrong.
The way that `$str =~ m/foo/` works is that the pattern is a
compiletime constant, so it becomes part of the OP_MATCH optree node
itself. Variable patterns, like `$str =~ $pat` are compiled into a
OP_MATCH + OP_REGCOMP, where the regcomp takes the pattern off the
stack and "compiles" it into a regexp, which is stored *in the actual
OP_MATCH node* of the optree. On thready perls, this goes via the pad
of course.
At leont's suggestion I then went to look at how pp_smartmatch does it,
and that has its own (static) set of functions to create a temporary
PMOP out of a pattern, which it then matches against.
This doesn't feel like a very effective API, and makes it really
nontrivial to implement such an function as outlined above.
I wonder if we want to tidy this up somewhat? Perhaps we could extract
the contents of pp_match into a helper function that then doesn't need
to have this weird communication-at-a-distance via the PMOP structure
itself, and that function can then be called by pp_match,
pp_smartmatch, and generally exposed as API for others to use.
Alternatively: Does anyone know of another easier way that I might have
missed buried somewhere in the API?
--
Paul "LeoNerd" Evans
leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
I have a string in an SV, and a quoted regexp object in another SV. I
want to know (as a boolean?) if the string matches the regexp.
Optionally I suppose there might be captures and maybe setting $1 etc..
is good, but if not I don't really mind. It's just a true/false test.
I would have imagined there'd be some sort of API function with a
signature something like
bool regexp_match(SV *rx, SV *s);
but to my observation there doesn't seem to be anything like that.
Stuck for ideas, I went off to read how pp_match does it; being the
actual PP func behind Perl syntax like `$str =~ $pat`. Again I had
somehow expected that it would receive the string and the pattern as
two SVs on the stack and it would just do its thing, so maybe I could
hack it up by pushing my values to the stack and fake-calling the pp
func directly.
But ho-boy was I wrong.
The way that `$str =~ m/foo/` works is that the pattern is a
compiletime constant, so it becomes part of the OP_MATCH optree node
itself. Variable patterns, like `$str =~ $pat` are compiled into a
OP_MATCH + OP_REGCOMP, where the regcomp takes the pattern off the
stack and "compiles" it into a regexp, which is stored *in the actual
OP_MATCH node* of the optree. On thready perls, this goes via the pad
of course.
At leont's suggestion I then went to look at how pp_smartmatch does it,
and that has its own (static) set of functions to create a temporary
PMOP out of a pattern, which it then matches against.
This doesn't feel like a very effective API, and makes it really
nontrivial to implement such an function as outlined above.
I wonder if we want to tidy this up somewhat? Perhaps we could extract
the contents of pp_match into a helper function that then doesn't need
to have this weird communication-at-a-distance via the PMOP structure
itself, and that function can then be called by pp_match,
pp_smartmatch, and generally exposed as API for others to use.
Alternatively: Does anyone know of another easier way that I might have
missed buried somewhere in the API?
--
Paul "LeoNerd" Evans
leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/