1 #ifdef RCSID
2 static char RCSid[] =
3 "$Header: d:/cvsroot/tads/tads3/test/test_prs_top.cpp,v 1.1 1999/07/11 00:47:03 MJRoberts Exp $";
4 #endif
5
6 /*
7 * Copyright (c) 1999, 2002 Michael J. Roberts. All Rights Reserved.
8 *
9 * Please see the accompanying license file, LICENSE.TXT, for information
10 * on using and copying this software.
11 */
12 /*
13 Name
14 test_prs.cpp - parser test: test parsing from the top level
15 Function
16
17 Notes
18
19 Modified
20 05/01/99 MJRoberts - Creation
21 */
22
23 #include <stdlib.h>
24 #include <stdio.h>
25
26 #include "os.h"
27 #include "t3std.h"
28 #include "tctok.h"
29 #include "resload.h"
30 #include "tcmain.h"
31 #include "tchostsi.h"
32 #include "tcglob.h"
33 #include "tcprs.h"
34 #include "tctarg.h"
35 #include "vmfile.h"
36 #include "tcunas.h"
37 #include "tct3unas.h"
38 #include "tcmake.h"
39 #include "vmimage.h"
40 #include "vmrunsym.h"
41 #include "t3test.h"
42
43
errexit(const char * msg)44 static void errexit(const char *msg)
45 {
46 printf("%s\n", msg);
47 exit(1);
48 }
49
main(int argc,char ** argv)50 int main(int argc, char **argv)
51 {
52 CResLoader *res_loader;
53 CTcHostIfc *hostifc;
54 int curarg;
55 int fatal_error_count = 0;
56 osfildef *fpout = 0;
57 CVmFile *imgfile = 0;
58 CTcUnasSrcCodeStr *unas_in;
59 CTcUnasOutStdio unas_out;
60 CTPNStmProg *node;
61 const char *image_fname;
62 int success;
63 int unasm = FALSE;
64 uchar xor_mask = 0;
65 char pathbuf[OSFNMAX];
66
67 /* initialize for testing */
68 test_init();
69
70 /* create the host interface object */
71 hostifc = new CTcHostIfcStdio();
72
73 /* create a resource loader */
74 os_get_special_path(pathbuf, sizeof(pathbuf), argv[0], OS_GSP_T3_RES);
75 res_loader = new CResLoader(pathbuf);
76
77 /* initialize the compiler */
78 CTcMain::init(hostifc, res_loader, "us-ascii");
79
80 /* use test reporting mode */
81 G_tok->set_test_report_mode(TRUE);
82 G_tcmain->set_test_report_mode(TRUE);
83
84 /* create the disassembler input stream */
85 unas_in = new CTcUnasSrcCodeStr(G_cs);
86
87 err_try
88 {
89 static const char tool_data[4] = { 't', 's', 't', 'P' };
90
91 /* scan options */
92 for (curarg = 1 ; curarg < argc ; ++curarg)
93 {
94 char *p;
95
96 /* get the argument string for easy reference */
97 p = argv[curarg];
98
99 /* if it's not an option, we're done */
100 if (*p != '-')
101 break;
102
103 /* if it's a -I argument, use it */
104 if (*(p + 1) == 'I')
105 {
106 char *path;
107
108 /*
109 * if it's with this argument, read it, otherwise move
110 * on to the next argument
111 */
112 if (*(p + 2) == '\0')
113 path = argv[++curarg];
114 else
115 path = p + 2;
116
117 /* add the directory to the include path list */
118 G_tok->add_inc_path(path);
119 }
120 else if (*(p + 1) == 'v')
121 {
122 /* set verbose mode */
123 G_tcmain->set_verbosity(TRUE);
124 }
125 else if (*(p + 1) == 'u')
126 {
127 /* note unassembly mode */
128 unasm = TRUE;
129 }
130 else
131 {
132 /*
133 * invalid usage - consume all the arguments and fall
134 * through to the usage checker
135 */
136 curarg = argc;
137 break;
138 }
139 }
140
141 /* check arguments */
142 if (curarg + 2 != argc)
143 {
144 /* terminate the compiler */
145 CTcMain::terminate();
146
147 /* delete our objects */
148 delete res_loader;
149
150 /* exit with an error */
151 errexit("usage: test_prs [options] <source-file> <image-file>\n"
152 "options:\n"
153 " -Idir - add dir to include path\n"
154 " -v - verbose error messages");
155 }
156
157 /* add the default system include directory to the include path */
158 os_get_special_path(pathbuf, sizeof(pathbuf), argv[0], OS_GSP_T3_INC);
159 G_tok->add_inc_path(pathbuf);
160
161 /* set up the tokenizer with the main input file */
162 if (G_tok->set_source(argv[curarg], argv[curarg]))
163 errexit("unable to open source file");
164
165 /* set up an output file */
166 image_fname = argv[curarg+1];
167 fpout = osfopwb(image_fname, OSFTT3IMG);
168 if (fpout == 0)
169 errexit("unable to open image file");
170 imgfile = new CVmFile();
171 imgfile->set_file(fpout, 0);
172
173 /* read the first token */
174 G_tok->next();
175
176 /* parse at the top level */
177 node = G_prs->parse_top();
178
179 /* if errors occurred during parsing, stop here */
180 if (G_tcmain->get_error_count() != 0 || node == 0)
181 goto done;
182
183 /* fold symbolic constants for all nodes */
184 node->fold_constants(G_prs->get_global_symtab());
185
186 /* if errors occurred during constant folding, stop now */
187 if (G_tcmain->get_error_count() != 0)
188 goto done;
189
190 /* generate code and write the image file */
191 node->build_image(imgfile, xor_mask, tool_data);
192
193 /* if errors occurred during code generation, stop now */
194 if (G_tcmain->get_error_count() != 0)
195 goto done;
196
197 /* disassemble the result if desired */
198 if (unasm)
199 CTcT3Unasm::disasm(unas_in, &unas_out);
200
201 done: ;
202 }
203 err_catch(exc)
204 {
205 /*
206 * if it's not a general internal or fatal error, log it; don't
207 * log general errors, since these will have been logged as
208 * specific internal errors before being thrown
209 */
210 if (exc->get_error_code() != TCERR_INTERNAL_ERROR
211 && exc->get_error_code() != TCERR_FATAL_ERROR)
212 G_tok->log_error(TC_SEV_FATAL, exc->get_error_code());
213
214 /* count the fatal error */
215 ++fatal_error_count;
216 }
217 err_end;
218
219 /* report errors */
220 fprintf(stderr,
221 "Warnings: %d\n"
222 "Errors: %d\n"
223 "Longest string: %d, longest list: %d\n",
224 G_tcmain->get_warning_count(),
225 G_tcmain->get_error_count() + fatal_error_count,
226 G_cg->get_max_str_len(), G_cg->get_max_list_cnt());
227
228 /*
229 * note whether or not the compilation was successful - it succeeded
230 * if we had no errors or fatal errors
231 */
232 success = (G_tcmain->get_error_count() + fatal_error_count == 0);
233
234 /* delete the image file object (this closes the file) */
235 delete imgfile;
236
237 /*
238 * if any errors occurred, delete the image file in the external
239 * file system - this prevents us from leaving around an incomplete
240 * or corrupted image file when compilation fails, and helps
241 * 'make'-type tools realize that they must generate the image file
242 * target again on the next build, even if source files didn't
243 * change
244 */
245 if (!success)
246 osfdel(image_fname);
247
248 /* delete the disassembler input object */
249 delete unas_in;
250
251 /* shut down the compiler */
252 CTcMain::terminate();
253
254 /* done with the res loader */
255 delete res_loader;
256
257 /* delete the host interface */
258 delete hostifc;
259
260 /* show any unfreed memory */
261 t3_list_memory_blocks(0);
262
263 /*
264 * terminate - exit with a success indication if we had no errors
265 * (other than warnings); exit with an error indication otherwise
266 */
267 return (success ? OSEXSUCC : OSEXFAIL);
268 }
269
270 /*
271 * dummy 'make' object implementation
272 */
write_build_config_to_sym_file(class CVmFile *)273 void CTcMake::write_build_config_to_sym_file(class CVmFile *)
274 {
275 }
276
277 /* ------------------------------------------------------------------------ */
278 /*
279 * dummy implementation of runtime symbol table
280 */
add_sym(const char *,size_t,const vm_val_t *)281 void CVmRuntimeSymbols::add_sym(const char *, size_t,
282 const vm_val_t *)
283 {
284 }
285