]> mj.ucw.cz Git - moe.git/blobdiff - judge/judge-tok.c
Added syntax for config files (to be reviewed)
[moe.git] / judge / judge-tok.c
index 017f6081339c065efd039c56583b77ee20a5ad99..b55195737155ff605368ea92a9e4f34286033132 100644 (file)
@@ -9,10 +9,33 @@
 #include <stdlib.h>
 #include <string.h>
 #include <getopt.h>
+#include <math.h>
 
 #include "judge.h"
 
-static int ignore_nl, ignore_trailing_nl;
+static int ignore_nl, ignore_trailing_nl, ignore_case;
+static int real_mode;
+static double rel_eps = 1e-5;
+static double abs_eps = 1e-30;
+
+static int tokens_equal(struct tokenizer *t1, struct tokenizer *t2)
+{
+  if (real_mode)
+    {
+      double x1, x2;
+      if (to_double(t1, &x1) && to_double(t2, &x2))
+       {
+         if (x1 == x2)
+           return 1;
+         double eps = fabs(x2 * rel_eps);
+         if (eps < abs_eps)
+           eps = abs_eps;
+         return (fabs(x1-x2) <= eps);
+       }
+      // If they fail to convert, compare them as strings.
+    }
+  return !(ignore_case ? strcasecmp : strcmp)(t1->token, t2->token);
+}
 
 static int trailing_nl(struct tokenizer *t)
 {
@@ -25,12 +48,16 @@ static int trailing_nl(struct tokenizer *t)
 
 static void usage(void)
 {
-  fprintf(stderr, "Usage: judge-tok [<options>] <file1> <file2>\n\
+  fprintf(stderr, "Usage: judge-tok [<options>] <output> <correct>\n\
 \n\
 Options:\n\
 -n\t\tIgnore newlines\n\
 -t\t\tIgnore newlines at the end of file\n\
-");
+-i\t\tIgnore case\n\
+-r\t\tMatch tokens as real numbers and allow small differences:\n\
+-e <epsilon>\tSet maximum allowed relative error (default: %g)\n\
+-E <epsilon>\tSet maximum allowed absolute error (default: %g)\n\
+", rel_eps, abs_eps);
   exit(2);
 }
 
@@ -39,7 +66,7 @@ int main(int argc, char **argv)
   struct tokenizer t1, t2;
   int opt;
 
-  while ((opt = getopt(argc, argv, "nt")) >= 0)
+  while ((opt = getopt(argc, argv, "ntire:E:")) >= 0)
     switch (opt)
       {
       case 'n':
@@ -48,6 +75,18 @@ int main(int argc, char **argv)
       case 't':
        ignore_trailing_nl++;
        break;
+      case 'i':
+       ignore_case++;
+       break;
+      case 'r':
+       real_mode++;
+       break;
+      case 'e':
+       rel_eps = atof(optarg);
+       break;
+      case 'E':
+       abs_eps = atof(optarg);
+       break;
       default:
        usage();
       }
@@ -74,7 +113,7 @@ int main(int argc, char **argv)
            tok_err(&t2, "Garbage at the end");
          break;
        }
-      else if (strcmp(a, b))
+      else if (!tokens_equal(&t1, &t2))
        tok_err(&t1, "Found <%s>, expected <%s>", a, b);
     }