Mercurial > repo
diff src/ploki/val.c @ 4223:ac0403686959
<oerjan> rm -rf src/ploki; mv ploki src
author | HackBot |
---|---|
date | Fri, 20 Dec 2013 22:18:50 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ploki/val.c Fri Dec 20 22:18:50 2013 +0000 @@ -0,0 +1,219 @@ +#include "config.h" +#include "IO.h" +#include "Str.h" +#include "val.h" +#include "xmalloc.h" + +#include <stdlib.h> +#include <assert.h> + +void v_init(struct val *v) { + v->ko = ko_new(); + v->type = V_UNDEF; +} + +void v_end(struct val *v) { + assert(v != NULL); + V_xxx_OFF(v); + ko_delete(v->ko); + v->type = V_UNDEF; +} + +int v_cmp_ls(struct val *v, struct val *b) { + if (V_LIST_P(v) && V_LIST_P(b)) { + return li_cmp(v->magic.list, b->magic.list); + } + V_STR(v); + V_STR(b); + return ko_cmp(v->ko, b->ko); +} + +void v_ok_str(struct val *v) { + if (V_STR_P(v)) { + return; + } + + if (V_EXT_P(v)) { + ko_cpy_s(v->ko, io_name(v->magic.ext, NULL)); + } else if (V_LIST_P(v)) { + size_t i; + struct list *li = v->magic.list; + struct val *cur; + + ko_zero(v->ko); + for (i = 0; i < li_length(li); ++i) { + cur = li_at(li, i); + V_STR(cur); + ko_cat(v->ko, cur->ko); + } + } else if (V_NUM_P(v)) { + ko_num(v->ko, v->num); + } else if (V_SUB_P(v)) { + v_ok_num(v); + ko_num(v->ko, v->num); + } else { + ko_zero(v->ko); + } + v->type |= V_STR_K; +} + +void v_ok_num(struct val *v) { + if (V_NUM_P(v)) { + return; + } + + if (V_EXT_P(v)) { + v->num = __LINE__; + } else if (V_SUB_P(v)) { + v->num = sub_id(v->magic.sub); + } else if (V_LIST_P(v)) { + size_t i; + + v->num = 0.0; + for (i = 0; i < li_length(v->magic.list); ++i) { + V_NUM(li_at(v->magic.list, i)); + v->num += li_at(v->magic.list, i)->num; + } + } else if (V_STR_P(v)) { + v->num = strtod(ko_szp(v->ko), NULL); + } else { + v->num = 0.0; + } + v->type |= V_NUM_K; +} + +int v_true(const struct val *v) { + if (V_EXT_P(v) || V_SUB_P(v)) { + return 1; + } + if (V_LIST_P(v)) { + return li_length(v->magic.list) != 0; + } + if (V_STR_P(v)) { + return ko_length(v->ko) != 0 && (ko_length(v->ko) > 1u || ko_at(v->ko, 0) != '0'); + } + if (V_NUM_P(v)) { + return v->num != 0.0; + } + return 0; +} + +void v_iniset(struct val *dst, const struct val *src) { + v_init(dst); + v_set(dst, src); +} + +void v_set(struct val *dst, const struct val *src) { + assert(src != NULL); + + V_xxx_OFF(dst); + dst->type = V_UNDEF; + + if (V_SUB_P(src)) { + dst->magic.sub = sub_incr(src->magic.sub); + dst->type |= V_SUB_K; + } else if (V_EXT_P(src)) { + dst->magic.ext = io_incr(src->magic.ext); + dst->type |= V_EXT_K; + } else if (V_LIST_P(src)) { + dst->magic.list = li_dup(src->magic.list); + dst->type |= V_LIST_K; + } + + if (V_STR_P(src)) { + ko_cpy(dst->ko, src->ko); + dst->type |= V_STR_K; + } + if (V_NUM_P(src)) { + dst->num = src->num; + dst->type |= V_NUM_K; + } +} + +void v_set_n(struct val *v, double d) { + V_xxx_OFF(v); + v->num = d; + v->type = V_NUM_K; +} + +void v_set_s(struct val *v, const String *s) { + V_xxx_OFF(v); + ko_cpy_m(v->ko, St_ptr(s), St_len(s)); + v->type = V_STR_K; +} + +void v_set_m(struct val *v, const void *p, size_t n) { + V_xxx_OFF(v); + ko_cpy_m(v->ko, p, n); + v->type = V_STR_K; +} + +void v_set_io(struct val *v, IO *io) { + V_xxx_OFF(v); + v->magic.ext = io_incr(io); + v->type = V_EXT_K; +} + +void v_set_sub(struct val *v, struct sub *s) { + V_xxx_OFF(v); + v->magic.sub = sub_incr(s); + v->type = V_SUB_K; +} + +void v_set_undef(struct val *v) { + V_xxx_OFF(v); + v->type = V_UNDEF; +} + +void v_cat(struct val *dst, struct val *src) { + if (V_LIST_P(dst) && V_LIST_P(src)) { + li_append(dst->magic.list, src->magic.list); + return; + } + + V_STR(src); + V_STR(dst); + V_xxx_OFF(dst); + ko_cat(dst->ko, src->ko); + dst->type = V_STR_K; +} + +void v_cat_m(struct val *v, const void *p, size_t n) { + V_STR(v); + V_xxx_OFF(v); + ko_cat_m(v->ko, p, n); + v->type = V_STR_K; +} + +void v_cat_s(struct val *v, const String *s) { + v_cat_m(v, St_ptr(s), St_len(s)); +} + +void v_cat_c(struct val *v, char c) { + v_cat_m(v, &c, 1); +} + +struct val *v_undef(void) { + struct val *v; + v = xmalloc(1, sizeof *v); + v_init(v); + return v; +} + +void v_delete(struct val *v) { + v_end(v); + xfree(v); +} + +const char *v_sptr(struct val *v, size_t *l) { + V_STR(v); + if (l) { + *l = ko_length(v->ko); + } + return ko_ptr(v->ko); +} + +struct kork *v_kork(struct val *v) { + V_STR(v); + return v->ko; +}