/armsrc/string.c

https://github.com/RfidResearchGroup/proxmark3 · C · 349 lines · 272 code · 51 blank · 26 comment · 130 complexity · 4237f21e75b275ef54ca442f98fb10e5 MD5 · raw file

  1. //-----------------------------------------------------------------------------
  2. // Jonathan Westhues, Sept 2005
  3. //
  4. // This code is licensed to you under the terms of the GNU GPL, version 2 or,
  5. // at your option, any later version. See the LICENSE.txt file for the text of
  6. // the license.
  7. //-----------------------------------------------------------------------------
  8. // Common string.h functions
  9. //-----------------------------------------------------------------------------
  10. #include "string.h"
  11. void *memcpy(void *dest, const void *src, int len) {
  12. uint8_t *d = dest;
  13. const uint8_t *s = src;
  14. while ((len--) > 0) {
  15. *d = *s;
  16. d++;
  17. s++;
  18. }
  19. return dest;
  20. }
  21. void *memmove(void *dest, const void *src, size_t len) {
  22. char *d = dest;
  23. const char *s = src;
  24. if (d < s)
  25. while (len--)
  26. *d++ = *s++;
  27. else {
  28. char *lasts = (char *)s + (len - 1);
  29. char *lastd = d + (len - 1);
  30. while (len--)
  31. *lastd-- = *lasts--;
  32. }
  33. return dest;
  34. }
  35. void *memset(void *dest, int c, int len) {
  36. uint8_t *d = dest;
  37. while ((len--) > 0) {
  38. *d = c;
  39. d++;
  40. }
  41. return dest;
  42. }
  43. int memcmp(const void *av, const void *bv, int len) {
  44. const uint8_t *a = av;
  45. const uint8_t *b = bv;
  46. while ((len--) > 0) {
  47. if (*a != *b) {
  48. return *a - *b;
  49. }
  50. a++;
  51. b++;
  52. }
  53. return 0;
  54. }
  55. void memxor(uint8_t *dest, uint8_t *src, size_t len) {
  56. for (; len > 0; len--, dest++, src++)
  57. *dest ^= *src;
  58. }
  59. int strlen(const char *str) {
  60. const char *p;
  61. for (p = str; *p != '\0'; ++p) {};
  62. return p - str;
  63. }
  64. char *strncat(char *dest, const char *src, unsigned int n) {
  65. unsigned int dest_len = strlen(dest);
  66. unsigned int i;
  67. for (i = 0 ; i < n && src[i] != '\0' ; i++)
  68. dest[dest_len + i] = src[i];
  69. dest[dest_len + i] = '\0';
  70. return dest;
  71. }
  72. char *strcat(char *dest, const char *src) {
  73. unsigned int dest_len = strlen(dest);
  74. unsigned int i;
  75. for (i = 0 ; src[i] != '\0' ; i++)
  76. dest[dest_len + i] = src[i];
  77. dest[dest_len + i] = '\0';
  78. return dest;
  79. }
  80. ////////////////////////////////////////// code to do 'itoa'
  81. /* reverse: reverse string s in place */
  82. void strreverse(char s[]) {
  83. int j = strlen(s) - 1;
  84. for (int i = 0; i < j; i++, j--) {
  85. int c = s[i];
  86. s[i] = s[j];
  87. s[j] = c;
  88. }
  89. }
  90. /* itoa: convert n to characters in s */
  91. void itoa(int n, char s[]) {
  92. int i, sign;
  93. if ((sign = n) < 0) /* record sign */
  94. n = -n; /* make n positive */
  95. i = 0;
  96. do { /* generate digits in reverse order */
  97. s[i++] = n % 10 + '0'; /* get next digit */
  98. } while ((n /= 10) > 0); /* delete it */
  99. if (sign < 0)
  100. s[i++] = '-';
  101. s[i] = '\0';
  102. strreverse(s);
  103. }
  104. //////////////////////////////////////// END 'itoa' CODE
  105. char *strcpy(char *dst, const char *src) {
  106. char *save = dst;
  107. for (; (*dst = *src) != '\0'; ++src, ++dst);
  108. return save;
  109. }
  110. char *strncpy(char *dst, const char *src, size_t n) {
  111. if (n != 0) {
  112. char *d = dst;
  113. const char *s = src;
  114. do {
  115. if ((*d++ = *s++) == 0) {
  116. /* NUL pad the remaining n-1 bytes */
  117. while (--n) {
  118. *d++ = 0;
  119. }
  120. break;
  121. }
  122. } while (--n);
  123. }
  124. return dst;
  125. }
  126. int strcmp(const char *s1, const char *s2) {
  127. while (*s1 == *s2++) {
  128. if (*s1++ == 0) {
  129. return (0);
  130. }
  131. }
  132. return (*(unsigned char *) s1 - * (unsigned char *) --s2);
  133. }
  134. char *__strtok_r(char *, const char *, char **);
  135. char *__strtok_r(char *s, const char *delim, char **last) {
  136. char *spanp, *tok;
  137. int c, sc;
  138. if (s == NULL && (s = *last) == NULL)
  139. return (NULL);
  140. /*
  141. * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
  142. */
  143. cont:
  144. c = *s++;
  145. for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
  146. if (c == sc)
  147. goto cont;
  148. }
  149. if (c == 0) {
  150. /* no non-delimiter characters */
  151. *last = NULL;
  152. return (NULL);
  153. }
  154. tok = s - 1;
  155. /*
  156. * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
  157. * Note that delim must have one NUL; we stop if we see that, too.
  158. */
  159. for (;;) {
  160. c = *s++;
  161. spanp = (char *)delim;
  162. do {
  163. if ((sc = *spanp++) == c) {
  164. if (c == 0)
  165. s = NULL;
  166. else
  167. s[-1] = '\0';
  168. *last = s;
  169. return (tok);
  170. }
  171. } while (sc != 0);
  172. }
  173. /* NOTREACHED */
  174. }
  175. char *strtok(char *s, const char *delim) {
  176. static char *last;
  177. return (__strtok_r(s, delim, &last));
  178. }
  179. char *strchr(const char *s, int c) {
  180. while (*s != (char)c)
  181. if (!*s++)
  182. return 0;
  183. return (char *)s;
  184. }
  185. size_t strspn(const char *s1, const char *s2) {
  186. size_t ret = 0;
  187. while (*s1 && strchr(s2, *s1++))
  188. ret++;
  189. return ret;
  190. }
  191. char *strrchr(const char *s, int c) {
  192. const char *ret = 0;
  193. do {
  194. if (*s == (char)c)
  195. ret = s;
  196. } while (*s++);
  197. return (char *)ret;
  198. }
  199. size_t strcspn(const char *s1, const char *s2) {
  200. size_t ret = 0;
  201. while (*s1)
  202. if (strchr(s2, *s1))
  203. return ret;
  204. else
  205. s1++, ret++;
  206. return ret;
  207. }
  208. char *strpbrk(const char *s1, const char *s2) {
  209. while (*s1)
  210. if (strchr(s2, *s1++))
  211. return (char *)--s1;
  212. return 0;
  213. }
  214. int strncmp(const char *s1, const char *s2, size_t n) {
  215. while (n--)
  216. if (*s1++ != *s2++)
  217. return *(unsigned char *)(s1 - 1) - *(unsigned char *)(s2 - 1);
  218. return 0;
  219. }
  220. #define isspace(a) __extension__ ({ unsigned char bb__isspace = (a) - 9; bb__isspace == (' ' - 9) || bb__isspace <= (13 - 9); })
  221. unsigned long strtoul(const char *p, char **out_p, int base) {
  222. unsigned long v = 0;
  223. while (isspace(*p))
  224. p++;
  225. if (((base == 16) || (base == 0)) &&
  226. ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) {
  227. p += 2;
  228. base = 16;
  229. }
  230. if (base == 0) {
  231. if (*p == '0')
  232. base = 8;
  233. else
  234. base = 10;
  235. }
  236. while (1) {
  237. char c = *p;
  238. if ((c >= '0') && (c <= '9') && (c - '0' < base))
  239. v = (v * base) + (c - '0');
  240. else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base))
  241. v = (v * base) + (c - 'a' + 10);
  242. else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base))
  243. v = (v * base) + (c - 'A' + 10);
  244. else
  245. break;
  246. p++;
  247. }
  248. if (out_p) *out_p = (char *)p;
  249. return v;
  250. }
  251. long strtol(const char *p, char **out_p, int base) {
  252. long v = 0;
  253. int is_neg = 0;
  254. while (isspace(*p))
  255. p++;
  256. if (*p == '-')
  257. is_neg = 1, p++;
  258. else if (*p == '+')
  259. is_neg = 0;
  260. if (((base == 16) || (base == 0)) &&
  261. ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) {
  262. p += 2;
  263. base = 16;
  264. }
  265. if (base == 0) {
  266. if (*p == '0')
  267. base = 8;
  268. else
  269. base = 10;
  270. }
  271. while (1) {
  272. char c = *p;
  273. if ((c >= '0') && (c <= '9') && (c - '0' < base))
  274. v = (v * base) + (c - '0');
  275. else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base))
  276. v = (v * base) + (c - 'a' + 10);
  277. else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base))
  278. v = (v * base) + (c - 'A' + 10);
  279. else
  280. break;
  281. p++;
  282. }
  283. if (is_neg)
  284. v = -v;
  285. if (out_p) *out_p = (char *)p;
  286. return v;
  287. }
  288. char c_tolower(int c) {
  289. // (int)a = 97, (int)A = 65
  290. // (a)97 - (A)65 = 32
  291. // therefore 32 + 65 = a
  292. return c > 64 && c < 91 ? c + 32 : c;
  293. }
  294. char c_isprint(unsigned char c) {
  295. if (c >= 0x20 && c <= 0x7e)
  296. return 1;
  297. return 0;
  298. }