From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: libc-alpha@sourceware.org, Paul Eggert <eggert@cs.ucla.edu>
Cc: bug-gnulib@gnu.org
Subject: [PATCH 1/2] posix: User scratch_buffer on fnmatch
Date: Mon, 4 Jan 2021 17:25:27 -0300 [thread overview]
Message-ID: <20210104202528.1228255-1-adhemerval.zanella@linaro.org> (raw)
It removes the alloca usage on the string convertion to wide characters
before calling the internal function.
Checked on x86_64-linux-gnu.
---
posix/fnmatch.c | 152 +++++++++++++++++-------------------------------
1 file changed, 53 insertions(+), 99 deletions(-)
diff --git a/posix/fnmatch.c b/posix/fnmatch.c
index 5896812c96..ac254fc9ac 100644
--- a/posix/fnmatch.c
+++ b/posix/fnmatch.c
@@ -75,6 +75,7 @@ extern int fnmatch (const char *pattern, const char *string, int flags);
#include <intprops.h>
#include <flexmember.h>
+#include <scratch_buffer.h>
#ifdef _LIBC
typedef ptrdiff_t idx_t;
@@ -231,119 +232,72 @@ is_char_class (const wchar_t *wcs)
#include "fnmatch_loop.c"
+static int
+fnmatch_convert_to_wide (const char *str, struct scratch_buffer *buf,
+ size_t *n)
+{
+ mbstate_t ps;
+ memset (&ps, '\0', sizeof (ps));
+
+ size_t nw = buf->length / sizeof (wchar_t);
+ *n = strnlen (str, nw - 1);
+ if (__glibc_likely (*n < nw))
+ {
+ const char *p = str;
+ *n = mbsrtowcs (buf->data, &p, *n + 1, &ps);
+ if (__glibc_unlikely (*n == (size_t) -1))
+ /* Something wrong.
+ XXX Do we have to set 'errno' to something which mbsrtows hasn't
+ already done? */
+ return -1;
+ if (p == NULL)
+ return 0;
+ memset (&ps, '\0', sizeof (ps));
+ }
+
+ *n = mbsrtowcs (NULL, &str, 0, &ps);
+ if (__glibc_unlikely (*n == (size_t) -1))
+ return -1;
+ if (!scratch_buffer_set_array_size (buf, *n + 1, sizeof (wchar_t)))
+ {
+ __set_errno (ENOMEM);
+ return -2;
+ }
+ assert (mbsinit (&ps));
+ mbsrtowcs (buf->data, &str, *n + 1, &ps);
+ return 0;
+}
int
fnmatch (const char *pattern, const char *string, int flags)
{
if (__glibc_unlikely (MB_CUR_MAX != 1))
{
- mbstate_t ps;
size_t n;
- const char *p;
- wchar_t *wpattern_malloc = NULL;
- wchar_t *wpattern;
- wchar_t *wstring_malloc = NULL;
- wchar_t *wstring;
- size_t alloca_used = 0;
+ struct scratch_buffer wpattern;
+ scratch_buffer_init (&wpattern);
+ struct scratch_buffer wstring;
+ scratch_buffer_init (&wstring);
+ int r;
/* Convert the strings into wide characters. */
- memset (&ps, '\0', sizeof (ps));
- p = pattern;
- n = strnlen (pattern, 1024);
- if (__glibc_likely (n < 1024))
- {
- wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
- alloca_used);
- n = mbsrtowcs (wpattern, &p, n + 1, &ps);
- if (__glibc_unlikely (n == (size_t) -1))
- /* Something wrong.
- XXX Do we have to set 'errno' to something which mbsrtows hasn't
- already done? */
- return -1;
- if (p)
- {
- memset (&ps, '\0', sizeof (ps));
- goto prepare_wpattern;
- }
- }
- else
- {
- prepare_wpattern:
- n = mbsrtowcs (NULL, &pattern, 0, &ps);
- if (__glibc_unlikely (n == (size_t) -1))
- /* Something wrong.
- XXX Do we have to set 'errno' to something which mbsrtows hasn't
- already done? */
- return -1;
- if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
- {
- __set_errno (ENOMEM);
- return -2;
- }
- wpattern_malloc = wpattern
- = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
- assert (mbsinit (&ps));
- if (wpattern == NULL)
- return -2;
- (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
- }
-
- assert (mbsinit (&ps));
- n = strnlen (string, 1024);
- p = string;
- if (__glibc_likely (n < 1024))
- {
- wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
- alloca_used);
- n = mbsrtowcs (wstring, &p, n + 1, &ps);
- if (__glibc_unlikely (n == (size_t) -1))
- {
- /* Something wrong.
- XXX Do we have to set 'errno' to something which
- mbsrtows hasn't already done? */
- free_return:
- free (wpattern_malloc);
- return -1;
- }
- if (p)
- {
- memset (&ps, '\0', sizeof (ps));
- goto prepare_wstring;
- }
- }
- else
+ r = fnmatch_convert_to_wide (pattern, &wpattern, &n);
+ if (r != 0)
+ return r;
+ r = fnmatch_convert_to_wide (string, &wstring, &n);
+ if (r != 0)
{
- prepare_wstring:
- n = mbsrtowcs (NULL, &string, 0, &ps);
- if (__glibc_unlikely (n == (size_t) -1))
- /* Something wrong.
- XXX Do we have to set 'errno' to something which mbsrtows hasn't
- already done? */
- goto free_return;
- if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
- {
- free (wpattern_malloc);
- __set_errno (ENOMEM);
- return -2;
- }
-
- wstring_malloc = wstring
- = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
- if (wstring == NULL)
- {
- free (wpattern_malloc);
- return -2;
- }
- assert (mbsinit (&ps));
- (void) mbsrtowcs (wstring, &string, n + 1, &ps);
+ scratch_buffer_free (&wpattern);
+ return n;
}
- int res = internal_fnwmatch (wpattern, wstring, wstring + n,
+ int res = internal_fnwmatch (wpattern.data, wstring.data,
+ (wchar_t *) wstring.data + n,
flags & FNM_PERIOD, flags, NULL,
- alloca_used);
+ false);
- free (wstring_malloc);
- free (wpattern_malloc);
+ scratch_buffer_free (&wstring);
+ scratch_buffer_free (&wpattern);
return res;
}
--
2.25.1
next reply other threads:[~2021-01-04 20:25 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-04 20:25 Adhemerval Zanella [this message]
2021-01-04 20:25 ` [PATCH 2/2] posix: Remove alloca usage for internal fnmatch implementation Adhemerval Zanella
2021-03-08 12:59 ` Florian Weimer
2021-10-20 15:12 ` Adhemerval Zanella
2021-10-21 9:54 ` Florian Weimer
2021-01-04 20:35 ` [PATCH 1/2] posix: User scratch_buffer on fnmatch Florian Weimer
2021-01-05 13:07 ` Adhemerval Zanella
2021-01-13 19:25 ` Paul Eggert
2021-01-13 19:39 ` Florian Weimer
2021-01-13 23:36 ` Bruno Haible
2021-01-14 10:00 ` Florian Weimer
2021-03-06 17:18 ` Paul Eggert
2021-03-06 20:17 ` dealing with non-ASCII-safe encodings Bruno Haible
2021-01-14 11:44 ` [PATCH 1/2] posix: User scratch_buffer on fnmatch Adhemerval Zanella
2021-01-15 6:56 ` Paul Eggert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://lists.gnu.org/mailman/listinfo/bug-gnulib
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210104202528.1228255-1-adhemerval.zanella@linaro.org \
--to=adhemerval.zanella@linaro.org \
--cc=bug-gnulib@gnu.org \
--cc=eggert@cs.ucla.edu \
--cc=libc-alpha@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).