cfad47cfa3/t3compiler/tads3/test/test_comp_obj.cpp

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
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_comp_obj.cpp - parser test: compile to object 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
42
static void errexit(const char *msg)
43
{
44
    printf("%s\n", msg);
45
    exit(1);
46
}
47
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
    CVmFile *objfile = 0;
56
    CTPNStmProg *node;
57
    const char *obj_fname;
58
    int success;
59
    char pathbuf[OSFNMAX];
60
61
    /* initialize for testing */
62
    test_init();
63
64
    /* create the host interface object */
65
    hostifc = new CTcHostIfcStdio();
66
67
    /* create a resource loader */
68
    os_get_special_path(pathbuf, sizeof(pathbuf), argv[0], OS_GSP_T3_RES);
69
    res_loader = new CResLoader(pathbuf);
70
71
    /* initialize the compiler */
72
    CTcMain::init(hostifc, res_loader, 0);
73
74
    /* keep all fixups when writing an object file */
75
    G_keep_objfixups = TRUE;
76
    G_keep_propfixups = TRUE;
77
    G_keep_enumfixups = TRUE;
78
    
79
    err_try
80
    {
81
        /* scan -I arguments */
82
        for (curarg = 1 ; curarg < argc ; ++curarg)
83
        {
84
            char *p;
85
            
86
            /* get the argument string for easy reference */
87
            p = argv[curarg];
88
            
89
            /* if it's not an option, we're done */
90
            if (*p != '-')
91
                break;
92
            
93
            /* if it's a -I argument, use it */
94
            if (*(p + 1) == 'I')
95
            {
96
                char *path;
97
                
98
                /* 
99
                 *   if it's with this argument, read it, otherwise move
100
                 *   on to the next argument 
101
                 */
102
                if (*(p + 2) == '\0')
103
                    path = argv[++curarg];
104
                else
105
                    path = p + 2;
106
                
107
                /* add the directory to the include path list */
108
                G_tok->add_inc_path(path);
109
            }
110
            else if (*(p + 1) == 'v')
111
            {
112
                /* set verbose mode */
113
                G_tcmain->set_verbosity(TRUE);
114
            }
115
            else if (*(p + 1) == 's')
116
            {
117
                char *fname;
118
                osfildef *symfp;
119
                CVmFile *symfile;
120
                
121
                /* load a symbol file */
122
                if (*(p + 2) == '\0')
123
                    fname = argv[++curarg];
124
                else
125
                    fname = p + 2;
126
127
                /* open the file */
128
                symfp = osfoprb(fname, OSFTT3SYM);
129
                if (symfp == 0)
130
                {
131
                    fprintf(stderr, "unable to open symbol file %s\n", fname);
132
                    continue;
133
                }
134
135
                /* load the symbol file */
136
                symfile = new CVmFile();
137
                symfile->set_file(symfp, 0);
138
                G_prs->read_symbol_file(symfile);
139
140
                /* done with the symbol file */
141
                delete symfile;
142
            }
143
            else
144
            {
145
                /* 
146
                 *   invalid usage - consume all the arguments and fall
147
                 *   through to the usage checker 
148
                 */
149
                curarg = argc;
150
                break;
151
            }
152
        }
153
        
154
        /* check arguments */
155
        if (curarg + 2 != argc)
156
        {
157
            /* terminate the compiler */
158
            CTcMain::terminate();
159
            
160
            /* delete our objects */
161
            delete res_loader;
162
            
163
            /* exit with an error */
164
            errexit("usage: test_comp_obj [options] <source-file> "
165
                    "<object-file>\n"
166
                    "options:\n"
167
                    "   -sfile - load symbols from file\n"
168
                    "   -Idir  - add dir to include path\n"
169
                    "   -v     - verbose error messages");
170
        }
171
        
172
        /* set up the tokenizer with the main input file */
173
        if (G_tok->set_source(argv[curarg], argv[curarg]))
174
            errexit("unable to open source file");
175
176
        /* set up an output file */
177
        obj_fname = argv[curarg+1];
178
        fpout = osfopwb(obj_fname, OSFTT3OBJ);
179
        if (fpout == 0)
180
            errexit("unable to open object file");
181
        objfile = new CVmFile();
182
        objfile->set_file(fpout, 0);
183
184
        /* read the first token */
185
        G_tok->next();
186
        
187
        /* parse at the top level */
188
        node = G_prs->parse_top();
189
190
        /* if errors occurred during parsing, stop here */
191
        if (G_tcmain->get_error_count() != 0 || node == 0)
192
            goto done;
193
        
194
        /* fold symbolic constants for all nodes */
195
        node->fold_constants(G_prs->get_global_symtab());
196
197
        /* if errors occurred during constant folding, stop now */
198
        if (G_tcmain->get_error_count() != 0)
199
            goto done;
200
201
        /* generate code and write the object file */
202
        node->build_object_file(objfile, 0);
203
204
    done: ;
205
    }
206
    err_catch(exc)
207
    {
208
        /* 
209
         *   if it's not a general internal or fatal error, log it; don't
210
         *   log general errors, since these will have been logged as
211
         *   specific internal errors before being thrown 
212
         */
213
        if (exc->get_error_code() != TCERR_INTERNAL_ERROR
214
            && exc->get_error_code() != TCERR_FATAL_ERROR)
215
            G_tok->log_error(TC_SEV_FATAL, exc->get_error_code());
216
217
        /* count the fatal error */
218
        ++fatal_error_count;
219
    }
220
    err_end;
221
222
    /* report errors */
223
    fprintf(stderr,
224
            "Warnings: %d\n"
225
            "Errors:   %d\n"
226
            "Longest string: %d, longest list: %d\n",
227
            G_tcmain->get_warning_count(),
228
            G_tcmain->get_error_count() + fatal_error_count,
229
            G_cg->get_max_str_len(), G_cg->get_max_list_cnt());
230
231
    /* 
232
     *   note whether or not the compilation was successful - it succeeded
233
     *   if we had no errors or fatal errors 
234
     */
235
    success = (G_tcmain->get_error_count() + fatal_error_count == 0);
236
237
    /* delete the object file object (this closes the file) */
238
    delete objfile;
239
240
    /* 
241
     *   if any errors occurred, delete the object file in the external
242
     *   file system - this prevents us from leaving around an incomplete
243
     *   or corrupted image file when compilation fails, and helps
244
     *   'make'-type tools realize that they must generate the image file
245
     *   target again on the next build, even if source files didn't
246
     *   change 
247
     */
248
    if (!success)
249
        osfdel(obj_fname);
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
 */
273
void CTcMake::write_build_config_to_sym_file(class CVmFile *)
274
{
275
}
276
277
/* ------------------------------------------------------------------------ */
278
/*
279
 *   dummy implementation of runtime symbol table 
280
 */
281
void CVmRuntimeSymbols::add_sym(const char *, size_t,
282
                                const vm_val_t *)
283
{
284
}