+ read_input(t, &s->tb);
+ s->tok_array = xmalloc(sizeof(struct tok) * s->tb.num_tokens);
+ s->line_array = xmalloc(sizeof(struct line) * (s->tb.num_lines+1));
+ s->num_lines = 0;
+
+ struct tok *tok = s->tok_array;
+ struct line *line = s->line_array;
+ line->toks = tok;
+ for (char *x = get_first(&s->tb); x; x = get_next(&s->tb))
+ if (*x)
+ {
+ tok->token = x;
+ tok->hash = string_hash(x);
+ tok++;
+ }
+ else
+ {
+ line->len = tok - line->toks;
+ if (shuffle_words)
+ qsort(line->toks, line->len, sizeof(struct tok), (int(*)(const void *, const void *)) compare_toks);
+ line->hash = line_hash(line->toks, line->len);
+ line->orig_line = ++s->num_lines;
+#if 0
+ for (struct tok *t=line->toks; t<tok; t++)
+ printf("<%08x|%s>", t->hash, t->token);
+ printf(" -> %08x (%d)\n", line->hash, line->orig_line);
+#endif
+ line++;
+ line->toks = tok;
+ }
+ if (line->toks != tok)
+ die("Bug #41: unterminated line");
+ if (s->num_lines != s->tb.num_lines)
+ die("Bug #42: got %d lines, expected %d", s->num_lines, s->tb.num_lines);
+
+ if (shuffle_lines)
+ qsort(s->line_array, s->num_lines, sizeof(struct line), (int(*)(const void *, const void *)) compare_lines);
+}
+
+static void compare(struct shouffle *s1, struct shouffle *s2)
+{
+ if (s1->num_lines != s2->num_lines)
+ {
+ printf("Output has %d lines, expecting %d\n", s1->num_lines, s2->num_lines);
+ exit(1);
+ }
+
+ uns errs = 0;
+ for (uns i=0; i<s1->num_lines; i++)
+ {
+ struct line *l1 = &s1->line_array[i], *l2 = &s2->line_array[i];
+ if (compare_lines(l1, l2))
+ {
+ printf("Line %d does not match\n", l1->orig_line);
+ printf(" %08x(%d) vs. %08x(%d)\n", l1->hash, l1->orig_line, l2->hash, l2->orig_line);
+ errs++;
+ }
+ }
+ if (errs)
+ exit(1);