1 // Basic string routines. Not hardware optimized, but not shabby.
9 #include <ros/memlayout.h>
17 for (n = 0; *s != '\0'; s++)
23 strnlen(const char *s, size_t size)
27 for (n = 0; size > 0 && *s != '\0'; s++, size--)
32 /* zra: These aren't being used, and they are dangerous, so I'm rm'ing them
34 strcpy(char *dst, const char *src)
39 while ((*dst++ = *src++) != '\0')
45 strcat(char *dst, const char *src)
47 strcpy(dst+strlen(dst),src);
53 strncpy(char *dst, const char *src, size_t size) {
58 for (i = 0; i < size; i++) {
59 // TODO: ivy bitches about this
61 // If strlen(src) < size, null-pad 'dst' out to 'size' chars
69 strlcpy(char *dst, const char *src, size_t size)
75 while (--size > 0 && *src != '\0')
83 strcmp(const char *p, const char *q)
85 while (*p && *p == *q)
87 return (int) ((unsigned char) *p - (unsigned char) *q);
91 strncmp(const char *p, const char *q, size_t n)
93 while (n > 0 && *p && *p == *q)
98 return (int) ((unsigned char) *p - (unsigned char) *q);
101 // Return a pointer to the first occurrence of 'c' in 's',
102 // or a null pointer if the string has no 'c'.
104 strchr(const char *s, char c)
112 // Return a pointer to the last occurrence of 'c' in 's',
113 // or a null pointer if the string has no 'c'.
115 strrchr(const char *s, char c)
126 memchr(void* mem, int chr, int len)
128 char* s = (char*)mem;
129 for(int i = 0; i < len; i++)
130 if(s[i] == (char)chr)
135 // Return a pointer to the first occurrence of 'c' in 's',
136 // or a pointer to the string-ending null character if the string has no 'c'.
138 strfind(const char *s, char c)
146 // memset aligned words.
148 memsetw(long* _v, long c, size_t n)
150 long *start, *end, *v;
153 end = _v + n/sizeof(long);
158 #if NUM_ADDR_BITS == 64
160 #elif NUM_ADDR_BITS != 32
164 while(v < end - (8-1))
166 v[3] = v[2] = v[1] = v[0] = c;
168 v[3] = v[2] = v[1] = v[0] = c;
178 // copy aligned words.
179 // unroll 9 ways to get multiple misses in flight
180 #define memcpyw(type, _dst, _src, n) \
182 type* restrict src = (type*)(_src); \
183 type* restrict dst = (type*)(_dst); \
184 type* srcend = src + (n)/sizeof(type); \
185 type* dstend = dst + (n)/sizeof(type); \
186 while (dst < dstend - (9-1)) { \
199 while(dst < dstend) \
204 memset(void *COUNT(_n) v, int c, size_t _n)
210 if (n == 0) return NULL; // zra: complain here?
214 while (n > 0 && ((uintptr_t)p & (sizeof(long)-1)))
220 if (n >= sizeof(long))
222 n0 = n / sizeof(long) * sizeof(long);
223 memsetw((long*)p, c, n0);
238 memcpy(void* dst, const void* src, size_t _n)
244 int align = sizeof(long)-1;
249 if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(long)-1)) == 0)
251 n0 = n / sizeof(long) * sizeof(long);
252 memcpyw(long, d, s, n0);
254 else if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(int)-1)) == 0)
256 n0 = n / sizeof(int) * sizeof(int);
257 memcpyw(int, d, s, n0);
259 else if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(short)-1)) == 0)
261 n0 = n / sizeof(short) * sizeof(short);
262 memcpyw(short, d, s, n0);
276 memmove(void *COUNT(_n) dst, const void *COUNT(_n) src, size_t _n)
282 const char *BND(src,src+_n) s;
283 char *BND(dst,dst+_n) d;
288 if (s < d && s + n > d) {
302 memcmp(const void *COUNT(n) v1, const void *COUNT(n) v2, size_t n)
304 const uint8_t *BND(v1,v1+n) s1 = (const uint8_t *) v1;
305 const uint8_t *BND(v2,v2+n) s2 = (const uint8_t *) v2;
309 return (int) *s1 - (int) *s2;
317 memfind(const void *COUNT(n) _s, int c, size_t n)
319 const void *SNT ends = (const char *) _s + n;
320 const void *BND(_s,_s + n) s = _s;
321 for (; s < ends; s++)
322 if (*(const unsigned char *) s == (unsigned char) c)
324 return (void *BND(_s,_s+n)) s;
328 strtol(const char *s, char **endptr, int base)
333 // gobble initial whitespace
334 while (*s == ' ' || *s == '\t')
343 // hex or octal base prefix
344 if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x'))
346 else if (base == 0 && s[0] == '0')
355 if (*s >= '0' && *s <= '9')
357 else if (*s >= 'a' && *s <= 'z')
359 else if (*s >= 'A' && *s <= 'Z')
365 s++, val = (val * base) + dig;
366 // we don't properly detect overflow!
370 *endptr = (char *) s;
371 return (neg ? -val : val);
375 strtoul(const char *s, char **endptr, int base)
378 unsigned long val = 0;
380 // gobble initial whitespace
381 while (*s == ' ' || *s == '\t')
390 // hex or octal base prefix
391 if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x'))
393 else if (base == 0 && s[0] == '0')
402 if (*s >= '0' && *s <= '9')
404 else if (*s >= 'a' && *s <= 'z')
406 else if (*s >= 'A' && *s <= 'Z')
412 s++, val = (val * base) + dig;
413 // we don't properly detect overflow!
417 *endptr = (char *) s;
418 return (neg ? -val : val);
421 int atoi(const char *s)
425 if (s[0] == '0' && s[1] == 'x')
426 warn("atoi() used on a hex string!");
427 // no overflow detection
428 return (int)strtol(s,NULL,10);
431 int sigchecksum(void *address, int length)
436 for (p = address; length-- > 0; p++)
442 void *sigscan(uint8_t *address, int length, char *signature)
447 e = address + length;
448 siglength = strlen(signature);
449 for (p = address; p + siglength < e; p += 16) {
450 if (memcmp(p, signature, siglength))