Archived
1
0
Fork 0
This repository has been archived on 2025-09-02. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
skcblitz/str.h

240 lines
5.1 KiB
C
Raw Permalink Normal View History

2025-09-02 14:43:36 +02:00
int str_time(char *str, ulong time) {
ulong secs = (time /= 1000000ULL) % 60ULL;
ulong mins = (time /= 60ULL) % 60ULL;
ulong hrs = (time /= 60ULL) % 24ULL;
time /= 24ULL;
return time ? sprintf(str, "%dD+%02d:%02d:%02d", time, hrs, mins, secs) : sprintf(str, "%02d:%02d:%02d", hrs, mins, secs);
}
int str_mtime(char *str, ulong time) {
int pos = str_time(str, time);
return pos + sprintf(str+pos, ".%03d", (time / 1000ULL) % 1000ULL);
}
int str_utime(char *str, ulong time) {
int pos = str_time(str, time);
return pos + sprintf(str+pos, ".%03d+%03d", (time / 1000ULL) % 1000ULL, time % 1000ULL);
}
int str_strip(const char *str, char *buf, int size, int len, char newl, char tab, char unk) {
int off = 0;
int pos = 0;
char c;
while(((len < 0) || (off < len)) && (c = str[off++]) && (pos < size - 1)) {
if(c == '\n') {
buf[pos++] = newl;
if(!newl) {
return pos - 1;
}
}
else if((c == '\t') && tab) {
for(int z = 0; (z < 4) && (pos < size - 1); z++)
buf[pos++] = tab;
}
else if(c == CHR_UNK) {
if(unk)
buf[pos++] = unk;
}
else if((c < 0) || (c >= CHR_SPC)) {
buf[pos++] = c;
}
}
buf[pos] = 0;
return pos;
}
// void str_stripq(char *str) {
// char c;
// int pos = 0;
// while(c = str[pos]) {
// if((c >= 0) && (c < CHR_SPC)) {
// str[pos] = '\x1f';
// }
// pos++;
// }
// }
uint utf_read(const char **ptr) {
uint ch;
byte utf;
char c = *((*ptr)++);
for(utf = 0; (utf < 6) && (c & (0x80 >> utf)); utf++) {
;
}
if(utf == 1)
return CHR_UNK;
for(ch = ((!utf) || ((((uint)c) << 6) | (((**ptr) & 0x3f) & ~(0xff >> utf)))) ? (c & (0x7f >> utf)) : 0; utf > 1; utf--) {
if(((c = **ptr) & 0xc0) == 0x80) {
// if(ch) {
ch <<= 6;
ch |= c & 0x3f;
// }
}
else {
return c ? CHR_UNK : 0;
}
(*ptr)++;
}
// fprintf(stderr, "%d / %c\n", ch, ch);
return (utf && !ch) ? CHR_UNK : ch;
}
uint utf_readn(const char *ptr, int *pos) {
const char *str = &ptr[*pos];
uint ch = utf_read(&str);
*pos = (int)(str-ptr);
return ch;
}
byte utf_write(char **ptr, int *len, uint ch) {
uint test;
uint mask = 0xffffff80;
char utf;
char c;
if(ch & 0x80000000) {
return 1;
}
for(utf = 0; ch & mask & ~(test = (0xffffffff << ((utf + 1) * 6 + (5 - utf)))); utf++) {
mask &= test;
}
// fprintf(stderr, "%d\n", utf);
if(utf + 1 >= (*len)) {
return 0;
}
(*len) -= utf + 1;
*((*ptr)++) = utf ? (~(0x7f >> utf) | (((uint)(ch >> (utf * 6))) & (0x3f >> utf))) : ch;
for(--utf; utf >= 0; utf--) {
*((*ptr)++) = 0x80 | (((uint)(ch >> (utf * 6))) & 0x3f);
}
return 1;
}
byte utf_rwriten(char *ptr, int *pos, int len, uint ch) {
char *str = &ptr[*pos];
len -= (*pos);
byte res = utf_write(&str, &len, ch);
*pos = (int)(str-ptr);
return res;
}
uint utf_rread(const char **ptr, const char *start) {
const char *tp = *ptr;
uint ch;
char c;
do {
if(tp == start)
return 0;
tp--;
} while(((c = (*tp)) & 0xc0) == 0x80);
*ptr = tp;
return (ch = utf_read(&tp)) ? ch : CHR_UNK;
}
uint utf_rreadn(const char *ptr, int *pos) {
const char *str = &ptr[*pos];
uint ch = utf_rread(&str, ptr);
*pos = (int)(str-ptr);
return ch;
}
int utf_len(const char *str) {
int len;
for(len = 0; utf_read(&str); len++) {
;
}
return len;
}
char str_lower(char c) {
return ((c >= 'A') && (c <= 'Z')) ? (c + 32) : c;
}
char str_upper(char c) {
return ((c >= 'a') && (c <= 'z')) ? (c - 32) : c;
}
byte str_eq_lower(const char *str1, const char *str2) {
int pos = 0;
char c;
while(c = str_lower(str1[pos])) {
if(str_lower(str2[pos++]) != c)
return 0;
}
return str2[pos] ? 0 : 1;
}
int str_cmp_lower(const char *str1, const char *str2) {
int pos = 0;
char c;
while(c = str_lower(str2[pos])) {
if(str_lower(str1[pos++]) != c)
return 0;
}
return str1[pos] ? pos : 0x7fffffff;
}
byte str_parse_int(const char *str, int *value, int base) {
char c;
byte tbase = 0;
int pos = 0;
int digits = 0;
long v = 0;
long nbase = base ? (base < 0 ? -base : base) : 10;
long nsign = 1;
while(c = str_lower(str[pos++])) {
if(pos == 1 && ((c == '+') || ((c == '-') && (base >= 0))))
nsign = (c == '+') ? 1 : -1;
else if(pos == 1 && c == '0') {
tbase = 1;
digits++;
}
else if(tbase && pos == 2 && c == 'x') {
nbase = 16;
digits--;
}
else if(((nbase == 16) && (c >= 'a' && c <= 'f')) || (c >= '0' && c <= '9')) {
v *= nbase;
v += ((long)((c >= '0' && c <= '9') ? (c - '0') : (10 + (c - 'a'))));
digits++;
}
else
return 0;
}
if(!digits)
return 0;
v *= nsign;
// errno = 0;
// long v = strtol(str, NULL, (base < 0) ? -base : base);
if((base < 0) ? (v < 0LL || v > 0xffffffffLL) : (v < -0x80000000LL || v > 0x7fffffffLL)) {
return 0;
}
*value = (int)((base < 0) ? (v & 0xffffffff) : (((v >> 32) & 0x80000000) | (v & 0x7fffffff)));
return 1;
}
byte str_parse_enum(const char *str, const char **names, int states, int *value) {
int comp;
int max = 0;
int best = 0;
if(str_parse_int(str, &comp, 0) && (comp >= 0) && (comp < states)) {
*value = comp;
return 1;
}
for(int z = 0; z < states; z++) {
if((comp = str_cmp_lower(names[z], str)) > best) {
max = comp;
best = z;
}
}
if(max) {
*value = best;
return 1;
}
return 0;
}
// char char_to_dc32(char c) {
//
// }