cfad47cfa3/t3compiler/tads3/test/test_link.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_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
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
    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
 */
238
void CTcMake::write_build_config_to_sym_file(class CVmFile *)
239
{
240
}
241
242
/* ------------------------------------------------------------------------ */
243
/*
244
 *   dummy implementation of runtime symbol table 
245
 */
246
void CVmRuntimeSymbols::add_sym(const char *, size_t,
247
                                const vm_val_t *)
248
{
249
}