1 // Basic string routines. Not hardware optimized, but not shabby.
5 #include <ros/memlayout.h>
13 for (n = 0; *s != '\0'; s++)
19 strnlen(const char *s, size_t size)
23 for (n = 0; size > 0 && *s != '\0'; s++, size--)
28 /* zra: These aren't being used, and they are dangerous, so I'm rm'ing them
30 strcpy(char *dst, const char *src)
35 while ((*dst++ = *src++) != '\0')
41 strcat(char *dst, const char *src)
43 strcpy(dst+strlen(dst),src);
49 strncpy(char *dst, const char *src, size_t size) {
54 for (i = 0; i < size; i++) {
56 // If strlen(src) < size, null-pad 'dst' out to 'size' chars
64 strlcpy(char *dst, const char *src, size_t size)
67 while (--size > 0 && *src != '\0')
76 strlcat(char *dst, const char *src, size_t size)
78 size_t rem; /* Buffer space remaining after null in dst. */
80 /* We must find the terminating NUL byte in dst, but abort the
81 * search if we go past 'size' bytes. At the end of this loop,
82 * 'dst' will point to either the NUL byte in the original
83 * destination or to one byte beyond the end of the buffer.
85 * 'rem' will be the amount of 'size' remaining beyond the NUL byte;
86 * potentially zero. This implies that 'size - rem' is equal to the
87 * distance from the beginning of the destination buffer to 'dst'.
89 * The return value of strlcat is the sum of the length of the
90 * original destination buffer (size - rem) plus the size of the
91 * src string (the return value of strlcpy). */
93 while ((rem > 0) && (*dst != '\0')) {
98 return (size - rem) + strlcpy(dst, src, rem);
102 strcmp(const char *p, const char *q)
104 while (*p && *p == *q)
106 return (int) ((unsigned char) *p - (unsigned char) *q);
110 strncmp(const char *p, const char *q, size_t n)
112 while (n > 0 && *p && *p == *q)
117 return (int) ((unsigned char) *p - (unsigned char) *q);
120 // Return a pointer to the first occurrence of 'c' in 's',
121 // or a null pointer if the string has no 'c'.
123 strchr(const char *s, char c)
131 // Return a pointer to the last occurrence of 'c' in 's',
132 // or a null pointer if the string has no 'c'.
134 strrchr(const char *s, char c)
144 void *memchr(const void *mem, int chr, int len)
146 char *s = (char*) mem;
148 for (int i = 0; i < len; i++)
149 if (s[i] == (char) chr)
154 // Return a pointer to the first occurrence of 'c' in 's',
155 // or a pointer to the string-ending null character if the string has no 'c'.
157 strfind(const char *s, char c)
165 // memset aligned words.
167 memsetw(long* _v, long c, size_t n)
169 long *start, *end, *v;
172 end = _v + n/sizeof(long);
177 #if NUM_ADDR_BITS == 64
179 #elif NUM_ADDR_BITS != 32
183 while(v < end - (8-1))
185 v[3] = v[2] = v[1] = v[0] = c;
187 v[3] = v[2] = v[1] = v[0] = c;
197 // copy aligned words.
198 // unroll 9 ways to get multiple misses in flight
199 #define memcpyw(type, _dst, _src, n) \
201 type* restrict src = (type*)(_src); \
202 type* restrict dst = (type*)(_dst); \
203 type* srcend = src + (n)/sizeof(type); \
204 type* dstend = dst + (n)/sizeof(type); \
205 while (dst < dstend - (9-1)) { \
218 while(dst < dstend) \
223 memset(void *v, int c, size_t _n)
229 if (n == 0) return NULL; // zra: complain here?
233 while (n > 0 && ((uintptr_t)p & (sizeof(long)-1)))
239 if (n >= sizeof(long))
241 n0 = n / sizeof(long) * sizeof(long);
242 memsetw((long*)p, c, n0);
257 memcpy(void* dst, const void* src, size_t _n)
263 int align = sizeof(long)-1;
268 if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(long)-1)) == 0)
270 n0 = n / sizeof(long) * sizeof(long);
271 memcpyw(long, d, s, n0);
273 else if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(int)-1)) == 0)
275 n0 = n / sizeof(int) * sizeof(int);
276 memcpyw(int, d, s, n0);
278 else if ((((uintptr_t)s | (uintptr_t)d) & (sizeof(short)-1)) == 0)
280 n0 = n / sizeof(short) * sizeof(short);
281 memcpyw(short, d, s, n0);
295 memmove(void *dst, const void *src, size_t _n)
307 if (s < d && s + n > d) {
321 memcmp(const void *v1, const void *v2, size_t n)
323 const uint8_t *s1 = (const uint8_t *) v1;
324 const uint8_t *s2 = (const uint8_t *) v2;
328 return (int) *s1 - (int) *s2;
336 memfind(const void *_s, int c, size_t n)
338 const void *ends = (const char *) _s + n;
340 for (; s < ends; s++)
341 if (*(const unsigned char *) s == (unsigned char) c)
347 strtol(const char *s, char **endptr, int base)
352 // gobble initial whitespace
353 while (*s == ' ' || *s == '\t')
362 // hex or octal base prefix
363 if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x'))
365 else if (base == 0 && s[0] == '0')
374 if (*s >= '0' && *s <= '9')
376 else if (*s >= 'a' && *s <= 'z')
378 else if (*s >= 'A' && *s <= 'Z')
384 s++, val = (val * base) + dig;
385 // we don't properly detect overflow!
389 *endptr = (char *) s;
390 return (neg ? -val : val);
394 strtoul(const char *s, char **endptr, int base)
397 unsigned long val = 0;
399 // gobble initial whitespace
400 while (*s == ' ' || *s == '\t')
409 // hex or octal base prefix
410 if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x'))
412 else if (base == 0 && s[0] == '0')
421 if (*s >= '0' && *s <= '9')
423 else if (*s >= 'a' && *s <= 'z')
425 else if (*s >= 'A' && *s <= 'Z')
431 s++, val = (val * base) + dig;
432 // we don't properly detect overflow!
436 *endptr = (char *) s;
437 return (neg ? -val : val);
440 int atoi(const char *s)
444 if (s[0] == '0' && s[1] == 'x')
445 warn("atoi() used on a hex string!");
446 // no overflow detection
447 return (int)strtol(s,NULL,10);
450 int sigchecksum(void *address, int length)
455 for (p = address; length-- > 0; p++)
461 void *sigscan(uint8_t *address, int length, char *signature)
466 e = address + length;
467 siglength = strlen(signature);
468 for (p = address; p + siglength < e; p += 16) {
469 if (memcmp(p, signature, siglength))