#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
#include <getopt.h>
#include <cdecl.h>
#include "test.h"
}
#define rerender(str, p, r) (rerender(str, #p, p, #r, r))
-int main(int argc, char **argv)
+static bool test_crossparse(const char *str, int mode)
{
char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
+ bool ret = false;
+
+ if (mode == MODE_ENGLISH) {
+ buf1 = rerender(str, cdecl_parse_english, cdecl_declare);
+ if (!buf1)
+ goto out;
+ buf2 = rerender(buf1, cdecl_parse_decl, cdecl_explain);
+ if (!buf2)
+ goto out;
+ buf3 = rerender(buf2, cdecl_parse_english, cdecl_declare);
+ if (!buf3)
+ goto out;
+ } else {
+ buf1 = rerender(str, cdecl_parse_decl, cdecl_explain);
+ if (!buf1)
+ goto out;
+ buf2 = rerender(buf1, cdecl_parse_english, cdecl_declare);
+ if (!buf2)
+ goto out;
+ buf3 = rerender(buf2, cdecl_parse_decl, cdecl_explain);
+ if (!buf3)
+ goto out;
+ }
+
+ if (!strcmp(buf1, buf3))
+ ret = true;
+out:
+ free(buf1);
+ free(buf2);
+ free(buf3);
+ return ret;
+}
+
+int main(int argc, char **argv)
+{
int opt, mode = MODE_CDECL;
int ret = EXIT_FAILURE;
return EXIT_FAILURE;
}
- if (mode == MODE_ENGLISH) {
- buf1 = rerender(argv[optind], cdecl_parse_english, cdecl_declare);
- if (!buf1)
- goto out;
- buf2 = rerender(buf1, cdecl_parse_decl, cdecl_explain);
- if (!buf2)
- goto out;
- buf3 = rerender(buf2, cdecl_parse_english, cdecl_declare);
- if (!buf3)
- goto out;
- } else {
- buf1 = rerender(argv[optind], cdecl_parse_decl, cdecl_explain);
- if (!buf1)
- goto out;
- buf2 = rerender(buf1, cdecl_parse_english, cdecl_declare);
- if (!buf2)
- goto out;
- buf3 = rerender(buf2, cdecl_parse_decl, cdecl_explain);
- if (!buf3)
- goto out;
+ for (int i = optind; i < argc; i++) {
+ if (!test_crossparse(argv[i], mode)) {
+ fprintf(stderr, "%s: failed cross-parse check of: %s\n",
+ progname, argv[i]);
+ return EXIT_FAILURE;
+ }
}
- if (!strcmp(buf1, buf3))
- ret = EXIT_SUCCESS;
-out:
- free(buf1);
- free(buf2);
- free(buf3);
- return ret;
+ return EXIT_SUCCESS;
}
crossparse=test/crossparse$EXEEXT
test -x $randomdecl || exit 77
+# Slow case: run tests one at a time to determine exactly which one failed.
+first_failed() {
+ ff_count=0
+
+ while test $# -gt 0
+ do
+ $crossparse "$1" 2>/dev/null || break
+ ff_count=`expr $ff_count + 1`
+ shift
+ done
+
+ echo "$ff_count"
+}
+
proc() {
result=pass
count=0
+ set x
while read decl
do
- count=`expr $count + 1`
- $crossparse "$decl" || { result=fail
- printf 'original input: %s\n' "$decl" 1>&2
- break
+ set "$@" "$decl"
+
+ # Accumulate tests in $@ and run them in batches to avoid
+ # significant startup costs.
+ if test $# -gt 25; then
+ shift
+ $crossparse "$@" || { result=fail
+ tmp_count=`first_failed "$@"`
+ count=`expr $count + $tmp_count`
+ break
}
+ count=`expr $count + $#`
+ set x
+ fi
done
+ shift
+ if test $# -gt 0 && test x"$result" = x"pass"; then
+ tmp_count=$#
+ $crossparse "$@" || { result=fail
+ tmp_count=`first_failed "$@"`
+ }
+ count=`expr $count + $tmp_count`
+ fi
+
echo "result=$result"
echo "count=$count"
}