X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/e031b4f0220432aef6e1864ea6359353dbd8aed3..59c178a65021036c13ddd6bb2eaad18db071f4e9:/test/crossparse.c?ds=inline
diff --git a/test/crossparse.c b/test/crossparse.c
index 75344cb..e19b438 100644
--- a/test/crossparse.c
+++ b/test/crossparse.c
@@ -1,17 +1,38 @@
+/*
+ * Test that libcdecl can parse its own output.
+ * Copyright © 2012, 2020 Nick Bowler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#include
#include
#include
#include
+#include
+#include
#include
#include
#include "test.h"
#define PROGNAME "crossparse"
static const char *progname = PROGNAME;
-static const char sopts[] = "ECVH";
+static const char sopts[] = "f:ECVH";
static const struct option lopts[] = {
{ "cdecl", 0, NULL, 'C' },
{ "english", 0, NULL, 'E' },
+ { "file", 2, NULL, 'f' },
{ "version", 0, NULL, 'V' },
{ "help", 0, NULL, 'H' },
{ 0 }
@@ -24,8 +45,11 @@ static void print_usage(FILE *f)
static void print_help(void)
{
+ const struct option *opt;
+
print_usage(stdout);
- puts("Detailed help coming soon.");
+ puts("Test that libcdecl can parse its own output.\n");
+ test_print_options(lopts);
}
enum {
@@ -69,11 +93,55 @@ err:
}
#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);
+
+ if (!ret) {
+ fprintf(stderr, "%s: failed cross-parse check of: %s\n",
+ progname, str);
+ }
+
+ return ret;
+}
+
+int main(int argc, char **argv)
+{
int opt, mode = MODE_CDECL;
- int ret = EXIT_FAILURE;
+ int ret = EXIT_SUCCESS;
+
+ const char *filename = NULL;
+ FILE *infile = NULL;
if (argc > 0)
progname = argv[0];
@@ -86,6 +154,10 @@ int main(int argc, char **argv)
case 'E':
mode = MODE_ENGLISH;
break;
+ case 'f':
+ infile = stdin;
+ filename = optarg;
+ break;
case 'V':
test_print_version(PROGNAME);
return EXIT_SUCCESS;
@@ -98,38 +170,35 @@ int main(int argc, char **argv)
}
}
- if (!argv[optind]) {
- print_usage(stderr);
- return EXIT_FAILURE;
- }
+ if (infile) {
+ char *line = NULL;
+ size_t n;
+
+ if (filename) {
+ infile = fopen(filename, "r");
+ if (!infile) {
+ fprintf(stderr, "%s: %s: %s\n", progname,
+ filename, strerror(errno));
+ 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;
+ while (getline(&line, &n, infile) >= 0) {
+ char *c = strchr(line, '\n');
+ if (c)
+ *c = '\0';
+ if (!test_crossparse(line, mode))
+ ret = EXIT_FAILURE;
+ }
+ } else if (argv[optind]) {
+ for (int i = optind; i < argc; i++) {
+ if (!test_crossparse(argv[i], mode))
+ ret = EXIT_FAILURE;
+ }
} 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;
+ print_usage(stderr);
+ return EXIT_FAILURE;
}
- if (!strcmp(buf1, buf3))
- ret = EXIT_SUCCESS;
-out:
- free(buf1);
- free(buf2);
- free(buf3);
return ret;
}