Foundations

This commit is contained in:
2026-08-29 01:50:50 +08:00
parent bf5fc3bda6
commit 8e95904cc4
100 changed files with 13997 additions and 0 deletions
+301
View File
@@ -0,0 +1,301 @@
#include <c_Str.h>
#include <c_Memory.h>
#include <string.h>
#include <limits.h>
#define idx(i, len) ((i) <= 0 ? (i) + (len) : (i) - 1)
#define convert(s, i, j) do { int _len; \
assert(s); _len = (int)strlen(s); \
i = idx(i, _len); j = idx(j, _len); \
if (i > j) { int t = i; i = j; j = t; } \
assert(i >= 0 && j <= _len); } while (0)
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
char *c_Str_sub(const char *s, int i, int j) {
char *str, *p;
convert(s, i, j);
p = str = C_ALLOC(j - i + 1);
while (i < j)
*p++ = s[i++];
*p = '\0';
return str;
}
char *c_Str_dup(const char *s, int i, int j, int n) {
int k;
char *str, *p;
assert(n >= 0);
convert(s, i, j);
p = str = C_ALLOC(n*(j - i) + 1);
if (j - i > 0)
while (n-- > 0)
for (k = i; k < j; k++)
*p++ = s[k];
*p = '\0';
return str;
}
char *c_Str_reverse(const char *s, int i, int j) {
char *str, *p;
convert(s, i, j);
p = str = C_ALLOC(j - i + 1);
while (j > i)
*p++ = s[--j];
*p = '\0';
return str;
}
char *c_Str_cat(const char *s1, int i1, int j1,
const char *s2, int i2, int j2) {
char *str, *p;
convert(s1, i1, j1);
convert(s2, i2, j2);
p = str = C_ALLOC(j1 - i1 + j2 - i2 + 1);
while (i1 < j1)
*p++ = s1[i1++];
while (i2 < j2)
*p++ = s2[i2++];
*p = '\0';
return str;
}
char *c_Str_catv(const char *s, ...) {
char *str, *p;
const char *save = s;
int i, j, len = 0;
va_list ap;
va_start(ap, s);
while (s) {
i = va_arg(ap, int);
j = va_arg(ap, int);
convert(s, i, j);
len += j - i;
s = va_arg(ap, const char *);
}
va_end(ap);
p = str = C_ALLOC(len + 1);
s = save;
va_start(ap, s);
while (s) {
i = va_arg(ap, int);
j = va_arg(ap, int);
convert(s, i, j);
while (i < j)
*p++ = s[i++];
s = va_arg(ap, const char *);
}
va_end(ap);
*p = '\0';
return str;
}
char *c_Str_map(const char *s, int i, int j,
const char *from, const char *to) {
static char map[256] = { 0 };
if (from && to) {
unsigned c;
for (c = 0; c < sizeof map; c++)
map[c] = c;
while (*from && *to)
map[(unsigned char)*from++] = *to++;
assert(*from == 0 && *to == 0);
} else {
assert(from == NULL && to == NULL && s);
assert(map['a']);
}
if (s) {
char *str, *p;
convert(s, i, j);
p = str = C_ALLOC(j - i + 1);
while (i < j)
*p++ = map[(unsigned char)s[i++]];
*p = '\0';
return str;
} else
return NULL;
}
int c_Str_pos(const char *s, int i) {
assert(s);
const int len = (int) strlen(s);
i = idx(i, len);
assert(i >= 0 && i <= len);
return i + 1;
}
int c_Str_len(const char *s, int i, int j) {
convert(s, i, j);
return j - i;
}
int c_Str_cmp(const char *s1, int i1, int j1,
const char *s2, int i2, int j2) {
convert(s1, i1, j1);
convert(s2, i2, j2);
s1 += i1;
s2 += i2;
if (j1 - i1 < j2 - i2) {
int cond = strncmp(s1, s2, j1 - i1);
return cond == 0 ? -1 : cond;
} else if (j1 - i1 > j2 - i2) {
const int cond = strncmp(s1, s2, j2 - i2);
return cond == 0 ? +1 : cond;
} else
return strncmp(s1, s2, j1 - i1);
}
int c_Str_chr(const char *s, int i, int j, int c) {
convert(s, i, j);
for ( ; i < j; i++)
if (s[i] == c)
return i + 1;
return 0;
}
int c_Str_rchr(const char *s, int i, int j, int c) {
convert(s, i, j);
while (j > i)
if (s[--j] == c)
return j + 1;
return 0;
}
int c_Str_upto(const char *s, int i, int j,
const char *set) {
assert(set);
convert(s, i, j);
for ( ; i < j; i++)
if (strchr(set, s[i]))
return i + 1;
return 0;
}
int c_Str_rupto(const char *s, int i, int j,
const char *set) {
assert(set);
convert(s, i, j);
while (j > i)
if (strchr(set, s[--j]))
return j + 1;
return 0;
}
int c_Str_find(const char *s, int i, int j,
const char *str) {
convert(s, i, j);
assert(str);
const int len = (int)strlen(str);
if (len == 0)
return i + 1;
else if (len == 1) {
for ( ; i < j; i++)
if (s[i] == *str)
return i + 1;
} else
for ( ; i + len <= j; i++)
if ((strncmp(&s[i], str, len) == 0))
return i + 1;
return 0;
}
int c_Str_rfind(const char *s, int i, int j, const char *str) {
convert(s, i, j);
assert(str);
const int len =(int)strlen(str);
if (len == 0)
return j + 1;
else if (len == 1) {
while (j > i)
if (s[--j] == *str)
return j + 1;
} else
for ( ; j - len >= i; j--)
if (strncmp(&s[j-len], str, len) == 0)
return j - len + 1;
return 0;
}
int c_Str_any(const char *s, int i, const char *set) {
assert(s);
assert(set);
const int len =(int)strlen(s);
i = idx(i, len);
assert(i >= 0 && i <= len);
if (i < len && strchr(set, s[i]))
return i + 2;
return 0;
}
int c_Str_many(const char *s, int i, int j,
const char *set) {
assert(set);
convert(s, i, j);
if (i < j && strchr(set, s[i])) {
do
i++;
while (i < j && strchr(set, s[i]));
return i + 1;
}
return 0;
}
int c_Str_rmany(const char *s, int i, int j,
const char *set) {
assert(set);
convert(s, i, j);
if (j > i && strchr(set, s[j-1])) {
do
--j;
while (j >= i && strchr(set, s[j]));
return j + 2;
}
return 0;
}
int c_Str_match(const char *s, int i, int j, const char *str) {
convert(s, i, j);
assert(str);
const int len =(int)strlen(str);
if (len == 0)
return i + 1;
else if (len == 1) {
if (i < j && s[i] == *str)
return i + 2;
} else if (i + len <= j && (strncmp(&s[i], str, len) == 0))
return i + len + 1;
return 0;
}
int c_Str_rmatch(const char *s, int i, int j, const char *str) {
convert(s, i, j);
assert(str);
const int len =(int)strlen(str);
if (len == 0)
return j + 1;
else if (len == 1) {
if (j > i && s[j-1] == *str)
return j;
} else if (j - len >= i
&& strncmp(&s[j-len], str, len) == 0)
return j - len + 1;
return 0;
}
void c_Str_fmt(int code, va_list_box *box,
int put(int c, void *cl), void *cl,
unsigned char flags[], int width, int precision) {
assert(box && flags);
char *s = va_arg(box->ap, char *);
int i = va_arg(box->ap, int);
int j = va_arg(box->ap, int);
convert(s, i, j);
c_Fmt_puts(s + i, j - i, put, cl, flags,
width, precision);
}
void c_Str_free(char* s) {
C_FREE(s);
}