Mercurial > repo
view src/ploki/kork.c @ 11562:6b0304dcec5c draft
<oerjan> ` cd bin; cp welcome \xd0\xb4\xd0\xbe\xd0\xb1\xd1\x80\xd0\xbe-\xd0\xbf\xd0\xbe\xd0\xb6\xd0\xb0\xd0\xbb\xd0\xbe\xd0\xb2\xd0\xb0\xd1\x82\xd1\x8c; sled \xd0\xb4\xd0\xbe\xd0\xb1\xd1\x80\xd0\xbe-\xd0\xbf\xd0\xbe\xd0\xb6\xd0\xb0\xd0\xbb\xd0\xbe\xd0\xb2\xd0\xb0\xd1\x82\xd1\x8c//s,welcome,welcome.ru,
author | HackEso <hackeso@esolangs.org> |
---|---|
date | Wed, 16 May 2018 04:46:17 +0100 |
parents | ac0403686959 |
children |
line wrap: on
line source
#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; }