Bump to version 1.22.1
[platform/upstream/busybox.git] / libbb / printable_string.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Unicode support routines.
4  *
5  * Copyright (C) 2010 Denys Vlasenko
6  *
7  * Licensed under GPLv2, see file LICENSE in this source tree.
8  */
9 #include "libbb.h"
10 #include "unicode.h"
11
12 const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str)
13 {
14         static char *saved[4];
15         static unsigned cur_saved; /* = 0 */
16
17         char *dst;
18         const char *s;
19
20         s = str;
21         while (1) {
22                 unsigned char c = *s;
23                 if (c == '\0') {
24                         /* 99+% of inputs do not need conversion */
25                         if (stats) {
26                                 stats->byte_count = (s - str);
27                                 stats->unicode_count = (s - str);
28                                 stats->unicode_width = (s - str);
29                         }
30                         return str;
31                 }
32                 if (c < ' ')
33                         break;
34                 if (c >= 0x7f)
35                         break;
36                 s++;
37         }
38
39 #if ENABLE_UNICODE_SUPPORT
40         dst = unicode_conv_to_printable(stats, str);
41 #else
42         {
43                 char *d = dst = xstrdup(str);
44                 while (1) {
45                         unsigned char c = *d;
46                         if (c == '\0')
47                                 break;
48                         if (c < ' ' || c >= 0x7f)
49                                 *d = '?';
50                         d++;
51                 }
52                 if (stats) {
53                         stats->byte_count = (d - dst);
54                         stats->unicode_count = (d - dst);
55                         stats->unicode_width = (d - dst);
56                 }
57         }
58 #endif
59
60         free(saved[cur_saved]);
61         saved[cur_saved] = dst;
62         cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1);
63
64         return dst;
65 }