1
0
Fork 0
forked from fun/fun

More built-ins.

This commit is contained in:
Johannes Findeisen 2025-09-15 03:59:03 +02:00
commit a4f4fcba99
8 changed files with 652 additions and 3 deletions

View file

@ -345,3 +345,153 @@ char *value_to_string_alloc(const Value *v) {
}
}
int value_equals(const Value *a, const Value *b) {
if (a->type != b->type) return 0;
switch (a->type) {
case VAL_INT: return a->i == b->i;
case VAL_STRING: {
const char *sa = a->s ? a->s : "";
const char *sb = b->s ? b->s : "";
return strcmp(sa, sb) == 0;
}
default: return 0;
}
}
int array_contains(const Value *v, const Value *needle) {
if (!v || v->type != VAL_ARRAY || !v->arr) return 0;
const Array *a = (const Array*)v->arr;
for (int i = 0; i < a->count; ++i) {
if (value_equals(&a->items[i], needle)) return 1;
}
return 0;
}
int array_index_of(const Value *v, const Value *needle) {
if (!v || v->type != VAL_ARRAY || !v->arr) return -1;
const Array *a = (const Array*)v->arr;
for (int i = 0; i < a->count; ++i) {
if (value_equals(&a->items[i], needle)) return i;
}
return -1;
}
void array_clear(Value *v) {
if (!v || v->type != VAL_ARRAY || !v->arr) return;
Array *a = (Array*)v->arr;
for (int i = 0; i < a->count; ++i) {
free_value(a->items[i]);
}
a->count = 0;
}
char *string_substr(const char *s, int start, int len) {
if (!s) return strdup("");
int n = (int)strlen(s);
if (start < 0) start = 0;
if (start > n) start = n;
if (len < 0) len = 0;
if (start + len > n) len = n - start;
char *out = (char*)malloc((size_t)len + 1);
if (!out) return strdup("");
memcpy(out, s + start, (size_t)len);
out[len] = '\0';
return out;
}
int string_find(const char *hay, const char *needle) {
if (!hay || !needle) return -1;
const char *p = strstr(hay, needle);
if (!p) return -1;
return (int)(p - hay);
}
Value string_split_to_array(const char *s, const char *sep) {
if (!s) s = "";
if (!sep) sep = "";
int seplen = (int)strlen(sep);
if (seplen == 0) {
/* split into characters */
int n = (int)strlen(s);
if (n <= 0) return make_array_from_values(NULL, 0);
Value *tmp = (Value*)malloc(sizeof(Value) * n);
if (!tmp) return make_array_from_values(NULL, 0);
for (int i = 0; i < n; ++i) {
char ch[2] = { s[i], 0 };
tmp[i] = make_string(ch);
}
Value arr = make_array_from_values(tmp, n);
for (int i = 0; i < n; ++i) free_value(tmp[i]);
free(tmp);
return arr;
}
/* split by separator */
Value *parts = NULL;
int count = 0;
int cap = 0;
const char *cur = s;
const char *pos = NULL;
while ((pos = strstr(cur, sep)) != NULL) {
int len = (int)(pos - cur);
char *piece = (char*)malloc((size_t)len + 1);
if (!piece) break;
memcpy(piece, cur, (size_t)len);
piece[len] = '\0';
if (count >= cap) {
cap = cap == 0 ? 4 : cap * 2;
parts = (Value*)realloc(parts, sizeof(Value) * cap);
}
parts[count++] = make_string(piece);
free(piece);
cur = pos + seplen;
}
/* tail */
char *tail = strdup(cur ? cur : "");
if (count >= cap) {
cap = cap == 0 ? 1 : cap + 1;
parts = (Value*)realloc(parts, sizeof(Value) * cap);
}
parts[count++] = make_string(tail ? tail : "");
free(tail);
Value arr = make_array_from_values(parts, count);
for (int i = 0; i < count; ++i) free_value(parts[i]);
free(parts);
return arr;
}
char *array_join_with_sep(const Value *v, const char *sep) {
if (!v || v->type != VAL_ARRAY || !v->arr) return strdup("");
if (!sep) sep = "";
const Array *a = (const Array*)v->arr;
/* compute total length */
size_t total = 0;
int n = a ? a->count : 0;
char **parts = (char**)malloc(sizeof(char*) * (n > 0 ? n : 1));
if (!parts) return strdup("");
for (int i = 0; i < n; ++i) {
parts[i] = value_to_string_alloc(&a->items[i]);
total += strlen(parts[i]);
if (i + 1 < n) total += strlen(sep);
}
char *out = (char*)malloc(total + 1);
if (!out) {
for (int i = 0; i < n; ++i) free(parts[i]);
free(parts);
return strdup("");
}
size_t off = 0;
for (int i = 0; i < n; ++i) {
size_t li = strlen(parts[i]);
memcpy(out + off, parts[i], li); off += li;
if (i + 1 < n) {
size_t ls = strlen(sep);
memcpy(out + off, sep, ls); off += ls;
}
free(parts[i]);
}
free(parts);
out[off] = '\0';
return out;
}