view src/ploki/val.c @ 8916:0234daffd946

<oerjan> addquote <int-e> I couldn\'t help thinking that maybe if one considers the ramifications in full detail it will turn out that overthinking is often not helpful and therefore, not something to be proud of.
author HackBot
date Sun, 14 Aug 2016 02:31:47 +0000
parents ac0403686959
children
line wrap: on
line source

#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;
}