X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=tools%2Fccanlint%2Ftests%2Fexamples_run.c;fp=tools%2Fccanlint%2Ftests%2Fexamples_run.c;h=3bdb655efcfb2fc3609392c0fef231ec8dff16d9;hp=0e473ca4050d142d1845563f3ea9a1e742f37629;hb=b87f63cb8228c8fcbf760defdcf9e4c332da7667;hpb=c3e9a05832ec5362bf108a7f1487aa4dcff96f99 diff --git a/tools/ccanlint/tests/examples_run.c b/tools/ccanlint/tests/examples_run.c index 0e473ca4..3bdb655e 100644 --- a/tools/ccanlint/tests/examples_run.c +++ b/tools/ccanlint/tests/examples_run.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -81,146 +82,108 @@ static bool scan_for(const void *ctx, const char *input, const char *fmt, ...) } static char *find_expect(struct ccan_file *file, - char **lines, char **input, bool *exact, + char **lines, char **input, + bool *contains, bool *whitespace, bool *error, unsigned *line) { - char *expect; - const char *fmt; + char *rest, *expect; + *error = false; for (; lines[*line]; (*line)++) { char *p = lines[*line] + strspn(lines[*line], " \t"); if (!strstarts(p, "//")) continue; p += strspn(p, "/ "); - foreach_ptr(fmt, - "given '%s', outputs '%s'", - "given '%s' outputs '%s'", - "given \"%s\", outputs \"%s\"", - "given \"%s\" outputs \"%s\"") { - if (scan_for(file, p, fmt, input, &expect)) { - *exact = true; - return expect; - } - } - - foreach_ptr(fmt, - "given '%s', output contains '%s'", - "given '%s' output contains '%s'", - "given \"%s\", output contains \"%s\"", - "given \"%s\" output contains \"%s\"") { - if (scan_for(file, p, fmt, input, &expect)) { - *exact = false; - return expect; - } - } - foreach_ptr(fmt, "outputs '%s'", "outputs \"%s\"") { - if (scan_for(file, p, fmt, &expect)) { - *input = cast_const(char *, ""); - *exact = true; - return expect; + /* With or without input? */ + if (strncasecmp(p, "given", strlen("given")) == 0) { + /* Must be of form */ + if (!scan_for(file, p, "given \"%s\" %s", input, &p)) { + *error = true; + return p; } + } else { + *input = NULL; } - foreach_ptr(fmt, - "given '%s', output contains '%s'", - "given '%s' output contains '%s'", - "given \"%s\", output contains \"%s\"", - "given \"%s\" output contains \"%s\"") { - if (scan_for(file, p, fmt, input, &expect)) { - *exact = false; - return expect; - } + if (scan_for(file, p, "outputs \"%s\"", &expect)) { + *whitespace = true; + *contains = false; + return expect; } - /* Unquoted versions... we can get this wrong! */ - foreach_ptr(fmt, - "given %s, outputs '%s'", - "given '%s', outputs %s", - "given %s, outputs \"%s\"", - "given \"%s\", outputs %s", - "given %s, outputs %s", - "given %s outputs '%s'", - "given '%s' outputs %s", - "given %s outputs \"%s\"", - "given \"%s\" outputs %s", - "given %s outputs %s") { - if (scan_for(file, p, fmt, input, &expect)) { - *exact = true; - return expect; - } + if (scan_for(file, p, "output contains \"%s\"", &expect)) { + *whitespace = true; + *contains = true; + return expect; } - foreach_ptr(fmt, - "given %s, output contains '%s'", - "given '%s', output contains %s", - "given %s, output contains \"%s\"", - "given \"%s\", output contains %s", - "given %s, output contains %s", - "given %s output contains '%s'", - "given '%s' output contains %s", - "given %s output contains \"%s\"", - "given \"%s\" output contains %s", - "given %s output contains %s") { - if (scan_for(file, p, fmt, input, &expect)) { - *exact = false; - return expect; - } + /* Whitespace-ignoring versions. */ + if (scan_for(file, p, "outputs %s", &expect)) { + *whitespace = false; + *contains = false; + return expect; } - foreach_ptr(fmt, - "outputs '%s'", - "outputs \"%s\"", - "outputs %s") { - if (scan_for(file, p, fmt, &expect)) { - *input = cast_const(char *, ""); - *exact = true; - return expect; - } + if (scan_for(file, p, "output contains %s", &expect)) { + *whitespace = false; + *contains = true; + return expect; } - foreach_ptr(fmt, - "output contains '%s'", - "output contains \"%s\"", - "output contains %s") { - if (scan_for(file, p, fmt, &expect)) { - *input = cast_const(char *, ""); - *exact = false; - return expect; - } + /* Other malformed line? */ + if (*input || !strncasecmp(p, "output", strlen("output"))) { + *error = true; + return p; } - } + } return NULL; } -static char *trim(char *string) -{ - while (strends(string, "\n")) - string[strlen(string)-1] = '\0'; - return string; -} - static char *unexpected(struct ccan_file *i, const char *input, - const char *expect, bool exact) + const char *expect, bool contains, bool whitespace) { char *output, *cmd; + const char *p; bool ok; unsigned int default_time = default_timeout_ms; - cmd = tal_fmt(i, "echo '%s' | %s %s", - input, i->compiled[COMPILE_NORMAL], input); + if (input) + cmd = tal_fmt(i, "echo '%s' | %s %s", + input, i->compiled[COMPILE_NORMAL], input); + else + cmd = tal_fmt(i, "%s", i->compiled[COMPILE_NORMAL]); output = run_with_timeout(i, cmd, &ok, &default_time); if (!ok) return tal_fmt(i, "Exited with non-zero status\n"); - if (exact) { - if (streq(output, expect) || streq(trim(output), expect)) + /* Substitute \n */ + while ((p = strstr(expect, "\\n")) != NULL) { + expect = tal_fmt(cmd, "%.*s\n%s", (int)(p - expect), expect, + p+2); + } + + if (!whitespace) { + /* Normalize to spaces. */ + expect = tal_strjoin(cmd, + tal_strsplit(cmd, expect, " \n\t", + STR_NO_EMPTY), + " ", STR_NO_TRAIL); + output = tal_strjoin(cmd, + tal_strsplit(cmd, output, " \n\t", + STR_NO_EMPTY), + " ", STR_NO_TRAIL); + } + + if (contains) { + if (strstr(output, expect)) return NULL; } else { - if (strstr(output, expect)) + if (streq(output, expect)) return NULL; } + return output; } @@ -237,21 +200,32 @@ static void run_examples(struct manifest *m, list_for_each(list, i, list) { char **lines, *expect, *input, *output; unsigned int linenum = 0; - bool exact; + bool contains, whitespace, error; lines = get_ccan_file_lines(i); - for (expect = find_expect(i, lines, &input, &exact, + for (expect = find_expect(i, lines, &input, + &contains, &whitespace, &error, &linenum); expect; linenum++, expect = find_expect(i, lines, &input, - &exact, &linenum)) { + &contains, &whitespace, + &error, &linenum)) { + if (error) { + score_file_error(score, i, linenum+1, + "Unparsable test line '%s'", + lines[linenum]); + score->pass = false; + break; + } + if (i->compiled[COMPILE_NORMAL] == NULL) continue; score->total++; - output = unexpected(i, input, expect, exact); + output = unexpected(i, input, expect, + contains, whitespace); if (!output) { score->score++; continue; @@ -259,7 +233,7 @@ static void run_examples(struct manifest *m, score_file_error(score, i, linenum+1, "output '%s' didn't %s '%s'\n", output, - exact ? "match" : "contain", + contains ? "contain" : "match", expect); score->pass = false; }