20#include "pedigree/kernel/compiler.h"
21#include "pedigree/kernel/processor/types.h"
22#include "pedigree/kernel/utilities/utility.h"
27extern void* malloc(
size_t);
28extern void free(
void*);
30EXPORTED_PUBLIC
size_t strlen(
const char* s);
31char* strcpy(
char* dest,
const char* src);
32EXPORTED_PUBLIC
char* strncpy(
char* dest,
const char* src,
size_t len);
33EXPORTED_PUBLIC
unsigned long strtoul(
const char* nptr,
char** endptr,
int base);
34EXPORTED_PUBLIC
int strcmp(
const char* p1,
const char* p2);
35EXPORTED_PUBLIC
int strncmp(
const char* p1,
const char* p2,
size_t n);
36char* strcat(
char* dest,
const char* src);
37char* strncat(
char* dest,
const char* src,
size_t n);
38char* strchr(
const char* str,
int target);
39char* strrchr(
const char* str,
int target);
40int vsprintf(
char* buf,
const char* fmt, va_list arg);
41unsigned long strtoul(
const char* nptr,
char** endptr,
int base);
46 if (c <
'a' || c >
'z')
53 if (c <
'A' || c >
'Z')
59int max(
size_t a,
size_t b) {
63int min(
size_t a,
size_t b) {
67WEAK size_t _StringLength(
const char* src) {
74 const char* orig = src;
79 return (src + n) - orig;
93WEAK size_t _BoundedStringLength(
const char* src,
size_t maxlen) {
99 while ((n < maxlen) && *src++) {
106char* StringCopy(
char* dest,
const char* src) {
107 char* orig_dest = dest;
118char* StringCopyN(
char* dest,
const char* src,
size_t len) {
119 char* orig_dest = dest;
120 while (len &&
LIKELY(*src)) {
137int StringFormat(
char* buf,
const char* fmt, ...) {
142 i = VStringFormat(buf, fmt, args);
148WEAK int StringCompare(
const char* restrict p1,
const char* restrict p2) {
156 if ((!c1) || (c1 != c2)) {
164WEAK int StringCompareN(
const char* restrict p1,
const char* restrict p2,
size_t n) {
167 }
else if (p1 == p2) {
173 for (i = 0; i < n; ++i) {
177 if ((!c1) || (c1 != c2)) {
185WEAK int StringCompareNOffset(
const char* restrict p1,
const char* restrict p2,
size_t n,
189 }
else if (p1 == p2) {
195 for (i = 0; i < n; ++i) {
199 if ((!c1) || (c1 != c2)) {
210WEAK int StringMatch(
const char* restrict p1,
const char* restrict p2) {
211 return StringCompare(p1, p2) == 0 ? 0 : 1;
214WEAK int StringMatchN(
const char* restrict p1,
const char* restrict p2,
size_t n) {
217 }
else if (p1 == p2) {
222 unsigned c1 = 0, c2 = 0;
223 for (i = 0; i < n; ++i) {
227 if ((!c1) || (c1 != c2)) {
232 return (c1 == c2) ? 0 : 1;
235WEAK int StringMatchNOffset(
const char* restrict p1,
const char* restrict p2,
size_t n,
237 return StringCompareNOffset(p1, p2, n, offset) == 0 ? 0 : 1;
240char* StringConcat(
char* dest,
const char* src) {
241 char* origDest = dest;
244 while (src && *src) {
253char* StringConcatN(
char* dest,
const char* src,
size_t n) {
254 char* origDest = dest;
257 while (src && *src && n) {
267#if !(UTILITY_LINUX && defined(__APPLE__))
269 return (c ==
' ' || c ==
'\n' || c ==
'\r' || c ==
'\t');
273 return (c >=
'A' && c <=
'Z');
277 return (c >=
'a' && c <=
'z');
281 return (c >=
'0' && c <=
'9');
285 return isupper(c) || islower(c) || isdigit(c);
290#pragma GCC diagnostic push
291#pragma GCC diagnostic ignored "-Wcast-qual"
293unsigned long StringToUnsignedLong(
const char* nptr,
char** endptr,
int base) {
294 register const char* s = nptr;
295 register unsigned long acc;
297 register unsigned long cutoff;
298 register int neg = 0, any, cutlim;
305 }
while (isspace(c));
311 if ((base == 0 || base == 16) && c ==
'0' && (*s ==
'x' || *s ==
'X')) {
317 base = c ==
'0' ? 8 : 10;
318 cutoff = (
unsigned long)ULONG_MAX / (
unsigned long)base;
319 cutlim = (
unsigned long)ULONG_MAX % (
unsigned long)base;
320 for (acc = 0, any = 0;; c = *s++) {
324 c -= isupper(c) ?
'A' - 10 :
'a' - 10;
329 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
342 *endptr = (
char*)(any ? s - 1 : nptr);
347char* StringFind(
const char* str,
int target) {
372char* StringReverseFind(
const char* str,
int target) {
377 const char* result = NULL;
384 return (char*)result; \
401#pragma GCC diagnostic pop
403int StringContains(
const char* str,
const char* search) {
404 size_t alen = StringLength(str);
405 size_t blen = StringLength(search);
406 return StringContainsN(str, alen, search, blen);
409static int isPrefix(
const char* word,
size_t wordLength,
size_t pos) {
410 size_t suffixLength = wordLength - pos;
411 return StringCompareN(word, word + pos, suffixLength) == 0 ? 1 : 0;
414static size_t suffixLength(
const char* word,
size_t wordLength,
size_t pos) {
416 for (; (word[pos - i] == word[wordLength - 1 - i]) && (i < pos); i++)
421int StringContainsN(
const char* str,
size_t len,
const char* search,
size_t slen) {
429 }
else if (len == slen) {
430 return StringCompareN(str, search, slen) == 0;
435 size_t* delta2 = (
size_t*)malloc(slen *
sizeof(
size_t));
437 for (
size_t i = 0; i < 256; ++i) {
442 for (
size_t i = 0; i < slen; ++i) {
443 delta1[(int)search[i]] = slen - 1 - i;
447 ByteSet(delta2, 0, slen *
sizeof(
size_t));
449 ssize_t lastPrefix = slen - 1;
450 for (ssize_t i = slen - 1; i >= 0; --i) {
451 if (isPrefix(search, slen, i + 1)) {
454 delta2[i] = lastPrefix + (slen - 1 - i);
456 for (
size_t i = 0; i < slen - 1; ++i) {
457 size_t suffixLen = suffixLength(search, slen, i);
458 if (search[i - suffixLen] != search[slen - 1 - suffixLen]) {
459 delta2[slen - 1 - suffixLen] = slen - 1 - i + suffixLen;
463 for (
size_t i = slen - 1; i < len;) {
464 ssize_t j = slen - 1;
465 while (j >= 0 && (str[i] == search[j])) {
475 i += max(delta1[(
int)str[i]], delta2[j]);
482int StringCompareCase(
const char* restrict s1,
const char* restrict s2,
int sensitive,
483 size_t length,
size_t* offset) {
486 return StringCompareNOffset(s1, s2, length, offset);
491 }
else if (s1 == s2) {
493 *offset = StringLength(s1);
502 static size_t local = 0;
508 char c1 = 0, c2 = 0, r1 = 0, r2 = 0;
509 for (i = 0; i < length; ++i) {
531size_t nextCharacter(
const char* s,
size_t i) {
537 const uint8_t* u8buf = (
const uint8_t*)s;
538 if (
LIKELY(u8buf[i] <= 0x7F)) {
540 }
else if ((u8buf[i] & 0xC0) == 0xC0) {
541 if ((u8buf[i] & 0xF8) == 0xF0) {
543 }
else if ((u8buf[i] & 0xF0) == 0xE0) {
552size_t prevCharacter(
const char* s,
size_t i) {
563size_t strlen(
const char* s) {
564 return StringLength(s);
567char* strcpy(
char* dest,
const char* src) {
568 return StringCopy(dest, src);
571char* strncpy(
char* dest,
const char* src,
size_t len) {
572 return StringCopyN(dest, src, len);
575int strcmp(
const char* p1,
const char* p2) {
576 return StringCompare(p1, p2);
579int strncmp(
const char* p1,
const char* p2,
size_t n) {
580 return StringCompareN(p1, p2, n);
583char* strcat(
char* dest,
const char* src) {
584 return StringConcat(dest, src);
587char* strncat(
char* dest,
const char* src,
size_t n) {
588 return StringConcatN(dest, src, n);
591char* strchr(
const char* str,
int target) {
592 return StringFind(str, target);
595char* strrchr(
const char* str,
int target) {
596 return StringReverseFind(str, target);
599int vsprintf(
char* buf,
const char* fmt, va_list arg) {
600 return VStringFormat(buf, fmt, arg);
603unsigned long strtoul(
const char* nptr,
char** endptr,
int base) {
604 return StringToUnsignedLong(nptr, endptr, base);