1 
2 #include <stdio.h>   /* printf etc */
3 #include <stdlib.h>  /* exit */
4 #include <string.h>  /* memmove */
5 #include "header.h"
6 
7 typedef enum {
8     e_token_omitted = 0,
9     e_unexpected_token = 1,
10     e_string_omitted = 2,
11     e_unexpected_token_in_among = 3,
12     /* For codes above here, report "after " t->previous_token after the error. */
13     e_unresolved_substring = 14,
14     e_not_allowed_inside_reverse = 15,
15     e_empty_grouping = 16,
16     e_already_backwards = 17,
17     e_empty_among = 18,
18     e_adjacent_bracketed_in_among = 19,
19     e_substring_preceded_by_substring = 20,
20     /* For codes below here, tokeniser->b is printed before the error. */
21     e_redeclared = 30,
22     e_undeclared = 31,
23     e_declared_as_different_mode = 32,
24     e_not_of_type_x = 33,
25     e_not_of_type_string_or_integer = 34,
26     e_misplaced = 35,
27     e_redefined = 36,
28     e_misused = 37
29 } error_code;
30 
31 /* recursive usage: */
32 
33 static void read_program_(struct analyser * a, int terminator);
34 static struct node * read_C(struct analyser * a);
35 static struct node * C_style(struct analyser * a, const char * s, int token);
36 
37 
print_node_(struct node * p,int n,const char * s)38 static void print_node_(struct node * p, int n, const char * s) {
39 
40     int i;
41     for (i = 0; i < n; i++) fputs(i == n - 1 ? s : "  ", stdout);
42     printf("%s ", name_of_token(p->type));
43     if (p->name) report_b(stdout, p->name->b);
44     if (p->literalstring) {
45         printf("'");
46         report_b(stdout, p->literalstring);
47         printf("'");
48     } else if (p->type == c_number) {
49         printf("%d", p->number);
50     }
51     printf("\n");
52     if (p->AE) print_node_(p->AE, n+1, "# ");
53     if (p->left) print_node_(p->left, n+1, "  ");
54     if (p->aux) print_node_(p->aux, n+1, "@ ");
55     if (p->right) print_node_(p->right, n, "  ");
56 }
57 
print_program(struct analyser * a)58 extern void print_program(struct analyser * a) {
59     print_node_(a->program, 0, "  ");
60 }
61 
new_node(struct analyser * a,int type)62 static struct node * new_node(struct analyser * a, int type) {
63     NEW(node, p);
64     p->next = a->nodes; a->nodes = p;
65     p->left = 0;
66     p->right = 0;
67     p->aux = 0;
68     p->AE = 0;
69     p->name = 0;
70     p->literalstring = 0;
71     p->mode = a->mode;
72     p->line_number = a->tokeniser->line_number;
73     p->type = type;
74     return p;
75 }
76 
name_of_mode(int n)77 static const char * name_of_mode(int n) {
78     switch (n) {
79         case m_backward: return "string backward";
80         case m_forward:  return "string forward";
81     /*  case m_integer:  return "integer";  */
82     }
83     fprintf(stderr, "Invalid mode %d in name_of_mode()\n", n);
84     exit(1);
85 }
86 
name_of_type(int n)87 static const char * name_of_type(int n) {
88     switch (n) {
89         case 's': return "string";
90         case 'i': return "integer";
91         case 'r': return "routine";
92         case 'R': return "routine or grouping";
93         case 'g': return "grouping";
94     }
95     fprintf(stderr, "Invalid type %d in name_of_type()\n", n);
96     exit(1);
97 }
98 
name_of_name_type(int code)99 static const char * name_of_name_type(int code) {
100     switch (code) {
101         case t_string: return "string";
102         case t_boolean: return "boolean";
103         case t_integer: return "integer";
104         case t_routine: return "routine";
105         case t_external: return "external";
106         case t_grouping: return "grouping";
107     }
108     fprintf(stderr, "Invalid type code %d in name_of_name_type()\n", code);
109     exit(1);
110 }
111 
count_error(struct analyser * a)112 static void count_error(struct analyser * a) {
113     struct tokeniser * t = a->tokeniser;
114     if (t->error_count >= 20) { fprintf(stderr, "... etc\n"); exit(1); }
115     t->error_count++;
116 }
117 
error2(struct analyser * a,error_code n,int x)118 static void error2(struct analyser * a, error_code n, int x) {
119     struct tokeniser * t = a->tokeniser;
120     count_error(a);
121     fprintf(stderr, "%s:%d: ", t->file, t->line_number);
122     if ((int)n >= (int)e_redeclared) report_b(stderr, t->b);
123     switch (n) {
124         case e_token_omitted:
125             fprintf(stderr, "%s omitted", name_of_token(t->omission)); break;
126         case e_unexpected_token_in_among:
127             fprintf(stderr, "in among(...), ");
128             /* fall through */
129         case e_unexpected_token:
130             fprintf(stderr, "unexpected %s", name_of_token(t->token));
131             if (t->token == c_number) fprintf(stderr, " %d", t->number);
132             if (t->token == c_name) {
133                 fprintf(stderr, " ");
134                 report_b(stderr, t->b);
135             } break;
136         case e_string_omitted:
137             fprintf(stderr, "string omitted"); break;
138 
139         case e_unresolved_substring:
140             fprintf(stderr, "unresolved substring on line %d", x); break;
141         case e_not_allowed_inside_reverse:
142             fprintf(stderr, "%s not allowed inside reverse(...)", name_of_token(t->token)); break;
143         case e_empty_grouping:
144             fprintf(stderr, "empty grouping"); break;
145         case e_already_backwards:
146             fprintf(stderr, "backwards used when already in this mode"); break;
147         case e_empty_among:
148             fprintf(stderr, "empty among(...)"); break;
149         case e_adjacent_bracketed_in_among:
150             fprintf(stderr, "two adjacent bracketed expressions in among(...)"); break;
151         case e_substring_preceded_by_substring:
152             fprintf(stderr, "substring preceded by another substring on line %d", x); break;
153 
154         case e_redeclared:
155             fprintf(stderr, " re-declared"); break;
156         case e_undeclared:
157             fprintf(stderr, " undeclared"); break;
158         case e_declared_as_different_mode:
159             fprintf(stderr, " declared as %s mode; used as %s mode",
160                             name_of_mode(a->mode), name_of_mode(x)); break;
161         case e_not_of_type_x:
162             fprintf(stderr, " not of type %s", name_of_type(x)); break;
163         case e_not_of_type_string_or_integer:
164             fprintf(stderr, " not of type string or integer"); break;
165         case e_misplaced:
166             fprintf(stderr, " misplaced"); break;
167         case e_redefined:
168             fprintf(stderr, " redefined"); break;
169         case e_misused:
170             fprintf(stderr, " mis-used as %s mode",
171                             name_of_mode(x)); break;
172     }
173     if ((int)n < (int)e_unresolved_substring && t->previous_token > 0)
174         fprintf(stderr, " after %s", name_of_token(t->previous_token));
175     fprintf(stderr, "\n");
176 }
177 
error(struct analyser * a,error_code n)178 static void error(struct analyser * a, error_code n) { error2(a, n, 0); }
179 
error4(struct analyser * a,struct name * q)180 static void error4(struct analyser * a, struct name * q) {
181     count_error(a);
182     fprintf(stderr, "%s:%d: ", a->tokeniser->file, q->used->line_number);
183     report_b(stderr, q->b);
184     fprintf(stderr, " undefined\n");
185 }
186 
omission_error(struct analyser * a,int n)187 static void omission_error(struct analyser * a, int n) {
188     a->tokeniser->omission = n;
189     error(a, e_token_omitted);
190 }
191 
check_token(struct analyser * a,int code)192 static int check_token(struct analyser * a, int code) {
193     struct tokeniser * t = a->tokeniser;
194     if (t->token != code) { omission_error(a, code); return false; }
195     return true;
196 }
197 
get_token(struct analyser * a,int code)198 static int get_token(struct analyser * a, int code) {
199     struct tokeniser * t = a->tokeniser;
200     read_token(t);
201     {
202         int x = check_token(a, code);
203         if (!x) t->token_held = true;
204         return x;
205     }
206 }
207 
look_for_name(struct analyser * a)208 static struct name * look_for_name(struct analyser * a) {
209     symbol * q = a->tokeniser->b;
210     struct name * p;
211     for (p = a->names; p; p = p->next) {
212         symbol * b = p->b;
213         int n = SIZE(b);
214         if (n == SIZE(q) && memcmp(q, b, n * sizeof(symbol)) == 0) {
215             p->referenced = true;
216             return p;
217         }
218     }
219     return 0;
220 }
221 
find_name(struct analyser * a)222 static struct name * find_name(struct analyser * a) {
223     struct name * p = look_for_name(a);
224     if (p == 0) error(a, e_undeclared);
225     return p;
226 }
227 
check_routine_mode(struct analyser * a,struct name * p,int mode)228 static void check_routine_mode(struct analyser * a, struct name * p, int mode) {
229     if (p->mode < 0) p->mode = mode; else
230     if (p->mode != mode) error2(a, e_misused, mode);
231 }
232 
check_name_type(struct analyser * a,struct name * p,int type)233 static void check_name_type(struct analyser * a, struct name * p, int type) {
234     switch (type) {
235         case 's':
236             if (p->type == t_string) return;
237             break;
238         case 'i':
239             if (p->type == t_integer) return;
240             break;
241         case 'b':
242             if (p->type == t_boolean) return;
243             break;
244         case 'R':
245             if (p->type == t_grouping) return;
246             /* FALLTHRU */
247         case 'r':
248             if (p->type == t_routine || p->type == t_external) return;
249             break;
250         case 'g':
251             if (p->type == t_grouping) return;
252             break;
253     }
254     error2(a, e_not_of_type_x, type);
255 }
256 
read_names(struct analyser * a,int type)257 static void read_names(struct analyser * a, int type) {
258     struct tokeniser * t = a->tokeniser;
259     if (!get_token(a, c_bra)) return;
260     while (true) {
261         int token = read_token(t);
262         switch (token) {
263             case c_len: {
264                 /* Context-sensitive token - once declared as a name, it loses
265                  * its special meaning, for compatibility with older versions
266                  * of snowball.
267                  */
268                 static const symbol c_len_lit[] = {
269                     'l', 'e', 'n'
270                 };
271                 t->b = MOVE_TO_B(t->b, c_len_lit);
272                 goto handle_as_name;
273             }
274             case c_lenof: {
275                 /* Context-sensitive token - once declared as a name, it loses
276                  * its special meaning, for compatibility with older versions
277                  * of snowball.
278                  */
279                 static const symbol c_lenof_lit[] = {
280                     'l', 'e', 'n', 'o', 'f'
281                 };
282                 t->b = MOVE_TO_B(t->b, c_lenof_lit);
283                 goto handle_as_name;
284             }
285             case c_name:
286 handle_as_name:
287                 if (look_for_name(a) != 0) error(a, e_redeclared); else {
288                     NEW(name, p);
289                     p->b = copy_b(t->b);
290                     p->type = type;
291                     p->mode = -1; /* routines, externals */
292                     /* We defer assigning counts until after we've eliminated
293                      * variables whose values are never used. */
294                     p->count = -1;
295                     p->referenced = false;
296                     p->used_in_among = false;
297                     p->used = 0;
298                     p->value_used = false;
299                     p->initialised = false;
300                     p->used_in_definition = false;
301                     p->local_to = 0;
302                     p->grouping = 0;
303                     p->definition = 0;
304                     p->declaration_line_number = t->line_number;
305                     p->next = a->names;
306                     a->names = p;
307                     if (token != c_name) {
308                         disable_token(t, token);
309                     }
310                 }
311                 break;
312             default:
313                 if (!check_token(a, c_ket)) t->token_held = true;
314                 return;
315         }
316     }
317 }
318 
new_literalstring(struct analyser * a)319 static symbol * new_literalstring(struct analyser * a) {
320     NEW(literalstring, p);
321     p->b = copy_b(a->tokeniser->b);
322     p->next = a->literalstrings;
323     a->literalstrings = p;
324     return p->b;
325 }
326 
read_AE_test(struct analyser * a)327 static int read_AE_test(struct analyser * a) {
328 
329     struct tokeniser * t = a->tokeniser;
330     switch (read_token(t)) {
331         case c_assign: return c_mathassign;
332         case c_plusassign:
333         case c_minusassign:
334         case c_multiplyassign:
335         case c_divideassign:
336         case c_eq:
337         case c_ne:
338         case c_gr:
339         case c_ge:
340         case c_ls:
341         case c_le: return t->token;
342         default: error(a, e_unexpected_token); t->token_held = true; return c_eq;
343     }
344 }
345 
binding(int t)346 static int binding(int t) {
347     switch (t) {
348         case c_plus: case c_minus: return 1;
349         case c_multiply: case c_divide: return 2;
350         default: return -2;
351     }
352 }
353 
mark_used_in(struct analyser * a,struct name * q,struct node * p)354 static void mark_used_in(struct analyser * a, struct name * q, struct node * p) {
355     if (!q->used) {
356         q->used = p;
357         q->local_to = a->program_end->name;
358     } else if (q->local_to) {
359         if (q->local_to != a->program_end->name) {
360             /* Used in more than one routine/external. */
361             q->local_to = NULL;
362         }
363     }
364 }
365 
name_to_node(struct analyser * a,struct node * p,int type)366 static void name_to_node(struct analyser * a, struct node * p, int type) {
367     struct name * q = find_name(a);
368     if (q) {
369         check_name_type(a, q, type);
370         mark_used_in(a, q, p);
371     }
372     p->name = q;
373 }
374 
read_AE(struct analyser * a,struct name * assigned_to,int B)375 static struct node * read_AE(struct analyser * a, struct name * assigned_to, int B) {
376     struct tokeniser * t = a->tokeniser;
377     struct node * p;
378     struct node * q;
379     switch (read_token(t)) {
380         case c_minus: /* monadic */
381             q = read_AE(a, assigned_to, 100);
382             if (q->type == c_neg) {
383                 /* Optimise away double negation, which avoids generators
384                  * having to worry about generating "--" (decrement operator
385                  * in many languages).
386                  */
387                 p = q->right;
388                 /* Don't free q, it's in the linked list a->nodes. */
389                 break;
390             }
391             if (q->type == c_number) {
392                 /* Negated constant. */
393                 q->number = -q->number;
394                 p = q;
395                 break;
396             }
397             p = new_node(a, c_neg);
398             p->right = q;
399             break;
400         case c_bra:
401             p = read_AE(a, assigned_to, 0);
402             get_token(a, c_ket);
403             break;
404         case c_name:
405             p = new_node(a, c_name);
406             name_to_node(a, p, 'i');
407             if (p->name) {
408                 // $x = x + 1 shouldn't count as a use of x.
409                 p->name->value_used = (p->name != assigned_to);
410             }
411             break;
412         case c_maxint:
413         case c_minint:
414             a->int_limits_used = true;
415             /* fall through */
416         case c_cursor:
417         case c_limit:
418         case c_len:
419         case c_size:
420             p = new_node(a, t->token);
421             break;
422         case c_number:
423             p = new_node(a, c_number);
424             p->number = t->number;
425             break;
426         case c_lenof:
427         case c_sizeof: {
428             int token = t->token;
429             p = C_style(a, "S", token);
430             if (!p->literalstring) break;
431 
432             /* Replace lenof or sizeof on a literal string with a numeric
433              * constant.
434              */
435             int result;
436             if (token == c_lenof && t->encoding == ENC_UTF8) {
437                 // UTF-8.
438                 int i = 0;
439                 symbol * b = p->literalstring;
440                 result = 0;
441                 while (i < SIZE(b)) {
442                     int dummy;
443                     i += get_utf8(b + i, &dummy);
444                     ++result;
445                 }
446             } else {
447                 result = SIZE(p->literalstring);
448             }
449             p->type = c_number;
450             p->literalstring = NULL;
451             p->number = result;
452             break;
453         }
454         default:
455             error(a, e_unexpected_token);
456             t->token_held = true;
457             return 0;
458     }
459     while (true) {
460         int token = read_token(t);
461         int b = binding(token);
462         if (binding(token) <= B) {
463             t->token_held = true;
464             return p;
465         }
466         struct node * r = read_AE(a, assigned_to, b);
467         if (p->type == c_number && r->type == c_number) {
468             // Evaluate constant sub-expression.
469             q = new_node(a, c_number);
470             switch (token) {
471                 case c_plus:
472                     q->number = p->number + r->number;
473                     break;
474                 case c_minus:
475                     q->number = p->number - r->number;
476                     break;
477                 case c_multiply:
478                     q->number = p->number * r->number;
479                     break;
480                 case c_divide:
481                     q->number = p->number / r->number;
482                     break;
483                 default:
484                     fprintf(stderr, "Unexpected AE operator %s\n",
485                             name_of_token(token));
486                     exit(1);
487             }
488         } else {
489             q = new_node(a, token);
490             q->left = p;
491             q->right = r;
492         }
493         p = q;
494     }
495 }
496 
read_C_connection(struct analyser * a,struct node * q,int op)497 static struct node * read_C_connection(struct analyser * a, struct node * q, int op) {
498     struct tokeniser * t = a->tokeniser;
499     struct node * p = new_node(a, op);
500     struct node * p_end = q;
501     p->left = q;
502     do {
503         q = read_C(a);
504         p_end->right = q; p_end = q;
505     } while (read_token(t) == op);
506     t->token_held = true;
507     return p;
508 }
509 
read_C_list(struct analyser * a)510 static struct node * read_C_list(struct analyser * a) {
511     struct tokeniser * t = a->tokeniser;
512     struct node * p = new_node(a, c_bra);
513     struct node * p_end = 0;
514     while (true) {
515         int token = read_token(t);
516         if (token == c_ket) return p;
517         if (token < 0) { omission_error(a, c_ket); return p; }
518         t->token_held = true;
519         {
520             struct node * q = read_C(a);
521             while (true) {
522                 token = read_token(t);
523                 if (token != c_and && token != c_or) {
524                     t->token_held = true;
525                     break;
526                 }
527                 q = read_C_connection(a, q, token);
528             }
529             if (p_end == 0) p->left = q; else p_end->right = q;
530             p_end = q;
531         }
532     }
533 }
534 
C_style(struct analyser * a,const char * s,int token)535 static struct node * C_style(struct analyser * a, const char * s, int token) {
536     int i;
537     struct node * p = new_node(a, token);
538     for (i = 0; s[i] != 0; i++) switch (s[i]) {
539         case 'C':
540             p->left = read_C(a); continue;
541         case 'D':
542             p->aux = read_C(a); continue;
543         case 'A':
544             p->AE = read_AE(a, 0, 0); continue;
545         case 'f':
546             get_token(a, c_for); continue;
547         case 'S':
548             {
549                 int str_token = read_token(a->tokeniser);
550                 if (str_token == c_name) name_to_node(a, p, 's'); else
551                 if (str_token == c_literalstring) p->literalstring = new_literalstring(a);
552                 else error(a, e_string_omitted);
553             }
554             continue;
555         case 'b':
556         case 's':
557         case 'i':
558             if (get_token(a, c_name)) name_to_node(a, p, s[i]);
559             continue;
560     }
561     return p;
562 }
563 
read_literalstring(struct analyser * a)564 static struct node * read_literalstring(struct analyser * a) {
565     struct node * p = new_node(a, c_literalstring);
566     p->literalstring = new_literalstring(a);
567     return p;
568 }
569 
reverse_b(symbol * b)570 static void reverse_b(symbol * b) {
571     int i = 0; int j = SIZE(b) - 1;
572     while (i < j) {
573         int ch1 = b[i]; int ch2 = b[j];
574         b[i++] = ch2; b[j--] = ch1;
575     }
576 }
577 
compare_amongvec(const void * pv,const void * qv)578 static int compare_amongvec(const void *pv, const void *qv) {
579     const struct amongvec * p = (const struct amongvec*)pv;
580     const struct amongvec * q = (const struct amongvec*)qv;
581     symbol * b_p = p->b; int p_size = p->size;
582     symbol * b_q = q->b; int q_size = q->size;
583     int smaller_size = p_size < q_size ? p_size : q_size;
584     int i;
585     for (i = 0; i < smaller_size; i++)
586         if (b_p[i] != b_q[i]) return b_p[i] - b_q[i];
587     if (p_size - q_size)
588         return p_size - q_size;
589     return p->line_number - q->line_number;
590 }
591 
592 #define PTR_NULL_CHECK(P, Q) do {\
593         if ((Q) == NULL) {\
594             if ((P) != NULL) return 1;\
595         } else {\
596             if ((P) == NULL) return -1;\
597         }\
598     } while (0)
599 
compare_node(const struct node * p,const struct node * q)600 static int compare_node(const struct node *p, const struct node *q) {
601     PTR_NULL_CHECK(p, q);
602     if (q == NULL) {
603         /* p must be NULL too. */
604         return 0;
605     }
606 
607     if (p->type != q->type) return p->type > q->type ? 1 : -1;
608     if (p->mode != q->mode) return p->mode > q->mode ? 1 : -1;
609     if (p->type == c_number) {
610         if (p->number != q->number)
611             return p->number > q->number ? 1 : -1;
612     }
613 
614     PTR_NULL_CHECK(p->left, q->left);
615     if (p->left) {
616         int r = compare_node(p->left, q->left);
617         if (r != 0) return r;
618     }
619 
620     PTR_NULL_CHECK(p->AE, q->AE);
621     if (p->AE) {
622         int r = compare_node(p->AE, q->AE);
623         if (r != 0) return r;
624     }
625 
626     PTR_NULL_CHECK(p->aux, q->aux);
627     if (p->aux) {
628         int r = compare_node(p->aux, q->aux);
629         if (r != 0) return r;
630     }
631 
632     PTR_NULL_CHECK(p->name, q->name);
633     if (p->name) {
634         int r;
635         if (SIZE(p->name->b) != SIZE(q->name->b)) {
636             return SIZE(p->name->b) - SIZE(q->name->b);
637         }
638         r = memcmp(p->name->b, q->name->b,
639                    SIZE(p->name->b) * sizeof(symbol));
640         if (r != 0) return r;
641     }
642 
643     PTR_NULL_CHECK(p->literalstring, q->literalstring);
644     if (p->literalstring) {
645         int r;
646         if (SIZE(p->literalstring) != SIZE(q->literalstring)) {
647             return SIZE(p->literalstring) - SIZE(q->literalstring);
648         }
649         r = memcmp(p->literalstring, q->literalstring,
650                    SIZE(p->literalstring) * sizeof(symbol));
651         if (r != 0) return r;
652     }
653 
654     return compare_node(p->right, q->right);
655 }
656 
make_among(struct analyser * a,struct node * p,struct node * substring)657 static void make_among(struct analyser * a, struct node * p, struct node * substring) {
658 
659     NEW(among, x);
660     NEWVEC(amongvec, v, p->number);
661     struct node * q = p->left;
662     struct amongvec * w0 = v;
663     struct amongvec * w1 = v;
664     int result = 1;
665 
666     int direction = substring != 0 ? substring->mode : p->mode;
667     int backward = direction == m_backward;
668 
669     if (a->amongs == 0) a->amongs = x; else a->amongs_end->next = x;
670     a->amongs_end = x;
671     x->next = 0;
672     x->b = v;
673     x->number = a->among_count++;
674     x->function_count = 0;
675     x->starter = 0;
676     x->nocommand_count = 0;
677     x->amongvar_needed = false;
678 
679     if (q->type == c_bra) { x->starter = q; q = q->right; }
680 
681     while (q) {
682         if (q->type == c_literalstring) {
683             symbol * b = q->literalstring;
684             w1->b = b;           /* pointer to case string */
685             w1->action = NULL;   /* action gets filled in below */
686             w1->line_number = q->line_number;
687             w1->size = SIZE(b);  /* number of characters in string */
688             w1->i = -1;          /* index of longest substring */
689             w1->result = -1;     /* number of corresponding case expression */
690             if (q->left) {
691                 struct name * function = q->left->name;
692                 w1->function = function;
693                 function->used_in_among = true;
694                 check_routine_mode(a, function, direction);
695                 x->function_count++;
696             } else {
697                 w1->function = 0;
698             }
699             w1++;
700         } else if (q->left == 0) {
701             /* empty command: () */
702             w0 = w1;
703         } else {
704             /* Check for previous action which is the same as this one and use
705              * the same action code if we find one.
706              */
707             int among_result = -1;
708             struct amongvec * w;
709             for (w = v; w < w0; ++w) {
710                 if (w->action && compare_node(w->action->left, q->left) == 0) {
711                     if (w->result <= 0) {
712                         printf("Among code %d isn't positive\n", w->result);
713                         exit(1);
714                     }
715                     among_result = w->result;
716                     break;
717                 }
718             }
719             if (among_result < 0) {
720                 among_result = result++;
721             }
722 
723             while (w0 != w1) {
724                 w0->action = q;
725                 w0->result = among_result;
726                 w0++;
727             }
728         }
729         q = q->right;
730     }
731     if (w1-v != p->number) { fprintf(stderr, "oh! %d %d\n", (int)(w1-v), p->number); exit(1); }
732     x->command_count = result - 1;
733     {
734         NEWVEC(node*, commands, x->command_count);
735         memset(commands, 0, x->command_count * sizeof(struct node*));
736         for (w0 = v; w0 < w1; w0++) {
737             if (w0->result > 0) {
738                 /* result == -1 when there's no command. */
739                 if (w0->result > x->command_count) {
740                     fprintf(stderr, "More among codes than expected\n");
741                     exit(1);
742                 }
743                 if (!commands[w0->result - 1])
744                     commands[w0->result - 1] = w0->action;
745             } else {
746                 ++x->nocommand_count;
747             }
748             if (backward) reverse_b(w0->b);
749         }
750         x->commands = commands;
751     }
752     qsort(v, w1 - v, sizeof(struct amongvec), compare_amongvec);
753 
754     /* the following loop is O(n squared) */
755     for (w0 = w1 - 1; w0 >= v; w0--) {
756         symbol * b = w0->b;
757         int size = w0->size;
758         struct amongvec * w;
759 
760         for (w = w0 - 1; w >= v; w--) {
761             if (w->size < size && memcmp(w->b, b, w->size * sizeof(symbol)) == 0) {
762                 w0->i = w - v;  /* fill in index of longest substring */
763                 break;
764             }
765         }
766     }
767     if (backward) for (w0 = v; w0 < w1; w0++) reverse_b(w0->b);
768 
769     for (w0 = v; w0 < w1 - 1; w0++)
770         if (w0->size == (w0 + 1)->size &&
771             memcmp(w0->b, (w0 + 1)->b, w0->size * sizeof(symbol)) == 0) {
772             count_error(a);
773             fprintf(stderr, "%s:%d: among(...) has repeated string '",
774                     a->tokeniser->file, (w0 + 1)->line_number);
775             report_b(stderr, (w0 + 1)->b);
776             fprintf(stderr, "'\n");
777             count_error(a);
778             fprintf(stderr, "%s:%d: previously seen here\n",
779                     a->tokeniser->file, w0->line_number);
780         }
781 
782     x->literalstring_count = p->number;
783     p->among = x;
784 
785     x->substring = substring;
786     if (substring != 0) substring->among = x;
787     if (x->command_count > 1 ||
788         (x->command_count == 1 && x->nocommand_count > 0) ||
789         x->starter != 0) {
790         /* We need to set among_var rather than just checking if find_among*()
791          * returns zero or not.
792          */
793         x->amongvar_needed = a->amongvar_needed = true;
794     }
795 }
796 
797 static int
is_just_true(struct node * q)798 is_just_true(struct node * q)
799 {
800     if (!q) return 1;
801     if (q->type != c_bra && q->type != c_true) return 0;
802     return is_just_true(q->left) && is_just_true(q->right);
803 }
804 
read_among(struct analyser * a)805 static struct node * read_among(struct analyser * a) {
806     struct tokeniser * t = a->tokeniser;
807     struct node * p = new_node(a, c_among);
808     struct node * p_end = 0;
809     int previous_token = -1;
810     struct node * substring = a->substring;
811 
812     a->substring = 0;
813     p->number = 0; /* counts the number of literals */
814     if (!get_token(a, c_bra)) return p;
815     while (true) {
816         struct node * q;
817         int token = read_token(t);
818         switch (token) {
819             case c_literalstring:
820                 q = read_literalstring(a);
821                 if (read_token(t) == c_name) {
822                     struct node * r = new_node(a, c_name);
823                     name_to_node(a, r, 'r');
824                     q->left = r;
825                 }
826                 else t->token_held = true;
827                 p->number++; break;
828             case c_bra:
829                 if (previous_token == c_bra) error(a, e_adjacent_bracketed_in_among);
830                 q = read_C_list(a);
831                 if (is_just_true(q->left)) {
832                     /* Convert anything equivalent to () to () so we handle it
833                      * the same way.
834                      */
835                     q->left = 0;
836                 }
837                 break;
838             default:
839                 error(a, e_unexpected_token_in_among);
840                 previous_token = token;
841                 continue;
842             case c_ket:
843                 if (p->number == 0) error(a, e_empty_among);
844                 if (t->error_count == 0) make_among(a, p, substring);
845                 return p;
846         }
847         previous_token = token;
848         if (p_end == 0) p->left = q; else p_end->right = q;
849         p_end = q;
850     }
851 }
852 
read_substring(struct analyser * a)853 static struct node * read_substring(struct analyser * a) {
854 
855     struct node * p = new_node(a, c_substring);
856     if (a->substring != 0) error2(a, e_substring_preceded_by_substring, a->substring->line_number);
857     a->substring = p;
858     return p;
859 }
860 
check_modifyable(struct analyser * a)861 static void check_modifyable(struct analyser * a) {
862     if (!a->modifyable) error(a, e_not_allowed_inside_reverse);
863 }
864 
ae_uses_name(struct node * p,struct name * q)865 static int ae_uses_name(struct node * p, struct name * q) {
866     switch (p->type) {
867         case c_name:
868         case c_lenof:
869         case c_sizeof:
870             if (p->name == q) return 1;
871             break;
872         case c_neg:
873             return ae_uses_name(p->right, q);
874         case c_multiply:
875         case c_plus:
876         case c_minus:
877         case c_divide:
878             return ae_uses_name(p->left, q) || ae_uses_name(p->right, q);
879     }
880     return 0;
881 }
882 
read_C(struct analyser * a)883 static struct node * read_C(struct analyser * a) {
884     struct tokeniser * t = a->tokeniser;
885     int token = read_token(t);
886     switch (token) {
887         case c_bra: {
888             struct node * p = read_C_list(a);
889             if (p->type != c_bra) {
890                 fprintf(stderr, "read_C_list returned unexpected type %s\n",
891                         name_of_token(p->type));
892                 exit(1);
893             }
894             if (p->left && !p->left->right) {
895                 // Replace a single entry command list with the command it
896                 // contains in order to make subsequent optimisations easier.
897                 p = p->left;
898             }
899             return p;
900         }
901         case c_backwards:
902             {
903                 int mode = a->mode;
904                 if (a->mode == m_backward) error(a, e_already_backwards); else a->mode = m_backward;
905                 {   struct node * p = C_style(a, "C", token);
906                     a->mode = mode;
907                     return p;
908                 }
909             }
910         case c_reverse:
911             {
912                 int mode = a->mode;
913                 int modifyable = a->modifyable;
914                 a->modifyable = false;
915                 a->mode = mode == m_forward ? m_backward : m_forward;
916                 {
917                     struct node * p = C_style(a, "C", token);
918                     a->mode = mode;
919                     a->modifyable = modifyable;
920                     return p;
921                 }
922             }
923         case c_not:
924         case c_try:
925         case c_fail:
926         case c_test:
927         case c_do:
928         case c_goto:
929         case c_gopast:
930         case c_repeat:
931             return C_style(a, "C", token);
932         case c_loop:
933         case c_atleast:
934             return C_style(a, "AC", token);
935         case c_setmark: {
936             struct node * n = C_style(a, "i", token);
937             if (n->name) n->name->initialised = true;
938             return n;
939         }
940         case c_tomark:
941         case c_atmark:
942             return C_style(a, "A", token);
943         case c_hop: {
944             struct node * n = C_style(a, "A", token);
945             if (n->AE->type == c_number) {
946                 if (n->AE->number < 0) {
947                     fprintf(stderr,
948                             "%s:%d: warning: hop %d now signals f (as was "
949                             "always documented) rather than moving the cursor "
950                             "in the opposite direction\n",
951                             a->tokeniser->file,
952                             n->AE->line_number,
953                             n->AE->number);
954                     n->AE = NULL;
955                     n->type = c_false;
956                 } else if (n->AE->number == 0) {
957                     fprintf(stderr,
958                             "%s:%d: warning: hop 0 is a no-op\n",
959                             a->tokeniser->file,
960                             n->AE->line_number);
961                     n->AE = NULL;
962                     n->type = c_true;
963                 }
964             }
965             return n;
966         }
967         case c_delete:
968             check_modifyable(a);
969             /* fall through */
970         case c_next:
971         case c_tolimit:
972         case c_atlimit:
973         case c_leftslice:
974         case c_rightslice:
975         case c_true:
976         case c_false:
977         case c_debug:
978             return new_node(a, token);
979         case c_assignto:
980         case c_sliceto: {
981             struct node *n;
982             check_modifyable(a);
983             n = C_style(a, "s", token);
984             if (n->name) n->name->initialised = true;
985             return n;
986         }
987         case c_assign:
988         case c_insert:
989         case c_attach:
990         case c_slicefrom: {
991             struct node *n;
992             check_modifyable(a);
993             n = C_style(a, "S", token);
994             if (n->name) n->name->value_used = true;
995             return n;
996         }
997         case c_setlimit:
998             return C_style(a, "CfD", token);
999         case c_set:
1000         case c_unset: {
1001             struct node * n = C_style(a, "b", token);
1002             if (n->name) n->name->initialised = true;
1003             return n;
1004         }
1005         case c_dollar: {
1006             struct tokeniser * t = a->tokeniser;
1007             read_token(t);
1008             if (t->token == c_bra) {
1009                 /* Handle newer $(AE REL_OP AE) syntax. */
1010                 struct node * n = read_AE(a, 0, 0);
1011                 read_token(t);
1012                 int token = t->token;
1013                 switch (token) {
1014                     case c_assign:
1015                         count_error(a);
1016                         fprintf(stderr, "%s:%d: Expected relational operator (did you mean '=='?)\n",
1017 				t->file, t->line_number);
1018                         /* Assume it was == to try to avoid an error avalanche. */
1019                         token = c_eq;
1020                         /* FALLTHRU */
1021                     case c_eq:
1022                     case c_ne:
1023                     case c_gr:
1024                     case c_ge:
1025                     case c_ls:
1026                     case c_le: {
1027                         struct node * lhs = n;
1028                         struct node * rhs = read_AE(a, 0, 0);
1029                         if (lhs->type == c_number && rhs->type == c_number) {
1030                             // Evaluate constant numeric test expression.
1031                             int result;
1032                             switch (token) {
1033                                 case c_eq:
1034                                     result = (lhs->number == rhs->number);
1035                                     break;
1036                                 case c_ne:
1037                                     result = (lhs->number != rhs->number);
1038                                     break;
1039                                 case c_gr:
1040                                     result = (lhs->number > rhs->number);
1041                                     break;
1042                                 case c_ge:
1043                                     result = (lhs->number >= rhs->number);
1044                                     break;
1045                                 case c_ls:
1046                                     result = (lhs->number < rhs->number);
1047                                     break;
1048                                 case c_le:
1049                                     result = (lhs->number <= rhs->number);
1050                                     break;
1051                                 default:
1052                                     fprintf(stderr, "Unexpected numeric test operator %s\n",
1053                                             name_of_token(t->token));
1054                                     exit(1);
1055                             }
1056                             n = new_node(a, result ? c_true : c_false);
1057                         } else {
1058                             n = new_node(a, token);
1059                             n->left = lhs;
1060                             n->AE = rhs;
1061                         }
1062                         get_token(a, c_ket);
1063                         break;
1064                     }
1065                     default:
1066                         error(a, e_unexpected_token);
1067                         t->token_held = true;
1068                         break;
1069                 }
1070                 return n;
1071             }
1072 
1073             if (t->token == c_name) {
1074                 struct node * p;
1075                 struct name * q = find_name(a);
1076                 int mode = a->mode;
1077                 int modifyable = a->modifyable;
1078                 if (q && q->type == t_string) {
1079                     /* Assume for now that $ on string both initialises and
1080                      * uses the string variable.  FIXME: Can we do better?
1081                      */
1082                     q->initialised = true;
1083                     q->value_used = true;
1084                     a->mode = m_forward;
1085                     a->modifyable = true;
1086                     p = new_node(a, c_dollar);
1087                     p->left = read_C(a);
1088                     p->name = q;
1089                 } else {
1090                     if (q && q->type != t_integer) {
1091                         /* If $ is used on an unknown name or a name which
1092                          * isn't a string or an integer then we assume the
1093                          * unknown name is an integer as $ is used more often
1094                          * on integers than strings, so hopefully this it less
1095                          * likely to cause an error avalanche.
1096                          *
1097                          * For an unknown name, we'll already have reported an
1098                          * error.
1099                          */
1100                         error(a, e_not_of_type_string_or_integer);
1101                         q = NULL;
1102                     }
1103                     p = new_node(a, read_AE_test(a));
1104                     switch (p->type) {
1105                         case c_eq:
1106                         case c_ne:
1107                         case c_gr:
1108                         case c_ge:
1109                         case c_ls:
1110                         case c_le:
1111                             p->left = new_node(a, c_name);
1112                             p->left->name = q;
1113                             if (q) {
1114                                 q->value_used = true;
1115                             }
1116                             p->AE = read_AE(a, NULL, 0);
1117                             break;
1118                         default:
1119                             /* +=, etc don't "initialise" as they only
1120                              * amend an existing value.  Similarly, they
1121                              * don't count as using the value.
1122                              */
1123                             p->name = q;
1124                             p->AE = read_AE(a, q, 0);
1125                             if (p->type == c_mathassign && q) {
1126                                 /* $x = x + 1 doesn't initialise x. */
1127                                 q->initialised = !ae_uses_name(p->AE, q);
1128                             }
1129                             break;
1130                     }
1131                 }
1132                 if (q) mark_used_in(a, q, p);
1133                 a->mode = mode;
1134                 a->modifyable = modifyable;
1135                 return p;
1136             }
1137 
1138             error(a, e_unexpected_token);
1139             t->token_held = true;
1140             return new_node(a, c_dollar);
1141         }
1142         case c_name:
1143             {
1144                 struct name * q = find_name(a);
1145                 struct node * p = new_node(a, c_name);
1146                 if (q) {
1147                     mark_used_in(a, q, p);
1148                     switch (q->type) {
1149                         case t_boolean:
1150                             p->type = c_booltest;
1151                             q->value_used = true;
1152                             break;
1153                         case t_integer:
1154                             error(a, e_misplaced); /* integer name misplaced */
1155                             break;
1156                         case t_string:
1157                             q->value_used = true;
1158                             break;
1159                         case t_routine:
1160                         case t_external:
1161                             p->type = c_call;
1162                             check_routine_mode(a, q, a->mode);
1163                             break;
1164                         case t_grouping:
1165                             p->type = c_grouping; break;
1166                     }
1167                 }
1168                 p->name = q;
1169                 return p;
1170             }
1171         case c_non:
1172             {
1173                 struct node * p = new_node(a, token);
1174                 read_token(t);
1175                 if (t->token == c_minus) read_token(t);
1176                 if (!check_token(a, c_name)) { omission_error(a, c_name); return p; }
1177                 name_to_node(a, p, 'g');
1178                 return p;
1179             }
1180         case c_literalstring:
1181             return read_literalstring(a);
1182         case c_among: return read_among(a);
1183         case c_substring: return read_substring(a);
1184         default: error(a, e_unexpected_token); return 0;
1185     }
1186 }
1187 
next_symbol(symbol * p,symbol * W,int utf8)1188 static int next_symbol(symbol * p, symbol * W, int utf8) {
1189     if (utf8) {
1190         int ch;
1191         int j = get_utf8(p, & ch);
1192         W[0] = ch; return j;
1193     } else {
1194         W[0] = p[0]; return 1;
1195     }
1196 }
1197 
alter_grouping(symbol * p,symbol * q,int style,int utf8)1198 static symbol * alter_grouping(symbol * p, symbol * q, int style, int utf8) {
1199     int j = 0;
1200     symbol W[1];
1201     int width;
1202     if (style == c_plus) {
1203         while (j < SIZE(q)) {
1204             width = next_symbol(q + j, W, utf8);
1205             p = add_to_b(p, 1, W);
1206             j += width;
1207         }
1208     } else {
1209         while (j < SIZE(q)) {
1210             int i;
1211             width = next_symbol(q + j, W, utf8);
1212             for (i = 0; i < SIZE(p); i++) {
1213                 if (p[i] == W[0]) {
1214                     memmove(p + i, p + i + 1, (SIZE(p) - i - 1) * sizeof(symbol));
1215                     SIZE(p)--;
1216                 }
1217             }
1218             j += width;
1219         }
1220     }
1221     return p;
1222 }
1223 
read_define_grouping(struct analyser * a,struct name * q)1224 static void read_define_grouping(struct analyser * a, struct name * q) {
1225     struct tokeniser * t = a->tokeniser;
1226     int style = c_plus;
1227     {
1228         NEW(grouping, p);
1229         if (a->groupings == 0) a->groupings = p; else a->groupings_end->next = p;
1230         a->groupings_end = p;
1231         if (q) q->grouping = p;
1232         p->next = 0;
1233         p->name = q;
1234         p->line_number = a->tokeniser->line_number;
1235         p->b = create_b(0);
1236         while (true) {
1237             switch (read_token(t)) {
1238                 case c_name:
1239                     {
1240                         struct name * r = find_name(a);
1241                         if (r) {
1242                             check_name_type(a, r, 'g');
1243                             p->b = alter_grouping(p->b, r->grouping->b, style, false);
1244                             r->used_in_definition = true;
1245                         }
1246                     }
1247                     break;
1248                 case c_literalstring:
1249                     p->b = alter_grouping(p->b, t->b, style, (a->encoding == ENC_UTF8));
1250                     break;
1251                 default: error(a, e_unexpected_token); return;
1252             }
1253             switch (read_token(t)) {
1254                 case c_plus:
1255                 case c_minus: style = t->token; break;
1256                 default: goto label0;
1257             }
1258         }
1259     label0:
1260         {
1261             int i;
1262             int max = 0;
1263             int min = 1<<16;
1264             for (i = 0; i < SIZE(p->b); i++) {
1265                 if (p->b[i] > max) max = p->b[i];
1266                 if (p->b[i] < min) min = p->b[i];
1267             }
1268             p->largest_ch = max;
1269             p->smallest_ch = min;
1270             if (min == 1<<16) error(a, e_empty_grouping);
1271         }
1272         t->token_held = true; return;
1273     }
1274 }
1275 
read_define_routine(struct analyser * a,struct name * q)1276 static void read_define_routine(struct analyser * a, struct name * q) {
1277     struct node * p = new_node(a, c_define);
1278     a->amongvar_needed = false;
1279     if (q) {
1280         check_name_type(a, q, 'R');
1281         if (q->definition != 0) error(a, e_redefined);
1282         if (q->mode < 0) q->mode = a->mode; else
1283         if (q->mode != a->mode) error2(a, e_declared_as_different_mode, q->mode);
1284     }
1285     p->name = q;
1286     if (a->program == 0) a->program = p; else a->program_end->right = p;
1287     a->program_end = p;
1288     get_token(a, c_as);
1289     p->left = read_C(a);
1290     if (q) q->definition = p->left;
1291 
1292     if (a->substring != 0) {
1293         error2(a, e_unresolved_substring, a->substring->line_number);
1294         a->substring = 0;
1295     }
1296     p->amongvar_needed = a->amongvar_needed;
1297 }
1298 
read_define(struct analyser * a)1299 static void read_define(struct analyser * a) {
1300     if (get_token(a, c_name)) {
1301         struct name * q = find_name(a);
1302         int type;
1303         if (q) {
1304             type = q->type;
1305         } else {
1306             /* No declaration, so sniff next token - if it is 'as' then parse
1307              * as a routine, otherwise as a grouping.
1308              */
1309             if (read_token(a->tokeniser) == c_as) {
1310                 type = t_routine;
1311             } else {
1312                 type = t_grouping;
1313             }
1314             a->tokeniser->token_held = true;
1315         }
1316 
1317         if (type == t_grouping) {
1318             read_define_grouping(a, q);
1319         } else {
1320             read_define_routine(a, q);
1321         }
1322     }
1323 }
1324 
read_backwardmode(struct analyser * a)1325 static void read_backwardmode(struct analyser * a) {
1326     int mode = a->mode;
1327     a->mode = m_backward;
1328     if (get_token(a, c_bra)) {
1329         read_program_(a, c_ket);
1330         check_token(a, c_ket);
1331     }
1332     a->mode = mode;
1333 }
1334 
read_program_(struct analyser * a,int terminator)1335 static void read_program_(struct analyser * a, int terminator) {
1336     struct tokeniser * t = a->tokeniser;
1337     while (true) {
1338         switch (read_token(t)) {
1339             case c_strings:     read_names(a, t_string); break;
1340             case c_booleans:    read_names(a, t_boolean); break;
1341             case c_integers:    read_names(a, t_integer); break;
1342             case c_routines:    read_names(a, t_routine); break;
1343             case c_externals:   read_names(a, t_external); break;
1344             case c_groupings:   read_names(a, t_grouping); break;
1345             case c_define:      read_define(a); break;
1346             case c_backwardmode:read_backwardmode(a); break;
1347             case c_ket:
1348                 if (terminator == c_ket) return;
1349                 /* fall through */
1350             default:
1351                 error(a, e_unexpected_token); break;
1352             case -1:
1353                 if (terminator >= 0) omission_error(a, c_ket);
1354                 return;
1355         }
1356     }
1357 }
1358 
remove_dead_assignments(struct node * p,struct name * q)1359 static void remove_dead_assignments(struct node * p, struct name * q) {
1360     if (p->name == q) {
1361         switch (p->type) {
1362             case c_assignto:
1363             case c_sliceto:
1364             case c_mathassign:
1365             case c_plusassign:
1366             case c_minusassign:
1367             case c_multiplyassign:
1368             case c_divideassign:
1369             case c_setmark:
1370             case c_set:
1371             case c_unset:
1372             case c_dollar:
1373                 /* c_true is a no-op. */
1374                 p->type = c_true;
1375                 p->AE = NULL;
1376                 break;
1377             default:
1378                 /* There are no read accesses to this variable, so any
1379                  * references must be assignments.
1380                  */
1381                 fprintf(stderr, "Unhandled type of dead assignment via %s\n",
1382                         name_of_token(p->type));
1383                 exit(1);
1384         }
1385     }
1386     if (p->AE) remove_dead_assignments(p->AE, q);
1387     if (p->left) remove_dead_assignments(p->left, q);
1388     if (p->aux) remove_dead_assignments(p->aux, q);
1389     if (p->right) remove_dead_assignments(p->right, q);
1390 }
1391 
read_program(struct analyser * a)1392 extern void read_program(struct analyser * a) {
1393     read_program_(a, -1);
1394     {
1395         struct name * q = a->names;
1396         while (q) {
1397             switch (q->type) {
1398                 case t_external: case t_routine:
1399                     if (q->used && q->definition == 0) error4(a, q);
1400                     break;
1401                 case t_grouping:
1402                     if (q->used && q->grouping == 0) error4(a, q);
1403                     break;
1404             }
1405             q = q->next;
1406         }
1407     }
1408 
1409     if (a->tokeniser->error_count == 0) {
1410         struct name * q = a->names;
1411         struct name ** ptr = &(a->names);
1412         while (q) {
1413             if (!q->referenced) {
1414                 fprintf(stderr, "%s:%d: warning: %s '",
1415                         a->tokeniser->file,
1416                         q->declaration_line_number,
1417                         name_of_name_type(q->type));
1418                 report_b(stderr, q->b);
1419                 if (q->type == t_routine ||
1420                     q->type == t_external ||
1421                     q->type == t_grouping) {
1422                     fprintf(stderr, "' declared but not defined\n");
1423                 } else {
1424                     fprintf(stderr, "' defined but not used\n");
1425                     q = q->next;
1426                     *ptr = q;
1427                     continue;
1428                 }
1429             } else if (q->type == t_routine || q->type == t_grouping) {
1430                 /* It's OK to define a grouping but only use it to define other
1431                  * groupings.
1432                  */
1433                 if (!q->used && !q->used_in_definition) {
1434                     int line_num;
1435                     if (q->type == t_routine) {
1436                         line_num = q->definition->line_number;
1437                     } else {
1438                         line_num = q->grouping->line_number;
1439                     }
1440                     fprintf(stderr, "%s:%d: warning: %s '",
1441                             a->tokeniser->file,
1442                             line_num,
1443                             name_of_name_type(q->type));
1444                     report_b(stderr, q->b);
1445                     fprintf(stderr, "' defined but not used\n");
1446                 }
1447             } else if (q->type == t_external) {
1448                 /* Unused is OK. */
1449             } else if (!q->initialised) {
1450                 fprintf(stderr, "%s:%d: warning: %s '",
1451                         a->tokeniser->file,
1452                         q->declaration_line_number,
1453                         name_of_name_type(q->type));
1454                 report_b(stderr, q->b);
1455                 fprintf(stderr, "' is never initialised\n");
1456             } else if (!q->value_used) {
1457                 fprintf(stderr, "%s:%d: warning: %s '",
1458                         a->tokeniser->file,
1459                         q->declaration_line_number,
1460                         name_of_name_type(q->type));
1461                 report_b(stderr, q->b);
1462                 fprintf(stderr, "' is set but never used\n");
1463                 remove_dead_assignments(a->program, q);
1464                 q = q->next;
1465                 *ptr = q;
1466                 continue;
1467             }
1468             ptr = &(q->next);
1469             q = q->next;
1470         }
1471 
1472         {
1473             /* Now we've eliminated variables whose values are never used we
1474              * can number the variables, which is used by some generators.
1475              */
1476             int * name_count = a->name_count;
1477             struct name * n;
1478             for (n = a->names; n; n = n->next) {
1479                 n->count = name_count[n->type]++;
1480             }
1481         }
1482     }
1483 }
1484 
create_analyser(struct tokeniser * t)1485 extern struct analyser * create_analyser(struct tokeniser * t) {
1486     NEW(analyser, a);
1487     a->tokeniser = t;
1488     a->nodes = 0;
1489     a->names = 0;
1490     a->literalstrings = 0;
1491     a->program = 0;
1492     a->amongs = 0;
1493     a->among_count = 0;
1494     a->groupings = 0;
1495     a->mode = m_forward;
1496     a->modifyable = true;
1497     { int i; for (i = 0; i < t_size; i++) a->name_count[i] = 0; }
1498     a->substring = 0;
1499     a->int_limits_used = false;
1500     return a;
1501 }
1502 
close_analyser(struct analyser * a)1503 extern void close_analyser(struct analyser * a) {
1504     {
1505         struct node * q = a->nodes;
1506         while (q) {
1507             struct node * q_next = q->next;
1508             FREE(q);
1509             q = q_next;
1510         }
1511     }
1512     {
1513         struct name * q = a->names;
1514         while (q) {
1515             struct name * q_next = q->next;
1516             lose_b(q->b); FREE(q);
1517             q = q_next;
1518         }
1519     }
1520     {
1521         struct literalstring * q = a->literalstrings;
1522         while (q) {
1523             struct literalstring * q_next = q->next;
1524             lose_b(q->b); FREE(q);
1525             q = q_next;
1526         }
1527     }
1528     {
1529         struct among * q = a->amongs;
1530         while (q) {
1531             struct among * q_next = q->next;
1532             FREE(q->b);
1533             FREE(q->commands);
1534             FREE(q);
1535             q = q_next;
1536         }
1537     }
1538     {
1539         struct grouping * q = a->groupings;
1540         while (q) {
1541             struct grouping * q_next = q->next;
1542             lose_b(q->b); FREE(q);
1543             q = q_next;
1544         }
1545     }
1546     FREE(a);
1547 }
1548