diff src/ploki/kork.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/kork.c	Fri Dec 20 22:18:50 2013 +0000
@@ -0,0 +1,237 @@
+#include "config.h"
+#include "IO.h"
+#include "Str.h"
+#include "kork.h"
+#include "strutil.h"
+#include "xmalloc.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+
+typedef struct ko_dolphin dolphin;
+typedef struct kork kork;
+
+static dolphin nil = {
+	{ "FLIPPER", 1, 1, 0 },
+	0
+};
+
+static dolphin *incr(dolphin *dp) {
+	++dp->refs;
+	return dp;
+}
+
+static void decr(dolphin *dp) {
+	if (dp->refs) {
+		--dp->refs;
+		return;
+	}
+
+	St_clear(&dp->str);
+	xfree(dp);
+}
+
+kork *ko_new(void) {
+	kork *const k = xmalloc(1, sizeof *k);
+	k->kdp = incr(&nil);
+	k->offset = 0;
+	k->length = 0;
+	return k;
+}
+
+kork *ko_dup(const kork *old) {
+	kork *const k = xmalloc(1, sizeof *k);
+	*k = *old;
+	incr(k->kdp);
+	return k;
+}
+
+void ko_decouple(kork *k) {
+	dolphin *const dp = k->kdp;
+	if (!k->kdp->refs) {
+		return;
+	}
+	k->kdp = xmalloc(1, sizeof *k->kdp);
+	St_init(&k->kdp->str);
+	St_cpy_m(&k->kdp->str, St_ptr(&dp->str) + k->offset, k->length);
+	k->kdp->refs = 0;
+	k->offset = 0;
+	decr(dp);
+}
+
+void ko_delete(kork *k) {
+	decr(k->kdp);
+	xfree(k);
+}
+
+size_t (ko_length)(const kork *k) {
+	return ko_length(k);
+}
+
+int ko_at(const kork *k, size_t i) {
+	return i < k->length ? ST_INDEX(&k->kdp->str, k->offset + i) : EOF;
+}
+
+int ko_lastchar(const kork *k) {
+	return k->length ? ST_INDEX(&k->kdp->str, k->offset + k->length - 1u) : EOF;
+}
+
+int ko_cmp(const kork *k1, const kork *k2) {
+	return u_cmp(
+			St_ptr(&k1->kdp->str) + k1->offset, k1->length,
+			St_ptr(&k2->kdp->str) + k2->offset, k2->length
+			);
+}
+
+void (ko_zero)(kork *k) {
+	ko_zero(k);
+}
+
+const char *ko_ptr(const kork *k) {
+	return St_ptr(&k->kdp->str) + k->offset;
+}
+
+static void offoff(kork *k) {
+	ko_decouple(k);
+	if (k->offset) {
+		St_del(&k->kdp->str, 0, k->offset);
+		k->offset = 0;
+	}
+	assert(St_len(&k->kdp->str) >= k->length);
+}
+
+const String *ko_str(kork *k) {
+	offoff(k);
+	St_trunc(&k->kdp->str, k->length);
+	return &k->kdp->str;
+}
+
+const char *ko_szp(kork *k) {
+	if (k->kdp->refs && k->offset + k->length != St_len(&k->kdp->str)) {
+		offoff(k);
+	}
+	return St_ptr(&k->kdp->str) + k->offset;
+}
+
+void ko_grep(kork *k, int (*pred)(int)) {
+	offoff(k);
+	St_grep(&k->kdp->str, pred);
+	k->length = St_len(&k->kdp->str);
+}
+
+void ko_shift(kork *k, size_t n) {
+	if (n > k->length) {
+		n = k->length;
+	}
+	k->offset += n;
+	k->length -= n;
+}
+
+void ko_num(kork *k, double d) {
+	offoff(k);
+	St_num(&k->kdp->str, d);
+	k->length = St_len(&k->kdp->str);
+}
+
+void ko_cpy_m(kork *k, const void *p, size_t n) {
+	if (!n) {
+		ko_zero(k);
+		return;
+	}
+	offoff(k);
+	St_cpy_m(&k->kdp->str, p, n);
+	k->length = St_len(&k->kdp->str);
+}
+
+void ko_cpy(kork *k, const kork *z) {
+	ko_cpy_m(k, ko_ptr(z), ko_length(z));
+}
+
+void ko_cpy_s(kork *k, const char *s) {
+	ko_cpy_m(k, s, strlen(s));
+}
+
+void ko_cpy_c(kork *k, char c) {
+	offoff(k);
+	St_cpy_c(&k->kdp->str, c);
+	k->length = 1;
+}
+
+void ko_cat_m(kork *k, const void *p, size_t n) {
+	if (!n) {
+		return;
+	}
+	if (k->kdp->refs && k->offset + k->length != St_len(&k->kdp->str)) {
+		offoff(k);
+	}
+	assert(k->offset + k->length <= St_len(&k->kdp->str));
+	St_trunc(&k->kdp->str, k->offset + k->length);
+	St_cat_m(&k->kdp->str, p, n);
+	k->length += n;
+}
+
+void ko_cat(kork *k, const kork *z) {
+	ko_cat_m(k, ko_ptr(z), ko_length(z));
+}
+
+void ko_cat_c(kork *k, char c) {
+	ko_cat_m(k, &c, 1);
+}
+
+void ko_reverse(kork *k) {
+	offoff(k);
+	St_reverse(&k->kdp->str);
+}
+
+size_t ko_getline(IO *io, kork *k) {
+	size_t tmp;
+	offoff(k);
+	tmp = io_getline(io, &k->kdp->str);
+	k->length = St_len(&k->kdp->str);
+	return tmp;
+}
+
+size_t ko_read(IO *io, kork *k, size_t n) {
+	size_t tmp;
+	offoff(k);
+	tmp = io_read(io, &k->kdp->str, n);
+	k->length = St_len(&k->kdp->str);
+	return tmp;
+}
+
+void ko_lower(kork *k) {
+	offoff(k);
+	St_lower(&k->kdp->str);
+}
+
+void ko_upper(kork *k) {
+	offoff(k);
+	St_upper(&k->kdp->str);
+}
+
+size_t ko_chr(const kork *k, int c) {
+	const char *const p = memchr(St_ptr(&k->kdp->str) + k->offset, c, k->length);
+	if (!p) {
+		return -1;
+	}
+	return p - (St_ptr(&k->kdp->str) + k->offset);
+}
+
+void ko_shiftws(kork *k) {
+	while (
+			k->length &&
+			isspace((unsigned char)St_ptr(&k->kdp->str)[k->offset])
+		  ) {
+		++k->offset;
+		--k->length;
+	}
+}
+
+void ko_trunc(kork *k, size_t n) {
+	if (n >= k->length) {
+		return;
+	}
+	k->length = n;
+}