+2023-09-26 Paul Eggert <eggert@cs.ucla.edu>
+
+ Remaining support for GNULIB_MCEL_PREFER
+ Support mcel API in remaining modules where this might matter,
+ for apps that prefer it.
+ * lib/mbmemcasecmp.c, lib/mbscspn.c, lib/mbsncasecmp.c, lib/mbsnlen.c:
+ * lib/mbspbrk.c, lib/mbspcasecmp.c, lib/mbssep.c, lib/mbsspn.c:
+ * lib/regex-quote.c:
+ Include mcel.h instead of mbiterf.h or mbuiterf.h,
+ if GNULIB_MCEL_PREFER.
+ * lib/mbmemcasecmp.c (mbmemcasecmp), lib/mbscspn.c (mbscspn):
+ * lib/mbsncasecmp.c (mbsncasecmp), lib/mbsnlen.c (mbsnlen):
+ * lib/mbspbrk.c (mbspbrk), lib/mbspcasecmp.c (mbspcasecmp):
+ * lib/mbssep.c (mbssep), lib/mbsspn.c (mbsspn):
+ * lib/regex-quote.c (regex_quote_length, regex_quote_copy):
+ Use mcel API, if GNULIB_MCEL_PREFER.
+ * lib/mbscspn.c, lib/mbspbrk.c, lib/mbspcasecmp.c, lib/mbsspn.c:
+ Include stdlib.h, for MB_CUR_MAX.
+ * modules/mbmemcasecmp, modules/mbsncasecmp, modules/mbspcasecmp:
+ Depend on c32tolower.
+ * modules/regex-quote: Depend on mempcpy.
+
2023-09-25 Paul Eggert <eggert@cs.ucla.edu>
mbscasestr: support GNULIB_MCEL_PREFER
#include <limits.h>
#include <stdlib.h>
-#include "mbiterf.h"
+#if GNULIB_MCEL_PREFER
+# include "mcel.h"
+#else
+# include "mbiterf.h"
+#endif
int
mbmemcasecmp (const char *s1, size_t n1, const char *s2, size_t n2)
const char *iter1 = s1;
const char *iter2 = s2;
+ const char *s1_end = s1 + n1;
+ const char *s2_end = s2 + n2;
if (MB_CUR_MAX > 1)
{
- const char *s1_end = s1 + n1;
+#if GNULIB_MCEL_PREFER
+ while ((iter1 < s1_end) & (iter2 < s2_end))
+ {
+ mcel_t g1 = mcel_scan (iter1, s1_end); iter1 += g1.len;
+ mcel_t g2 = mcel_scan (iter2, s2_end); iter2 += g2.len;
+ int cmp = mcel_tocmp (c32tolower, g1, g2);
+ if (cmp)
+ return cmp;
+ }
+ return (iter1 < s1_end) - (iter2 < s2_end);
+#else
mbif_state_t state1;
mbif_init (state1);
- const char *s2_end = s2 + n2;
mbif_state_t state2;
mbif_init (state2);
/* s1 terminated before s2. */
return -1;
return 0;
+#endif
}
else
{
- const char *s1_end = s1 + n1;
- const char *s2_end = s2 + n2;
-
while (iter1 < s1_end && iter2 < s2_end)
{
unsigned char c1 = *iter1++;
/* Specification. */
#include <string.h>
-#include "mbuiterf.h"
+#include <stdlib.h>
+
+#if GNULIB_MCEL_PREFER
+# include "mcel.h"
+#else
+# include "mbuiterf.h"
+#endif
/* Find the first occurrence in the character string STRING of any character
in the character string ACCEPT. Return the number of bytes from the
/* General case. */
if (MB_CUR_MAX > 1)
{
+#if GNULIB_MCEL_PREFER
+ mcel_t a, g;
+ size_t i;
+ for (i = 0; string[i]; i += g.len)
+ {
+ g = mcel_scanz (string + i);
+ if (g.len == 1)
+ {
+ if (mbschr (accept, string[i]))
+ return i;
+ }
+ else
+ for (char const *aiter = accept; *aiter; aiter += a.len)
+ {
+ a = mcel_scanz (aiter);
+ if (mcel_cmp (g, a) == 0)
+ return i;
+ }
+ }
+ return i;
+#else
mbuif_state_t state;
const char *iter;
for (mbuif_init (state), iter = string; mbuif_avail (state, iter); )
}
found:
return iter - string;
+#endif
}
else
return strcspn (string, accept);
#include <ctype.h>
#include <limits.h>
+#include <stdlib.h>
-#include "mbuiterf.h"
+#if GNULIB_MCEL_PREFER
+# include "mcel.h"
+#else
+# include "mbuiterf.h"
+#endif
/* Compare the initial segment of the character string S1 consisting of at most
N characters with the initial segment of the character string S2 consisting
most often already in the very few first characters. */
if (MB_CUR_MAX > 1)
{
+#if GNULIB_MCEL_PREFER
+ while (true)
+ {
+ mcel_t g1 = mcel_scanz (iter1); iter1 += g1.len;
+ mcel_t g2 = mcel_scanz (iter2); iter2 += g2.len;
+ int cmp = mcel_tocmp (c32tolower, g1, g2);
+ n--;
+ if (cmp | !n | !g1.ch)
+ return cmp;
+ }
+#else
mbuif_state_t state1;
mbuif_init (state1);
/* s1 terminated before s2 and n. */
return -1;
return 0;
+#endif
}
else
for (;;)
#include <stdlib.h>
-#include "mbiterf.h"
+#if GNULIB_MCEL_PREFER
+# include "mcel.h"
+#else
+# include "mbiterf.h"
+#endif
/* Return the number of multibyte characters in the character string starting
at STRING and ending at STRING + LEN. */
size_t count = 0;
const char *string_end = string + len;
+
+#if GNULIB_MCEL_PREFER
+ for (; *string; string += mcel_scan (string, string_end).len)
+ count++;
+#else
mbif_state_t state;
const char *iter;
for (mbif_init (state), iter = string; mbif_avail (state, iter, string_end); )
count++;
iter += mb_len (cur);
}
+#endif
return count;
}
/* Specification. */
#include <string.h>
-#include "mbuiterf.h"
+#include <stdlib.h>
+
+#if GNULIB_MCEL_PREFER
+# include "mcel.h"
+#else
+# include "mbuiterf.h"
+#endif
/* Find the first occurrence in the character string STRING of any character
in the character string ACCEPT. Return the pointer to it, or NULL if none
/* General case. */
if (MB_CUR_MAX > 1)
{
+ char const *iter = string;
+#if GNULIB_MCEL_PREFER
+ mcel_t a, g;
+ for (char const *iter = string; *iter; iter += g.len)
+ {
+ g = mcel_scanz (iter);
+ if (g.len == 1)
+ {
+ if (mbschr (accept, *iter))
+ return (char *) iter;
+ }
+ else
+ for (char const *aiter = accept; *aiter; aiter += a.len)
+ {
+ a = mcel_scanz (aiter);
+ if (mcel_cmp (a, g) == 0)
+ return (char *) iter;
+ }
+ }
+#else
mbuif_state_t state;
- const char *iter;
- for (mbuif_init (state), iter = string; mbuif_avail (state, iter); )
+ for (mbuif_init (state); mbuif_avail (state, iter); )
{
mbchar_t cur = mbuif_next (state, iter);
if (mb_len (cur) == 1)
}
iter += mb_len (cur);
}
+#endif
return NULL;
}
else
#include <string.h>
#include <ctype.h>
+#include <stdlib.h>
-#include "mbuiterf.h"
+#if GNULIB_MCEL_PREFER
+# include "mcel.h"
+#else
+# include "mbuiterf.h"
+#endif
/* Compare the initial segment of the character string STRING consisting of
at most mbslen (PREFIX) characters with the character string PREFIX,
most often already in the very few first characters. */
if (MB_CUR_MAX > 1)
{
+#if GNULIB_MCEL_PREFER
+ while (*iter2)
+ {
+ if (!*iter1)
+ return NULL;
+ mcel_t g1 = mcel_scanz (iter1); iter1 += g1.len;
+ mcel_t g2 = mcel_scanz (iter2); iter2 += g2.len;
+ if (mcel_tocmp (c32tolower, g1, g2) != 0)
+ return NULL;
+ }
+ return (char *) iter1;
+#else
mbuif_state_t state1;
mbuif_init (state1);
else
/* STRING terminated before PREFIX. */
return NULL;
+#endif
}
else
for (;; iter1++, iter2++)
#include <stdlib.h>
-#include "mbuiterf.h"
+#if GNULIB_MCEL_PREFER
+# include "mcel.h"
+#else
+# include "mbuiterf.h"
+#endif
char *
mbssep (char **stringp, const char *delim)
if (MB_CUR_MAX > 1)
{
char *start = *stringp;
- char *ptr;
if (start == NULL)
return NULL;
/* No need to optimize the cases of 0 or 1 delimiters specially,
since mbspbrk already optimizes them. */
- ptr = mbspbrk (start, delim);
+ char *ptr = mbspbrk (start, delim);
if (ptr == NULL)
- {
- *stringp = NULL;
- return start;
- }
+ *stringp = NULL;
else
{
+#if GNULIB_MCEL_PREFER
+ *stringp = ptr + mcel_scanz (ptr).len;
+#else
mbuif_state_t state;
mbuif_init (state);
if (!mbuif_avail (state, ptr))
abort ();
mbchar_t cur = mbuif_next (state, ptr);
- *ptr = '\0';
*stringp = ptr + mb_len (cur);
- return start;
+#endif
+ *ptr = '\0';
}
+ return start;
}
else
return strsep (stringp, delim);
/* Specification. */
#include <string.h>
-#include "mbuiterf.h"
+#include <stdlib.h>
+
+#if GNULIB_MCEL_PREFER
+# include "mcel.h"
+#else
+# include "mbuiterf.h"
+#endif
/* Find the first occurrence in the character string STRING of any character
not in the character string REJECT. Return the number of bytes from the
if (reject[1] == '\0')
{
unsigned char uc = (unsigned char) reject[0];
+ const char *iter = string;
if (MB_CUR_MAX > 1)
{
+#if GNULIB_MCEL_PREFER
+ for (mcel_t g; *iter; iter += g.len)
+ {
+ g = mcel_scanz (iter);
+ if (! (g.len == 1 && (unsigned char) *iter == uc))
+ break;
+ }
+#else
mbuif_state_t state;
- const char *iter;
- for (mbuif_init (state), iter = string; mbuif_avail (state, iter); )
+ for (mbuif_init (state); mbuif_avail (state, iter); )
{
mbchar_t cur = mbuif_next (state, iter);
if (!(mb_len (cur) == 1 && (unsigned char) *iter == uc))
break;
iter += mb_len (cur);
}
- return iter - string;
+#endif
}
else
{
- const char *ptr;
-
- for (ptr = string; *ptr != '\0'; ptr++)
- if ((unsigned char) *ptr != uc)
+ for (; *iter != '\0'; iter++)
+ if ((unsigned char) *iter != uc)
break;
- return ptr - string;
}
+ return iter - string;
}
/* General case. */
if (MB_CUR_MAX > 1)
{
+#if GNULIB_MCEL_PREFER
+ for (size_t i = 0; ; )
+ {
+ char c = string[i];
+ if (!c)
+ return i;
+ mcel_t g = mcel_scanz (string + i);
+ if (g.len == 1)
+ {
+ if (!mbschr (reject, c))
+ return i;
+ }
+ else
+ {
+ for (char const *aiter = reject; ; )
+ {
+ if (!*aiter)
+ return i;
+ mcel_t a = mcel_scanz (aiter);
+ if (mcel_cmp (a, g) == 0)
+ break;
+ aiter += a.len;
+ }
+ }
+ i += g.len;
+ }
+#else
mbuif_state_t state;
const char *iter;
for (mbuif_init (state), iter = string; mbuif_avail (state, iter); )
}
found:
return iter - string;
+#endif
}
else
return strspn (string, reject);
#include <string.h>
-#include "mbuiter.h"
+#if GNULIB_MCEL_PREFER
+# include "mcel.h"
+#else
+# include "mbuiter.h"
+#endif
+
#include "xalloc.h"
/* Characters that are special in a BRE. */
length += 2; /* for '^' at the beginning and '$' at the end */
if (spec->multibyte)
{
+#if GNULIB_MCEL_PREFER
+ char const *iter = string;
+ for (mcel_t g; *iter; iter += g.len)
+ {
+ g = mcel_scanz (iter);
+ /* We know that special contains only ASCII characters. */
+ length += g.len == 1 && strchr (special, *iter);
+ }
+ length += iter - string;
+#else
mbui_iterator_t iter;
for (mbui_init (iter, string); mbui_avail (iter); mbui_advance (iter))
length += 1;
length += mb_len (mbui_cur (iter));
}
+#endif
}
else
{
*p++ = '^';
if (spec->multibyte)
{
+#if GNULIB_MCEL_PREFER
+ for (char const *iter = string; *iter; )
+ {
+ mcel_t g = mcel_scanz (iter);
+ *p = '\\';
+ /* We know that special contains only ASCII characters. */
+ p += g.len == 1 && strchr (special, *iter);
+ p = mempcpy (p, iter, g.len);
+ iter += g.len;
+ }
+#else
mbui_iterator_t iter;
for (mbui_init (iter, string); mbui_avail (iter); mbui_advance (iter))
lib/mbmemcasecmp.c
Depends-on:
+c32tolower
mbiterf
configure.ac:
lib/mbsncasecmp.c
Depends-on:
+c32tolower
mbuiterf
string
lib/mbspcasecmp.c
Depends-on:
+c32tolower
mbuiterf
string
stdbool
xalloc
mbuiter
+mempcpy
configure.ac:
AC_REQUIRE([AC_C_RESTRICT])