Merge pull request #2616 from jmichelp/fix14b
[RRG-proxmark3.git] / armsrc / string.c
blobb7e549ff12550cbb261ec2b8b31115562b510c0c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // Common string.h functions
17 //-----------------------------------------------------------------------------
18 #include "string.h"
20 void *memcpy(void *dest, const void *src, int len) {
21 uint8_t *d = dest;
22 const uint8_t *s = src;
23 while ((len--) > 0) {
24 *d = *s;
25 d++;
26 s++;
28 return dest;
31 void *memmove(void *dest, const void *src, size_t len) {
32 char *d = dest;
33 const char *s = src;
34 if (d < s)
35 while (len--)
36 *d++ = *s++;
37 else {
38 char *lasts = (char *)s + (len - 1);
39 char *lastd = d + (len - 1);
40 while (len--)
41 *lastd-- = *lasts--;
43 return dest;
46 void *memset(void *dest, uint8_t c, int len) {
47 uint8_t *d = dest;
48 while ((len--) > 0) {
49 *d = c;
50 d++;
52 return dest;
55 int memcmp(const void *av, const void *bv, int len) {
56 const uint8_t *a = av;
57 const uint8_t *b = bv;
59 while ((len--) > 0) {
60 if (*a != *b) {
61 return *a - *b;
63 a++;
64 b++;
66 return 0;
69 void memxor(uint8_t *dest, uint8_t *src, size_t len) {
70 for (; len > 0; len--, dest++, src++)
71 *dest ^= *src;
74 int strlen(const char *str) {
75 const char *p;
76 for (p = str; *p != '\0'; ++p) {};
77 return p - str;
80 char *strncat(char *dest, const char *src, unsigned int n) {
81 int dest_len = strlen(dest);
82 unsigned int i;
84 for (i = 0 ; i < n && src[i] != '\0' ; i++)
85 dest[dest_len + i] = src[i];
87 dest[dest_len + i] = '\0';
89 return dest;
92 char *strcat(char *dest, const char *src) {
93 int dest_len = strlen(dest);
94 unsigned int i;
96 for (i = 0 ; src[i] != '\0' ; i++)
97 dest[dest_len + i] = src[i];
98 dest[dest_len + i] = '\0';
100 return dest;
102 ////////////////////////////////////////// code to do 'itoa'
104 /* reverse: reverse string s in place */
105 void strreverse(char s[]) {
106 int j = strlen(s) - 1;
108 for (int i = 0; i < j; i++, j--) {
109 char c = s[i];
110 s[i] = s[j];
111 s[j] = c;
115 /* itoa: convert n to characters in s */
116 void itoa(int n, char s[]) {
117 int sign;
118 if ((sign = n) < 0) /* record sign */
119 n = -n; /* make n positive */
121 int i = 0;
122 do { /* generate digits in reverse order */
123 s[i++] = n % 10 + '0'; /* get next digit */
124 } while ((n /= 10) > 0); /* delete it */
125 if (sign < 0)
126 s[i++] = '-';
127 s[i] = '\0';
128 strreverse(s);
131 //////////////////////////////////////// END 'itoa' CODE
135 char *strcpy(char *dst, const char *src) {
136 char *save = dst;
138 for (; (*dst = *src) != '\0'; ++src, ++dst);
139 return save;
142 char *strncpy(char *dst, const char *src, size_t n) {
143 if (n != 0) {
144 char *d = dst;
145 const char *s = src;
147 do {
148 if ((*d++ = *s++) == 0) {
149 /* NUL pad the remaining n-1 bytes */
150 while (--n) {
151 *d++ = 0;
153 break;
155 } while (--n);
157 return dst;
160 int strcmp(const char *s1, const char *s2) {
161 while (*s1 == *s2++) {
162 if (*s1++ == 0) {
163 return (0);
166 return (*(unsigned char *) s1 - * (unsigned char *) --s2);
169 char *__strtok_r(char *, const char *, char **);
171 char *__strtok_r(char *s, const char *delim, char **last) {
172 char *spanp, *tok;
173 int c, sc;
175 if (s == NULL && (s = *last) == NULL)
176 return (NULL);
179 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
181 cont:
182 c = *s++;
183 for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
184 if (c == sc)
185 goto cont;
188 if (c == 0) {
189 /* no non-delimiter characters */
190 *last = NULL;
191 return (NULL);
193 tok = s - 1;
196 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
197 * Note that delim must have one NUL; we stop if we see that, too.
199 for (;;) {
200 c = *s++;
201 spanp = (char *)delim;
202 do {
203 if ((sc = *spanp++) == c) {
204 if (c == 0)
205 s = NULL;
206 else
207 s[-1] = '\0';
208 *last = s;
209 return (tok);
211 } while (sc != 0);
213 /* NOTREACHED */
216 char *strtok(char *s, const char *delim) {
217 static char *last;
219 return (__strtok_r(s, delim, &last));
223 char *strchr(const char *s, int c) {
224 while (*s != (char)c)
225 if (!*s++)
226 return 0;
227 return (char *)s;
230 size_t strspn(const char *s1, const char *s2) {
231 size_t ret = 0;
232 while (*s1 && strchr(s2, *s1++))
233 ret++;
234 return ret;
237 char *strrchr(const char *s, int c) {
238 const char *ret = 0;
239 do {
240 if (*s == (char)c)
241 ret = s;
242 } while (*s++);
243 return (char *)ret;
246 size_t strcspn(const char *s1, const char *s2) {
247 size_t ret = 0;
248 while (*s1)
249 if (strchr(s2, *s1))
250 return ret;
251 else
252 s1++, ret++;
253 return ret;
256 char *strpbrk(const char *s1, const char *s2) {
257 while (*s1)
258 if (strchr(s2, *s1++))
259 return (char *)--s1;
260 return 0;
263 int strncmp(const char *s1, const char *s2, size_t n) {
264 while (n--)
265 if (*s1++ != *s2++)
266 return *(unsigned char *)(s1 - 1) - *(unsigned char *)(s2 - 1);
267 return 0;
273 #define isspace(a) __extension__ ({ unsigned char bb__isspace = (a) - 9; bb__isspace == (' ' - 9) || bb__isspace <= (13 - 9); })
275 unsigned long strtoul(const char *p, char **out_p, int base) {
276 unsigned long v = 0;
278 while (isspace(*p))
279 p++;
280 if (((base == 16) || (base == 0)) &&
281 ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) {
282 p += 2;
283 base = 16;
285 if (base == 0) {
286 if (*p == '0')
287 base = 8;
288 else
289 base = 10;
291 while (1) {
292 char c = *p;
293 if ((c >= '0') && (c <= '9') && (c - '0' < base))
294 v = (v * base) + (c - '0');
295 else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base))
296 v = (v * base) + (c - 'a' + 10);
297 else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base))
298 v = (v * base) + (c - 'A' + 10);
299 else
300 break;
301 p++;
304 if (out_p) *out_p = (char *)p;
305 return v;
308 long strtol(const char *p, char **out_p, int base) {
309 long v = 0;
310 int is_neg = 0;
312 while (isspace(*p))
313 p++;
314 if (*p == '-')
315 is_neg = 1, p++;
316 else if (*p == '+')
317 is_neg = 0;
318 if (((base == 16) || (base == 0)) &&
319 ((*p == '0') && ((p[1] == 'x') || (p[1] == 'X')))) {
320 p += 2;
321 base = 16;
323 if (base == 0) {
324 if (*p == '0')
325 base = 8;
326 else
327 base = 10;
329 while (1) {
330 char c = *p;
331 if ((c >= '0') && (c <= '9') && (c - '0' < base))
332 v = (v * base) + (c - '0');
333 else if ((c >= 'a') && (c <= 'z') && (c - 'a' + 10 < base))
334 v = (v * base) + (c - 'a' + 10);
335 else if ((c >= 'A') && (c <= 'Z') && (c - 'A' + 10 < base))
336 v = (v * base) + (c - 'A' + 10);
337 else
338 break;
339 p++;
341 if (is_neg)
342 v = -v;
343 if (out_p) *out_p = (char *)p;
344 return v;
347 char c_tolower(int c) {
348 // (int)a = 97, (int)A = 65
349 // (a)97 - (A)65 = 32
350 // therefore 32 + 65 = a
351 return c > 64 && c < 91 ? c + 32 : c;
354 char c_isprint(unsigned char c) {
355 if (c >= 0x20 && c <= 0x7e)
356 return 1;
357 return 0;