kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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 }