Compare commits

..

2 Commits

Author SHA1 Message Date
DcraftBg
f527aca9d0 LibC: add strcasestr to string.h 2026-04-19 17:52:21 +03:00
DcraftBg
5fce3b64cc LibC: implemented strptime (partially) 2026-04-17 21:05:58 +03:00
3 changed files with 101 additions and 0 deletions

View File

@@ -46,6 +46,7 @@ char* strsep(char** __restrict stringp, const char* __restrict delim);
char* strsignal(int signum); char* strsignal(int signum);
size_t strspn(const char* s1, const char* s2); size_t strspn(const char* s1, const char* s2);
char* strstr(const char* s1, const char* s2); char* strstr(const char* s1, const char* s2);
char* strcasestr(const char* haystack, const char* needle);
char* strtok(char* __restrict s, const char* __restrict sep); char* strtok(char* __restrict s, const char* __restrict sep);
char* strtok_r(char* __restrict s, const char* __restrict sep, char** __restrict state); char* strtok_r(char* __restrict s, const char* __restrict sep, char** __restrict state);
size_t strxfrm(char* __restrict s1, const char* __restrict s2, size_t n); size_t strxfrm(char* __restrict s1, const char* __restrict s2, size_t n);

View File

@@ -304,6 +304,17 @@ char* strstr(const char* haystack, const char* needle)
return nullptr; return nullptr;
} }
char* strcasestr(const char* haystack, const char* needle)
{
const size_t needle_len = strlen(needle);
if (needle_len == 0)
return const_cast<char*>(haystack);
for (size_t i = 0; haystack[i]; i++)
if (strncasecmp(haystack + i, needle, needle_len) == 0)
return const_cast<char*>(haystack + i);
return nullptr;
}
#define CHAR_UCHAR(ch) \ #define CHAR_UCHAR(ch) \
static_cast<unsigned char>(ch) static_cast<unsigned char>(ch)

View File

@@ -8,6 +8,7 @@
#include <errno.h> #include <errno.h>
#include <langinfo.h> #include <langinfo.h>
#include <pthread.h> #include <pthread.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <time.h> #include <time.h>
@@ -626,3 +627,91 @@ size_t strftime(char* __restrict s, size_t maxsize, const char* __restrict forma
s[len++] = '\0'; s[len++] = '\0';
return len; return len;
} }
static int parse_tm_name(const char* buf, const char** out, int ab, int full, size_t count) {
int tm_name = -1;
for(size_t i = 0; i < count; ++i) {
const char *smol = nl_langinfo(ab + i),
*big = nl_langinfo(full + i);
size_t smol_len = strlen(smol),
big_len = strlen(big);
if(strncasecmp(buf, big, big_len) == 0) {
buf += big_len;
tm_name = i;
break;
}
if(strncasecmp(buf, smol, smol_len) == 0) {
buf += smol_len;
tm_name = i;
break;
}
}
*out = buf;
return tm_name;
}
char* strptime(const char* buf, const char* format, struct tm* tm) {
for(;;) {
while(*format && *format != '%') {
if(isspace(*format)) {
while(isspace(*buf)) buf++;
format++;
} else if(*buf++ != *format++) return NULL;
}
if(*format == '\0') break;
format++;
char fmt_chr = *format++;
switch(fmt_chr) {
case '%': if(*buf != '%') return NULL; break;
case 'a': case 'A': {
int day = parse_tm_name(buf, &buf, ABDAY_1, DAY_1, 7);
if(day == -1) return NULL;
tm->tm_wday = day;
} break;
case 'b': case 'B': case 'h': {
int mon = parse_tm_name(buf, &buf, ABMON_1, MON_1, 12);
if(mon == -1) return NULL;
tm->tm_mon = mon;
} break;
case 'd': case 'e': {
errno = 0;
long day = strtol(buf, (char**)&buf, 10);
if(errno) return NULL;
if(day < 1 || day > 31) return NULL;
tm->tm_mday = day;
} break;
case 'Y': {
errno = 0;
long year = strtol(buf, (char**)&buf, 10);
if(errno) return NULL;
tm->tm_year = year - 1900;
} break;
case 'H': {
errno = 0;
long hour = strtol(buf, (char**)&buf, 10);
if(errno) return NULL;
if(hour < 0 || hour > 23) return NULL;
tm->tm_hour = hour;
} break;
case 'M': {
errno = 0;
long minute = strtol(buf, (char**)&buf, 10);
if(errno) return NULL;
if(minute < 0 || minute > 59) return NULL;
tm->tm_min = minute;
} break;
case 'S': {
errno = 0;
long sec = strtol(buf, (char**)&buf, 10);
if(errno) return NULL;
if(sec < 0 || sec > 60) return NULL;
tm->tm_sec = sec;
} break;
default:
derrorln("TODO: strptime fmt {}", fmt_chr);
ASSERT_NOT_REACHED();
}
}
return (char*)buf;
}