comments updated
[henge/apc.git] / src / testapc.c
1 /*!@file
2 \brief APC test driver
3 \details This driver does what APC does, but in staggered stages with
4 additional debugging information
5 \author Jordan Lavatai
6 \date Aug 2016
7 ----------------------------------------------------------------------------*/
8 /* Standard */
9 #include <stdio.h> //print
10 #include <errno.h> //errors
11 #include <string.h> //strnlen
12 #include <setjmp.h> //non-local jumps
13 /* Posix */
14 #include <stdlib.h> //exit
15 #include <unistd.h> //getopt
16 /* Internal */
17 #include "parser.tab.h" //bison
18 #include "ir.h" //ir
19
20 /* Import apc.c but redefine its primary symbols for jumping */
21 #define main apc_main
22 #define yyparse testapc_yyparse
23 #include "apc.c"
24 #undef yyparse
25 #undef main
26
27 int main(int, char*[]);
28 int testapc_yyparse(void);
29 int test_yyparse(void);
30
31 extern //bison
32 int yyparse(void);
33 extern //lexer.c
34 int lexer_init(void);
35 extern //scanner.c
36 int scanner_init(void);
37 extern //apc.c
38 const char* cargs['Z'];
39
40 extern //apc/parser.tab.c
41 YYSTYPE yylval;
42 extern //lexer.c
43 int lexer(void);
44
45 static
46 jmp_buf testapc_jump;
47
48 /* Ansi Term Colors */
49 #define RED "\x1b[31m"
50 #define GREEN "\x1b[32m"
51 #define YELLOW "\x1b[33m"
52 #define BLUE "\x1b[34m"
53 #define MAGENTA "\x1b[35m"
54 #define CYAN "\x1b[36m"
55 #define CLRC "\x1b[0m" //clear current color
56
57 /* Main entry from terminal
58 parses debugging options for testing apc, and calls apc_main
59 */
60 int main
61 ( int argc,
62 char* argv[]
63 )
64 { setjmp(testapc_jump);
65 apc_main(argc, argv);
66 printf(GREEN "PASS" CLRC "\n");
67 exit(EXIT_SUCCESS);
68 }
69
70 #define MAX_TOK 1024
71 char tok_lval[MAX_TOK];
72
73 /* yyparse intercept
74 tests yyparse internally, then resets the scanner and runs bison's 'yyparse'
75 implementation after validating it with 'test_yyparse'.
76 */
77 int testapc_yyparse
78 #ifndef YYABORT
79 #define YYABORT 1
80 #endif
81 ()
82 { static char bPassedTest = 'f';
83 if (bPassedTest == 'f')
84 { if (test_yyparse())
85 { printf("Parse test aborted\n");
86 return YYABORT;
87 }
88 bPassedTest = 't';
89 longjmp(testapc_jump,0);
90 }
91 return yyparse();
92 }
93
94 /* test_yyparse
95 runs 'lexer' 'PASSES' times, or until finished
96 */
97 int test_yyparse
98 #define PASSES 1000
99 ()
100 { int i, tok;
101 static char* tok_string;
102 static char tok_pattern[] = "[" RED " %9s " CLRC "][" CYAN " %-12i " CLRC "]";
103 for (i = 0; i < PASSES; i++)
104 { switch (tok = lexer())
105 #define TOFFS 9
106 #define LOFFS 27
107 #define $($)#$
108 #define TOK_CASE(T,C) \
109 case T: \
110 tok_string = $(T); \
111 tok_pattern[LOFFS] = C; \
112 break
113 { TOK_CASE(NAME,'s');
114 TOK_CASE(REF,'x');
115 TOK_CASE(NUM,'i');
116 TOK_CASE(SS,'i');
117 TOK_CASE(CLOPEN,'i');
118 TOK_CASE(CLCLOSE,'i');
119 default:
120 tok_string = 0;
121 tok_pattern[LOFFS] = 'i';
122 break;
123 case 0:
124 goto done;
125 }
126 if (tok_string == NULL)
127 { tok_pattern[TOFFS] = 'i';
128 printf(tok_pattern, tok, yylval.val);
129 }
130 else
131 { tok_pattern[TOFFS] = 's';
132 printf(tok_pattern, tok_string, yylval.val);
133 }
134 if (i % 4 == 0 || yylval.val == 0)
135 printf(";\n");
136 }
137 done:
138 printf(";\n" GREEN "Done" CLRC ".\n");
139 return 0;
140 #if 0
141 error:
142 printf(";\n" RED "FAILED" CLRC ".\n");
143 return -1;
144 #endif
145 }