]> mj.ucw.cz Git - eval.git/blob - judge/judge-tok.c
Improved parsing of switches.
[eval.git] / judge / judge-tok.c
1 /*
2  *      A judge comparing two sequences of tokens
3  *
4  *      (c) 2007 Martin Krulis <bobrik@matfyz.cz>
5  *      (c) 2007 Martin Mares <mj@ucw.cz>
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <getopt.h>
12
13 #include "judge.h"
14
15 static int ignore_nl, ignore_trailing_nl;
16
17 static int trailing_nl(struct tokenizer *t)
18 {
19   // Ignore empty lines at the end of file
20   if (t->token[0] || !ignore_trailing_nl)
21     return 0;
22   t->flags &= ~TF_REPORT_LINES;
23   return !get_token(t);
24 }
25
26 static void usage(void)
27 {
28   fprintf(stderr, "Usage: judge-tok [<options>] <file1> <file2>\n\
29 \n\
30 Options:\n\
31 -n\t\tIgnore newlines\n\
32 -t\t\tIgnore newlines at the end of file\n\
33 ");
34   exit(2);
35 }
36
37 int main(int argc, char **argv)
38 {
39   struct tokenizer t1, t2;
40   int opt;
41
42   while ((opt = getopt(argc, argv, "nt")) >= 0)
43     switch (opt)
44       {
45       case 'n':
46         ignore_nl++;
47         break;
48       case 't':
49         ignore_trailing_nl++;
50         break;
51       default:
52         usage();
53       }
54   if (optind + 2 != argc)
55     usage();
56
57   tok_init(&t1, sopen_read(argv[optind]));
58   tok_init(&t2, sopen_read(argv[optind+1]));
59   if (!ignore_nl)
60     t1.flags = t2.flags = TF_REPORT_LINES;
61
62   for (;;)
63     {
64       char *a = get_token(&t1), *b = get_token(&t2);
65       if (!a)
66         {
67           if (b && !trailing_nl(&t2))
68             tok_err(&t1, "Ends too early");
69           break;
70         }
71       else if (!b)
72         {
73           if (a && !trailing_nl(&t1))
74             tok_err(&t2, "Garbage at the end");
75           break;
76         }
77       else if (strcmp(a, b))
78         tok_err(&t1, "Found <%s>, expected <%s>", a, b);
79     }
80
81   return 0;
82 }