further work on unicodization
authorDenys Vlasenko <vda.linux@googlemail.com>
Sat, 30 Jan 2010 22:16:21 +0000 (23:16 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 30 Jan 2010 22:16:21 +0000 (23:16 +0100)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
TODO_unicode [new file with mode: 0644]
coreutils/cal.c
coreutils/df.c
include/unicode.h
libbb/unicode.c
modutils/lsmod.c
networking/udhcp/dumpleases.c

diff --git a/TODO_unicode b/TODO_unicode
new file mode 100644 (file)
index 0000000..c29fd93
--- /dev/null
@@ -0,0 +1,45 @@
+Already fixed applets:
+cal
+lsmod
+df
+dumpleases
+
+Applets which may need unicode handling (more extensive than sanitizing
+of filenames in error messages):
+
+ls - uses unicode_strlen, not scrlen
+expand, unexpand - uses unicode_strlen, not scrlen
+ash, hush through lineedit - uses unicode_strlen, not scrlen
+top - need to sanitize process args
+ps - need to sanitize process args
+less
+more
+vi
+ed
+cut
+awk
+sed
+tr
+grep egrep fgrep
+fold
+sort
+head, tail
+catv - "display nonprinting chars" - what this could mean for unicode?
+wc
+chat
+dumpkmap
+last - just line up columns
+man
+microcom
+strings
+watch
+
+Unsure, may need fixing:
+
+hostname - do we really want to protect against bad chars in it?
+patch
+addgroup, adduser, delgroup, deluser
+telnet
+telnetd
+od
+printf
index 5ecb9131ddd2f319f1f321f7eb03d8beaac32b8e..207fa967b743ac961cf22c164c478a2bdd449326 100644 (file)
@@ -135,7 +135,7 @@ int cal_main(int argc UNUSED_PARAM, char **argv)
                        if (julian)
                                *hp++ = ' ';
                        {
-                               char *two_wchars = unicode_cut_nchars(2, buf);
+                               char *two_wchars = unicode_conv_to_printable_fixedwidth(NULL, buf, 2);
                                strcpy(hp, two_wchars);
                                free(two_wchars);
                        }
index ae68f0831fd630eefd113636a566b6a5e9fc6c16..4b23faa7a9bce7579871a241bf74b01738ebb72c 100644 (file)
@@ -114,9 +114,6 @@ int df_main(int argc UNUSED_PARAM, char **argv)
        while (1) {
                const char *device;
                const char *mount_point;
-#if ENABLE_FEATURE_ASSUME_UNICODE
-               size_t dev_len;
-#endif
 
                if (mount_table) {
                        mount_entry = getmntent(mount_table);
@@ -178,11 +175,15 @@ int df_main(int argc UNUSED_PARAM, char **argv)
 #endif
 
 #if ENABLE_FEATURE_ASSUME_UNICODE
-                       dev_len = unicode_strlen(device);
-                       if (dev_len > 20) {
-                               printf("%s\n%20s", device, "");
-                       } else {
-                               printf("%s%*s", device, 20 - (int)dev_len, "");
+                       {
+                               uni_stat_t uni_stat;
+                               char *uni_dev = unicode_conv_to_printable(&uni_stat, device);
+                               if (uni_stat.unicode_width > 20) {
+                                       printf("%s\n%20s", uni_dev, "");
+                               } else {
+                                       printf("%s%*s", uni_dev, 20 - (int)uni_stat.unicode_width, "");
+                               }
+                               free(uni_dev);
                        }
 #else
                        if (printf("\n%-20s" + 1, device) > 20)
index f1a252cc7d05e55b97d3467efc0279517193c580..f32e565997619deb25b803683f7556e75f81c2de 100644 (file)
@@ -14,15 +14,25 @@ enum {
 #if !ENABLE_FEATURE_ASSUME_UNICODE
 
 # define unicode_strlen(string) strlen(string)
-# define unicode_scrlen(string) TODO
 # define unicode_status UNICODE_OFF
 # define init_unicode() ((void)0)
 
 #else
 
 size_t FAST_FUNC unicode_strlen(const char *string);
-char* FAST_FUNC unicode_cut_nchars(unsigned width, const char *src);
-unsigned FAST_FUNC unicode_padding_to_width(unsigned width, const char *src);
+enum {
+       UNI_FLAG_PAD = (1 << 0),
+};
+typedef struct uni_stat_t {
+       unsigned byte_count;
+       unsigned unicode_count;
+       unsigned unicode_width;
+} uni_stat_t;
+//UNUSED: unsigned FAST_FUNC unicode_padding_to_width(unsigned width, const char *src);
+//UNUSED: char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags);
+char* FAST_FUNC unicode_conv_to_printable(uni_stat_t *stats, const char *src);
+char* FAST_FUNC unicode_conv_to_printable_maxwidth(uni_stat_t *stats, const char *src, unsigned maxwidth);
+char* FAST_FUNC unicode_conv_to_printable_fixedwidth(uni_stat_t *stats, const char *src, unsigned width);
 
 # if ENABLE_LOCALE_SUPPORT
 
index 878af84bc0d9b12e135b771d76246362aa0c8a6e..4e7e3a96ae01d4818aef887b28f48e4021393b4b 100644 (file)
@@ -246,29 +246,45 @@ size_t FAST_FUNC unicode_strlen(const char *string)
        return width;
 }
 
-char* FAST_FUNC unicode_cut_nchars(unsigned width, const char *src)
+static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags)
 {
        char *dst;
        unsigned dst_len;
+       unsigned uni_count;
+       unsigned uni_width;
 
        if (unicode_status != UNICODE_ON) {
-               char *d = dst = xmalloc(width + 1);
-               while ((int)--width >= 0) {
-                       unsigned char c = *src;
-                       if (c == '\0') {
-                               do
-                                       *d++ = ' ';
-                               while ((int)--width >= 0);
-                               break;
+               char *d;
+               if (flags & UNI_FLAG_PAD) {
+                       d = dst = xmalloc(width + 1);
+                       while ((int)--width >= 0) {
+                               unsigned char c = *src;
+                               if (c == '\0') {
+                                       do
+                                               *d++ = ' ';
+                                       while ((int)--width >= 0);
+                                       break;
+                               }
+                               *d++ = (c >= ' ' && c < 0x7f) ? c : '?';
+                               src++;
+                       }
+                       *d = '\0';
+               } else {
+                       d = dst = xstrndup(src, width);
+                       while (*d) {
+                               unsigned char c = *d;
+                               if (c < ' ' || c >= 0x7f)
+                                       *d = '?';
+                               d++;
                        }
-                       *d++ = (c >= ' ' && c < 0x7f) ? c : '?';
-                       src++;
                }
-               *d = '\0';
+               if (stats)
+                       stats->byte_count = stats->unicode_count = (d - dst);
                return dst;
        }
 
        dst = NULL;
+       uni_count = uni_width = 0;
        dst_len = 0;
        while (1) {
                int w;
@@ -301,7 +317,7 @@ char* FAST_FUNC unicode_cut_nchars(unsigned width, const char *src)
                        /* src = NULL: invalid sequence is seen,
                         * else: wc is set, src is advanced to next mb char
                         */
-                       if (src1) {/* no error */
+                       if (src1) { /* no error */
                                if (wc == 0) /* end-of-string */
                                        break;
                                src = src1;
@@ -315,8 +331,8 @@ char* FAST_FUNC unicode_cut_nchars(unsigned width, const char *src)
                        goto subst;
                w = wcwidth(wc);
                if ((ENABLE_UNICODE_COMBINING_WCHARS && w < 0) /* non-printable wchar */
-                || (!ENABLE_UNICODE_COMBINING_WCHARS && wc <= 0)
-                || (!ENABLE_UNICODE_WIDE_WCHARS && wc > 1)
+                || (!ENABLE_UNICODE_COMBINING_WCHARS && w <= 0)
+                || (!ENABLE_UNICODE_WIDE_WCHARS && w > 1)
                ) {
  subst:
                        wc = CONFIG_SUBST_WCHAR;
@@ -331,6 +347,8 @@ char* FAST_FUNC unicode_cut_nchars(unsigned width, const char *src)
                        break;
                }
 
+               uni_count++;
+               uni_width += w;
                dst = xrealloc(dst, dst_len + MB_CUR_MAX);
 #if ENABLE_LOCALE_SUPPORT
                {
@@ -343,15 +361,37 @@ char* FAST_FUNC unicode_cut_nchars(unsigned width, const char *src)
        }
 
        /* Pad to remaining width */
-       dst = xrealloc(dst, dst_len + width + 1);
-       while ((int)--width >= 0) {
-               dst[dst_len++] = ' ';
+       if (flags & UNI_FLAG_PAD) {
+               dst = xrealloc(dst, dst_len + width + 1);
+               uni_count += width;
+               uni_width += width;
+               while ((int)--width >= 0) {
+                       dst[dst_len++] = ' ';
+               }
        }
        dst[dst_len] = '\0';
+       if (stats) {
+               stats->byte_count = dst_len;
+               stats->unicode_count = uni_count;
+               stats->unicode_width = uni_width;
+       }
 
        return dst;
 }
+char* FAST_FUNC unicode_conv_to_printable(uni_stat_t *stats, const char *src)
+{
+       return unicode_conv_to_printable2(stats, src, INT_MAX, 0);
+}
+char* FAST_FUNC unicode_conv_to_printable_maxwidth(uni_stat_t *stats, const char *src, unsigned maxwidth)
+{
+       return unicode_conv_to_printable2(stats, src, maxwidth, 0);
+}
+char* FAST_FUNC unicode_conv_to_printable_fixedwidth(uni_stat_t *stats, const char *src, unsigned width)
+{
+       return unicode_conv_to_printable2(stats, src, width, UNI_FLAG_PAD);
+}
 
+#ifdef UNUSED
 unsigned FAST_FUNC unicode_padding_to_width(unsigned width, const char *src)
 {
        if (unicode_status != UNICODE_ON) {
@@ -382,3 +422,4 @@ unsigned FAST_FUNC unicode_padding_to_width(unsigned width, const char *src)
                        return 0;
        }
 }
+#endif
index cc6b6162f8813eb9fe3ba1eaa5401467534215a9..50621c24553dc874b2184bbc27c94b82f7eeca02 100644 (file)
@@ -46,9 +46,6 @@ int lsmod_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
 #if ENABLE_FEATURE_LSMOD_PRETTY_2_6_OUTPUT
        char *token[4];
        parser_t *parser = config_open("/proc/modules");
-# if ENABLE_FEATURE_ASSUME_UNICODE
-       size_t name_len;
-# endif
        init_unicode();
 
        printf("%-24sSize  Used by", "Module");
@@ -64,9 +61,13 @@ int lsmod_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
                        } else
                                token[3] = (char *) "";
 # if ENABLE_FEATURE_ASSUME_UNICODE
-                       name_len = unicode_strlen(token[0]);
-                       name_len = (name_len > 19) ? 0 : 19 - name_len;
-                       printf("%s%*s %8s %2s %s\n", token[0], name_len, "", token[1], token[2], token[3]);
+                       {
+                               uni_stat_t uni_stat;
+                               char *uni_name = unicode_conv_to_printable(&uni_stat, token[0]);
+                               unsigned pad_len = (uni_stat.unicode_width > 19) ? 0 : 19 - uni_stat.unicode_width;
+                               printf("%s%*s %8s %2s %s\n", uni_name, pad_len, "", token[1], token[2], token[3]);
+                               free(uni_name);
+                       }
 # else
                        printf("%-19s %8s %2s %s\n", token[0], token[1], token[2], token[3]);
 # endif
@@ -78,9 +79,13 @@ int lsmod_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
                        // so trimming the trailing char is just what we need!
                        token[3][strlen(token[3])-1] = '\0';
 # if ENABLE_FEATURE_ASSUME_UNICODE
-                       name_len = unicode_strlen(token[0]);
-                       name_len = (name_len > 19) ? 0 : 19 - name_len;
-                       printf("%s%*s %8s %2s %s\n", token[0], name_len, "", token[1], token[2], token[3]);
+                       {
+                               uni_stat_t uni_stat;
+                               char *uni_name = unicode_conv_to_printable(&uni_stat, token[0]);
+                               unsigned pad_len = (uni_stat.unicode_width > 19) ? 0 : 19 - uni_stat.unicode_width;
+                               printf("%s%*s %8s %2s %s\n", uni_name, pad_len, "", token[1], token[2], token[3]);
+                               free(uni_name);
+                       }
 # else
                        printf("%-19s %8s %2s %s\n", token[0], token[1], token[2], token[3]);
 # endif
index d8f5da7fb74a50e1e9fb435f2c18c1d4dd6c171a..eab9713f478d78f612379908412541932fbaad25 100644 (file)
@@ -71,8 +71,11 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv)
                /* actually, 15+1 and 19+1, +1 is a space between columns */
                /* lease.hostname is char[20] and is always NUL terminated */
 #if ENABLE_FEATURE_ASSUME_UNICODE
-               printf(" %-16s%s%*s", inet_ntoa(addr), lease.hostname,
-                       20 - (int)unicode_strlen(lease.hostname), "");
+               {
+                       char *uni_name = unicode_conv_to_printable_fixedwidth(NULL, lease.hostname, 20);
+                       printf(" %-16s%s", inet_ntoa(addr), uni_name);
+                       free(uni_name);
+               }
 #else
                printf(" %-16s%-20s", inet_ntoa(addr), lease.hostname);
 #endif