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/kernel.h> 8 #include <linux/math64.h> 9 #include <linux/export.h> 10 #include <linux/ctype.h> 11 #include <linux/string_helpers.h> 12 13 /** 14 * string_get_size - get the size in the specified units 15 * @size: The size to be converted 16 * @units: units to use (powers of 1000 or 1024) 17 * @buf: buffer to format to 18 * @len: length of buffer 19 * 20 * This function returns a string formatted to 3 significant figures 21 * giving the size in the required units. Returns 0 on success or 22 * error on failure. @buf is always zero terminated. 23 * 24 */ 25 int string_get_size(u64 size, const enum string_size_units units, 26 char *buf, int len) 27 { 28 static const char *units_10[] = { "B", "kB", "MB", "GB", "TB", "PB", 29 "EB", "ZB", "YB", NULL}; 30 static const char *units_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", 31 "EiB", "ZiB", "YiB", NULL }; 32 static const char **units_str[] = { 33 [STRING_UNITS_10] = units_10, 34 [STRING_UNITS_2] = units_2, 35 }; 36 static const unsigned int divisor[] = { 37 [STRING_UNITS_10] = 1000, 38 [STRING_UNITS_2] = 1024, 39 }; 40 int i, j; 41 u64 remainder = 0, sf_cap; 42 char tmp[8]; 43 44 tmp[0] = '\0'; 45 i = 0; 46 if (size >= divisor[units]) { 47 while (size >= divisor[units] && units_str[units][i]) { 48 remainder = do_div(size, divisor[units]); 49 i++; 50 } 51 52 sf_cap = size; 53 for (j = 0; sf_cap*10 < 1000; j++) 54 sf_cap *= 10; 55 56 if (j) { 57 remainder *= 1000; 58 do_div(remainder, divisor[units]); 59 snprintf(tmp, sizeof(tmp), ".%03lld", 60 (unsigned long long)remainder); 61 tmp[j+1] = '\0'; 62 } 63 } 64 65 snprintf(buf, len, "%lld%s %s", (unsigned long long)size, 66 tmp, units_str[units][i]); 67 68 return 0; 69 } 70 EXPORT_SYMBOL(string_get_size); 71 72 static bool unescape_space(char **src, char **dst) 73 { 74 char *p = *dst, *q = *src; 75 76 switch (*q) { 77 case 'n': 78 *p = '\n'; 79 break; 80 case 'r': 81 *p = '\r'; 82 break; 83 case 't': 84 *p = '\t'; 85 break; 86 case 'v': 87 *p = '\v'; 88 break; 89 case 'f': 90 *p = '\f'; 91 break; 92 default: 93 return false; 94 } 95 *dst += 1; 96 *src += 1; 97 return true; 98 } 99 100 static bool unescape_octal(char **src, char **dst) 101 { 102 char *p = *dst, *q = *src; 103 u8 num; 104 105 if (isodigit(*q) == 0) 106 return false; 107 108 num = (*q++) & 7; 109 while (num < 32 && isodigit(*q) && (q - *src < 3)) { 110 num <<= 3; 111 num += (*q++) & 7; 112 } 113 *p = num; 114 *dst += 1; 115 *src = q; 116 return true; 117 } 118 119 static bool unescape_hex(char **src, char **dst) 120 { 121 char *p = *dst, *q = *src; 122 int digit; 123 u8 num; 124 125 if (*q++ != 'x') 126 return false; 127 128 num = digit = hex_to_bin(*q++); 129 if (digit < 0) 130 return false; 131 132 digit = hex_to_bin(*q); 133 if (digit >= 0) { 134 q++; 135 num = (num << 4) | digit; 136 } 137 *p = num; 138 *dst += 1; 139 *src = q; 140 return true; 141 } 142 143 static bool unescape_special(char **src, char **dst) 144 { 145 char *p = *dst, *q = *src; 146 147 switch (*q) { 148 case '\"': 149 *p = '\"'; 150 break; 151 case '\\': 152 *p = '\\'; 153 break; 154 case 'a': 155 *p = '\a'; 156 break; 157 case 'e': 158 *p = '\e'; 159 break; 160 default: 161 return false; 162 } 163 *dst += 1; 164 *src += 1; 165 return true; 166 } 167 168 int string_unescape(char *src, char *dst, size_t size, unsigned int flags) 169 { 170 char *out = dst; 171 172 while (*src && --size) { 173 if (src[0] == '\\' && src[1] != '\0' && size > 1) { 174 src++; 175 size--; 176 177 if (flags & UNESCAPE_SPACE && 178 unescape_space(&src, &out)) 179 continue; 180 181 if (flags & UNESCAPE_OCTAL && 182 unescape_octal(&src, &out)) 183 continue; 184 185 if (flags & UNESCAPE_HEX && 186 unescape_hex(&src, &out)) 187 continue; 188 189 if (flags & UNESCAPE_SPECIAL && 190 unescape_special(&src, &out)) 191 continue; 192 193 *out++ = '\\'; 194 } 195 *out++ = *src++; 196 } 197 *out = '\0'; 198 199 return out - dst; 200 } 201 EXPORT_SYMBOL(string_unescape); 202