string.c (3739B)
1 //===-- string.c - kit freestanding string primitives -------------------===// 2 // 3 // SPDX-License-Identifier: 0BSD 4 //===----------------------------------------------------------------------===// 5 6 #include <stddef.h> 7 8 __attribute__((weak)) void* memchr(const void* s, int c, size_t n) { 9 const unsigned char* p = (const unsigned char*)s; 10 unsigned char v = (unsigned char)c; 11 for (size_t i = 0; i < n; i++) { 12 if (p[i] == v) return (void*)(p + i); 13 } 14 return NULL; 15 } 16 17 __attribute__((weak)) void* memccpy(void* dest, const void* src, int c, 18 size_t n) { 19 unsigned char* d = (unsigned char*)dest; 20 const unsigned char* s = (const unsigned char*)src; 21 unsigned char v = (unsigned char)c; 22 for (size_t i = 0; i < n; i++) { 23 d[i] = s[i]; 24 if (s[i] == v) return d + i + 1u; 25 } 26 return NULL; 27 } 28 29 __attribute__((weak)) size_t strlen(const char* s) { 30 size_t n = 0; 31 while (s[n] != '\0') n++; 32 return n; 33 } 34 35 __attribute__((weak)) size_t strnlen(const char* s, size_t maxlen) { 36 size_t n = 0; 37 while (n < maxlen && s[n] != '\0') n++; 38 return n; 39 } 40 41 __attribute__((weak)) char* strcpy(char* dest, const char* src) { 42 char* d = dest; 43 while ((*d++ = *src++) != '\0') { 44 } 45 return dest; 46 } 47 48 __attribute__((weak)) char* strncpy(char* dest, const char* src, size_t n) { 49 size_t i = 0; 50 for (; i < n && src[i] != '\0'; i++) dest[i] = src[i]; 51 for (; i < n; i++) dest[i] = '\0'; 52 return dest; 53 } 54 55 __attribute__((weak)) char* strcat(char* dest, const char* src) { 56 strcpy(dest + strlen(dest), src); 57 return dest; 58 } 59 60 __attribute__((weak)) char* strncat(char* dest, const char* src, size_t n) { 61 char* d = dest + strlen(dest); 62 size_t i = 0; 63 while (i < n && src[i] != '\0') { 64 d[i] = src[i]; 65 i++; 66 } 67 d[i] = '\0'; 68 return dest; 69 } 70 71 __attribute__((weak)) int strcmp(const char* s1, const char* s2) { 72 const unsigned char* a = (const unsigned char*)s1; 73 const unsigned char* b = (const unsigned char*)s2; 74 while (*a != '\0' && *a == *b) { 75 a++; 76 b++; 77 } 78 return (int)*a - (int)*b; 79 } 80 81 __attribute__((weak)) int strncmp(const char* s1, const char* s2, size_t n) { 82 const unsigned char* a = (const unsigned char*)s1; 83 const unsigned char* b = (const unsigned char*)s2; 84 for (size_t i = 0; i < n; i++) { 85 if (a[i] != b[i] || a[i] == '\0') return (int)a[i] - (int)b[i]; 86 } 87 return 0; 88 } 89 90 __attribute__((weak)) char* strchr(const char* s, int c) { 91 char v = (char)c; 92 for (;;) { 93 if (*s == v) return (char*)s; 94 if (*s == '\0') return NULL; 95 s++; 96 } 97 } 98 99 __attribute__((weak)) char* strrchr(const char* s, int c) { 100 char v = (char)c; 101 const char* last = NULL; 102 for (;;) { 103 if (*s == v) last = s; 104 if (*s == '\0') return (char*)last; 105 s++; 106 } 107 } 108 109 static int kit_str_contains(const char* s, char c) { 110 while (*s != '\0') { 111 if (*s == c) return 1; 112 s++; 113 } 114 return 0; 115 } 116 117 __attribute__((weak)) size_t strspn(const char* s, const char* accept) { 118 size_t n = 0; 119 while (s[n] != '\0' && kit_str_contains(accept, s[n])) n++; 120 return n; 121 } 122 123 __attribute__((weak)) size_t strcspn(const char* s, const char* reject) { 124 size_t n = 0; 125 while (s[n] != '\0' && !kit_str_contains(reject, s[n])) n++; 126 return n; 127 } 128 129 __attribute__((weak)) char* strpbrk(const char* s, const char* accept) { 130 while (*s != '\0') { 131 if (kit_str_contains(accept, *s)) return (char*)s; 132 s++; 133 } 134 return NULL; 135 } 136 137 __attribute__((weak)) char* strstr(const char* haystack, const char* needle) { 138 if (*needle == '\0') return (char*)haystack; 139 for (; *haystack != '\0'; haystack++) { 140 const char* h = haystack; 141 const char* n = needle; 142 while (*n != '\0' && *h == *n) { 143 h++; 144 n++; 145 } 146 if (*n == '\0') return (char*)haystack; 147 } 148 return NULL; 149 }