8 #define unless(C) if(!(C))
16 void *mem = malloc(HEAD + (CREATE_SIZE + 1) * sizeof(symbol));
20 p = (symbol *) (HEAD + (char *) mem);
21 CAPACITY(p) = CREATE_SIZE;
22 SET_SIZE(p, CREATE_SIZE);
31 free((char *) p - HEAD);
35 new_p = X_skip_utf8(p, c, lb, l, n); skips n characters forwards from p + c
36 if n +ve, or n characters backwards from p +c - 1 if n -ve. new_p is the new
37 position, or 0 on failure.
39 -- used to implement hop and next in the utf8 case.
43 skip_utf8(const symbol * p, int c, int lb, int l, int n)
59 if (b >= 0xC0 || b < 0x80)
61 /* break unless b is 10------ */
80 break; /* 1100 0000 */
89 /* Code for character groupings: utf8 cases */
92 get_utf8(const symbol * p, int c, int l, int *slot)
100 if (b0 < 0xC0 || c == l)
106 if (b0 < 0xE0 || c == l)
108 *slot = (b0 & 0x1F) << 6 | (b1 & 0x3F);
111 *slot = (b0 & 0xF) << 12 | (b1 & 0x3F) << 6 | (*p & 0x3F);
116 get_b_utf8(const symbol * p, int c, int lb, int *slot)
124 if (b0 < 0x80 || c == lb)
130 if (b1 >= 0xC0 || c == lb)
132 *slot = (b1 & 0x1F) << 6 | (b0 & 0x3F);
135 *slot = (*p & 0xF) << 12 | (b1 & 0x3F) << 6 | (b0 & 0x3F);
140 in_grouping_U(struct SN_env * z, unsigned char *s, int min, int max)
143 int w = get_utf8(z->p, z->c, z->l, &ch);
146 if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
153 in_grouping_b_U(struct SN_env * z, unsigned char *s, int min, int max)
156 int w = get_b_utf8(z->p, z->c, z->lb, &ch);
159 if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
166 out_grouping_U(struct SN_env * z, unsigned char *s, int min, int max)
169 int w = get_utf8(z->p, z->c, z->l, &ch);
172 unless(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0;
178 out_grouping_b_U(struct SN_env * z, unsigned char *s, int min, int max)
181 int w = get_b_utf8(z->p, z->c, z->lb, &ch);
184 unless(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0;
189 /* Code for character groupings: non-utf8 cases */
192 in_grouping(struct SN_env * z, unsigned char *s, int min, int max)
199 if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
206 in_grouping_b(struct SN_env * z, unsigned char *s, int min, int max)
213 if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
220 out_grouping(struct SN_env * z, unsigned char *s, int min, int max)
227 unless(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0;
233 out_grouping_b(struct SN_env * z, unsigned char *s, int min, int max)
240 unless(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0;
246 eq_s(struct SN_env * z, int s_size, symbol * s)
248 if (z->l - z->c < s_size || memcmp(z->p + z->c, s, s_size * sizeof(symbol)) != 0)
255 eq_s_b(struct SN_env * z, int s_size, symbol * s)
257 if (z->c - z->lb < s_size || memcmp(z->p + z->c - s_size, s, s_size * sizeof(symbol)) != 0)
264 eq_v(struct SN_env * z, symbol * p)
266 return eq_s(z, SIZE(p), p);
270 eq_v_b(struct SN_env * z, symbol * p)
272 return eq_s_b(z, SIZE(p), p);
276 find_among(struct SN_env * z, struct among * v, int v_size)
284 symbol *q = z->p + c;
291 int first_key_inspected = 0;
295 int k = i + ((j - i) >> 1);
297 int common = common_i < common_j ? common_i : common_j; /* smaller */
303 for (i = common; i < w->s_size; i++)
310 diff = q[common] - w->s[i];
329 break; /* v->s has been inspected */
331 break; /* only one item in v */
334 * - but now we need to go round once more to get v->s inspected.
335 * This looks messy, but is actually the optimal approach.
338 if (first_key_inspected)
340 first_key_inspected = 1;
346 if (common_i >= w->s_size)
348 z->c = c + w->s_size;
349 if (w->function == 0)
352 int res = w->function(z);
354 z->c = c + w->s_size;
365 /* find_among_b is for backwards processing. Same comments apply */
368 find_among_b(struct SN_env * z, struct among * v, int v_size)
376 symbol *q = z->p + c - 1;
383 int first_key_inspected = 0;
387 int k = i + ((j - i) >> 1);
389 int common = common_i < common_j ? common_i : common_j;
395 for (i = w->s_size - 1 - common; i >= 0; i--)
397 if (c - common == lb)
402 diff = q[-common] - w->s[i];
424 if (first_key_inspected)
426 first_key_inspected = 1;
432 if (common_i >= w->s_size)
434 z->c = c - w->s_size;
435 if (w->function == 0)
438 int res = w->function(z);
440 z->c = c - w->s_size;
452 /* Increase the size of the buffer pointed to by p to at least n symbols.
453 * If insufficient memory, returns NULL and frees the old buffer.
456 increase_size(symbol * p, int n)
459 int new_size = n + 20;
460 void *mem = realloc((char *) p - HEAD,
461 HEAD + (new_size + 1) * sizeof(symbol));
468 q = (symbol *) (HEAD + (char *) mem);
469 CAPACITY(q) = new_size;
473 /* to replace symbols between c_bra and c_ket in z->p by the
475 Returns 0 on success, -1 on error.
476 Also, frees z->p (and sets it to NULL) on error.
479 replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s, int *adjptr)
490 adjustment = s_size - (c_ket - c_bra);
494 if (adjustment + len > CAPACITY(z->p))
496 z->p = increase_size(z->p, adjustment + len);
500 memmove(z->p + c_ket + adjustment,
502 (len - c_ket) * sizeof(symbol));
503 SET_SIZE(z->p, adjustment + len);
507 else if (z->c > c_bra)
510 unless(s_size == 0) memmove(z->p + c_bra, s, s_size * sizeof(symbol));
512 *adjptr = adjustment;
517 slice_check(struct SN_env * z)
524 z->l > SIZE(z->p)) /* this line could be removed */
527 fprintf(stderr, "faulty slice operation:\n");
536 slice_from_s(struct SN_env * z, int s_size, symbol * s)
540 return replace_s(z, z->bra, z->ket, s_size, s, NULL);
544 slice_from_v(struct SN_env * z, symbol * p)
546 return slice_from_s(z, SIZE(p), p);
550 slice_del(struct SN_env * z)
552 return slice_from_s(z, 0, 0);
556 insert_s(struct SN_env * z, int bra, int ket, int s_size, symbol * s)
560 if (replace_s(z, bra, ket, s_size, s, &adjustment))
563 z->bra += adjustment;
565 z->ket += adjustment;
570 insert_v(struct SN_env * z, int bra, int ket, symbol * p)
574 if (replace_s(z, bra, ket, SIZE(p), p, &adjustment))
577 z->bra += adjustment;
579 z->ket += adjustment;
584 slice_to(struct SN_env * z, symbol * p)
592 int len = z->ket - z->bra;
594 if (CAPACITY(p) < len)
596 p = increase_size(p, len);
600 memmove(p, z->p + z->bra, len * sizeof(symbol));
607 assign_to(struct SN_env * z, symbol * p)
611 if (CAPACITY(p) < len)
613 p = increase_size(p, len);
617 memmove(p, z->p, len * sizeof(symbol));
624 debug(struct SN_env * z, int number, int line_count)
627 int limit = SIZE(z->p);
629 /* if (number >= 0) printf("%3d (line %4d): '", number, line_count); */
631 printf("%3d (line %4d): [%d]'", number, line_count, limit);
632 for (i = 0; i <= limit; i++)