summaryrefslogtreecommitdiff
path: root/Src/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/utils.c')
-rw-r--r--Src/utils.c64
1 files changed, 31 insertions, 33 deletions
diff --git a/Src/utils.c b/Src/utils.c
index a81c4ed04..21b722f6a 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -279,6 +279,7 @@ zerrmsg(const char *fmt, va_list ap)
case 'c':
num = va_arg(ap, int);
#ifdef MULTIBYTE_SUPPORT
+ mb_metacharinit();
zputs(wcs_nicechar(num, NULL, NULL), stderr);
#else
zputs(nicechar(num), stderr);
@@ -402,6 +403,20 @@ nicechar(int c)
/**/
#ifdef MULTIBYTE_SUPPORT
+static mbstate_t mb_shiftstate;
+
+/*
+ * Initialise multibyte state: called before a sequence of
+ * wcs_nicechar() or mb_metacharlenconv().
+ */
+
+/**/
+mod_export void
+mb_metacharinit(void)
+{
+ memset(&mb_shiftstate, 0, sizeof(mb_shiftstate));
+}
+
/*
* The number of bytes we need to allocate for a "nice" representation
* of a multibyte character.
@@ -430,6 +445,9 @@ nicechar(int c)
* Either the initial ASCII part or the wide character part may be empty
* (but not both). (Note the complication that the wide character
* part may contain metafied characters.)
+ *
+ * The caller needs to call mb_metacharinit() before the first call, to
+ * set up the multibyte shift state for a range of characters.
*/
/**/
@@ -475,8 +493,11 @@ wcs_nicechar(wchar_t c, size_t *widthp, char **swidep)
}
}
- if (ret == -1 ||
- (ret = wctomb(mbstr, c)) == -1) {
+ if (ret != -1)
+ ret = wcrtomb(mbstr, c, &mb_shiftstate);
+
+ if (ret == -1) {
+ memset(&mb_shiftstate, 0, sizeof(mb_shiftstate));
/*
* Can't or don't want to convert character: use UCS-2 or
* UCS-4 code in print escape format.
@@ -513,18 +534,6 @@ wcs_nicechar(wchar_t c, size_t *widthp, char **swidep)
/**/
#endif /* MULTIBYTE_SUPPORT */
-
-/* Output a string's visible representation. */
-
-#if 0 /**/
-void
-nicefputs(char *s, FILE *f)
-{
- for (; *s; s++)
- zputs(nicechar(*s), f);
-}
-#endif
-
/* get a symlink-free pathname for s relative to PWD */
/**/
@@ -699,7 +708,7 @@ get_username(void)
#ifdef HAVE_GETPWUID
struct passwd *pswd;
uid_t current_uid;
-
+
current_uid = getuid();
if (current_uid != cached_uid) {
cached_uid = current_uid;
@@ -900,12 +909,12 @@ dircmp(char *s, char *t)
mod_export LinkList prepromptfns;
/* the last time we checked mail */
-
+
/**/
time_t lastmailcheck;
-
+
/* the last time we checked the people in the WATCH variable */
-
+
/**/
time_t lastwatch;
@@ -2818,6 +2827,7 @@ mod_export int
wcsitype(wchar_t c, int itype)
{
int len;
+ mbstate_t mbs;
VARARR(char, outstr, MB_CUR_MAX);
if (!isset(MULTIBYTE))
@@ -2830,7 +2840,8 @@ wcsitype(wchar_t c, int itype)
* If it doesn't, use iswalnum on the original character.
* If that fails, resort to the appropriate wide character array.
*/
- len = wctomb(outstr, c);
+ memset(&mbs, 0, sizeof(mbs));
+ len = wcrtomb(outstr, c, &mbs);
if (len == 0) {
/* NULL is special */
@@ -3725,6 +3736,7 @@ mb_niceformat(const char *s, FILE *stream, char **outstrp, int heap)
ptr = unmetafy(ums, &umlen);
memset(&mbs, 0, sizeof mbs);
+ mb_metacharinit();
while (umlen > 0) {
size_t cnt = eol ? MB_INVALID : mbrtowc(&c, ptr, umlen, &mbs);
@@ -3853,20 +3865,6 @@ mb_width(const char *s)
return width;
}
-static mbstate_t mb_shiftstate;
-
-/*
- * Initialise multibyte state: called before a sequence of
- * mb_metacharlenconv().
- */
-
-/**/
-void
-mb_metacharinit(void)
-{
- memset(&mb_shiftstate, 0, sizeof(mb_shiftstate));
-}
-
/*
* Length of metafied string s which contains the next multibyte
* character; single (possibly metafied) character if string is not null