From patchwork Mon Jun 12 00:47:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ahelenia_Ziemia=C5=84ska?= X-Patchwork-Id: 1793734 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=rBjtNanr; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QfY2M5TnYz20Vx for ; Mon, 12 Jun 2023 10:48:11 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 40D253858D32 for ; Mon, 12 Jun 2023 00:48:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 40D253858D32 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1686530888; bh=Nqyp832opQvG1CpfSLldTVLz6w0HbAmAna4sxDICPtY=; h=Date:To:Cc:Subject:References:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=rBjtNanrZydQA9mrLCQGV5Bz0tmaxL9d5PJ+DFxGcb1wzT9yO6qtvOG35WgwmEBuh T6kSjCIx/KzD/6eapxYmagrClD3GgKOe6/yYbq1pYrptgaVKMR12X7K3q8aECYM15m JekfqG8SX4HlBseS6xSiJ6fQhAODoamtm3RySFks= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from tarta.nabijaczleweli.xyz (unknown [139.28.40.42]) by sourceware.org (Postfix) with ESMTP id D1CAB3858D20 for ; Mon, 12 Jun 2023 00:47:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D1CAB3858D20 Received: from tarta.nabijaczleweli.xyz (unknown [192.168.1.250]) by tarta.nabijaczleweli.xyz (Postfix) with ESMTPSA id 4CF65580; Mon, 12 Jun 2023 02:47:47 +0200 (CEST) Date: Mon, 12 Jun 2023 02:47:46 +0200 To: Adhemerval Zanella Netto Cc: libc-alpha@sourceware.org, Carlos O'Donell Subject: [PATCH v7 1/3] posix: regcomp(): clear RE_DOT_NOT_NULL Message-ID: References: <4450a8f3-3774-5bbc-ebe2-64d8a25fdacc@linaro.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <4450a8f3-3774-5bbc-ebe2-64d8a25fdacc@linaro.org> User-Agent: NeoMutt/20230517 X-Spam-Status: No, score=-10.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_INFOUSMEBIZ, PDS_RDNS_DYNAMIC_FP, RDNS_DYNAMIC, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: =?utf-8?b?0L3QsNCxIHZpYSBMaWJjLWFscGhh?= From: =?utf-8?q?Ahelenia_Ziemia=C5=84ska?= Reply-To: =?utf-8?b?0L3QsNCx?= Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" The POSIX API always stops at first NUL so there's no change for that. The BSD REG_STARTEND API, with its explicit range, can include NULs within that range, and those NULs are matched with . and [^]. Heretofor, for a string of "a\0c", glibc would match "[^q]c", but not ".c". This is both inconsistent and nonconformant to BSD REG_STARTEND. With this patch, they're identical like you'd expect, and the tst-reg-startend.c: ..c: a^@c: no match$ failure is removed. Another approach would be to remove it from _RE_SYNTAX_POSIX_COMMON, but it's unclear to me what the custody chain is like for that and what other regex APIs glibc offers that could be affected by this. Signed-off-by: Ahelenia Ziemiańska --- No changes (rebased cleanly); full resend. posix/regcomp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posix/regcomp.c b/posix/regcomp.c index 12650714c0..a928ef6c2d 100644 --- a/posix/regcomp.c +++ b/posix/regcomp.c @@ -462,7 +462,7 @@ regcomp (regex_t *__restrict preg, const char *__restrict pattern, int cflags) { reg_errcode_t ret; reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED - : RE_SYNTAX_POSIX_BASIC); + : RE_SYNTAX_POSIX_BASIC) & ~RE_DOT_NOT_NULL; preg->buffer = NULL; preg->allocated = 0; From patchwork Mon Jun 12 00:47:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ahelenia_Ziemia=C5=84ska?= X-Patchwork-Id: 1793735 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=F41Y68ts; dkim-atps=neutral Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QfY2R1mnPz20Vx for ; Mon, 12 Jun 2023 10:48:15 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D5F54385770A for ; Mon, 12 Jun 2023 00:48:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D5F54385770A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1686530890; bh=2zd0d5rlj+ZtyDE4z0psSjOIMQ6evAgKnIwjW5/yMDE=; h=Date:To:Cc:Subject:References:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=F41Y68tsHkLhWsJxDliNiSgKByqKhWjnEDR7nqKI0zoB5TOkDcN8n6qDKGxVCLXLW SyZoF1/4D/q6LJ2P+IH/okChv8yCH81JrGuYIgNIX0UzcGrlPCUCMS/XhmBazRk+W5 Uh4k8InZMEX0U2ze6HnUBh5E47eph32cIuHpX/UY= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from tarta.nabijaczleweli.xyz (unknown [139.28.40.42]) by sourceware.org (Postfix) with ESMTP id 2BCC13858D33 for ; Mon, 12 Jun 2023 00:47:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2BCC13858D33 Received: from tarta.nabijaczleweli.xyz (unknown [192.168.1.250]) by tarta.nabijaczleweli.xyz (Postfix) with ESMTPSA id 209A3582; Mon, 12 Jun 2023 02:47:53 +0200 (CEST) Date: Mon, 12 Jun 2023 02:47:52 +0200 To: Adhemerval Zanella Netto Cc: libc-alpha@sourceware.org, Carlos O'Donell Subject: [PATCH v7 2/3] posix: regexec(): fix REG_STARTEND, pmatch->rm_so != 0 w/^ anchor Message-ID: <695cd581035b59c759477b806640ee0b70df05f7.1686530834.git.nabijaczleweli@nabijaczleweli.xyz> References: <4450a8f3-3774-5bbc-ebe2-64d8a25fdacc@linaro.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <4450a8f3-3774-5bbc-ebe2-64d8a25fdacc@linaro.org> User-Agent: NeoMutt/20230517 X-Spam-Status: No, score=-10.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_INFOUSMEBIZ, PDS_RDNS_DYNAMIC_FP, RDNS_DYNAMIC, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: =?utf-8?b?0L3QsNCxIHZpYSBMaWJjLWFscGhh?= From: =?utf-8?q?Ahelenia_Ziemia=C5=84ska?= Reply-To: =?utf-8?b?0L3QsNCx?= Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" re_search_internal () starts with /* If initial states with non-begbuf contexts have no elements, the regex must be anchored. If preg->newline_anchor is set, we'll never use init_state_nl, so do not check it. */ if (dfa->init_state->nodes.nelem == 0 && dfa->init_state_word->nodes.nelem == 0 && (dfa->init_state_nl->nodes.nelem == 0 || !preg->newline_anchor)) { if (start != 0 && last_start != 0) return REG_NOMATCH; start = last_start = 0; } and heretofor start and last_start (for example when "abc", {1, 2}, so matching just the "b") were != 0, and the return was taken for a "^b" regex, which is erroneous. Fix this by giving re_search_internal (string+rm_so, start=0), then fixing up the returned matches in an after-pass. This brings us to compatibility with the BSD spec and implementations. Signed-off-by: Ahelenia Ziemiańska --- posix/regexec.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/posix/regexec.c b/posix/regexec.c index bd0cd412d0..2ef868e1f6 100644 --- a/posix/regexec.c +++ b/posix/regexec.c @@ -187,38 +187,53 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len); string; if REG_NOTEOL is set, then $ does not match at the end. Return 0 if a match is found, REG_NOMATCH if not, REG_BADPAT if - EFLAGS is invalid. */ + EFLAGS is invalid. + + If REG_STARTEND, the bounds are + [STRING + PMATCH->rm_so, STRING + PMATCH->rm_eo) + instead of the usual + [STRING, STRING + strlen(STRING)), + but returned matches are still referenced to STRING, + and matching is unaffected (i.e. "abc", {1, 2} matches regex "^b$"). + re_search_internal () has a built-in assumption of + (start != 0) <=> (^ doesn't match), so give it a truncated view + and fix up the matches afterward. */ int regexec (const regex_t *__restrict preg, const char *__restrict string, size_t nmatch, regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) { reg_errcode_t err; - Idx start, length; + Idx startoff = 0, length; re_dfa_t *dfa = preg->buffer; + size_t i = 0; if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND)) return REG_BADPAT; if (eflags & REG_STARTEND) { - start = pmatch[0].rm_so; - length = pmatch[0].rm_eo; + startoff = pmatch[0].rm_so; + string += startoff; + length = pmatch[0].rm_eo - startoff; } else - { - start = 0; - length = strlen (string); - } + length = strlen (string); lock_lock (dfa->lock); if (preg->no_sub) - err = re_search_internal (preg, string, length, start, length, - length, 0, NULL, eflags); - else - err = re_search_internal (preg, string, length, start, length, - length, nmatch, pmatch, eflags); + nmatch = 0; + err = re_search_internal (preg, string, length, 0, length, + length, nmatch, pmatch, eflags); lock_unlock (dfa->lock); + + if (err == REG_NOERROR && startoff) + for (i = 0; i < nmatch; ++i) + if (pmatch[i].rm_so != -1) + { + pmatch[i].rm_so += startoff; + pmatch[i].rm_eo += startoff; + } return err != REG_NOERROR; } From patchwork Mon Jun 12 00:47:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ahelenia_Ziemia=C5=84ska?= X-Patchwork-Id: 1793736 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=uq0Oi/Pb; dkim-atps=neutral Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QfY3C3b97z20Vx for ; Mon, 12 Jun 2023 10:48:55 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 63F873858D32 for ; Mon, 12 Jun 2023 00:48:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 63F873858D32 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1686530933; bh=OsKEQDugO+5ug2/02MhgfQmkfHeNk/EdalvZKRNiM2g=; h=Date:To:Cc:Subject:References:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=uq0Oi/PbRkFAZyLYEHjRjD7zD6KUvXDCxQVaXHvh/bXdrghTb2O/+mwXaiziifSLU i8DCUvtvmvFjOOCrL71CIGYu5k7Rmi1mzRZBvzp4P0KU//xCfsfeM8AMyHxLeyOxiA o6DpiIXI2WYPqRoPUrkTNB1BUAP2BgJ3leAMHnvg= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from tarta.nabijaczleweli.xyz (unknown [139.28.40.42]) by sourceware.org (Postfix) with ESMTP id 5565D3858C50 for ; Mon, 12 Jun 2023 00:47:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5565D3858C50 Received: from tarta.nabijaczleweli.xyz (unknown [192.168.1.250]) by tarta.nabijaczleweli.xyz (Postfix) with ESMTPSA id 4AA6A584; Mon, 12 Jun 2023 02:47:57 +0200 (CEST) Date: Mon, 12 Jun 2023 02:47:56 +0200 To: Adhemerval Zanella Netto Cc: libc-alpha@sourceware.org, Carlos O'Donell Subject: [PATCH v7 3/3] posix: add test for REG_STARTEND Message-ID: <081705a028f41d488ff81dbe198674aa4df83b1c.1686530834.git.nabijaczleweli@nabijaczleweli.xyz> References: <4450a8f3-3774-5bbc-ebe2-64d8a25fdacc@linaro.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <4450a8f3-3774-5bbc-ebe2-64d8a25fdacc@linaro.org> User-Agent: NeoMutt/20230517 X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_INFOUSMEBIZ, PDS_RDNS_DYNAMIC_FP, RDNS_DYNAMIC, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: =?utf-8?b?0L3QsNCxIHZpYSBMaWJjLWFscGhh?= From: =?utf-8?q?Ahelenia_Ziemia=C5=84ska?= Reply-To: =?utf-8?b?0L3QsNCx?= Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" This test passes on NetBSD, the illumos gate, musl with https://www.openwall.com/lists/musl/2023/05/14/1, and now glibc. It's nothing revolutionary and the behaviour it tests is largely guaranteed by the 4.4BSD-Lite manual; nevertheless, it used to fail with tst-reg-startend.c: ^a: a^@c: no match$ tst-reg-startend.c: ^a: a^@c: wanted {1, 2}, got {1, 4}$ tst-reg-startend.c: ^a: abc: no match$ tst-reg-startend.c: ^a: abc: wanted {1, 2}, got {1, 4}$ tst-reg-startend.c: ^a.c$: a^@c: no match$ tst-reg-startend.c: ^a.c$: abc: no match$ tst-reg-startend.c: ^a.*c$: a^@c: no match$ tst-reg-startend.c: ^a.*c$: abc: no match$ tst-reg-startend.c: ^a[^c]c$: a^@c: no match$ tst-reg-startend.c: ^a[^c]c$: abc: no match$ tst-reg-startend.c: ^a..: a^@c: no match$ tst-reg-startend.c: ^a..: abc: no match$ tst-reg-startend.c: ..c: a^@c: no match$ Signed-off-by: Ahelenia Ziemiańska --- posix/Makefile | 1 + posix/tst-reg-startend.c | 142 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 posix/tst-reg-startend.c diff --git a/posix/Makefile b/posix/Makefile index e19b74cd67..abc0ff1f60 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -295,6 +295,7 @@ tests := \ tst-posix_spawn-setsid \ tst-preadwrite \ tst-preadwrite64 \ + tst-reg-startend \ tst-regcomp-truncated \ tst-regex \ tst-regex2 \ diff --git a/posix/tst-reg-startend.c b/posix/tst-reg-startend.c new file mode 100644 index 0000000000..854d430676 --- /dev/null +++ b/posix/tst-reg-startend.c @@ -0,0 +1,142 @@ +/* This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. */ + + +#include +#include +#include +#include +#include +#include +#include + + +static const regmatch_t bound = {1, 4}; + + +struct reg_res { + const char *regex; + regmatch_t result; +}; +static const struct reg_res reg_res_ac[] = { + {"^a", {1, 2}}, + {"c$", {3, 4}}, + {"^a.c$", {1, 4}}, + {"^a.*c$", {1, 4}}, + {"^a[^c]c$", {1, 4}}, + {"^a..", {1, 4}}, + {"..c", {1, 4}}, + {"[^z]c", {2, 4}}, + {} +}; +static const char *const data_ac[] = {"_a\0cdef", "_abcdef", NULL}; + +static const struct reg_res reg_res_aa[] = { + {"^", {1, 1}}, + {"^a", {1, 2}}, + {"a$", {3, 4}}, + {"^\\(a\\).\\1$", {1, 4}}, + {"^a[^a]*" , {1, 3}}, + {} +}; +static const char *const data_aa[] = {"_a\0adef", "_abadef", NULL}; + + +static void +testbunch (const struct reg_res *reg_reses, const char *const *const data) +{ +#define BASEERR(data) \ + support_record_failure (), \ + fprintf (stdout, __FILE__ ": %s: ", reg_reses->regex), \ + fwrite (data + bound.rm_so, 1, bound.rm_eo - bound.rm_so, stdout) + + for (; reg_reses->regex; ++reg_reses) + { + regex_t rgx; + assert (!regcomp (&rgx, reg_reses->regex, 0)); + + for (const char *const *dt = data; *dt; ++dt) + { + regmatch_t match = bound; + if (regexec (&rgx, *dt, 1, &match, REG_STARTEND)) + BASEERR(dt), fputs (": no match\n", stdout); + + if (memcmp(&match, ®_reses->result, sizeof (regmatch_t))) + BASEERR(dt), fprintf (stdout, ": wanted {%d, %d}, got {%d, %d}\n", + (int)reg_reses->result.rm_so, + (int)reg_reses->result.rm_eo, + (int)match.rm_so, (int)match.rm_eo); + } + + regfree(&rgx); + } +} + + +struct mb_data_exp { + const char *data; + bool exp; +}; +static const struct mb_data_exp mb_data_exp[] = { + {"_aaćdef", false}, + {"_aćdef", true}, + {} +}; + +static void +testmb (void) +{ + regex_t rgx; + const struct reg_res reg_reses[] = {{"ać"}}; + assert (!regcomp (&rgx, reg_reses->regex, 0)); + + for (const struct mb_data_exp *de = mb_data_exp; de->data; ++de) + { + regmatch_t match = bound; + if (regexec (&rgx, de->data, 1, &match, REG_STARTEND) == de->exp) + BASEERR(de->data), fprintf (stdout, ": %s match\n", + de->exp ? "no" : "yes"); + + if (memcmp(&match, &bound, sizeof (regmatch_t))) + BASEERR(de->data), fprintf (stdout, ": wanted {%d, %d}, got {%d, %d}\n", + (int)bound.rm_so, (int)bound.rm_eo, + (int)match.rm_so, (int)match.rm_eo); + } + + regfree(&rgx); +} + + +static int +do_test (void) +{ + assert (setlocale (LC_ALL, "C.UTF-8")); + + testbunch (reg_res_ac, data_ac); + testbunch (reg_res_aa, data_aa); + testmb (); + return 0; +} + + +#include