string.c: Simplify and rename wide character helpers.
[paraslash.git] / string.c
index f8b64b77c08d0c109c62129bdfeac04b775b3d6b..d9dcc62d2ea45efc6a3c2899185a2033d5e74339 100644 (file)
--- a/string.c
+++ b/string.c
@@ -562,10 +562,18 @@ int para_atoi64(const char *str, int64_t *value)
        tmp = strtoll(str, &endptr, 10);
        if (errno == ERANGE && (tmp == LLONG_MAX || tmp == LLONG_MIN))
                return -E_ATOI_OVERFLOW;
-       if (errno != 0 && tmp == 0) /* other error */
-               return -E_STRTOLL;
+       /*
+        * If there were no digits at all, strtoll() stores the original value
+        * of str in *endptr.
+        */
        if (endptr == str)
                return -E_ATOI_NO_DIGITS;
+       /*
+        * The implementation may also set errno and return 0 in case no
+        * conversion was performed.
+        */
+       if (errno != 0 && tmp == 0)
+               return -E_ATOI_NO_DIGITS;
        if (*endptr != '\0') /* Further characters after number */
                return -E_ATOI_JUNK_AT_END;
        *value = tmp;
@@ -625,7 +633,7 @@ int get_loglevel_by_name(const char *txt)
                return LL_CRIT;
        if (loglevel_equal(txt, "emerg"))
                return LL_EMERG;
-       return -1;
+       return -E_BAD_LL;
 }
 
 static int get_next_word(const char *buf, const char *delim, char **word)
@@ -947,36 +955,24 @@ static bool utf8_mode(void)
        return have_utf8;
 }
 
-/*
- * glibc's wcswidth returns -1 if the string contains a tab character, which
- * makes the function next to useless. The two functions below are taken from
- * mutt.
- */
-
-#define IsWPrint(wc) (iswprint(wc) || wc >= 0xa0)
-
-static int mutt_wcwidth(wchar_t wc, size_t pos)
+static int xwcwidth(wchar_t wc, size_t pos)
 {
        int n;
 
+       /* special-case for tab */
        if (wc == 0x09) /* tab */
                return (pos | 7) + 1 - pos;
        n = wcwidth(wc);
-       if (IsWPrint(wc) && n > 0)
-               return n;
-       if (!(wc & ~0x7f))
-               return 2;
-       if (!(wc & ~0xffff))
-               return 6;
-       return 10;
+       /* wcswidth() returns -1 for non-printable characters */
+       return n >= 0? n : 1;
 }
 
-static size_t mutt_wcswidth(const wchar_t *s, size_t n)
+static size_t xwcswidth(const wchar_t *s, size_t n)
 {
        size_t w = 0;
 
        while (n--)
-               w += mutt_wcwidth(*s++, w);
+               w += xwcwidth(*s++, w);
        return w;
 }
 
@@ -1021,7 +1017,7 @@ int skip_cells(const char *s, size_t cells_to_skip, size_t *bytes_to_skip)
                if (mbret == (size_t)-1 || mbret == (size_t)-2)
                        return -ERRNO_TO_PARA_ERROR(EILSEQ);
                bytes_parsed += mbret;
-               cells_skipped += mutt_wcwidth(wc, cells_skipped);
+               cells_skipped += xwcwidth(wc, cells_skipped);
        }
        *bytes_to_skip = bytes_parsed;
        return 1;
@@ -1065,12 +1061,12 @@ __must_check int strwidth(const char *s, size_t *result)
                return -ERRNO_TO_PARA_ERROR(errno);
        if (num_wchars == 0)
                return 0;
-       dest = para_malloc(num_wchars * sizeof(*dest));
+       dest = para_malloc((num_wchars + 1) * sizeof(*dest));
        src = s;
        memset(&state, 0, sizeof(state));
        num_wchars = mbsrtowcs(dest, &src, num_wchars, &state);
        assert(num_wchars > 0 && num_wchars != (size_t)-1);
-       *result = mutt_wcswidth(dest, num_wchars);
+       *result = xwcswidth(dest, num_wchars);
        free(dest);
        return 1;
 }