1 #ifdef RCSID
2 static char RCSid[] =
3 "$Header: d:/cvsroot/tads/tads3/test/test_comp_obj.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_link.cpp - parser test: link object files to image file
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 "tcmake.h"
37 #include "vmimage.h"
38 #include "vmrunsym.h"
39 #include "t3test.h"
40
41
errexit(const char * msg)42 static void errexit(const char *msg)
43 {
44 printf("%s\n", msg);
45 exit(1);
46 }
47
main(int argc,char ** argv)48 int main(int argc, char **argv)
49 {
50 CResLoader *res_loader;
51 CTcHostIfc *hostifc;
52 int curarg;
53 int fatal_error_count = 0;
54 osfildef *fpout = 0;
55 int next_local = 0;
56 CVmFile *imgfile = 0;
57 CVmFile *objfile = 0;
58 const char *imgfname;
59 int success;
60 char pathbuf[OSFNMAX];
61 static const char tool_data[4] = { 't', 's', 't', 'L' };
62
63 /* initialize for testing */
64 test_init();
65
66 /* create the host interface object */
67 hostifc = new CTcHostIfcStdio();
68
69 /* create a resource loader */
70 os_get_special_path(pathbuf, sizeof(pathbuf), argv[0], OS_GSP_T3_RES);
71 res_loader = new CResLoader(pathbuf);
72
73 /* initialize the compiler */
74 CTcMain::init(hostifc, res_loader, 0);
75
76 err_try
77 {
78 /* scan arguments */
79 for (curarg = 1 ; curarg < argc ; ++curarg)
80 {
81 char *p;
82
83 /* get the argument string for easy reference */
84 p = argv[curarg];
85
86 /* if it's not an option, we're done */
87 if (*p != '-')
88 break;
89
90 if (*(p + 1) == 'v')
91 {
92 /* set verbose mode */
93 G_tcmain->set_verbosity(TRUE);
94 }
95 else
96 {
97 /*
98 * invalid usage - consume all the arguments and fall
99 * through to the usage checker
100 */
101 curarg = argc;
102 break;
103 }
104 }
105
106 /* check arguments */
107 if (curarg + 2 > argc)
108 {
109 /* terminate the compiler */
110 CTcMain::terminate();
111
112 /* delete our objects */
113 delete res_loader;
114
115 /* exit with an error */
116 errexit("usage: test_link [options] obj-file [obj-file [...]] "
117 "image-file\n"
118 "options:\n"
119 " -v - verbose error messages");
120 }
121
122 /* set up an output file */
123 imgfname = argv[argc - 1];
124 fpout = osfopwb(imgfname, OSFTT3IMG);
125 if (fpout == 0)
126 errexit("unable to open image file");
127 imgfile = new CVmFile();
128 imgfile->set_file(fpout, 0);
129
130 /* read the object files */
131 for ( ; curarg < argc - 1 ; ++curarg)
132 {
133 osfildef *fpobj;
134
135 /* open this object file */
136 fpobj = osfoprb(argv[curarg], OSFTT3OBJ);
137 if (fpobj == 0)
138 {
139 printf("unable to open object file \"%s\"\n", argv[curarg]);
140 goto done;
141 }
142
143 /* note the loading */
144 printf("loading %s\n", argv[curarg]);
145
146 /* set up the CVmFile object for it */
147 objfile = new CVmFile();
148 objfile->set_file(fpobj, 0);
149
150 /* read the object file */
151 G_cg->load_object_file(objfile, argv[curarg]);
152
153 /* done with the object file */
154 delete objfile;
155 objfile = 0;
156 }
157
158 /* check for unresolved externals */
159 if (G_prs->check_unresolved_externs())
160 goto done;
161
162 /* write the image file */
163 G_cg->write_to_image(imgfile, 0, tool_data);
164
165 done: ;
166 }
167 err_catch(exc)
168 {
169 /*
170 * if it's not a general internal or fatal error, log it; don't
171 * log general errors, since these will have been logged as
172 * specific internal errors before being thrown
173 */
174 if (exc->get_error_code() != TCERR_INTERNAL_ERROR
175 && exc->get_error_code() != TCERR_FATAL_ERROR)
176 G_tok->log_error(TC_SEV_FATAL, exc->get_error_code());
177
178 /* count the fatal error */
179 ++fatal_error_count;
180 }
181 err_end;
182
183 /* report errors */
184 fprintf(stderr,
185 "Warnings: %d\n"
186 "Errors: %d\n"
187 "Longest string: %d, longest list: %d\n",
188 G_tcmain->get_warning_count(),
189 G_tcmain->get_error_count() + fatal_error_count,
190 G_cg->get_max_str_len(), G_cg->get_max_list_cnt());
191
192 /*
193 * note whether or not the compilation was successful - it succeeded
194 * if we had no errors or fatal errors
195 */
196 success = (G_tcmain->get_error_count() + fatal_error_count == 0);
197
198 /* delete the object file object (this closes the file) */
199 delete imgfile;
200
201 /* if we have an open object file, close it */
202 if (objfile != 0)
203 delete objfile;
204
205 /*
206 * if any errors occurred, delete the object file in the external
207 * file system - this prevents us from leaving around an incomplete
208 * or corrupted image file when compilation fails, and helps
209 * 'make'-type tools realize that they must generate the image file
210 * target again on the next build, even if source files didn't
211 * change
212 */
213 if (!success)
214 osfdel(imgfname);
215
216 /* shut down the compiler */
217 CTcMain::terminate();
218
219 /* done with the res loader */
220 delete res_loader;
221
222 /* delete the host interface */
223 delete hostifc;
224
225 /* show any unfreed memory */
226 t3_list_memory_blocks(0);
227
228 /*
229 * terminate - exit with a success indication if we had no errors
230 * (other than warnings); exit with an error indication otherwise
231 */
232 return (success ? OSEXSUCC : OSEXFAIL);
233 }
234
235 /*
236 * dummy 'make' object implementation
237 */
write_build_config_to_sym_file(class CVmFile *)238 void CTcMake::write_build_config_to_sym_file(class CVmFile *)
239 {
240 }
241
242 /* ------------------------------------------------------------------------ */
243 /*
244 * dummy implementation of runtime symbol table
245 */
add_sym(const char *,size_t,const vm_val_t *)246 void CVmRuntimeSymbols::add_sym(const char *, size_t,
247 const vm_val_t *)
248 {
249 }
250