123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574 |
- #! /usr/bin/gawk -f
- # checkmk/checkmk. Generated from checkmk.in by configure.
- # checkmk - translate more concise versions of test suite specifications
- # into C programs suitable for use with the Check unit test
- # framework.
- # -- LICENSE --
- #
- # Written by Micah Cowan <micah@cowan.name>
- # Copyright (c) 2006, 2010 Micah Cowan
- #
- # Redistribution of this program in any form, with or without
- # modifications, is permitted, provided that the above copyright is
- # retained in distributions of this program in source form.
- #
- # (This is a free, non-copyleft license compatible with pretty much any
- # other free or proprietary license, including the GPL. It's essentially
- # a scaled-down version of the "modified" BSD license.)
- BEGIN {
- progname="checkmk";
- is_stdin=0;
- outfname="/dev/stdout";
- # Tokens
- pp_ws = "[ \t\f\v\r\n]+";
- pp_ws_op = "[ \t\f\v\r\n]*";
- pp_digit = "[0-9]+"
- pp_prefix = pp_ws_op "#" pp_ws_op;
- pp_sep = "[ \t\f\v\r\n]+";
- pp_name = ".+";
- pp_hex_quad = "[A-F0-9a-f][A-F0-9a-f][A-F0-9a-f][A-F0-9a-f]"
- pp_ucn = "\\\\(u" pp_hex_quad "|U" pp_hex_quad pp_hex_quad ")";
- pp_test_name = "([A-Za-z_]|" pp_ucn ")([A-Za-z0-9_]|" pp_ucn ")*";
- pp_tag = "([Ss][Uu][Ii][Tt][Ee]|[Tt][Cc][Aa][Ss][Ee])";
- pp_test_tag = "[Tt][Ee][Ss][Tt]";
- pp_main_pre_tag = "[Mm][Aa][Ii][Nn]-[Pp][Rr][Ee]";
- pp_main_post_tag = "[Mm][Aa][Ii][Nn]-[Pp][Oo][Ss][Tt]";
- # Tests with arguments
- pp_test_exit_tag = "[Tt][Ee][Ss][Tt]-[Ee][Xx][Ii][Tt]" pp_ws_op "[(]" \
- pp_ws_op "[+-]?" pp_ws_op pp_digit pp_ws_op "[)]";
- pp_test_signal_tag = "[Tt][Ee][Ss][Tt]-[Ss][Ii][Gg][Nn][Aa][Ll]" pp_ws_op \
- "[(]" pp_ws_op "[+-]?" pp_ws_op pp_digit pp_ws_op "[)]";
- pp_test_loop_tag = "[Tt][Ee][Ss][Tt]-[Ll][Oo][Oo][Pp]" pp_ws_op "[(]" \
- pp_ws_op "[+-]?" pp_ws_op pp_digit pp_ws_op "[,]" pp_ws_op \
- "[+-]?" pp_ws_op pp_digit pp_ws_op "[)]";
- pp_test_loop_exit_tag = "[Tt][Ee][Ss][Tt]-[Ll][Oo][Oo][Pp]-[Ee][Xx][Ii][Tt]" \
- pp_ws_op "[(]" pp_ws_op "[+-]?" pp_ws_op pp_digit pp_ws_op \
- "[,]" pp_ws_op "[+-]?" pp_ws_op pp_digit pp_ws_op "[,]" \
- pp_ws_op "[+-]?" pp_ws_op pp_digit pp_ws_op "[)]";
- pp_test_loop_signal_tag = "[Tt][Ee][Ss][Tt]-[Ll][Oo][Oo][Pp]-[Ss][Ii][Gg]" \
- "[Nn][Aa][Ll]" pp_ws_op "[(]" pp_ws_op "[+-]?" pp_ws_op pp_digit \
- pp_ws_op "[,]" pp_ws_op "[+-]?" pp_ws_op pp_digit pp_ws_op \
- "[,]" pp_ws_op "[+-]?" pp_ws_op pp_digit pp_ws_op "[)]";
- pp_suite_or_tcase_line = "^" pp_prefix pp_tag pp_ws pp_name "$";
- pp_test_line_prefix = "^" pp_prefix pp_test_tag pp_ws;
- pp_test_exit_line_prefix = "^" pp_prefix pp_test_exit_tag pp_ws;
- pp_test_signal_line_prefix = "^" pp_prefix pp_test_signal_tag pp_ws;
- pp_test_loop_line_prefix = "^" pp_prefix pp_test_loop_tag pp_ws;
- pp_test_loop_exit_line_prefix = "^" pp_prefix pp_test_loop_exit_tag pp_ws;
- pp_test_loop_signal_line_prefix = "^" pp_prefix pp_test_loop_signal_tag pp_ws;
- pp_test_line = pp_test_line_prefix pp_name pp_ws_op "$";
- pp_test_exit_line = pp_test_exit_line_prefix pp_name pp_ws_op "$";
- pp_test_signal_line = pp_test_signal_line_prefix pp_name pp_ws_op "$";
- pp_test_loop_line = pp_test_loop_line_prefix pp_name pp_ws_op "$";
- pp_test_loop_exit_line = pp_test_loop_exit_line_prefix pp_name pp_ws_op "$";
- pp_test_loop_signal_line = pp_test_loop_signal_line_prefix pp_name pp_ws_op "$";
- pp_main_pre_line = "^" pp_prefix pp_main_pre_tag pp_ws_op "$";
- pp_main_post_line = "^" pp_prefix pp_main_post_tag pp_ws_op "$";
- # Global vars
- in_test = needs_line_decl = 0;
- cur_suite = cur_tcase = "Core";
- cur_test = "";
- exit_okay = start = 1;
- num_cur_tcases = num_cur_tests = 0;
- test_type = num_tests = 0;
- arg1 = 0;
- arg2 = 1;
- arg3 = 2;
- test_name = 0;
- test_type_flag = 1;
- }
- # Run on the first line of the input file.
- start {
- print_boilerplate();
- start = 0;
- }
- # (Executed every line:)
- {
- print_line = 1;
- }
- $0 ~ pp_suite_or_tcase_line {
- if (in_main())
- in_main_error();
- # Skip to the start of the tag ("suite" or "tcase").
- match($0, pp_prefix);
- rol = substr($0, RLENGTH+1);
- # Save away the tag.
- match(rol, "^" pp_tag);
- tag = substr(rol, 1, RLENGTH);
- # Advance past the ws following tag.
- rol = substr(rol, RLENGTH+1);
- match(rol, pp_ws);
- rol = substr(rol, RLENGTH+1);
- # The suite or tcase name is the rest of the line, minus any
- # trailing ws.
- if (match(rol, pp_ws "$")) {
- name = substr(rol, 1, RSTART-1);
- } else {
- name = rol;
- }
- if (tolower(tag) == "suite") {
- # Does this suite already exist?
- if ((name, 0) in suite_tcase_map) {
- error_with_line("Suite \"" name "\" already exists.");
- }
- cur_suite = name;
- num_cur_tcases = 0;
- }
- else if ((name, 0, 0) in tcase_test_map) {
- error_with_line("Test Case \"" name "\" already exists.");
- }
- cur_tcase = name;
- num_cur_tests = 0;
- finish_test();
- print_line = 0;
- if (!clean_mode)
- needs_line_decl = 1;
- }
- $0 ~ pp_test_line {
- # Pre checks
- test_pre();
- # Get the test name
- match($0, pp_test_line_prefix)
- cur_test = substr($0, RLENGTH+1);
- # Remove trailing ws.
- sub(pp_ws_op "$", "", cur_test);
- # Check for duplicate tests / cases and valid names
- duplicate_check();
- # Boilerplate printing code
- test_post();
- # Set type before calling register
- test_type = 0;
- register_test();
- print_line = 0;
- in_test = 1;
- }
- $0 ~ pp_test_loop_line {
- test_pre();
- match($0, pp_test_loop_line_prefix)
- cur_test = substr($0, RLENGTH+1);
- sub(pp_ws_op "$", "", cur_test);
- duplicate_check();
- # Split the line into an array to extract the arguments
- split($0, arr, pp_ws_op "[(),]" pp_ws_op);
- # Eliminate possible whitespace between sign and numbers
- gsub(pp_ws_op, "", arr[2]);
- gsub(pp_ws_op, "", arr[3]);
- test_post();
- test_type = 1;
- register_test();
- print_line = 0;
- in_test = 1;
- }
- $0 ~ pp_test_exit_line {
- test_pre();
- match($0, pp_test_exit_line_prefix)
- cur_test = substr($0, RLENGTH+1);
- sub(pp_ws_op "$", "", cur_test);
- duplicate_check();
- split($0, arr, pp_ws_op "[(),]" pp_ws_op);
- gsub(pp_ws_op, "", arr[2]);
- test_post();
- test_type = 2;
- register_test();
- print_line = 0;
- in_test = 1;
- }
- $0 ~ pp_test_signal_line {
- test_pre();
- match($0, pp_test_signal_line_prefix)
- cur_test = substr($0, RLENGTH+1);
- sub(pp_ws_op "$", "", cur_test);
- duplicate_check();
- split($0, arr, pp_ws_op "[(),]" pp_ws_op);
- gsub(pp_ws_op, "", arr[2]);
- test_post();
- test_type = 3;
- register_test();
- print_line = 0;
- in_test = 1;
- }
- $0 ~ pp_test_loop_exit_line {
- test_pre();
- match($0, pp_test_loop_exit_line_prefix)
- cur_test = substr($0, RLENGTH+1);
- sub(pp_ws_op "$", "", cur_test);
- duplicate_check();
- split($0, arr, pp_ws_op "[(),]" pp_ws_op);
- gsub(pp_ws_op, "", arr[2]);
- gsub(pp_ws_op, "", arr[3]);
- gsub(pp_ws_op, "", arr[4]);
- test_post();
- test_type = 4;
- register_test();
- print_line = 0;
- in_test = 1;
- }
- $0 ~ pp_test_loop_signal_line {
- test_pre();
- match($0, pp_test_loop_signal_line_prefix)
- cur_test = substr($0, RLENGTH+1);
- sub(pp_ws_op "$", "", cur_test);
- duplicate_check();
- split($0, arr, pp_ws_op "[(),]" pp_ws_op);
- gsub(pp_ws_op, "", arr[2]);
- gsub(pp_ws_op, "", arr[3]);
- gsub(pp_ws_op, "", arr[4]);
- test_post();
- test_type = 5;
- register_test();
- print_line = 0;
- in_test = 1;
- }
- $0 ~ pp_main_pre_line {
- main_pre();
- print "";
- print " /* User-specified pre-run code */";
- if (!clean_mode)
- needs_line_decl = 1;
- print_line = 0;
- }
- $0 ~ pp_main_post_line {
- main_post();
- print "";
- print " /* User-specified post-run code */";
- if (!clean_mode)
- needs_line_decl = 1;
- print_line = 0;
- }
- print_line {
- if (/[^ \t\f\v\r\n]/ && needs_line_decl && !clean_mode) {
- print "#line " FNR;
- needs_line_decl = 0;
- }
- print;
- }
- END {
- if (!exit_okay) {
- # We're exiting due to an error. Don't do anything else.
- }
- else if (num_tests) {
- if (!main_post_done) {
- main_post();
- print "";
- print " return nf == 0 ? 0 : 1;";
- }
- print "}";
- }
- else {
- error("Expected at least one #test line.");
- }
- }
- ### Functions ###
- function test_pre()
- {
- if (in_main())
- in_main_error();
- if (in_test) {
- finish_test();
- print "";
- }
- ++num_tests;
- }
- function duplicate_check()
- {
- # Confirm that the test name is a valid C identifier.
- if (!match(cur_test, "^" pp_test_name "$")) {
- error_with_line("Malformed test name \"" cur_test \
- "\" (must be a C identifier).");
- }
- # Verify that it has not already been used.
- if (cur_test in test_registry) {
- error_with_line("Test \"" cur_test "\" already exists.");
- }
- # Verify that any implied test case is not a repeat.
- if (num_cur_tests == 0 && (cur_tcase, 0, 0) in tcase_test_map) {
- error_with_line("Test Case \"" name "\" already exists.");
- }
- }
- function test_post()
- {
- print "START_TEST(" cur_test ")";
- print "{";
- if (!clean_mode)
- print "#line " FNR+1;
- needs_line_decl = 0;
- }
- function main_post()
- {
- if (main_post_done)
- error_with_line("main-post specified multiple times.");
- if (!main_pre_done)
- main_pre();
- main_post_done = 1;
- print "";
- print_runner_bindings();
- print "";
- print " srunner_run_all(sr, CK_ENV);";
- print " nf = srunner_ntests_failed(sr);";
- print " srunner_free(sr);";
- }
- function in_main()
- {
- return main_pre_done || main_post_done;
- }
- function in_main_error()
- {
- error_with_line("Cannot specify tests after main-pre or main-post.");
- }
- function main_pre()
- {
- if (main_post_done)
- error_with_line("main-pre specified after main-post.");
- if (main_pre_done)
- error_with_line("main-pre specified multiple times.");
- main_pre_done = 1;
- finish_test();
- print "";
- print "int main(void)";
- print "{";
- print_main_declarations();
- }
- function suite_var_name(num)
- {
- return "s" num+1;
- }
- function tcase_var_name(snum, tcnum)
- {
- return "tc" snum+1 "_" tcnum+1;
- }
- function print_main_declarations()
- {
- for (i=0; i != num_suites; ++i) {
- s = suite_names[i];
- svar = suite_var_name(i);
- print " Suite *" svar " = suite_create(" string_encode(s) ");";
- for (j=0; j != suite_num_tcases[s]; ++j) {
- tc = suite_tcase_map[s, j];
- tcvar = tcase_var_name(i, j);
- print " TCase *" tcvar " = tcase_create(" \
- string_encode(tc) ");";
- }
- }
- print " SRunner *sr = srunner_create(s1);";
- print " int nf;";
- }
- function string_encode(raw)
- {
- # The next line might look funny, but remember that the first
- # argument will go through both string interpolation /and/ regex
- # interpolation, so the backslashes must be double-escaped. The
- # substitution string is supposed to result in an actual
- # double-backslash.
- gsub("\\\\", "\\\\", raw);
- gsub("\"", "\\\"", raw);
- return "\"" raw "\"";
- }
- function print_runner_bindings()
- {
- for (i=0; i != num_suites; ++i) {
- s = suite_names[i];
- svar = suite_var_name(i);
- for (j=0; j != suite_num_tcases[s]; ++j) {
- tc = suite_tcase_map[s, j];
- tcvar = tcase_var_name(i, j);
- print " suite_add_tcase(" svar ", " tcvar ");";
- for (k=0; k != tcase_num_tests[tc]; ++k) {
- t = tcase_test_map[tc, k, test_name];
- test_type = tcase_test_map[tc, k, test_type_flag];
- if (test_type == 0) {
- print " tcase_add_test(" tcvar ", " t ");";
- }
- else if (test_type == 1) {
- print " tcase_add_loop_test(" tcvar ", " t ", " \
- test_parameters[t, arg1] ", " test_parameters[t, arg2] \
- ");";
- }
- else if (test_type == 2) {
- print " tcase_add_exit_test(" tcvar ", " t ", " \
- test_parameters[t, arg1] ");";
- }
- else if (test_type == 3) {
- print " tcase_add_test_raise_signal(" tcvar ", " t ", " \
- test_parameters[t, arg1] ");";
- }
- else if (test_type == 4) {
- print " tcase_add_loop_exit_test(" tcvar ", " t ", " \
- test_parameters[t, arg1] ", " test_parameters[t, arg2] \
- ", " test_parameters[t, arg3] ");";
- }
- else if (test_type == 5) {
- print " tcase_add_loop_test_raise_signal(" tcvar ", " t \
- ", " test_parameters[t, arg1] ", " test_parameters[t, arg2] \
- ", " test_parameters[t, arg3] ");";
- }
- }
- }
- }
- if (num_suites > 1) {
- print "";
- for (i=1; i != num_suites; ++i) {
- svar = suite_var_name(i);
- print " srunner_add_suite(sr, " svar ");";
- }
- }
- }
- function register_test()
- {
- if (num_cur_tcases == 0) {
- suite_names[num_suites++] = cur_suite;
- }
- if (num_cur_tests == 0) {
- suite_tcase_map[cur_suite, num_cur_tcases++] = cur_tcase;
- suite_num_tcases[cur_suite] = num_cur_tcases;
- }
- tcase_test_map[cur_tcase, num_cur_tests, test_name] = cur_test;
- tcase_test_map[cur_tcase, num_cur_tests++, test_type_flag] = test_type;
- tcase_num_tests[cur_tcase] = num_cur_tests;
- test_registry[cur_test] = 1;
- # Store arguments to array
- test_parameters[cur_test, arg1] = arr[2];
- test_parameters[cur_test, arg2] = arr[3];
- test_parameters[cur_test, arg3] = arr[4];
- }
- function finish_test()
- {
- if (in_test) {
- in_test = 0;
- print "}";
- print "END_TEST";
- }
- }
- function print_boilerplate()
- {
- print "/*";
- print " * DO NOT EDIT THIS FILE. Generated by " progname ".";
- if (!FILENAME || FILENAME == "-") {
- clean_mode=1;
- is_stdin=1;
- }
- if (is_stdin)
- srcfile = "(standard input)";
- else
- srcfile = "\"" FILENAME "\"";
- print " * Edit the original source file " srcfile " instead.";
- print " */";
- print "";
- print "#include <check.h>";
- print "";
- if (!clean_mode)
- print "#line 1 " string_encode(FILENAME)
- }
- function error_with_line(err)
- {
- error((is_stdin ? "(standard input)" : FILENAME) " line " FNR ": " err);
- }
- function error(err)
- {
- print progname ": " err > "/dev/stderr";
- exit_okay = 0;
- exit 1;
- }
|