summaryrefslogtreecommitdiffhomepage
path: root/libbb
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-01-31 05:15:38 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-01-31 05:15:38 +0100
commitd8528b8e56bab7643722e4453121882d23c23c07 (patch)
treec742df066326cd571327b10d4cca3341c798d129 /libbb
parented910c750d7908a31262488e04d38b7bf3d75322 (diff)
ls: unicode fixes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r--libbb/Kbuild1
-rw-r--r--libbb/printable_string.c65
2 files changed, 66 insertions, 0 deletions
diff --git a/libbb/Kbuild b/libbb/Kbuild
index 243626d67..7e793109e 100644
--- a/libbb/Kbuild
+++ b/libbb/Kbuild
@@ -73,6 +73,7 @@ lib-y += perror_nomsg_and_die.o
lib-y += pidfile.o
lib-y += platform.o
lib-y += printable.o
+lib-y += printable_string.o
lib-y += print_flags.o
lib-y += process_escape_sequence.o
lib-y += procps.o
diff --git a/libbb/printable_string.c b/libbb/printable_string.c
new file mode 100644
index 000000000..47565de0d
--- /dev/null
+++ b/libbb/printable_string.c
@@ -0,0 +1,65 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Unicode support routines.
+ *
+ * Copyright (C) 2010 Denys Vlasenko
+ *
+ * Licensed under GPL version 2, see file LICENSE in this tarball for details.
+ */
+#include "libbb.h"
+#include "unicode.h"
+
+const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str)
+{
+ static char *saved[4];
+ static unsigned cur_saved; /* = 0 */
+
+ char *dst;
+ const char *s;
+
+ s = str;
+ while (1) {
+ unsigned char c = *s;
+ if (c == '\0') {
+ /* 99+% of inputs do not need conversion */
+ if (stats) {
+ stats->byte_count = (s - str);
+ stats->unicode_count = (s - str);
+ stats->unicode_width = (s - str);
+ }
+ return str;
+ }
+ if (c < ' ')
+ break;
+ if (c >= 0x7f)
+ break;
+ s++;
+ }
+
+#if ENABLE_FEATURE_ASSUME_UNICODE
+ dst = unicode_conv_to_printable(stats, str);
+#else
+ {
+ char *d = dst = xstrdup(str);
+ while (1) {
+ unsigned char c = *d;
+ if (c == '\0')
+ break;
+ if (c < ' ' || c >= 0x7f)
+ *d = '?';
+ d++;
+ }
+ if (stats) {
+ stats->byte_count = (d - dst);
+ stats->unicode_count = (d - dst);
+ stats->unicode_width = (d - dst);
+ }
+ }
+#endif
+
+ free(saved[cur_saved]);
+ saved[cur_saved] = dst;
+ cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1);
+
+ return dst;
+}