diff --git a/lib/mbrtowc-factory.c b/lib/mbrtowc-factory.c new file mode 100644 index 0000000..8786382 --- /dev/null +++ b/lib/mbrtowc-factory.c @@ -0,0 +1,580 @@ +/* Factory that produces an mbrtowc-like function for a given locale. + Copyright (C) 2018 Free Software Foundation, Inc. + Written by Bruno Haible , 2018. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#include +#include + +#include "localcharset.h" + +#if __GLIBC__ >= 2 + +static mbstate_t internal_state; + +static size_t +utf8_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) +{ + if (s == NULL) + { + pwc = NULL; + s = ""; + n = 1; + } + + if (n == 0) + return (size_t)(-2); + + /* Here n > 0. */ + + if (ps == NULL) + ps = &internal_state; + + /* ps->__count is + (number of bytes already read) + (number of total bytes expected) << 8, + ps->__value.__wch is the part already read. */ + size_t read = ps->__count & 0xff; + unsigned int wc; + + if (read == 0) + { + if (!(ps->__count == 0)) + abort (); + unsigned char c = (unsigned char) s[0]; + if (c < 0x80) + { + if (pwc != NULL) + *pwc = c; + return 1; + } + else if (c >= 0xc2) + { + if (c < 0xe0) + { + if (n >= 2) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40) + { + if (pwc != NULL) + *pwc = ((unsigned int) (c & 0x1f) << 6) + | (unsigned int) (c2 ^ 0x80); + return 2; + } + else + goto invalid; + } + else /* n == 1 */ + { + ps->__count = 0x0201; + ps->__value.__wch = (unsigned int) (c & 0x1f) << 6; + return (size_t)(-2); + } + } + else if (c < 0xf0) + { + if (n >= 3) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xe1 || c2 >= 0xa0) + && (c != 0xed || c2 < 0xa0)) + { + unsigned char c3 = (unsigned char) s[2]; + + if ((c3 ^ 0x80) < 0x40) + { + if (pwc != NULL) + *pwc = ((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (c2 ^ 0x80) << 6) + | (unsigned int) (c3 ^ 0x80); + return 3; + } + else + goto invalid; + } + else + goto invalid; + } + else if (n == 2) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xe1 || c2 >= 0xa0) + && (c != 0xed || c2 < 0xa0)) + { + ps->__count = 0x0302; + ps->__value.__wch = ((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (c2 ^ 0x80) << 6); + return (size_t)(-2); + } + else + goto invalid; + } + else /* n == 1 */ + { + ps->__count = 0x0301; + ps->__value.__wch = (unsigned int) (c & 0x0f) << 12; + return (size_t)(-2); + } + } + else if (c <= 0xf4) + { + if (n >= 4) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xf1 || c2 >= 0x90) + && (c < 0xf4 || (c == 0xf4 && c2 < 0x90))) + { + unsigned char c3 = (unsigned char) s[2]; + + if ((c3 ^ 0x80) < 0x40) + { + unsigned char c4 = (unsigned char) s[3]; + + if ((c4 ^ 0x80) < 0x40) + { + if (pwc != NULL) + *pwc = ((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (c2 ^ 0x80) << 12) + | ((unsigned int) (c3 ^ 0x80) << 6) + | (unsigned int) (c4 ^ 0x80); + return 4; + } + else + goto invalid; + } + else + goto invalid; + } + else + goto invalid; + } + else if (n == 3) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xf1 || c2 >= 0x90) + && (c < 0xf4 || (c == 0xf4 && c2 < 0x90))) + { + unsigned char c3 = (unsigned char) s[2]; + + if ((c3 ^ 0x80) < 0x40) + { + ps->__count = 0x0403; + ps->__value.__wch = ((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (c2 ^ 0x80) << 12) + | ((unsigned int) (c3 ^ 0x80) << 6); + return (size_t)(-2); + } + else + goto invalid; + } + else + goto invalid; + } + else if (n == 2) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xf1 || c2 >= 0x90) + && (c < 0xf4 || (c == 0xf4 && c2 < 0x90))) + { + ps->__count = 0x0402; + ps->__value.__wch = ((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (c2 ^ 0x80) << 12); + return (size_t)(-2); + } + else + goto invalid; + } + else /* n == 1 */ + { + ps->__count = 0x0401; + ps->__value.__wch = (unsigned int) (c & 0x07) << 18; + return (size_t)(-2); + } + } + else + goto invalid; + } + else + goto invalid; + } + else + { + size_t expected = ps->__count >> 8; + if (!(expected > read && expected <= 4)) + abort (); + wc = ps->__value.__wch; + { + unsigned char c = (unsigned char) s[0]; + if (!(c >= 0x80 && c < 0xc0)) + goto invalid; + c = c & 0x3f; + wc |= c << (6 * (expected - read - 1)); + } + if (read == 1) + { + if (expected == 3) + { + if (!(wc >= 0x800 && !(wc >= 0xd800 && wc < 0xe000))) + goto invalid; + } + if (expected == 4) + { + if (!(wc >= 0x10000 && wc < 0x110000)) + goto invalid; + } + } + size_t orig_read = read; + for (;;) + { + read++; + if (read == expected) + { + if (pwc != NULL) + *pwc = wc; + ps->__count = 0; + return read - orig_read; + } + n--; + if (n == 0) + break; + s++; + { + unsigned char c = (unsigned char) s[0]; + if (!(c >= 0x80 && c < 0xc0)) + goto invalid; + c = c & 0x3f; + wc |= c << (6 * (expected - read - 1)); + } + } + ps->__count = (expected << 8) | read; + ps->__value.__wch = wc; + return (size_t)(-2); + } + + invalid: + errno = EILSEQ; + /* The conversion state is undefined, says POSIX. */ + return (size_t)(-1); +} + +#endif + +#if defined __APPLE__ && defined __MACH__ /* macOS 10.13 */ + +static mbstate_t internal_state; + +typedef struct +{ + unsigned int wc_part; /* Part of wc, (number of bytes read) * 6 bits */ + unsigned int remaining; /* Number of remaining bytes */ + /* In Mac OS X 10.13: 0xBF80 if (number of bytes read) == 1, otherwise 0. + In Mac OS X 10.5: 0x80 or 0x800 or 0x10000, depending on number of total bytes expected. */ + unsigned int flag; +} real_mbstate_t; + +static size_t +utf8_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) +{ + if (s == NULL) + { + pwc = NULL; + s = ""; + n = 1; + } + + if (n == 0) + return (size_t)(-2); + + /* Here n > 0. */ + + if (ps == NULL) + ps = &internal_state; + + real_mbstate_t *pstate = (real_mbstate_t *) ps; + size_t remaining = pstate->remaining; + unsigned int wc; + + if (remaining == 0) + { + if (!(pstate->wc_part == 0 && pstate->flag == 0)) + abort (); + unsigned char c = (unsigned char) s[0]; + if (c < 0x80) + { + if (pwc != NULL) + *pwc = c; + return 1; + } + else if (c >= 0xc2) + { + if (c < 0xe0) + { + if (n >= 2) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40) + { + if (pwc != NULL) + *pwc = ((unsigned int) (c & 0x1f) << 6) + | (unsigned int) (c2 ^ 0x80); + return 2; + } + else + goto invalid; + } + else /* n == 1 */ + { + pstate->wc_part = (unsigned int) (c & 0x1f); + pstate->remaining = 1; + pstate->flag = 0xBF80; + return (size_t)(-2); + } + } + else if (c < 0xf0) + { + if (n >= 3) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xe1 || c2 >= 0xa0) + && (c != 0xed || c2 < 0xa0)) + { + unsigned char c3 = (unsigned char) s[2]; + + if ((c3 ^ 0x80) < 0x40) + { + if (pwc != NULL) + *pwc = ((unsigned int) (c & 0x0f) << 12) + | ((unsigned int) (c2 ^ 0x80) << 6) + | (unsigned int) (c3 ^ 0x80); + return 3; + } + else + goto invalid; + } + else + goto invalid; + } + else if (n == 2) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xe1 || c2 >= 0xa0) + && (c != 0xed || c2 < 0xa0)) + { + pstate->wc_part = ((unsigned int) (c & 0x0f) << 6) + | (unsigned int) (c2 ^ 0x80); + pstate->remaining = 1; + pstate->flag = 0; + return (size_t)(-2); + } + else + goto invalid; + } + else /* n == 1 */ + { + pstate->wc_part = (unsigned int) (c & 0x0f); + pstate->remaining = 2; + pstate->flag = 0xBF80; + return (size_t)(-2); + } + } + else if (c <= 0xf4) + { + if (n >= 4) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xf1 || c2 >= 0x90) + && (c < 0xf4 || (c == 0xf4 && c2 < 0x90))) + { + unsigned char c3 = (unsigned char) s[2]; + + if ((c3 ^ 0x80) < 0x40) + { + unsigned char c4 = (unsigned char) s[3]; + + if ((c4 ^ 0x80) < 0x40) + { + if (pwc != NULL) + *pwc = ((unsigned int) (c & 0x07) << 18) + | ((unsigned int) (c2 ^ 0x80) << 12) + | ((unsigned int) (c3 ^ 0x80) << 6) + | (unsigned int) (c4 ^ 0x80); + return 4; + } + else + goto invalid; + } + else + goto invalid; + } + else + goto invalid; + } + else if (n == 3) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xf1 || c2 >= 0x90) + && (c < 0xf4 || (c == 0xf4 && c2 < 0x90))) + { + unsigned char c3 = (unsigned char) s[2]; + + if ((c3 ^ 0x80) < 0x40) + { + pstate->wc_part = ((unsigned int) (c & 0x07) << 12) + | ((unsigned int) (c2 ^ 0x80) << 6) + | (unsigned int) (c3 ^ 0x80); + pstate->remaining = 1; + pstate->flag = 0; + return (size_t)(-2); + } + else + goto invalid; + } + else + goto invalid; + } + else if (n == 2) + { + unsigned char c2 = (unsigned char) s[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xf1 || c2 >= 0x90) + && (c < 0xf4 || (c == 0xf4 && c2 < 0x90))) + { + pstate->wc_part = ((unsigned int) (c & 0x07) << 6) + | (unsigned int) (c2 ^ 0x80); + pstate->remaining = 2; + pstate->flag = 0; + return (size_t)(-2); + } + else + goto invalid; + } + else /* n == 1 */ + { + pstate->wc_part = (unsigned int) (c & 0x07); + pstate->remaining = 3; + pstate->flag = 0xBF80; + return (size_t)(-2); + } + } + else + goto invalid; + } + else + goto invalid; + } + else + { + if (!(remaining <= 3)) + abort (); + wc = pstate->wc_part << (6 * pstate->remaining); + { + unsigned char c = (unsigned char) s[0]; + if (!(c >= 0x80 && c < 0xc0)) + goto invalid; + c = c & 0x3f; + wc |= c << (6 * (remaining - 1)); + } + if (pstate->flag) + { + if (remaining == 2) + { + if (!(wc >= 0x800 && !(wc >= 0xd800 && wc < 0xe000))) + goto invalid; + } + if (remaining == 3) + { + if (!(wc >= 0x10000 && wc < 0x110000)) + goto invalid; + } + } + const char *orig_s = s; + for (;;) + { + s++; + remaining--; + if (remaining == 0) + { + if (pwc != NULL) + *pwc = wc; + pstate->wc_part = 0; + pstate->remaining = 0; + pstate->flag = 0; + return s - orig_s; + } + n--; + if (n == 0) + break; + { + unsigned char c = (unsigned char) s[0]; + if (!(c >= 0x80 && c < 0xc0)) + goto invalid; + c = c & 0x3f; + wc |= c << (6 * (remaining - 1)); + } + } + pstate->wc_part = wc >> (6 * remaining); + pstate->remaining = remaining; + pstate->flag = 0; + return (size_t)(-2); + } + + invalid: + errno = EILSEQ; + /* The conversion state is undefined, says POSIX. */ + return (size_t)(-1); +} + +#endif + +mbrtowc_func_t +get_optimized_mbrtowc (void) +{ +#if __GLIBC__ >= 2 || (defined __APPLE__ && defined __MACH__) + const char *encoding = locale_charset (); + + if (strcmp (encoding, "UTF-8") == 0) + return utf8_mbrtowc; + else +#endif + /* No optimization. */ + return mbrtowc; +} diff --git a/lib/mbsinit-factory.c b/lib/mbsinit-factory.c new file mode 100644 index 0000000..137cd23 --- /dev/null +++ b/lib/mbsinit-factory.c @@ -0,0 +1,28 @@ +/* Factory that produces an mbsinit-like function for a given locale. + Copyright (C) 2018 Free Software Foundation, Inc. + Written by Bruno Haible , 2018. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +mbsinit_func_t +get_optimized_mbsinit (void) +{ + /* No optimization is needed. */ + return mbsinit; +} diff --git a/lib/mbsreset-factory.c b/lib/mbsreset-factory.c new file mode 100644 index 0000000..2114027 --- /dev/null +++ b/lib/mbsreset-factory.c @@ -0,0 +1,65 @@ +/* Factory that produces an mbsreset-like function for a given locale. + Copyright (C) 2018 Free Software Foundation, Inc. + Written by Bruno Haible , 2018. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include + +#include "localcharset.h" + +/* sizeof (mbstate_t) is 128 on macOS. But only the first few bytes of the + state actually matter. */ + +#if defined __APPLE__ && defined __MACH__ + +typedef struct +{ + unsigned int wc_part; + unsigned int remaining; + unsigned int flag; +} real_mbstate_t; + +static void +utf8_mbsreset (mbstate_t *ps) +{ + memset (ps, '\0', sizeof (real_mbstate_t)); +} + +#endif + +static void +generic_mbsreset (mbstate_t *ps) +{ + memset (ps, '\0', sizeof (mbstate_t)); +} + +mbsreset_func_t +get_optimized_mbsreset (void) +{ +#if defined __APPLE__ && defined __MACH__ + const char *encoding = locale_charset (); + + if (strcmp (encoding, "UTF-8") == 0) + return utf8_mbsreset; + else +#endif + /* No optimization. */ + return generic_mbsreset; +} diff --git a/lib/wchar.in.h b/lib/wchar.in.h index 655340c..679992a 100644 --- a/lib/wchar.in.h +++ b/lib/wchar.in.h @@ -1067,6 +1067,25 @@ _GL_WARN_ON_USE (wcsftime, "wcsftime is unportable - " #endif +/* Factories that produce functions for a given locale. */ +#if @GNULIB_MBRTOWC_FACTORY@ +typedef size_t (*mbrtowc_func_t) (wchar_t *, const char *, size_t, mbstate_t *); +_GL_FUNCDECL_SYS (get_optimized_mbrtowc, mbrtowc_func_t, (void)); +#endif +#if @GNULIB_MBSINIT_FACTORY@ +typedef int (*mbsinit_func_t) (const mbstate_t *); +_GL_FUNCDECL_SYS (get_optimized_mbsinit, mbsinit_func_t, (void)); +#endif +#if @GNULIB_MBSRESET_FACTORY@ +typedef void (*mbsreset_func_t) (mbstate_t *); +_GL_FUNCDECL_SYS (get_optimized_mbsreset, mbsreset_func_t, (void)); +#endif +#if @GNULIB_WCWIDTH_FACTORY@ +typedef int (*wcwidth_func_t) (wchar_t); +_GL_FUNCDECL_SYS (get_optimized_wcwidth, wcwidth_func_t, (void)); +#endif + + #endif /* address@hidden@_WCHAR_H */ #endif /* address@hidden@_WCHAR_H */ #endif diff --git a/lib/wcwidth-factory.c b/lib/wcwidth-factory.c new file mode 100644 index 0000000..611bf40 --- /dev/null +++ b/lib/wcwidth-factory.c @@ -0,0 +1,56 @@ +/* Factory that produces a wcwidth-like function for a given locale. + Copyright (C) 2018 Free Software Foundation, Inc. + Written by Bruno Haible , 2018. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include + +#include "localcharset.h" +#include "uniwidth.h" + +static int +utf8_wcwidth (wchar_t wc) +{ + return uc_width (wc, "UTF-8"); +} + +#if !HAVE_WCWIDTH +static int +fallback_wcwidth (wchar_t wc) +{ + return wc == 0 ? 0 : iswprint (wc) ? 1 : -1; +} +#endif + +wcwidth_func_t +get_optimized_wcwidth (void) +{ + const char *encoding = locale_charset (); + + if (strcmp (encoding, "UTF-8") == 0) + return utf8_wcwidth; + else + /* No optimization. */ +#if HAVE_WCWIDTH + return wcwidth; +#else + return fallback_wcwidth; +#endif +} diff --git a/m4/wchar_h.m4 b/m4/wchar_h.m4 index 416e0a1..ca415a9 100644 --- a/m4/wchar_h.m4 +++ b/m4/wchar_h.m4 @@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved. dnl Written by Eric Blake. -# wchar_h.m4 serial 42 +# wchar_h.m4 serial 43 AC_DEFUN([gl_WCHAR_H], [ @@ -180,6 +180,10 @@ AC_DEFUN([gl_WCHAR_H_DEFAULTS], GNULIB_WCSTOK=0; AC_SUBST([GNULIB_WCSTOK]) GNULIB_WCSWIDTH=0; AC_SUBST([GNULIB_WCSWIDTH]) GNULIB_WCSFTIME=0; AC_SUBST([GNULIB_WCSFTIME]) + GNULIB_MBRTOWC_FACTORY=0; AC_SUBST([GNULIB_MBRTOWC_FACTORY]) + GNULIB_MBSINIT_FACTORY=0; AC_SUBST([GNULIB_MBSINIT_FACTORY]) + GNULIB_MBSRESET_FACTORY=0; AC_SUBST([GNULIB_MBSRESET_FACTORY]) + GNULIB_WCWIDTH_FACTORY=0; AC_SUBST([GNULIB_WCWIDTH_FACTORY]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_BTOWC=1; AC_SUBST([HAVE_BTOWC]) HAVE_MBSINIT=1; AC_SUBST([HAVE_MBSINIT]) diff --git a/modules/mbrtowc-factory b/modules/mbrtowc-factory new file mode 100644 index 0000000..90d348d --- /dev/null +++ b/modules/mbrtowc-factory @@ -0,0 +1,24 @@ +Description: +Factory that produces an mbrtowc-like function for a given locale. + +Files: +lib/mbrtowc-factory.c + +Depends-on: +wchar +mbrtowc + +configure.ac: +gl_WCHAR_MODULE_INDICATOR([mbrtowc-factory]) + +Makefile.am: +lib_SOURCES += mbrtowc-factory.c + +Include: + + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/mbsinit-factory b/modules/mbsinit-factory new file mode 100644 index 0000000..5c311a8 --- /dev/null +++ b/modules/mbsinit-factory @@ -0,0 +1,24 @@ +Description: +Factory that produces an mbsinit-like function for a given locale. + +Files: +lib/mbsinit-factory.c + +Depends-on: +wchar +mbsinit + +configure.ac: +gl_WCHAR_MODULE_INDICATOR([mbsinit-factory]) + +Makefile.am: +lib_SOURCES += mbsinit-factory.c + +Include: + + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/mbsreset-factory b/modules/mbsreset-factory new file mode 100644 index 0000000..dd08563 --- /dev/null +++ b/modules/mbsreset-factory @@ -0,0 +1,23 @@ +Description: +Factory that produces an mbsreset-like function for a given locale. + +Files: +lib/mbsreset-factory.c + +Depends-on: +wchar + +configure.ac: +gl_WCHAR_MODULE_INDICATOR([mbsreset-factory]) + +Makefile.am: +lib_SOURCES += mbsreset-factory.c + +Include: + + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/wchar b/modules/wchar index 31770d8..3a83b63 100644 --- a/modules/wchar +++ b/modules/wchar @@ -73,6 +73,10 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's/@''GNULIB_WCSTOK''@/$(GNULIB_WCSTOK)/g' \ -e 's/@''GNULIB_WCSWIDTH''@/$(GNULIB_WCSWIDTH)/g' \ -e 's/@''GNULIB_WCSFTIME''@/$(GNULIB_WCSFTIME)/g' \ + -e 's/@''GNULIB_MBRTOWC_FACTORY''@/$(GNULIB_MBRTOWC_FACTORY)/g' \ + -e 's/@''GNULIB_MBSINIT_FACTORY''@/$(GNULIB_MBSINIT_FACTORY)/g' \ + -e 's/@''GNULIB_MBSRESET_FACTORY''@/$(GNULIB_MBSRESET_FACTORY)/g' \ + -e 's/@''GNULIB_WCWIDTH_FACTORY''@/$(GNULIB_WCWIDTH_FACTORY)/g' \ < $(srcdir)/wchar.in.h | \ sed -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \ -e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \ diff --git a/modules/wcwidth-factory b/modules/wcwidth-factory new file mode 100644 index 0000000..b91e76c --- /dev/null +++ b/modules/wcwidth-factory @@ -0,0 +1,24 @@ +Description: +Factory that produces a wcwidth-like function for a given locale. + +Files: +lib/wcwidth-factory.c + +Depends-on: +wchar +wcwidth + +configure.ac: +gl_WCHAR_MODULE_INDICATOR([wcwidth-factory]) + +Makefile.am: +lib_SOURCES += wcwidth-factory.c + +Include: + + +License: +LGPLv2+ + +Maintainer: +all