strto.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. * linux/lib/vsprintf.c
  3. *
  4. * Copyright (C) 1991, 1992 Linus Torvalds
  5. */
  6. /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
  7. /*
  8. * Wirzenius wrote this portably, Torvalds fucked it up :-)
  9. */
  10. #include <common.h>
  11. #include <errno.h>
  12. #include <malloc.h>
  13. #include <linux/ctype.h>
  14. /* from lib/kstrtox.c */
  15. static const char *_parse_integer_fixup_radix(const char *s, uint *basep)
  16. {
  17. /* Look for a 0x prefix */
  18. if (s[0] == '0') {
  19. int ch = tolower(s[1]);
  20. if (ch == 'x') {
  21. *basep = 16;
  22. s += 2;
  23. } else if (!*basep) {
  24. /* Only select octal if we don't have a base */
  25. *basep = 8;
  26. }
  27. }
  28. /* Use decimal by default */
  29. if (!*basep)
  30. *basep = 10;
  31. return s;
  32. }
  33. /**
  34. * decode_digit() - Decode a single character into its numeric digit value
  35. *
  36. * This ignore case
  37. *
  38. * @ch: Character to convert (expects '0'..'9', 'a'..'f' or 'A'..'F')
  39. * Return: value of digit (0..0xf) or 255 if the character is invalid
  40. */
  41. static uint decode_digit(int ch)
  42. {
  43. if (!isxdigit(ch))
  44. return 256;
  45. ch = tolower(ch);
  46. return ch <= '9' ? ch - '0' : ch - 'a' + 0xa;
  47. }
  48. ulong simple_strtoul(const char *cp, char **endp, uint base)
  49. {
  50. ulong result = 0;
  51. uint value;
  52. cp = _parse_integer_fixup_radix(cp, &base);
  53. while (value = decode_digit(*cp), value < base) {
  54. result = result * base + value;
  55. cp++;
  56. }
  57. if (endp)
  58. *endp = (char *)cp;
  59. return result;
  60. }
  61. ulong hextoul(const char *cp, char **endp)
  62. {
  63. return simple_strtoul(cp, endp, 16);
  64. }
  65. ulong dectoul(const char *cp, char **endp)
  66. {
  67. return simple_strtoul(cp, endp, 10);
  68. }
  69. int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
  70. {
  71. char *tail;
  72. unsigned long val;
  73. size_t len;
  74. *res = 0;
  75. len = strlen(cp);
  76. if (len == 0)
  77. return -EINVAL;
  78. val = simple_strtoul(cp, &tail, base);
  79. if (tail == cp)
  80. return -EINVAL;
  81. if ((*tail == '\0') ||
  82. ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
  83. *res = val;
  84. return 0;
  85. }
  86. return -EINVAL;
  87. }
  88. long simple_strtol(const char *cp, char **endp, unsigned int base)
  89. {
  90. if (*cp == '-')
  91. return -simple_strtoul(cp + 1, endp, base);
  92. return simple_strtoul(cp, endp, base);
  93. }
  94. unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)
  95. {
  96. unsigned long result = simple_strtoul(cp, endp, base);
  97. switch (tolower(**endp)) {
  98. case 'g':
  99. result *= 1024;
  100. /* fall through */
  101. case 'm':
  102. result *= 1024;
  103. /* fall through */
  104. case 'k':
  105. result *= 1024;
  106. (*endp)++;
  107. if (**endp == 'i')
  108. (*endp)++;
  109. if (**endp == 'B')
  110. (*endp)++;
  111. }
  112. return result;
  113. }
  114. unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base)
  115. {
  116. unsigned long long result = simple_strtoull(cp, endp, base);
  117. switch (tolower(**endp)) {
  118. case 'g':
  119. result *= 1024;
  120. /* fall through */
  121. case 'm':
  122. result *= 1024;
  123. /* fall through */
  124. case 'k':
  125. result *= 1024;
  126. (*endp)++;
  127. if (**endp == 'i')
  128. (*endp)++;
  129. if (**endp == 'B')
  130. (*endp)++;
  131. }
  132. return result;
  133. }
  134. unsigned long long simple_strtoull(const char *cp, char **endp,
  135. unsigned int base)
  136. {
  137. unsigned long long result = 0;
  138. uint value;
  139. cp = _parse_integer_fixup_radix(cp, &base);
  140. while (value = decode_digit(*cp), value < base) {
  141. result = result * base + value;
  142. cp++;
  143. }
  144. if (endp)
  145. *endp = (char *) cp;
  146. return result;
  147. }
  148. long long simple_strtoll(const char *cp, char **endp, unsigned int base)
  149. {
  150. if (*cp == '-')
  151. return -simple_strtoull(cp + 1, endp, base);
  152. return simple_strtoull(cp, endp, base);
  153. }
  154. long trailing_strtoln_end(const char *str, const char *end, char const **endp)
  155. {
  156. const char *p;
  157. if (!end)
  158. end = str + strlen(str);
  159. p = end - 1;
  160. if (p > str && isdigit(*p)) {
  161. do {
  162. if (!isdigit(p[-1])) {
  163. if (endp)
  164. *endp = p;
  165. return dectoul(p, NULL);
  166. }
  167. } while (--p > str);
  168. }
  169. if (endp)
  170. *endp = end;
  171. return -1;
  172. }
  173. long trailing_strtoln(const char *str, const char *end)
  174. {
  175. return trailing_strtoln_end(str, end, NULL);
  176. }
  177. long trailing_strtol(const char *str)
  178. {
  179. return trailing_strtoln(str, NULL);
  180. }
  181. void str_to_upper(const char *in, char *out, size_t len)
  182. {
  183. for (; len > 0 && *in; len--)
  184. *out++ = toupper(*in++);
  185. if (len)
  186. *out = '\0';
  187. }
  188. const char **str_to_list(const char *instr)
  189. {
  190. const char **ptr;
  191. char *str, *p;
  192. int count, i;
  193. /* don't allocate if the string is empty */
  194. str = *instr ? strdup(instr) : (char *)instr;
  195. if (!str)
  196. return NULL;
  197. /* count the number of space-separated strings */
  198. for (count = *str != '\0', p = str; *p; p++) {
  199. if (*p == ' ') {
  200. count++;
  201. *p = '\0';
  202. }
  203. }
  204. /* allocate the pointer array, allowing for a NULL terminator */
  205. ptr = calloc(count + 1, sizeof(char *));
  206. if (!ptr) {
  207. if (*str)
  208. free(str);
  209. return NULL;
  210. }
  211. for (i = 0, p = str; i < count; p += strlen(p) + 1, i++)
  212. ptr[i] = p;
  213. return ptr;
  214. }
  215. void str_free_list(const char **ptr)
  216. {
  217. if (ptr)
  218. free((char *)ptr[0]);
  219. free(ptr);
  220. }