1
5
6# include "mpstrings.h"
7
8
16
17# define STRCMP_RESULT(a) ((a) < 0 ? -1 : ((a) > 0 ? 1 : 0))
18
19static int mp_aux_comp_strings_entry(void *p, const void *pa, const void *pb)
20{
21 const mp_lstring *a = (const mp_lstring *) pa;
22 const mp_lstring *b = (const mp_lstring *) pb;
23 unsigned char *s = a->str;
24 unsigned char *t = b->str;
25 size_t l = a->len <= b->len ? a->len : b->len;
26 (void) p;
27 while (l-- > 0) {
28 if (*s != *t) {
29 return STRCMP_RESULT(*s - *t);
30 } else {
31 s++;
32 t++;
33 }
34 }
35 return STRCMP_RESULT((int)(a->len - b->len));
36}
37
38void *mp_aux_copy_strings_entry(const void *p)
39{
40 mp_string ff = mp_memory_allocate(sizeof(mp_lstring));
41 if (ff) {
42 const mp_lstring *fp = (const mp_lstring *) p;
43 ff->str = mp_memory_allocate((size_t) fp->len + 1);
44 if (ff->str) {
45 memcpy((char *) ff->str, (char *) fp->str, fp->len + 1);
46 ff->len = fp->len;
47 ff->refs = 0;
48 return ff;
49 }
50 }
51 return NULL;
52}
53
54static void *delete_strings_entry(void *p)
55{
56 mp_string ff = (mp_string) p;
57 mp_memory_free(ff->str);
58 mp_memory_free(ff);
59 return NULL;
60}
61
62static mp_string new_strings_entry(void)
63{
64 mp_string ff = mp_memory_allocate(sizeof(mp_lstring));
65 ff->str = NULL;
66 ff->len = 0;
67 ff->refs = 0;
68 return ff;
69}
70
71char *mp_strdup(const char *s)
72{
73 if (s) {
74 char *w = lmt_memory_strdup(s);
75 if (w) {
76 return w;
77 } else {
78 printf("mplib ran out of memory, case 3");
79 exit(EXIT_FAILURE);
80 }
81 }
82 return NULL;
83}
84
85char *mp_strndup(const char *p, size_t l)
86{
87 if (p) {
88 char *r = mp_memory_allocate(l * sizeof(char) + 1);
89 if (r) {
90 char *s = memcpy(r, p, l);
91 *(s + l) = '\0';
92 return s;
93 } else {
94 printf("mplib ran out of memory, case 4");
95 exit(EXIT_FAILURE);
96 }
97 }
98 return NULL;
99}
100
101
102
103
104
105
106void mp_initialize_strings(MP mp)
107{
108 mp->strings = avl_create(mp_aux_comp_strings_entry, mp_aux_copy_strings_entry, delete_strings_entry, mp_memory_allocate, mp_memory_free, NULL);
109 mp->cur_string = NULL;
110 mp->cur_length = 0;
111 mp->cur_string_size = 0;
112}
113
114void mp_dealloc_strings(MP mp)
115{
116 if (mp->strings != NULL) {
117 avl_destroy(mp->strings);
118 } else {
119 mp->strings = NULL;
120 mp_memory_free(mp->cur_string);
121 mp->cur_string = NULL;
122 mp->cur_length = 0;
123 mp->cur_string_size = 0;
124 }
125}
126
127
131
132
133
134
135
136
137
138mp_string mp_rtsl(MP mp, const char *s, size_t l)
139{
140 mp_string nstr;
141 mp_string str = new_strings_entry();
142 str->str = (unsigned char *) mp_strndup(s, l);
143 str->len = l;
144 nstr = (mp_string) avl_find(str, mp->strings);
145 if (nstr == NULL) {
146 avl_ins(str, mp->strings, avl_false);
147 nstr = (mp_string) avl_find(str, mp->strings);
148 }
149 delete_strings_entry(str);
150 add_str_ref(nstr);
151 return nstr;
152}
153
154mp_string mp_rts(MP mp, const char *s)
155{
156 return mp_rtsl(mp, s, strlen(s));
157}
158
159
160
172
173# define EXTRA_STRING 500
174
175void mp_str_room(MP mp, int wsize)
176{
177
178 if ((mp->cur_length + (size_t) wsize + 1) > mp->cur_string_size) {
179 size_t nsize = mp->cur_string_size + mp->cur_string_size / 5 + EXTRA_STRING;
180 if (nsize < (size_t) wsize) {
181 nsize = (size_t) wsize + EXTRA_STRING;
182 }
183 mp->cur_string = (unsigned char *) mp_memory_reallocate(mp->cur_string, (size_t) nsize * sizeof(unsigned char));
184 memset(mp->cur_string + mp->cur_length, 0, nsize-mp->cur_length);
185 mp->cur_string_size = nsize;
186 }
187}
188
189void mp_append_char(MP mp, unsigned char c)
190{
191 *(mp->cur_string + mp->cur_length) = c;
192 mp->cur_length++;
193}
194
195void mp_append_str(MP mp, const char *s)
196{
197 int j = 0;
198 while ((unsigned char) s[j]) {
199 *(mp->cur_string + mp->cur_length) = s[j++];
200 mp->cur_length++;
201 }
202}
203
204void mp_reset_cur_string(MP mp)
205{
206 mp_memory_free(mp->cur_string);
207 mp->cur_length = 0;
208 mp->cur_string_size = 63;
209 mp->cur_string = (unsigned char *) mp_memory_allocate(64 * sizeof(unsigned char));
210 memset(mp->cur_string, 0, 64);
211}
212
213
225
226void mp_flush_string(MP mp, mp_string s) {
227 if (s->refs == 0) {
228 mp->strs_in_use--;
229 mp->pool_in_use = mp->pool_in_use - (int) s->len;
230 avl_del(s, mp->strings, NULL);
231 }
232}
233
234
238
239mp_string mp_intern(MP mp, const char *s)
240{
241 mp_string r = mp_rts(mp, s);
242 r->refs = MAX_STR_REF;
243 return r;
244}
245
246
253
254mp_string mp_make_string(MP mp)
255{
256
257 mp_string str;
258 mp_lstring tmp;
259 tmp.str = mp->cur_string;
260 tmp.len = mp->cur_length;
261 str = (mp_string) avl_find(&tmp, mp->strings);
262 if (str == NULL) {
263 str = mp_memory_allocate(sizeof(mp_lstring));
264 str->str = mp->cur_string;
265 str->len = tmp.len;
266 avl_ins(str, mp->strings, avl_false);
267 str = (mp_string) avl_find(&tmp, mp->strings);
268 mp->pool_in_use = mp->pool_in_use + (int) str->len;
269 if (mp->pool_in_use > mp->max_pl_used) {
270 mp->max_pl_used = mp->pool_in_use;
271 }
272 mp->strs_in_use++;
273 if (mp->strs_in_use > mp->max_strs_used) {
274 mp->max_strs_used = mp->strs_in_use;
275 }
276 }
277 add_str_ref(str);
278 mp_reset_cur_string (mp);
279 return str;
280}
281
282int mp_str_vs_str(MP mp, mp_string s, mp_string t)
283{
284 (void) mp;
285 return mp_aux_comp_strings_entry(NULL, (const void *) s, (const void *) t);
286}
287
288mp_string mp_cat(MP mp, mp_string a, mp_string b)
289{
290 mp_string str;
291 size_t saved_cur_length = mp->cur_length;
292 unsigned char *saved_cur_string = mp->cur_string;
293 size_t saved_cur_string_size = mp->cur_string_size;
294 size_t needed = a->len + b->len;
295 mp->cur_length = 0;
296
297 mp->cur_string = (unsigned char *) mp_memory_allocate((size_t) (needed + 1) * sizeof(unsigned char));
298 mp->cur_string_size = 0;
299 mp_str_room(mp, (int) needed + 1);
300 memcpy(mp->cur_string, a->str, a->len);
301 memcpy(mp->cur_string + a->len, b->str, b->len);
302 mp->cur_length = needed;
303 mp->cur_string[needed] = '\0';
304 str = mp_make_string(mp);
305 mp_memory_free(mp->cur_string);
306 mp->cur_length = saved_cur_length;
307 mp->cur_string = saved_cur_string;
308 mp->cur_string_size = saved_cur_string_size;
309 return str;
310}
311
312mp_string mp_chop_string(MP mp, mp_string s, int a, int b)
313{
314 int l = (int) s->len;
315 int reversed;
316 if (a <= b) {
317 reversed = 0;
318 } else {
319 int k = a;
320 a = b;
321 b = k;
322 reversed = 1;
323 }
324 if (a < 0) {
325 a = 0;
326 if (b < 0) {
327 b = 0;
328 }
329 }
330 if (b > l) {
331 b = l;
332 if (a > l) {
333 a = l;
334 }
335 }
336 mp_str_room(mp, (b - a));
337 if (reversed) {
338 for (int k = b - 1; k >= a; k--) {
339 mp_append_char(mp, *(s->str + k));
340 }
341 } else {
342 for (int k = a; k < b; k++) {
343 mp_append_char(mp, *(s->str + k));
344 }
345 }
346 return mp_make_string(mp);
347}
348 |