/*!@file \brief APC test driver \details This driver does what APC does, but in staggered stages with additional debugging information \author Jordan Lavatai \date Aug 2016 ----------------------------------------------------------------------------*/ /* Standard */ #include //print #include //errors #include //strnlen #include //non-local jumps /* Posix */ #include //exit #include //getopt /* Internal */ #include "parser.tab.h" //bison #include "ir.h" //ir /* Import apc.c but redefine its primary symbols for jumping */ #define main apc_main #define yyparse testapc_yyparse #include "apc.c" #undef yyparse #undef main int main(int, char*[]); int testapc_yyparse(void); int test_yyparse(void); extern //bison int yyparse(void); extern //lexer.c int lexer_init(void); extern //scanner.c int scanner_init(void); extern //apc.c const char* cargs['Z']; extern //apc/parser.tab.c YYSTYPE yylval; extern //lexer.c int lexer(void); static jmp_buf testapc_jump; /* Ansi Term Colors */ #define RED "\x1b[31m" #define GREEN "\x1b[32m" #define YELLOW "\x1b[33m" #define BLUE "\x1b[34m" #define MAGENTA "\x1b[35m" #define CYAN "\x1b[36m" #define CLRC "\x1b[0m" //clear current color /* Main entry from terminal parses debugging options for testing apc, and calls apc_main */ int main ( int argc, char* argv[] ) { setjmp(testapc_jump); apc_main(argc, argv); printf(GREEN "PASS" CLRC "\n"); exit(EXIT_SUCCESS); } #define MAX_TOK 1024 char tok_lval[MAX_TOK]; /* yyparse intercept tests yyparse internally, then resets the scanner and runs bison's 'yyparse' implementation after validating it with 'test_yyparse'. */ int testapc_yyparse #ifndef YYABORT #define YYABORT 1 #endif () { static char bPassedTest = 'f'; if (bPassedTest == 'f') { if (test_yyparse()) { printf("Parse test aborted\n"); return YYABORT; } bPassedTest = 't'; longjmp(testapc_jump,0); } return yyparse(); } /* test_yyparse runs 'lexer' 'PASSES' times, or until finished */ int test_yyparse #define PASSES 1000 () { int i, tok; static char* tok_string; static char tok_pattern[] = "[" RED " %9s " CLRC "][" CYAN " %-12i " CLRC "]"; for (i = 0; i < PASSES; i++) { switch (tok = lexer()) #define TOFFS 9 #define LOFFS 27 #define $($)#$ #define TOK_CASE(T,C) \ case T: \ tok_string = $(T); \ tok_pattern[LOFFS] = C; \ break { TOK_CASE(NAME,'s'); TOK_CASE(REF,'x'); TOK_CASE(NUM,'i'); TOK_CASE(SS,'i'); TOK_CASE(CLOPEN,'i'); TOK_CASE(CLCLOSE,'i'); default: tok_string = 0; tok_pattern[LOFFS] = 'i'; break; case 0: goto done; } if (tok_string == NULL) { tok_pattern[TOFFS] = 'i'; printf(tok_pattern, tok, yylval.val); } else { tok_pattern[TOFFS] = 's'; printf(tok_pattern, tok_string, yylval.val); } if (i % 4 == 0 || yylval.val == 0) printf(";\n"); } done: printf(";\n" GREEN "Done" CLRC ".\n"); return 0; #if 0 error: printf(";\n" RED "FAILED" CLRC ".\n"); return -1; #endif }