Mercurial > repo
comparison 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 |
comparison
equal
deleted
inserted
replaced
4222:b0f3e267bb1e | 4223:ac0403686959 |
---|---|
1 #include "config.h" | |
2 #include "IO.h" | |
3 #include "Str.h" | |
4 #include "kork.h" | |
5 #include "strutil.h" | |
6 #include "xmalloc.h" | |
7 | |
8 #include <stdio.h> | |
9 #include <assert.h> | |
10 #include <string.h> | |
11 #include <ctype.h> | |
12 | |
13 typedef struct ko_dolphin dolphin; | |
14 typedef struct kork kork; | |
15 | |
16 static dolphin nil = { | |
17 { "FLIPPER", 1, 1, 0 }, | |
18 0 | |
19 }; | |
20 | |
21 static dolphin *incr(dolphin *dp) { | |
22 ++dp->refs; | |
23 return dp; | |
24 } | |
25 | |
26 static void decr(dolphin *dp) { | |
27 if (dp->refs) { | |
28 --dp->refs; | |
29 return; | |
30 } | |
31 | |
32 St_clear(&dp->str); | |
33 xfree(dp); | |
34 } | |
35 | |
36 kork *ko_new(void) { | |
37 kork *const k = xmalloc(1, sizeof *k); | |
38 k->kdp = incr(&nil); | |
39 k->offset = 0; | |
40 k->length = 0; | |
41 return k; | |
42 } | |
43 | |
44 kork *ko_dup(const kork *old) { | |
45 kork *const k = xmalloc(1, sizeof *k); | |
46 *k = *old; | |
47 incr(k->kdp); | |
48 return k; | |
49 } | |
50 | |
51 void ko_decouple(kork *k) { | |
52 dolphin *const dp = k->kdp; | |
53 if (!k->kdp->refs) { | |
54 return; | |
55 } | |
56 k->kdp = xmalloc(1, sizeof *k->kdp); | |
57 St_init(&k->kdp->str); | |
58 St_cpy_m(&k->kdp->str, St_ptr(&dp->str) + k->offset, k->length); | |
59 k->kdp->refs = 0; | |
60 k->offset = 0; | |
61 decr(dp); | |
62 } | |
63 | |
64 void ko_delete(kork *k) { | |
65 decr(k->kdp); | |
66 xfree(k); | |
67 } | |
68 | |
69 size_t (ko_length)(const kork *k) { | |
70 return ko_length(k); | |
71 } | |
72 | |
73 int ko_at(const kork *k, size_t i) { | |
74 return i < k->length ? ST_INDEX(&k->kdp->str, k->offset + i) : EOF; | |
75 } | |
76 | |
77 int ko_lastchar(const kork *k) { | |
78 return k->length ? ST_INDEX(&k->kdp->str, k->offset + k->length - 1u) : EOF; | |
79 } | |
80 | |
81 int ko_cmp(const kork *k1, const kork *k2) { | |
82 return u_cmp( | |
83 St_ptr(&k1->kdp->str) + k1->offset, k1->length, | |
84 St_ptr(&k2->kdp->str) + k2->offset, k2->length | |
85 ); | |
86 } | |
87 | |
88 void (ko_zero)(kork *k) { | |
89 ko_zero(k); | |
90 } | |
91 | |
92 const char *ko_ptr(const kork *k) { | |
93 return St_ptr(&k->kdp->str) + k->offset; | |
94 } | |
95 | |
96 static void offoff(kork *k) { | |
97 ko_decouple(k); | |
98 if (k->offset) { | |
99 St_del(&k->kdp->str, 0, k->offset); | |
100 k->offset = 0; | |
101 } | |
102 assert(St_len(&k->kdp->str) >= k->length); | |
103 } | |
104 | |
105 const String *ko_str(kork *k) { | |
106 offoff(k); | |
107 St_trunc(&k->kdp->str, k->length); | |
108 return &k->kdp->str; | |
109 } | |
110 | |
111 const char *ko_szp(kork *k) { | |
112 if (k->kdp->refs && k->offset + k->length != St_len(&k->kdp->str)) { | |
113 offoff(k); | |
114 } | |
115 return St_ptr(&k->kdp->str) + k->offset; | |
116 } | |
117 | |
118 void ko_grep(kork *k, int (*pred)(int)) { | |
119 offoff(k); | |
120 St_grep(&k->kdp->str, pred); | |
121 k->length = St_len(&k->kdp->str); | |
122 } | |
123 | |
124 void ko_shift(kork *k, size_t n) { | |
125 if (n > k->length) { | |
126 n = k->length; | |
127 } | |
128 k->offset += n; | |
129 k->length -= n; | |
130 } | |
131 | |
132 void ko_num(kork *k, double d) { | |
133 offoff(k); | |
134 St_num(&k->kdp->str, d); | |
135 k->length = St_len(&k->kdp->str); | |
136 } | |
137 | |
138 void ko_cpy_m(kork *k, const void *p, size_t n) { | |
139 if (!n) { | |
140 ko_zero(k); | |
141 return; | |
142 } | |
143 offoff(k); | |
144 St_cpy_m(&k->kdp->str, p, n); | |
145 k->length = St_len(&k->kdp->str); | |
146 } | |
147 | |
148 void ko_cpy(kork *k, const kork *z) { | |
149 ko_cpy_m(k, ko_ptr(z), ko_length(z)); | |
150 } | |
151 | |
152 void ko_cpy_s(kork *k, const char *s) { | |
153 ko_cpy_m(k, s, strlen(s)); | |
154 } | |
155 | |
156 void ko_cpy_c(kork *k, char c) { | |
157 offoff(k); | |
158 St_cpy_c(&k->kdp->str, c); | |
159 k->length = 1; | |
160 } | |
161 | |
162 void ko_cat_m(kork *k, const void *p, size_t n) { | |
163 if (!n) { | |
164 return; | |
165 } | |
166 if (k->kdp->refs && k->offset + k->length != St_len(&k->kdp->str)) { | |
167 offoff(k); | |
168 } | |
169 assert(k->offset + k->length <= St_len(&k->kdp->str)); | |
170 St_trunc(&k->kdp->str, k->offset + k->length); | |
171 St_cat_m(&k->kdp->str, p, n); | |
172 k->length += n; | |
173 } | |
174 | |
175 void ko_cat(kork *k, const kork *z) { | |
176 ko_cat_m(k, ko_ptr(z), ko_length(z)); | |
177 } | |
178 | |
179 void ko_cat_c(kork *k, char c) { | |
180 ko_cat_m(k, &c, 1); | |
181 } | |
182 | |
183 void ko_reverse(kork *k) { | |
184 offoff(k); | |
185 St_reverse(&k->kdp->str); | |
186 } | |
187 | |
188 size_t ko_getline(IO *io, kork *k) { | |
189 size_t tmp; | |
190 offoff(k); | |
191 tmp = io_getline(io, &k->kdp->str); | |
192 k->length = St_len(&k->kdp->str); | |
193 return tmp; | |
194 } | |
195 | |
196 size_t ko_read(IO *io, kork *k, size_t n) { | |
197 size_t tmp; | |
198 offoff(k); | |
199 tmp = io_read(io, &k->kdp->str, n); | |
200 k->length = St_len(&k->kdp->str); | |
201 return tmp; | |
202 } | |
203 | |
204 void ko_lower(kork *k) { | |
205 offoff(k); | |
206 St_lower(&k->kdp->str); | |
207 } | |
208 | |
209 void ko_upper(kork *k) { | |
210 offoff(k); | |
211 St_upper(&k->kdp->str); | |
212 } | |
213 | |
214 size_t ko_chr(const kork *k, int c) { | |
215 const char *const p = memchr(St_ptr(&k->kdp->str) + k->offset, c, k->length); | |
216 if (!p) { | |
217 return -1; | |
218 } | |
219 return p - (St_ptr(&k->kdp->str) + k->offset); | |
220 } | |
221 | |
222 void ko_shiftws(kork *k) { | |
223 while ( | |
224 k->length && | |
225 isspace((unsigned char)St_ptr(&k->kdp->str)[k->offset]) | |
226 ) { | |
227 ++k->offset; | |
228 --k->length; | |
229 } | |
230 } | |
231 | |
232 void ko_trunc(kork *k, size_t n) { | |
233 if (n >= k->length) { | |
234 return; | |
235 } | |
236 k->length = n; | |
237 } |