Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / lib / string_helpers.c
1 /*
2  * Helpers for formatting and printing strings
3  *
4  * Copyright 31 August 2008 James Bottomley
5  * Copyright (C) 2013, Intel Corporation
6  */
7 #include <linux/bug.h>
8 #include <linux/kernel.h>
9 #include <linux/math64.h>
10 #include <linux/export.h>
11 #include <linux/ctype.h>
12 #include <linux/errno.h>
13 #include <linux/string.h>
14 #include <linux/string_helpers.h>
15
16 /**
17  * string_get_size - get the size in the specified units
18  * @size:       The size to be converted in blocks
19  * @blk_size:   Size of the block (use 1 for size in bytes)
20  * @units:      units to use (powers of 1000 or 1024)
21  * @buf:        buffer to format to
22  * @len:        length of buffer
23  *
24  * This function returns a string formatted to 3 significant figures
25  * giving the size in the required units.  @buf should have room for
26  * at least 9 bytes and will always be zero terminated.
27  *
28  */
29 void string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
30                      char *buf, int len)
31 {
32         static const char *const units_10[] = {
33                 "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"
34         };
35         static const char *const units_2[] = {
36                 "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"
37         };
38         static const char *const *const units_str[] = {
39                 [STRING_UNITS_10] = units_10,
40                 [STRING_UNITS_2] = units_2,
41         };
42         static const unsigned int divisor[] = {
43                 [STRING_UNITS_10] = 1000,
44                 [STRING_UNITS_2] = 1024,
45         };
46         int i, j;
47         u32 remainder = 0, sf_cap, exp;
48         char tmp[8];
49         const char *unit;
50
51         tmp[0] = '\0';
52         i = 0;
53         if (!size)
54                 goto out;
55
56         while (blk_size >= divisor[units]) {
57                 remainder = do_div(blk_size, divisor[units]);
58                 i++;
59         }
60
61         exp = divisor[units] / (u32)blk_size;
62         if (size >= exp) {
63                 remainder = do_div(size, divisor[units]);
64                 remainder *= blk_size;
65                 i++;
66         } else {
67                 remainder *= size;
68         }
69
70         size *= blk_size;
71         size += remainder / divisor[units];
72         remainder %= divisor[units];
73
74         while (size >= divisor[units]) {
75                 remainder = do_div(size, divisor[units]);
76                 i++;
77         }
78
79         sf_cap = size;
80         for (j = 0; sf_cap*10 < 1000; j++)
81                 sf_cap *= 10;
82
83         if (j) {
84                 remainder *= 1000;
85                 remainder /= divisor[units];
86                 snprintf(tmp, sizeof(tmp), ".%03u", remainder);
87                 tmp[j+1] = '\0';
88         }
89
90  out:
91         if (i >= ARRAY_SIZE(units_2))
92                 unit = "UNK";
93         else
94                 unit = units_str[units][i];
95
96         snprintf(buf, len, "%u%s %s", (u32)size,
97                  tmp, unit);
98 }
99 EXPORT_SYMBOL(string_get_size);
100
101 static bool unescape_space(char **src, char **dst)
102 {
103         char *p = *dst, *q = *src;
104
105         switch (*q) {
106         case 'n':
107                 *p = '\n';
108                 break;
109         case 'r':
110                 *p = '\r';
111                 break;
112         case 't':
113                 *p = '\t';
114                 break;
115         case 'v':
116                 *p = '\v';
117                 break;
118         case 'f':
119                 *p = '\f';
120                 break;
121         default:
122                 return false;
123         }
124         *dst += 1;
125         *src += 1;
126         return true;
127 }
128
129 static bool unescape_octal(char **src, char **dst)
130 {
131         char *p = *dst, *q = *src;
132         u8 num;
133
134         if (isodigit(*q) == 0)
135                 return false;
136
137         num = (*q++) & 7;
138         while (num < 32 && isodigit(*q) && (q - *src < 3)) {
139                 num <<= 3;
140                 num += (*q++) & 7;
141         }
142         *p = num;
143         *dst += 1;
144         *src = q;
145         return true;
146 }
147
148 static bool unescape_hex(char **src, char **dst)
149 {
150         char *p = *dst, *q = *src;
151         int digit;
152         u8 num;
153
154         if (*q++ != 'x')
155                 return false;
156
157         num = digit = hex_to_bin(*q++);
158         if (digit < 0)
159                 return false;
160
161         digit = hex_to_bin(*q);
162         if (digit >= 0) {
163                 q++;
164                 num = (num << 4) | digit;
165         }
166         *p = num;
167         *dst += 1;
168         *src = q;
169         return true;
170 }
171
172 static bool unescape_special(char **src, char **dst)
173 {
174         char *p = *dst, *q = *src;
175
176         switch (*q) {
177         case '\"':
178                 *p = '\"';
179                 break;
180         case '\\':
181                 *p = '\\';
182                 break;
183         case 'a':
184                 *p = '\a';
185                 break;
186         case 'e':
187                 *p = '\e';
188                 break;
189         default:
190                 return false;
191         }
192         *dst += 1;
193         *src += 1;
194         return true;
195 }
196
197 /**
198  * string_unescape - unquote characters in the given string
199  * @src:        source buffer (escaped)
200  * @dst:        destination buffer (unescaped)
201  * @size:       size of the destination buffer (0 to unlimit)
202  * @flags:      combination of the flags (bitwise OR):
203  *      %UNESCAPE_SPACE:
204  *              '\f' - form feed
205  *              '\n' - new line
206  *              '\r' - carriage return
207  *              '\t' - horizontal tab
208  *              '\v' - vertical tab
209  *      %UNESCAPE_OCTAL:
210  *              '\NNN' - byte with octal value NNN (1 to 3 digits)
211  *      %UNESCAPE_HEX:
212  *              '\xHH' - byte with hexadecimal value HH (1 to 2 digits)
213  *      %UNESCAPE_SPECIAL:
214  *              '\"' - double quote
215  *              '\\' - backslash
216  *              '\a' - alert (BEL)
217  *              '\e' - escape
218  *      %UNESCAPE_ANY:
219  *              all previous together
220  *
221  * Description:
222  * The function unquotes characters in the given string.
223  *
224  * Because the size of the output will be the same as or less than the size of
225  * the input, the transformation may be performed in place.
226  *
227  * Caller must provide valid source and destination pointers. Be aware that
228  * destination buffer will always be NULL-terminated. Source string must be
229  * NULL-terminated as well.
230  *
231  * Return:
232  * The amount of the characters processed to the destination buffer excluding
233  * trailing '\0' is returned.
234  */
235 int string_unescape(char *src, char *dst, size_t size, unsigned int flags)
236 {
237         char *out = dst;
238
239         while (*src && --size) {
240                 if (src[0] == '\\' && src[1] != '\0' && size > 1) {
241                         src++;
242                         size--;
243
244                         if (flags & UNESCAPE_SPACE &&
245                                         unescape_space(&src, &out))
246                                 continue;
247
248                         if (flags & UNESCAPE_OCTAL &&
249                                         unescape_octal(&src, &out))
250                                 continue;
251
252                         if (flags & UNESCAPE_HEX &&
253                                         unescape_hex(&src, &out))
254                                 continue;
255
256                         if (flags & UNESCAPE_SPECIAL &&
257                                         unescape_special(&src, &out))
258                                 continue;
259
260                         *out++ = '\\';
261                 }
262                 *out++ = *src++;
263         }
264         *out = '\0';
265
266         return out - dst;
267 }
268 EXPORT_SYMBOL(string_unescape);
269
270 static bool escape_passthrough(unsigned char c, char **dst, char *end)
271 {
272         char *out = *dst;
273
274         if (out < end)
275                 *out = c;
276         *dst = out + 1;
277         return true;
278 }
279
280 static bool escape_space(unsigned char c, char **dst, char *end)
281 {
282         char *out = *dst;
283         unsigned char to;
284
285         switch (c) {
286         case '\n':
287                 to = 'n';
288                 break;
289         case '\r':
290                 to = 'r';
291                 break;
292         case '\t':
293                 to = 't';
294                 break;
295         case '\v':
296                 to = 'v';
297                 break;
298         case '\f':
299                 to = 'f';
300                 break;
301         default:
302                 return false;
303         }
304
305         if (out < end)
306                 *out = '\\';
307         ++out;
308         if (out < end)
309                 *out = to;
310         ++out;
311
312         *dst = out;
313         return true;
314 }
315
316 static bool escape_special(unsigned char c, char **dst, char *end)
317 {
318         char *out = *dst;
319         unsigned char to;
320
321         switch (c) {
322         case '\\':
323                 to = '\\';
324                 break;
325         case '\a':
326                 to = 'a';
327                 break;
328         case '\e':
329                 to = 'e';
330                 break;
331         default:
332                 return false;
333         }
334
335         if (out < end)
336                 *out = '\\';
337         ++out;
338         if (out < end)
339                 *out = to;
340         ++out;
341
342         *dst = out;
343         return true;
344 }
345
346 static bool escape_null(unsigned char c, char **dst, char *end)
347 {
348         char *out = *dst;
349
350         if (c)
351                 return false;
352
353         if (out < end)
354                 *out = '\\';
355         ++out;
356         if (out < end)
357                 *out = '0';
358         ++out;
359
360         *dst = out;
361         return true;
362 }
363
364 static bool escape_octal(unsigned char c, char **dst, char *end)
365 {
366         char *out = *dst;
367
368         if (out < end)
369                 *out = '\\';
370         ++out;
371         if (out < end)
372                 *out = ((c >> 6) & 0x07) + '0';
373         ++out;
374         if (out < end)
375                 *out = ((c >> 3) & 0x07) + '0';
376         ++out;
377         if (out < end)
378                 *out = ((c >> 0) & 0x07) + '0';
379         ++out;
380
381         *dst = out;
382         return true;
383 }
384
385 static bool escape_hex(unsigned char c, char **dst, char *end)
386 {
387         char *out = *dst;
388
389         if (out < end)
390                 *out = '\\';
391         ++out;
392         if (out < end)
393                 *out = 'x';
394         ++out;
395         if (out < end)
396                 *out = hex_asc_hi(c);
397         ++out;
398         if (out < end)
399                 *out = hex_asc_lo(c);
400         ++out;
401
402         *dst = out;
403         return true;
404 }
405
406 /**
407  * string_escape_mem - quote characters in the given memory buffer
408  * @src:        source buffer (unescaped)
409  * @isz:        source buffer size
410  * @dst:        destination buffer (escaped)
411  * @osz:        destination buffer size
412  * @flags:      combination of the flags (bitwise OR):
413  *      %ESCAPE_SPACE:
414  *              '\f' - form feed
415  *              '\n' - new line
416  *              '\r' - carriage return
417  *              '\t' - horizontal tab
418  *              '\v' - vertical tab
419  *      %ESCAPE_SPECIAL:
420  *              '\\' - backslash
421  *              '\a' - alert (BEL)
422  *              '\e' - escape
423  *      %ESCAPE_NULL:
424  *              '\0' - null
425  *      %ESCAPE_OCTAL:
426  *              '\NNN' - byte with octal value NNN (3 digits)
427  *      %ESCAPE_ANY:
428  *              all previous together
429  *      %ESCAPE_NP:
430  *              escape only non-printable characters (checked by isprint)
431  *      %ESCAPE_ANY_NP:
432  *              all previous together
433  *      %ESCAPE_HEX:
434  *              '\xHH' - byte with hexadecimal value HH (2 digits)
435  * @esc:        NULL-terminated string of characters any of which, if found in
436  *              the source, has to be escaped
437  *
438  * Description:
439  * The process of escaping byte buffer includes several parts. They are applied
440  * in the following sequence.
441  *      1. The character is matched to the printable class, if asked, and in
442  *         case of match it passes through to the output.
443  *      2. The character is not matched to the one from @esc string and thus
444  *         must go as is to the output.
445  *      3. The character is checked if it falls into the class given by @flags.
446  *         %ESCAPE_OCTAL and %ESCAPE_HEX are going last since they cover any
447  *         character. Note that they actually can't go together, otherwise
448  *         %ESCAPE_HEX will be ignored.
449  *
450  * Caller must provide valid source and destination pointers. Be aware that
451  * destination buffer will not be NULL-terminated, thus caller have to append
452  * it if needs.
453  *
454  * Return:
455  * The total size of the escaped output that would be generated for
456  * the given input and flags. To check whether the output was
457  * truncated, compare the return value to osz. There is room left in
458  * dst for a '\0' terminator if and only if ret < osz.
459  */
460 int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
461                       unsigned int flags, const char *esc)
462 {
463         char *p = dst;
464         char *end = p + osz;
465         bool is_dict = esc && *esc;
466
467         while (isz--) {
468                 unsigned char c = *src++;
469
470                 /*
471                  * Apply rules in the following sequence:
472                  *      - the character is printable, when @flags has
473                  *        %ESCAPE_NP bit set
474                  *      - the @esc string is supplied and does not contain a
475                  *        character under question
476                  *      - the character doesn't fall into a class of symbols
477                  *        defined by given @flags
478                  * In these cases we just pass through a character to the
479                  * output buffer.
480                  */
481                 if ((flags & ESCAPE_NP && isprint(c)) ||
482                     (is_dict && !strchr(esc, c))) {
483                         /* do nothing */
484                 } else {
485                         if (flags & ESCAPE_SPACE && escape_space(c, &p, end))
486                                 continue;
487
488                         if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end))
489                                 continue;
490
491                         if (flags & ESCAPE_NULL && escape_null(c, &p, end))
492                                 continue;
493
494                         /* ESCAPE_OCTAL and ESCAPE_HEX always go last */
495                         if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end))
496                                 continue;
497
498                         if (flags & ESCAPE_HEX && escape_hex(c, &p, end))
499                                 continue;
500                 }
501
502                 escape_passthrough(c, &p, end);
503         }
504
505         return p - dst;
506 }
507 EXPORT_SYMBOL(string_escape_mem);