diff options
Diffstat (limited to 'Src/utils.c')
-rw-r--r-- | Src/utils.c | 81 |
1 files changed, 45 insertions, 36 deletions
diff --git a/Src/utils.c b/Src/utils.c index 21a3a0c34..59a496fcf 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -3968,6 +3968,50 @@ nicedup(const char *s, int heap) /* + * The guts of mb_metacharlenconv(). This version assumes we are + * processing a true multibyte character string without tokens, and + * takes the shift state as an argument. + */ + +/**/ +mod_export int +mb_metacharlenconv_r(const char *s, wint_t *wcp, mbstate_t *mbsp) +{ + size_t ret = MB_INVALID; + char inchar; + const char *ptr; + wchar_t wc; + + for (ptr = s; *ptr; ) { + if (*ptr == Meta) { + inchar = *++ptr ^ 32; + DPUTS(!*ptr, + "BUG: unexpected end of string in mb_metacharlen()\n"); + } else + inchar = *ptr; + ptr++; + ret = mbrtowc(&wc, &inchar, 1, mbsp); + + if (ret == MB_INVALID) + break; + if (ret == MB_INCOMPLETE) + continue; + if (wcp) + *wcp = wc; + return ptr - s; + } + + if (wcp) + *wcp = WEOF; + /* No valid multibyte sequence */ + memset(mbsp, 0, sizeof(*mbsp)); + if (ptr > s) { + return 1 + (*s == Meta); /* Treat as single byte character */ + } else + return 0; /* Probably shouldn't happen */ +} + +/* * Length of metafied string s which contains the next multibyte * character; single (possibly metafied) character if string is not null * but character is not valid (e.g. possibly incomplete at end of string). @@ -3982,11 +4026,6 @@ nicedup(const char *s, int heap) mod_export int mb_metacharlenconv(const char *s, wint_t *wcp) { - char inchar; - const char *ptr; - size_t ret; - wchar_t wc; - if (!isset(MULTIBYTE)) { /* treat as single byte, possibly metafied */ if (wcp) @@ -4009,37 +4048,7 @@ mb_metacharlenconv(const char *s, wint_t *wcp) return 1; } - ret = MB_INVALID; - for (ptr = s; *ptr; ) { - if (*ptr == Meta) { - inchar = *++ptr ^ 32; -#ifdef DEBUG - if (!*ptr) - fprintf(stderr, - "BUG: unexpected end of string in mb_metacharlen()\n"); -#endif - } else - inchar = *ptr; - ptr++; - ret = mbrtowc(&wc, &inchar, 1, &mb_shiftstate); - - if (ret == MB_INVALID) - break; - if (ret == MB_INCOMPLETE) - continue; - if (wcp) - *wcp = wc; - return ptr - s; - } - - if (wcp) - *wcp = WEOF; - /* No valid multibyte sequence */ - memset(&mb_shiftstate, 0, sizeof(mb_shiftstate)); - if (ptr > s) { - return 1 + (*s == Meta); /* Treat as single byte character */ - } else - return 0; /* Probably shouldn't happen */ + return mb_metacharlenconv_r(s, wcp, &mb_shiftstate); } /* |