On Mon, Feb 26, 2018 at 3:35 AM, Ævar Arnfjörð Bjarmason
<[email protected]> wrote:
> Add the scaffolding necessary for precompiling wildmatch()
> patterns.
>
> There is currently no point in doing this with the wildmatch()
> function we have now, since it can't make any use of precompiling the
> pattern.
>
> But adding this interface and making use of it will make it easy to
> refactor the wildmatch() function to parse the pattern into opcodes as
> some glob() implementations do, or to drop an alternate wildmatch()
> backend in which trades parsing slowness for faster matching, such as
> the PCRE v2 conversion function that understands the wildmatch()
> syntax.
>
> It's very unlikely that we'll remove the wildmatch() function as a
> convenience wrapper even if we end up requiring a separate compilation
> step in some future implementation. There are a lot of one-shot
> wildmatches in the codebase, in that case most likely wildmatch() will
> be kept around as a shorthand for wildmatch_{compile,match,free}().
>
> I modeled this interface on the PCRE v2 interface. I didn't go with a
> glob(3) & globfree(3)-like interface because that would require every
> wildmatch() user to pass a dummy parameter, which I got rid of in
> 55d3426929 ("wildmatch: remove unused wildopts parameter",
> 2017-06-22).
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]>
> ---
> wildmatch.c | 25 +++++++++++++++++++++++++
> wildmatch.h | 11 +++++++++++
> 2 files changed, 36 insertions(+)
>
> diff --git a/wildmatch.c b/wildmatch.c
> index d074c1be10..032f339391 100644
> --- a/wildmatch.c
> +++ b/wildmatch.c
> @@ -276,3 +276,28 @@ int wildmatch(const char *pattern, const char *text,
> unsigned int flags)
> {
> return dowild((const uchar*)pattern, (const uchar*)text, flags);
> }
> +
> +struct wildmatch_compiled *wildmatch_compile(const char *pattern,
> + unsigned int flags)
> +{
> + struct wildmatch_compiled *wildmatch_compiled = xmalloc(
> + sizeof(struct wildmatch_compiled));
struct wildmatch_compiled *data = xmalloc(sizeof(*data));
?
It shortens the line a bit. We already use WM_ prefix for wildmatch
flags, perhaps we can use it for wildmatch structs too (e.g.
wm_compiled instead)
> + wildmatch_compiled->pattern = xstrdup(pattern);
> + wildmatch_compiled->flags = flags;
> +
> + return wildmatch_compiled;
> +}
> +
> +int wildmatch_match(struct wildmatch_compiled *wildmatch_compiled,
> + const char *text)
> +{
> + return wildmatch(wildmatch_compiled->pattern, text,
> + wildmatch_compiled->flags);
> +}
> +
> +void wildmatch_free(struct wildmatch_compiled *wildmatch_compiled)
> +{
> + if (wildmatch_compiled)
> + free((void *)wildmatch_compiled->pattern);
Why do make pattern type "const char *" then remove "const" with
typecast here? Why not just "char *" in wildmatch_compiled?
If the reason is to avoid other users from peeking in and modifying
it, then perhaps you can move struct wildmatch_compiled to wildmatch.c
and keep it an opaque struct pointer.
> + free(wildmatch_compiled);
> +}
> diff --git a/wildmatch.h b/wildmatch.h
> index b8c826aa68..2fc00e0ca0 100644
> --- a/wildmatch.h
> +++ b/wildmatch.h
> @@ -10,5 +10,16 @@
> #define WM_ABORT_ALL -1
> #define WM_ABORT_TO_STARSTAR -2
>
> +struct wildmatch_compiled {
> + const char *pattern;
> + unsigned int flags;
> +};
> +
> int wildmatch(const char *pattern, const char *text, unsigned int flags);
> +struct wildmatch_compiled *wildmatch_compile(const char *pattern,
> + unsigned int flags);
> +int wildmatch_match(struct wildmatch_compiled *wildmatch_compiled,
> + const char *text);
> +void wildmatch_free(struct wildmatch_compiled *wildmatch_compiled);
> +
> #endif
> --
> 2.15.1.424.g9478a66081
>
--
Duy