Mercurial > repo
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; +}