string.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // SPDX-License-Identifier: GPL-2.0
  2. #define IN_BOOT_STRING_C 1
  3. #include <linux/ctype.h>
  4. #include <linux/kernel.h>
  5. #include <linux/errno.h>
  6. #undef CONFIG_KASAN
  7. #undef CONFIG_KASAN_GENERIC
  8. #undef CONFIG_KMSAN
  9. #include "../lib/string.c"
  10. /*
  11. * Duplicate some functions from the common lib/string.c
  12. * instead of fully including it.
  13. */
  14. int strncmp(const char *cs, const char *ct, size_t count)
  15. {
  16. unsigned char c1, c2;
  17. while (count) {
  18. c1 = *cs++;
  19. c2 = *ct++;
  20. if (c1 != c2)
  21. return c1 < c2 ? -1 : 1;
  22. if (!c1)
  23. break;
  24. count--;
  25. }
  26. return 0;
  27. }
  28. void *memset64(uint64_t *s, uint64_t v, size_t count)
  29. {
  30. uint64_t *xs = s;
  31. while (count--)
  32. *xs++ = v;
  33. return s;
  34. }
  35. char *skip_spaces(const char *str)
  36. {
  37. while (isspace(*str))
  38. ++str;
  39. return (char *)str;
  40. }
  41. char *strim(char *s)
  42. {
  43. size_t size;
  44. char *end;
  45. size = strlen(s);
  46. if (!size)
  47. return s;
  48. end = s + size - 1;
  49. while (end >= s && isspace(*end))
  50. end--;
  51. *(end + 1) = '\0';
  52. return skip_spaces(s);
  53. }
  54. /* Works only for digits and letters, but small and fast */
  55. #define TOLOWER(x) ((x) | 0x20)
  56. static unsigned int simple_guess_base(const char *cp)
  57. {
  58. if (cp[0] == '0') {
  59. if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
  60. return 16;
  61. else
  62. return 8;
  63. } else {
  64. return 10;
  65. }
  66. }
  67. /**
  68. * simple_strtoull - convert a string to an unsigned long long
  69. * @cp: The start of the string
  70. * @endp: A pointer to the end of the parsed string will be placed here
  71. * @base: The number base to use
  72. */
  73. unsigned long long simple_strtoull(const char *cp, char **endp,
  74. unsigned int base)
  75. {
  76. unsigned long long result = 0;
  77. if (!base)
  78. base = simple_guess_base(cp);
  79. if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
  80. cp += 2;
  81. while (isxdigit(*cp)) {
  82. unsigned int value;
  83. value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
  84. if (value >= base)
  85. break;
  86. result = result * base + value;
  87. cp++;
  88. }
  89. if (endp)
  90. *endp = (char *)cp;
  91. return result;
  92. }
  93. long simple_strtol(const char *cp, char **endp, unsigned int base)
  94. {
  95. if (*cp == '-')
  96. return -simple_strtoull(cp + 1, endp, base);
  97. return simple_strtoull(cp, endp, base);
  98. }
  99. int kstrtobool(const char *s, bool *res)
  100. {
  101. if (!s)
  102. return -EINVAL;
  103. switch (s[0]) {
  104. case 'y':
  105. case 'Y':
  106. case '1':
  107. *res = true;
  108. return 0;
  109. case 'n':
  110. case 'N':
  111. case '0':
  112. *res = false;
  113. return 0;
  114. case 'o':
  115. case 'O':
  116. switch (s[1]) {
  117. case 'n':
  118. case 'N':
  119. *res = true;
  120. return 0;
  121. case 'f':
  122. case 'F':
  123. *res = false;
  124. return 0;
  125. default:
  126. break;
  127. }
  128. default:
  129. break;
  130. }
  131. return -EINVAL;
  132. }