Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997, 1998
32
    		 Crown Copyright (c) 1997, 1998
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
Line 73... Line 103...
73
#include "ustring.h"
103
#include "ustring.h"
74
#include "variable.h"
104
#include "variable.h"
75
#include "xalloc.h"
105
#include "xalloc.h"
76
 
106
 
77
 
107
 
78
/*
108
/**
79
    DEFAULT MACHINE OPTION
109
 * DEFAULT MACHINE OPTION
80
 
110
 *
81
    This macro is used to determine the machine dependent options to
111
 * This macro is used to determine the machine dependent options to be used.
82
    be used.
-
 
83
*/
112
 */
84
 
113
 
85
#ifndef FS_MACHINE
114
#ifndef FS_MACHINE
86
#ifdef FS_DOS
115
#ifdef FS_DOS
87
#define FS_MACHINE		"dos"
116
#define FS_MACHINE		"dos"
88
#else
117
#else
89
#define FS_MACHINE		"unix"
118
#define FS_MACHINE		"unix"
90
#endif
119
#endif
91
#endif
120
#endif
92
 
-
 
93
 
-
 
94
/*
-
 
95
    COMMAND-LINE FLAGS
-
 
96
 
-
 
97
    These flags may be set by command-line options to indicate various
-
 
98
    actions to the compiler.
-
 
99
*/
-
 
100
 
-
 
101
static int builtin_asserts = 1 ;
-
 
102
static int builtin_macros = 1 ;
-
 
103
static int check_level = 0 ;
-
 
104
static int complete_program = 0 ;
-
 
105
static int have_startup = 0 ;
-
 
106
static int spec_linker = 0 ;
-
 
107
static int started_scope = 0 ;
-
 
108
static int output_last = 1 ;
-
 
109
static int unmangle_names = 0 ;
-
 
110
static int quit_immediately = 0 ;
-
 
111
static string dump_name = NULL ;
-
 
112
static string dump_opt = NULL ;
-
 
113
static string spec_name = NULL ;
-
 
114
static string table_name = NULL ;
-
 
115
 
121
 
116
 
122
 
117
/*
123
/*
118
    TABLE OF COMMAND-LINE ARGUMENTS
124
 * COMMAND-LINE FLAGS
-
 
125
 *
-
 
126
 * These flags may be set by command-line options to indicate various actions
-
 
127
 * to the compiler.
-
 
128
 */
119
 
129
 
-
 
130
static int builtin_asserts = 1;
-
 
131
static int builtin_macros = 1;
-
 
132
static int check_level = 0;
-
 
133
static int complete_program = 0;
-
 
134
static int have_startup = 0;
-
 
135
static int spec_linker = 0;
-
 
136
static int started_scope = 0;
-
 
137
static int output_last = 1;
-
 
138
static int unmangle_names = 0;
-
 
139
static int quit_immediately = 0;
-
 
140
static string dump_name = NULL;
-
 
141
static string dump_opt = NULL;
-
 
142
static string spec_name = NULL;
-
 
143
static string table_name = NULL;
-
 
144
 
-
 
145
 
-
 
146
/*
-
 
147
 * TABLE OF COMMAND-LINE ARGUMENTS
-
 
148
 *
120
    This table describes all the command-line options.  Each is given by
149
 * This table describes all the command-line options. Each is given by an
121
    an option letter, followed by a flag indicating whether the option can
150
 * option letter, followed by a flag indicating whether the option can be
122
    be split into two components, and a description of the second option
151
 * split into two components, and a description of the second option
123
    component.
152
 * component.
124
*/
153
 */
125
 
154
 
126
typedef struct {
155
typedef struct {
127
    char opt ;
156
    char opt;
128
    char space ;
157
    char space;
129
    CONST char *arg ;
158
    CONST char *arg;
130
    CONST char *desc ;
159
    CONST char *desc;
131
} PROGRAM_ARG ;
160
} PROGRAM_ARG;
132
 
161
 
133
static PROGRAM_ARG prog_args [] = {
162
static PROGRAM_ARG prog_args[] = {
134
    { 'A', 1, "<pre>(<tok>)", "assert a predicate" },
163
    { 'A', 1, "<pre>(<tok>)", "assert a predicate" },
135
    { 'D', 1, "<mac>=<def>", "define a macro" },
164
    { 'D', 1, "<mac>=<def>", "define a macro" },
136
    { 'E', 0, NULL, "preprocess input file only" },
165
    { 'E', 0, NULL, "preprocess input file only" },
137
    { 'F', 1, "<file>", "read list of options from file" },
166
    { 'F', 1, "<file>", "read list of options from file" },
138
    { 'H', 0, NULL, "report file inclusions" },
167
    { 'H', 0, NULL, "report file inclusions" },
Line 169... Line 198...
169
    { 'x', 1, "<debug>", "debugging options" },
198
    { 'x', 1, "<debug>", "debugging options" },
170
#endif
199
#endif
171
    { 'z', 0, NULL, "ignore compilation errors" },
200
    { 'z', 0, NULL, "ignore compilation errors" },
172
    { '?', 0, NULL, "print this help page" },
201
    { '?', 0, NULL, "print this help page" },
173
    { '-', 0, NULL, "specify end of options" }
202
    { '-', 0, NULL, "specify end of options" }
174
} ;
203
};
175
 
204
 
176
#define no_prog_args	array_size ( prog_args )
205
#define no_prog_args	array_size(prog_args)
177
 
206
 
178
 
207
 
179
/*
208
/**
180
    PRINT PROGRAM USAGE
209
 * PRINT PROGRAM USAGE
181
 
210
 *
182
    This routine prints the program usage to the file f.
211
 * This routine prints the program usage to the file f.
183
*/
-
 
184
 
-
 
185
static void report_usage
-
 
186
    PROTO_N ( ( f ) )
-
 
187
    PROTO_T ( FILE *f )
-
 
188
{
-
 
189
    int i ;
-
 
190
    fprintf_v ( f, "Usage: %s [options] [input] [output]\n", progname ) ;
-
 
191
    for ( i = 0 ; i < no_prog_args ; i++ ) {
-
 
192
	char opt = prog_args [i].opt ;
-
 
193
	CONST char *arg = prog_args [i].arg ;
-
 
194
	CONST char *desc = prog_args [i].desc ;
-
 
195
	if ( arg == NULL ) arg = "\t" ;
-
 
196
	if ( desc == NULL ) desc = "(not documented)" ;
-
 
197
	fprintf_v ( f, " -%c%s\t%s\n", opt, arg, desc ) ;
-
 
198
    }
-
 
199
    fputc_v ( '\n', f ) ;
-
 
200
    return ;
-
 
201
}
-
 
202
 
-
 
203
 
-
 
204
/*
-
 
205
    SET MACHINE DEPENDENT FLAGS
-
 
206
 
-
 
207
    This routine sets the machine dependent options for the machine
-
 
208
    described by mach.  The routine returns false for an unknown machine
-
 
209
    descriptor.
-
 
210
*/
212
 */
211
 
213
 
212
static int set_machine
214
static void
213
    PROTO_N ( ( mach ) )
215
report_usage(FILE *f)
214
    PROTO_T ( CONST char *mach )
-
 
215
{
216
{
216
    if ( streq ( mach, "dos" ) ) {
-
 
217
	allow_dos_newline = 1 ;
-
 
218
	good_fseek = 0 ;
-
 
219
	binary_mode = 1 ;
-
 
220
	file_sep = '\\' ;
-
 
221
	drive_sep = ':' ;
-
 
222
	return ( 1 ) ;
-
 
223
    }
217
    int i;
-
 
218
    fprintf_v(f, "Usage: %s [options] [input] [output]\n", progname);
224
    if ( streq ( mach, "unix" ) ) {
219
    for (i = 0; i < no_prog_args; i++) {
225
	allow_dos_newline = 0 ;
220
	char opt = prog_args[i].opt;
226
	good_fseek = 1 ;
221
	CONST char *arg = prog_args[i].arg;
227
	binary_mode = 0 ;
222
	CONST char *desc = prog_args[i].desc;
228
	file_sep = '/' ;
223
	if (arg == NULL) arg = "\t";
229
	drive_sep = 0 ;
224
	if (desc == NULL) desc = "(not documented)";
230
	return ( 1 ) ;
225
	fprintf_v(f, " -%c%s\t%s\n", opt, arg, desc);
231
    }
226
    }
-
 
227
    fputc_v('\n', f);
232
    return ( 0 ) ;
228
    return;
233
}
229
}
234
 
230
 
235
 
231
 
236
/*
232
/**
237
    PRE-SET A COMPILE-TIME OPTION
233
 * SET MACHINE DEPENDENT FLAGS
238
 
-
 
239
    This routine pre-sets the value of option A to be B.
-
 
240
*/
-
 
241
 
-
 
242
#define preset( A, B )\
-
 
243
    OPT_CATALOG [A].def [0] = ( B ) ;\
-
 
244
    OPT_CATALOG [A].def [1] = ( B )
-
 
245
 
-
 
246
 
-
 
247
/*
234
 *
248
    READ AN ARGUMENT FROM A FILE
-
 
249
 
-
 
250
    This routine reads a command-line argument from the file f into the
235
 * This routine sets the machine dependent options for the machine described
251
    buffer s of length n, returning the result.
236
 * by mach. The routine returns false for an unknown machine descriptor.
252
*/
237
 */
253
 
238
 
254
static char *read_arg
239
static int
255
    PROTO_N ( ( f, s, n ) )
-
 
256
    PROTO_T ( FILE *f X char *s X int n )
240
set_machine(CONST char *mach)
257
{
241
{
-
 
242
    if (streq(mach, "dos")) {
-
 
243
	allow_dos_newline = 1;
-
 
244
	good_fseek = 0;
-
 
245
	binary_mode = 1;
-
 
246
	file_sep = '\\';
-
 
247
	drive_sep = ':';
-
 
248
	return(1);
-
 
249
    }
-
 
250
    if (streq(mach, "unix")) {
-
 
251
	allow_dos_newline = 0;
-
 
252
	good_fseek = 1;
-
 
253
	binary_mode = 0;
-
 
254
	file_sep = '/';
-
 
255
	drive_sep = 0;
-
 
256
	return(1);
-
 
257
    }
-
 
258
    return(0);
-
 
259
}
-
 
260
 
-
 
261
 
-
 
262
/**
-
 
263
 * PRE-SET A COMPILE-TIME OPTION
-
 
264
 *
-
 
265
 * This routine pre-sets the value of option A to be B.
-
 
266
 */
-
 
267
 
-
 
268
#define preset(A, B)\
-
 
269
    OPT_CATALOG[A].def[0] = (B);\
-
 
270
    OPT_CATALOG[A].def[1] = (B)
-
 
271
 
-
 
272
 
-
 
273
/**
-
 
274
 * READ AN ARGUMENT FROM A FILE
-
 
275
 *
-
 
276
 * This routine reads a command-line argument from the file f into the buffer
-
 
277
 * s of length n, returning the result.
-
 
278
 */
-
 
279
 
-
 
280
static char *
-
 
281
read_arg(FILE *f, char *s, int n)
-
 
282
{
258
    char *p = fgets ( s, n, f ) ;
283
    char *p = fgets(s, n, f);
259
    if ( p ) {
284
    if (p) {
260
	char c = *p ;
285
	char c = *p;
261
	if ( c == '#' || c == '\n' ) {
286
	if (c == '#' || c == '\n') {
262
	    /* Ignore empty lines and comments */
287
	    /* Ignore empty lines and comments */
263
	    p = read_arg ( f, s, n ) ;
288
	    p = read_arg(f, s, n);
264
	} else {
289
	} else {
265
	    /* Remove terminal newline */
290
	    /* Remove terminal newline */
266
	    char *q = strrchr ( p, '\n' ) ;
291
	    char *q = strrchr(p, '\n');
267
	    if ( q ) *q = 0 ;
292
	    if (q) *q = 0;
268
	}
293
	}
269
    }
294
    }
270
    return ( p ) ;
295
    return(p);
271
}
296
}
272
 
297
 
273
 
298
 
274
/*
299
/**
275
    PROCESS A LIST OF ARGUMENTS
300
 * PROCESS A LIST OF ARGUMENTS
276
 
301
 *
277
    This routine is called by main to process the command-line arguments
302
 * This routine is called by main to process the command-line arguments given
278
    given by argc and argv.  It returns a list of strings giving the
303
 * by argc and argv. It returns a list of strings giving the input and output
279
    input and output files.
304
 * files.
280
*/
305
 */
281
 
306
 
282
static LIST ( string ) process_args
307
static LIST(string)
283
    PROTO_N ( ( argc, argv ) )
-
 
284
    PROTO_T ( int argc X char **argv )
308
process_args(int argc, char **argv)
285
{
309
{
286
    char opt = 0 ;
310
    char opt = 0;
287
    FILE *f = NULL ;
311
    FILE *f = NULL;
288
    char buff [1000] ;
312
    char buff[1000];
289
    int allow_opt = 1 ;
313
    int allow_opt = 1;
290
    string output = NULL ;
314
    string output = NULL;
291
    LIST ( string ) files = NULL_list ( string ) ;
315
    LIST(string)files = NULL_list(string);
292
 
316
 
293
    /* Set development default options */
317
    /* Set development default options */
294
#ifdef DEBUG
318
#ifdef DEBUG
295
    output_tokdec = 1 ;
319
    output_tokdec = 1;
296
#endif
320
#endif
297
 
321
 
298
    /* Scan through the arguments */
322
    /* Scan through the arguments */
299
    for ( ; ; ) {
323
    for (; ;) {
300
	char *arg = NULL ;
324
	char *arg = NULL;
301
	if ( f != NULL ) {
325
	if (f != NULL) {
302
	    /* Get next option from file */
326
	    /* Get next option from file */
303
	    arg = read_arg ( f, buff, ( int ) sizeof ( buff ) ) ;
327
	    arg = read_arg(f, buff,(int)sizeof(buff));
304
	    if ( arg == NULL ) {
328
	    if (arg == NULL) {
305
		/* End of file reached */
329
		/* End of file reached */
306
		fclose_v ( f ) ;
330
		fclose_v(f);
307
		f = NULL ;
331
		f = NULL;
308
	    }
332
	    }
309
	}
333
	}
310
	if ( arg == NULL && argc ) {
334
	if (arg == NULL && argc) {
311
	    /* Get next option from array */
335
	    /* Get next option from array */
312
	    arg = *( argv++ ) ;
336
	    arg = *(argv++);
313
	    argc-- ;
337
	    argc--;
314
	}
338
	}
315
	if ( arg == NULL ) {
339
	if (arg == NULL) {
316
	    /* No more options */
340
	    /* No more options */
317
	    break ;
341
	    break;
318
	}
342
	}
319
	if ( opt == 0 ) {
343
	if (opt == 0) {
320
	    /* Find option letter */
344
	    /* Find option letter */
321
	    if ( arg [0] == '-' && allow_opt ) {
345
	    if (arg[0] == '-' && allow_opt) {
322
		opt = arg [1] ;
346
		opt = arg[1];
323
		if ( opt ) arg += 2 ;
347
		if (opt) arg += 2;
324
	    }
348
	    }
325
	}
349
	}
326
	if ( opt == 0 ) {
350
	if (opt == 0) {
327
	    /* Input or output file 'arg' */
351
	    /* Input or output file 'arg' */
328
	    string uarg = xustrcpy ( ustrlit ( arg ) ) ;
352
	    string uarg = xustrcpy(ustrlit(arg));
329
	    CONS_string ( uarg, files, files ) ;
353
	    CONS_string(uarg, files, files);
330
 
354
 
331
	} else {
355
	} else {
332
	    /* Command-line options */
356
	    /* Command-line options */
333
	    int i ;
357
	    int i;
334
	    int known = 0 ;
358
	    int known = 0;
335
	    char next_opt = 0 ;
359
	    char next_opt = 0;
336
 
360
 
337
	    /* Search through options */
361
	    /* Search through options */
338
	    for ( i = 0 ; i < no_prog_args ; i++ ) {
362
	    for (i = 0; i < no_prog_args; i++) {
339
		if ( opt == prog_args [i].opt ) {
363
		if (opt == prog_args[i].opt) {
340
		    if ( prog_args [i].arg ) {
364
		    if (prog_args[i].arg) {
341
			/* Complex options */
365
			/* Complex options */
342
			if ( arg [0] == 0 && prog_args [i].space ) {
366
			if (arg[0] == 0 && prog_args[i].space) {
343
			    next_opt = opt ;
367
			    next_opt = opt;
344
			    known = 1 ;
368
			    known = 1;
345
			} else {
369
			} else {
346
			    known = 2 ;
370
			    known = 2;
347
			}
371
			}
348
		    } else {
372
		    } else {
349
			/* Simple options */
373
			/* Simple options */
350
			if ( arg [0] == 0 ) {
374
			if (arg[0] == 0) {
351
			    known = 2 ;
375
			    known = 2;
352
			    break ;
376
			    break;
353
			}
377
			}
354
		    }
378
		    }
355
		}
379
		}
356
	    }
380
	    }
357
 
381
 
358
	    /* Deal with complete options */
382
	    /* Deal with complete options */
359
	    if ( known == 2 ) {
383
	    if (known == 2) {
360
		string uarg = ustrlit ( arg ) ;
384
		string uarg = ustrlit(arg);
361
		switch ( opt ) {
385
		switch (opt) {
362
 
386
 
363
		    case 'A' : {
387
		    case 'A': {
364
			/* Assertion */
388
			/* Assertion */
365
			BUFFER *bf = &internal_buff ;
389
			BUFFER *bf = &internal_buff;
366
			if ( streq ( arg, "-" ) ) {
390
			if (streq(arg, "-")) {
367
			    builtin_asserts = 0 ;
391
			    builtin_asserts = 0;
368
			    break ;
392
			    break;
369
			}
393
			}
370
			bfprintf ( bf, "#assert %x\n", arg ) ;
394
			bfprintf(bf, "#assert %x\n", arg);
371
			preset ( OPT_ppdir_assert, OPTION_ALLOW ) ;
395
			preset(OPT_ppdir_assert, OPTION_ALLOW);
372
			preset ( OPT_ppdir_unassert, OPTION_ALLOW ) ;
396
			preset(OPT_ppdir_unassert, OPTION_ALLOW);
373
			preset ( OPT_ppdir_assert_ignore, OPTION_OFF ) ;
397
			preset(OPT_ppdir_assert_ignore, OPTION_OFF);
374
			preset ( OPT_ppdir_unassert_ignore, OPTION_OFF ) ;
398
			preset(OPT_ppdir_unassert_ignore, OPTION_OFF);
375
			have_startup = 1 ;
399
			have_startup = 1;
376
			break ;
400
			break;
377
		    }
401
		    }
378
 
402
 
379
		    case 'D' : {
403
		    case 'D': {
380
			/* Macro definition */
404
			/* Macro definition */
381
			char c ;
405
			char c;
382
			CONST char *def = "1" ;
406
			CONST char *def = "1";
383
			BUFFER *bf = &internal_buff ;
407
			BUFFER *bf = &internal_buff;
384
			bfprintf ( bf, "#define " ) ;
408
			bfprintf(bf, "#define ");
385
			while ( c = *( arg++ ), c != 0 ) {
409
			while (c = *(arg++), c != 0) {
386
			    if ( c == '=' ) {
410
			    if (c == '=') {
387
				def = arg ;
411
				def = arg;
388
				break ;
412
				break;
389
			    }
413
			    }
390
			    bfputc ( bf, ( int ) c ) ;
414
			    bfputc(bf,(int)c);
391
			}
415
			}
392
			bfprintf ( bf, " %x\n", def ) ;
416
			bfprintf(bf, " %x\n", def);
393
			have_startup = 1 ;
417
			have_startup = 1;
394
			break ;
418
			break;
395
		    }
419
		    }
396
 
420
 
397
		    case 'E' : {
421
		    case 'E': {
398
			/* Preprocessor option */
422
			/* Preprocessor option */
399
			preproc_only = 1 ;
423
			preproc_only = 1;
400
			break ;
424
			break;
401
		    }
425
		    }
402
 
426
 
403
		    case 'F' : {
427
		    case 'F': {
404
			/* Open option file */
428
			/* Open option file */
405
			if ( f != NULL ) {
429
			if (f != NULL) {
406
			    CONST char *err = "Nested option files" ;
430
			    CONST char *err = "Nested option files";
407
			    error ( ERROR_WARNING, err ) ;
431
			    error(ERROR_WARNING, err);
408
			    break ;
432
			    break;
409
			}
433
			}
410
			f = fopen ( arg, "r" ) ;
434
			f = fopen(arg, "r");
411
			if ( f == NULL ) {
435
			if (f == NULL) {
412
			    CONST char *err = "Can't open option file '%s'" ;
436
			    CONST char *err = "Can't open option file '%s'";
413
			    error ( ERROR_WARNING, err, arg ) ;
437
			    error(ERROR_WARNING, err, arg);
414
			}
438
			}
415
			break ;
439
			break;
416
		    }
440
		    }
417
 
441
 
418
		    case 'H' : {
442
		    case 'H': {
419
			/* Inclusion reporting option */
443
			/* Inclusion reporting option */
420
			preset ( OPT_include_verbose, OPTION_WARN ) ;
444
			preset(OPT_include_verbose, OPTION_WARN);
421
			break ;
445
			break;
422
		    }
446
		    }
423
 
447
 
424
		    case 'I' : {
448
		    case 'I': {
425
			/* Include file search directory */
449
			/* Include file search directory */
426
			uarg = xustrcpy ( uarg ) ;
450
			uarg = xustrcpy(uarg);
427
			add_directory ( uarg, NULL_string ) ;
451
			add_directory(uarg, NULL_string);
428
			break ;
452
			break;
429
		    }
453
		    }
430
 
454
 
431
		    case 'M' : {
455
		    case 'M': {
432
			/* Machine dependent options */
456
			/* Machine dependent options */
433
			known = set_machine ( arg ) ;
457
			known = set_machine(arg);
434
			break ;
458
			break;
435
		    }
459
		    }
436
 
460
 
437
		    case 'N' : {
461
		    case 'N': {
438
			/* Named include file search directory */
462
			/* Named include file search directory */
439
			string dir ;
463
			string dir;
440
			uarg = xustrcpy ( uarg ) ;
464
			uarg = xustrcpy(uarg);
441
			dir = ustrchr ( uarg, ':' ) ;
465
			dir = ustrchr(uarg, ':');
442
			if ( dir == NULL ) {
466
			if (dir == NULL) {
443
			    CONST char *err = "Bad '-%c' option" ;
467
			    CONST char *err = "Bad '-%c' option";
444
			    error ( ERROR_WARNING, err, opt ) ;
468
			    error(ERROR_WARNING, err, opt);
445
			    add_directory ( uarg, NULL_string ) ;
469
			    add_directory(uarg, NULL_string);
446
			} else {
470
			} else {
447
			    *dir = 0 ;
471
			    *dir = 0;
448
			    add_directory ( dir + 1, uarg ) ;
472
			    add_directory(dir + 1, uarg);
449
			}
473
			}
450
			break ;
474
			break;
451
		    }
475
		    }
452
 
476
 
453
		    case 'O' : {
477
		    case 'O': {
454
			/* Optimisation mode */
478
			/* Optimisation mode */
455
			output_inline = 1 ;
479
			output_inline = 1;
456
			output_unused = 0 ;
480
			output_unused = 0;
457
			break ;
481
			break;
458
		    }
482
		    }
459
 
483
 
460
		    case 'R' : {
484
		    case 'R': {
461
			/* Reverse order of files */
485
			/* Reverse order of files */
462
			output_last = 0 ;
486
			output_last = 0;
463
			break ;
487
			break;
464
		    }
488
		    }
465
 
489
 
466
		    case 'S' : {
490
		    case 'S': {
467
			/* Spec linker option */
491
			/* Spec linker option */
468
			spec_linker = 1 ;
492
			spec_linker = 1;
469
			break ;
493
			break;
470
		    }
494
		    }
471
 
495
 
472
		    case 'U' : {
496
		    case 'U': {
473
			/* Macro undefinition */
497
			/* Macro undefinition */
474
			BUFFER *bf = &internal_buff ;
498
			BUFFER *bf = &internal_buff;
475
			if ( streq ( arg, "-" ) ) {
499
			if (streq(arg, "-")) {
476
			    builtin_macros = 0 ;
500
			    builtin_macros = 0;
477
			    break ;
501
			    break;
478
			}
502
			}
479
			bfprintf ( bf, "#undef %x\n", arg ) ;
503
			bfprintf(bf, "#undef %x\n", arg);
480
			have_startup = 1 ;
504
			have_startup = 1;
481
			break ;
505
			break;
482
		    }
506
		    }
483
 
507
 
484
		    case 'V' : {
508
		    case 'V': {
485
			/* Switch on verbose mode */
509
			/* Switch on verbose mode */
486
			verbose = 1 ;
510
			verbose = 1;
487
			break ;
511
			break;
488
		    }
512
		    }
489
 
513
 
490
		    case 'W' : {
514
		    case 'W': {
491
			/* Switch on checks */
515
			/* Switch on checks */
492
			char c ;
516
			char c;
493
			CONST char *sev = "warning" ;
517
			CONST char *sev = "warning";
494
			BUFFER *bf = &internal_buff ;
518
			BUFFER *bf = &internal_buff;
495
			if ( streq ( arg, "all" ) ) {
519
			if (streq(arg, "all")) {
496
			    check_level = 1 ;
520
			    check_level = 1;
497
			    break ;
521
			    break;
498
			}
522
			}
499
			if ( !started_scope ) {
523
			if (!started_scope) {
500
			    bfprintf ( bf, "#pragma TenDRA begin\n" ) ;
524
			    bfprintf(bf, "#pragma TenDRA begin\n");
501
			    started_scope = 1 ;
525
			    started_scope = 1;
502
			}
526
			}
503
			bfprintf ( bf, "#pragma TenDRA option \"" ) ;
527
			bfprintf(bf, "#pragma TenDRA option \"");
504
			while ( c = *( arg++ ), c != 0 ) {
528
			while (c = *(arg++), c != 0) {
505
			    if ( c == '=' ) {
529
			    if (c == '=') {
506
				sev = arg ;
530
				sev = arg;
507
				break ;
531
				break;
508
			    }
532
			    }
509
			    bfputc ( bf, ( int ) c ) ;
533
			    bfputc(bf,(int)c);
510
			}
534
			}
511
			bfprintf ( bf, "\" %x\n", sev ) ;
535
			bfprintf(bf, "\" %x\n", sev);
512
			have_startup = 1 ;
536
			have_startup = 1;
513
			break ;
537
			break;
514
		    }
538
		    }
515
 
539
 
516
		    case 'X' : {
540
		    case 'X': {
517
			/* Disable exception handling */
541
			/* Disable exception handling */
518
			output_except = 0 ;
542
			output_except = 0;
519
			break ;
543
			break;
520
		    }
544
		    }
521
 
545
 
522
		    case 'Z' : {
546
		    case 'Z': {
523
			/* Set maximum number of errors */
547
			/* Set maximum number of errors */
524
			BUFFER *bf = &internal_buff ;
548
			BUFFER *bf = &internal_buff;
525
			if ( !started_scope ) {
549
			if (!started_scope) {
526
			    bfprintf ( bf, "#pragma TenDRA begin\n" ) ;
550
			    bfprintf(bf, "#pragma TenDRA begin\n");
527
			    started_scope = 1 ;
551
			    started_scope = 1;
528
			}
552
			}
529
			bfprintf ( bf, "#pragma TenDRA set error limit" ) ;
553
			bfprintf(bf, "#pragma TenDRA set error limit");
530
			bfprintf ( bf, " %x\n", uarg ) ;
554
			bfprintf(bf, " %x\n", uarg);
531
			have_startup = 1 ;
555
			have_startup = 1;
532
			break ;
556
			break;
533
		    }
557
		    }
534
 
558
 
535
		    case 'a' : {
559
		    case 'a': {
536
			/* Complete program checks */
560
			/* Complete program checks */
537
			complete_program = 1 ;
561
			complete_program = 1;
538
			break ;
562
			break;
539
		    }
563
		    }
540
 
564
 
541
		    case 'c' : {
565
		    case 'c': {
542
			/* Disable TDF output */
566
			/* Disable TDF output */
543
			output_capsule = 0 ;
567
			output_capsule = 0;
544
			break ;
568
			break;
545
		    }
569
		    }
546
 
570
 
547
		    case 'd' : {
571
		    case 'd': {
548
			/* Dump file */
572
			/* Dump file */
549
			string dump ;
573
			string dump;
550
			uarg = xustrcpy ( uarg ) ;
574
			uarg = xustrcpy(uarg);
551
			dump = ustrchr ( uarg, '=' ) ;
575
			dump = ustrchr(uarg, '=');
552
			if ( dump == NULL ) {
576
			if (dump == NULL) {
553
			    CONST char *err = "Bad '-%c' option" ;
577
			    CONST char *err = "Bad '-%c' option";
554
			    error ( ERROR_WARNING, err, opt ) ;
578
			    error(ERROR_WARNING, err, opt);
555
			    break ;
579
			    break;
556
			}
580
			}
557
			if ( dump_name ) {
581
			if (dump_name) {
558
			    CONST char *err = "Multiple dump files" ;
582
			    CONST char *err = "Multiple dump files";
559
			    error ( ERROR_WARNING, err ) ;
583
			    error(ERROR_WARNING, err);
560
			}
584
			}
561
			dump_opt = uarg ;
585
			dump_opt = uarg;
562
			dump_name = dump + 1 ;
586
			dump_name = dump + 1;
563
			break ;
587
			break;
564
		    }
588
		    }
565
 
589
 
566
		    case 'e' : {
590
		    case 'e': {
567
			/* End-up file */
591
			/* End-up file */
568
			LIST ( string ) p ;
592
			LIST(string)p;
569
			uarg = xustrcpy ( uarg ) ;
593
			uarg = xustrcpy(uarg);
570
			CONS_string ( uarg, NULL_list ( string ), p ) ;
594
			CONS_string(uarg, NULL_list(string), p);
571
			endup_files = APPEND_list ( endup_files, p ) ;
595
			endup_files = APPEND_list(endup_files, p);
572
			have_startup = 1 ;
596
			have_startup = 1;
573
			break ;
597
			break;
574
		    }
598
		    }
575
 
599
 
576
		    case 'f' : {
600
		    case 'f': {
577
			/* Start-up file */
601
			/* Start-up file */
578
			LIST ( string ) p ;
602
			LIST(string)p;
579
			uarg = xustrcpy ( uarg ) ;
603
			uarg = xustrcpy(uarg);
580
			CONS_string ( uarg, NULL_list ( string ), p ) ;
604
			CONS_string(uarg, NULL_list(string), p);
581
			startup_files = APPEND_list ( startup_files, p ) ;
605
			startup_files = APPEND_list(startup_files, p);
582
			have_startup = 1 ;
606
			have_startup = 1;
583
			break ;
607
			break;
584
		    }
608
		    }
585
 
609
 
586
		    case 'g' : {
610
		    case 'g': {
587
			/* Diagnostics mode */
611
			/* Diagnostics mode */
588
			if ( uarg [0] == 0 ) {
612
			if (uarg[0] == 0) {
589
			    output_diag = DIAG_VERSION ;
613
			    output_diag = DIAG_VERSION;
590
			} else if ( uarg [1] == 0 ) {
614
			} else if (uarg[1] == 0) {
591
			    switch ( uarg [0] ) {
615
			    switch (uarg[0]) {
592
				case '0' : output_diag = 0 ; break ;
616
				case '0': output_diag = 0; break;
593
				case '1' : output_diag = 1 ; break ;
617
				case '1': output_diag = 1; break;
594
				case '2' : output_diag = 2 ; break ;
618
				case '2': output_diag = 2; break;
595
				default : known = 0 ; break ;
619
				default : known = 0; break;
596
			    }
620
			    }
597
			} else {
621
			} else {
598
			    known = 0 ;
622
			    known = 0;
599
			}
623
			}
600
			break ;
624
			break;
601
		    }
625
		    }
602
 
626
 
603
		    case 'h' :
627
		    case 'h':
604
		    case '?' : {
628
		    case '?': {
605
			/* Help option */
629
			/* Help option */
606
			report_usage ( error_file ) ;
630
			report_usage(error_file);
607
			break ;
631
			break;
608
		    }
632
		    }
609
 
633
 
610
		    case 'j' : {
634
		    case 'j': {
611
			/* Output options */
635
			/* Output options */
612
			output_option ( uarg ) ;
636
			output_option(uarg);
613
			break ;
637
			break;
614
		    }
638
		    }
615
 
639
 
616
		    case 'm' : {
640
		    case 'm': {
617
			/* Error options */
641
			/* Error options */
618
			error_option ( uarg ) ;
642
			error_option(uarg);
619
			break ;
643
			break;
620
		    }
644
		    }
621
 
645
 
622
		    case 'n' : {
646
		    case 'n': {
623
			/* Portability table */
647
			/* Portability table */
624
			if ( table_name ) {
648
			if (table_name) {
625
			    CONST char *err = "Multiple portability tables" ;
649
			    CONST char *err = "Multiple portability tables";
626
			    error ( ERROR_WARNING, err ) ;
650
			    error(ERROR_WARNING, err);
627
			}
651
			}
628
			table_name = xustrcpy ( uarg ) ;
652
			table_name = xustrcpy(uarg);
629
			break ;
653
			break;
630
		    }
654
		    }
631
 
655
 
632
		    case 'o' : {
656
		    case 'o': {
633
			/* Output file */
657
			/* Output file */
634
			if ( output ) {
658
			if (output) {
635
			    CONST char *err = "Multiple output files" ;
659
			    CONST char *err = "Multiple output files";
636
			    error ( ERROR_WARNING, err ) ;
660
			    error(ERROR_WARNING, err);
637
			}
661
			}
638
			output = xustrcpy ( uarg ) ;
662
			output = xustrcpy(uarg);
639
			break ;
663
			break;
640
		    }
664
		    }
641
 
665
 
642
		    case 'q' : {
666
		    case 'q': {
643
			/* Quit immediately */
667
			/* Quit immediately */
644
			quit_immediately = 1 ;
668
			quit_immediately = 1;
645
			break ;
669
			break;
646
		    }
670
		    }
647
 
671
 
648
		    case 'r' : {
672
		    case 'r': {
649
			/* Error marker file */
673
			/* Error marker file */
650
			output_name [ OUTPUT_ERROR ] = xustrcpy ( uarg ) ;
674
			output_name[OUTPUT_ERROR] = xustrcpy(uarg);
651
			break ;
675
			break;
652
		    }
676
		    }
653
 
677
 
654
		    case 's' : {
678
		    case 's': {
655
			/* Spec output file */
679
			/* Spec output file */
656
			if ( spec_name ) {
680
			if (spec_name) {
657
			    CONST char *err = "Multiple spec output files" ;
681
			    CONST char *err = "Multiple spec output files";
658
			    error ( ERROR_WARNING, err ) ;
682
			    error(ERROR_WARNING, err);
659
			}
683
			}
660
			spec_name = xustrcpy ( uarg ) ;
684
			spec_name = xustrcpy(uarg);
661
			break ;
685
			break;
662
		    }
686
		    }
663
 
687
 
664
		    case 't' : {
688
		    case 't': {
665
			/* Output TDF token declarations */
689
			/* Output TDF token declarations */
666
			output_tokdec = 1 ;
690
			output_tokdec = 1;
667
			break ;
691
			break;
668
		    }
692
		    }
669
 
693
 
670
		    case 'u' : {
694
		    case 'u': {
671
			/* Unmangle an identifier name */
695
			/* Unmangle an identifier name */
672
			unmangle_names = 1 ;
696
			unmangle_names = 1;
673
			break ;
697
			break;
674
		    }
698
		    }
675
 
699
 
676
		    case 'v' : {
700
		    case 'v': {
677
			/* Print version number */
701
			/* Print version number */
678
			string v = report_version ( 1 ) ;
702
			string v = report_version(1);
679
			fprintf_v ( error_file, "%s\n\n", strlit ( v ) ) ;
703
			fprintf_v(error_file, "%s\n\n", strlit(v));
680
			break ;
704
			break;
681
		    }
705
		    }
682
 
706
 
683
		    case 'w' : {
707
		    case 'w': {
684
			/* Suppress all warnings */
708
			/* Suppress all warnings */
685
			preset ( OPT_warning, OPTION_OFF ) ;
709
			preset(OPT_warning, OPTION_OFF);
686
			check_level = 0 ;
710
			check_level = 0;
687
			break ;
711
			break;
688
		    }
712
		    }
689
 
713
 
690
		    case 'z' : {
714
		    case 'z': {
691
			/* Ignore compilation errors */
715
			/* Ignore compilation errors */
692
			preset ( OPT_error, OPTION_WARN ) ;
716
			preset(OPT_error, OPTION_WARN);
693
			max_errors = ULONG_MAX ;
717
			max_errors = ULONG_MAX;
694
			break ;
718
			break;
695
		    }
719
		    }
696
 
720
 
697
		    case '-' : {
721
		    case '-': {
698
			/* Last option */
722
			/* Last option */
699
			allow_opt = 0 ;
723
			allow_opt = 0;
700
			break ;
724
			break;
701
		    }
725
		    }
702
 
726
 
703
#ifdef DEBUG
727
#ifdef DEBUG
704
		    case 'x' : {
728
		    case 'x': {
705
			/* Debug options */
729
			/* Debug options */
706
			debug_option ( arg ) ;
730
			debug_option(arg);
707
			quit_immediately = 1 ;
731
			quit_immediately = 1;
708
			break ;
732
			break;
709
		    }
733
		    }
710
#endif
734
#endif
711
		}
735
		}
712
	    }
736
	    }
713
 
737
 
714
	    /* Deal with unknown options */
738
	    /* Deal with unknown options */
715
	    if ( known == 0 ) {
739
	    if (known == 0) {
716
		CONST char *err = "Unknown option, '-%c%s'" ;
740
		CONST char *err = "Unknown option, '-%c%s'";
717
		error ( ERROR_WARNING, err, opt, arg ) ;
741
		error(ERROR_WARNING, err, opt, arg);
718
	    }
742
	    }
719
	    opt = next_opt ;
743
	    opt = next_opt;
720
	}
744
	}
721
    }
745
    }
722
    if ( opt ) {
746
    if (opt) {
723
	CONST char *err = "Incomplete option, '-%c'" ;
747
	CONST char *err = "Incomplete option, '-%c'";
724
	error ( ERROR_WARNING, err, opt ) ;
748
	error(ERROR_WARNING, err, opt);
725
    }
749
    }
726
 
750
 
727
    /* Examine list of files */
751
    /* Examine list of files */
728
    if ( IS_NULL_list ( files ) ) {
752
    if (IS_NULL_list(files)) {
729
	CONS_string ( NULL, NULL_list ( string ), files ) ;
753
	CONS_string(NULL, NULL_list(string), files);
730
    }
754
    }
731
    if ( output || IS_NULL_list ( TAIL_list ( files ) ) ) {
755
    if (output || IS_NULL_list(TAIL_list(files))) {
732
	CONS_string ( output, files, files ) ;
756
	CONS_string(output, files, files);
733
	output_last = 1 ;
757
	output_last = 1;
734
    }
758
    }
735
    files = REVERSE_list ( files ) ;
759
    files = REVERSE_list(files);
736
    return ( files ) ;
760
    return(files);
737
}
761
}
738
 
762
 
739
 
763
 
740
/*
764
/**
741
    INITIALISE FILE LOCATIONS
765
 * INITIALISE FILE LOCATIONS
742
 
766
 *
743
    This routine initialises the standard file locations.
767
 * This routine initialises the standard file locations.
744
*/
768
 */
745
 
769
 
746
static void init_loc
770
static void
747
    PROTO_Z ()
771
init_loc(void)
748
{
772
{
749
    IGNORE set_crt_loc ( ustrlit ( "<builtin-in>" ), 1 ) ;
773
    IGNORE set_crt_loc(ustrlit("<builtin-in>"), 1);
750
    builtin_loc = crt_loc ;
774
    builtin_loc = crt_loc;
751
    IGNORE set_crt_loc ( ustrlit ( "<command-line>" ), 1 ) ;
775
    IGNORE set_crt_loc(ustrlit("<command-line>"), 1);
752
    preproc_loc = crt_loc ;
776
    preproc_loc = crt_loc;
753
    decl_loc = crt_loc ;
777
    decl_loc = crt_loc;
754
    stmt_loc = crt_loc ;
778
    stmt_loc = crt_loc;
755
    return ;
779
    return;
756
}
780
}
757
 
781
 
758
 
782
 
759
/*
783
/**
760
    PERFORM LANGUAGE DEPENDENT INITIALISATION
784
 * PERFORM LANGUAGE DEPENDENT INITIALISATION
761
 
785
 *
762
    This routine performs any language dependent initialisation not
786
 * This routine performs any language dependent initialisation not covered in
763
    covered in the main initialisation routines.  Note that the default
787
 * the main initialisation routines. Note that the default language is C++.
764
    language is C++.
-
 
765
*/
788
 */
766
 
789
 
767
static void init_lang
790
static void
768
    PROTO_N ( ( c ) )
-
 
769
    PROTO_T ( int c )
791
init_lang(int c)
770
{
792
{
771
    if ( c ) {
793
    if (c) {
772
	crt_linkage = dspec_c ;
794
	crt_linkage = dspec_c;
773
	set_std_namespace ( NULL_id ) ;
795
	set_std_namespace(NULL_id);
774
    }
796
    }
775
    init_tok ( c ) ;
797
    init_tok(c);
776
    return ;
798
    return;
777
}
799
}
778
 
800
 
779
 
801
 
780
/*
802
/**
781
    CALL MAIN INITIALISATION ROUTINES
803
 * CALL MAIN INITIALISATION ROUTINES
782
 
804
 *
783
    This routine calls all the initialisation routines.
805
 * This routine calls all the initialisation routines.
784
*/
806
 */
785
 
807
 
786
static void init_main
808
static void
787
    PROTO_Z ()
809
init_main(void)
788
{
810
{
789
    /* Set file locations */
811
    /* Set file locations */
790
    crt_loc = builtin_loc ;
812
    crt_loc = builtin_loc;
791
    decl_loc = builtin_loc ;
813
    decl_loc = builtin_loc;
792
    stmt_loc = builtin_loc ;
814
    stmt_loc = builtin_loc;
793
    preproc_loc = builtin_loc ;
815
    preproc_loc = builtin_loc;
794
 
816
 
795
    /* Initialise errors and options */
817
    /* Initialise errors and options */
796
    init_hash () ;
818
    init_hash();
797
    init_lang ( LANGUAGE_C ) ;
819
    init_lang(LANGUAGE_C);
798
    init_catalog () ;
820
    init_catalog();
799
    init_option ( check_level ) ;
821
    init_option(check_level);
800
    if ( output_diag ) record_location = 1 ;
822
    if (output_diag) record_location = 1;
801
    init_dump ( dump_name, dump_opt ) ;
823
    init_dump(dump_name, dump_opt);
802
    if ( do_header ) dump_start ( &crt_loc, NIL ( INCL_DIR ) ) ;
824
    if (do_header) dump_start(&crt_loc, NIL(INCL_DIR));
803
 
825
 
804
    /* Initialise macros and keywords */
826
    /* Initialise macros and keywords */
805
    init_char () ;
827
    init_char();
806
    init_constant () ;
828
    init_constant();
807
    init_keywords () ;
829
    init_keywords();
808
    init_macros ( builtin_macros, builtin_asserts ) ;
830
    init_macros(builtin_macros, builtin_asserts);
809
 
831
 
810
    /* Read the portability table */
832
    /* Read the portability table */
811
    read_table ( table_name ) ;
833
    read_table(table_name);
812
 
834
 
813
    /* Initialise types and namespaces */
835
    /* Initialise types and namespaces */
814
    init_namespace () ;
836
    init_namespace();
815
    push_namespace ( global_namespace ) ;
837
    push_namespace(global_namespace);
816
    init_types () ;
838
    init_types();
817
    init_literal () ;
839
    init_literal();
818
    init_exception () ;
840
    init_exception();
819
    init_printf () ;
841
    init_printf();
820
    init_initialise () ;
842
    init_initialise();
821
    init_token_args () ;
843
    init_token_args();
822
    init_templates () ;
844
    init_templates();
823
    if ( do_header ) dump_end ( &crt_loc ) ;
845
    if (do_header) dump_end(&crt_loc);
824
    return ;
846
    return;
825
}
847
}
826
 
848
 
827
 
849
 
828
/*
850
/**
829
    CALL MAIN TERMINATION ROUTINES
851
 * CALL MAIN TERMINATION ROUTINES
830
 
852
 *
831
    This routine frees any memory unneeded after the parsing routines.
853
 * This routine frees any memory unneeded after the parsing routines.
832
*/
854
 */
833
 
855
 
834
static void term_main
856
static void
835
    PROTO_Z ()
857
term_main(void)
836
{
858
{
837
    free_candidates ( &candidates ) ;
859
    free_candidates(&candidates);
838
    free_buffer ( &field_buff ) ;
860
    free_buffer(&field_buff);
839
    free_buffer ( &token_buff ) ;
861
    free_buffer(&token_buff);
840
    term_macros () ;
862
    term_macros();
841
    term_input () ;
863
    term_input();
842
    term_catalog () ;
864
    term_catalog();
843
    term_itypes () ;
865
    term_itypes();
844
    return ;
866
    return;
845
}
867
}
846
 
868
 
847
 
869
 
848
/*
870
/**
849
    CALL MAIN FILE PROCESSING ROUTINES
871
 * CALL MAIN FILE PROCESSING ROUTINES
850
 
872
 *
851
    This routine calls the main routines for processing the given list
873
 * This routine calls the main routines for processing the given list of
852
    of files.  This will have at least two elements, the last of which is
874
 * files. This will have at least two elements, the last of which is the
853
    the output file.
875
 * output file.
854
*/
876
 */
855
 
877
 
856
static void process_files
878
static void
857
    PROTO_N ( ( files ) )
-
 
858
    PROTO_T ( LIST ( string ) files )
879
process_files(LIST(string)files)
859
{
880
{
860
    /* Find output file */
881
    /* Find output file */
861
    int action ;
882
    int action;
862
    unsigned len ;
883
    unsigned len;
863
    string output ;
884
    string output;
864
    PARSE_STATE st ;
885
    PARSE_STATE st;
865
    unsigned max_len = 2 ;
886
    unsigned max_len = 2;
866
    int mode = text_mode ;
887
    int mode = text_mode;
867
    LIST ( string ) input ;
888
    LIST(string)input;
868
 
889
 
869
    /* Find output file */
890
    /* Find output file */
870
    if ( output_last ) {
891
    if (output_last) {
871
	LIST ( string ) end = END_list ( files ) ;
892
	LIST(string)end = END_list(files);
872
	output = DEREF_string ( HEAD_list ( end ) ) ;
893
	output = DEREF_string(HEAD_list(end));
873
	input = files ;
894
	input = files;
-
 
895
    } else {
-
 
896
	output = DEREF_string(HEAD_list(files));
-
 
897
	input = TAIL_list(files);
-
 
898
    }
-
 
899
    output_name[OUTPUT_TDF] = output;
-
 
900
    output_name[OUTPUT_SPEC] = spec_name;
-
 
901
 
-
 
902
    /* Find processing action */
-
 
903
    save_state(&st, 0);
-
 
904
    crt_state_depth = 0;
-
 
905
    if (spec_linker) {
-
 
906
	output_capsule = 0 ;	/* remove later */
-
 
907
	init_capsule();
-
 
908
	max_len = 0;
-
 
909
	action = 2;
-
 
910
    } else if (preproc_only) {
-
 
911
	output_name[OUTPUT_PREPROC] = output;
-
 
912
	output_tdf = 0;
-
 
913
	output_capsule = 0;
-
 
914
	action = 1;
874
    } else {
915
    } else {
875
	output = DEREF_string ( HEAD_list ( files ) ) ;
-
 
876
	input = TAIL_list ( files ) ;
-
 
877
    }
-
 
878
    output_name [ OUTPUT_TDF ] = output ;
-
 
879
    output_name [ OUTPUT_SPEC ] = spec_name ;
-
 
880
 
-
 
881
    /* Find processing action */
-
 
882
    save_state ( &st, 0 ) ;
-
 
883
    crt_state_depth = 0 ;
-
 
884
    if ( spec_linker ) {
-
 
885
	output_capsule = 0 ;	/* remove later */
-
 
886
	init_capsule () ;
916
	init_capsule();
887
	max_len = 0 ;
-
 
888
	action = 2 ;
-
 
889
    } else if ( preproc_only ) {
-
 
890
	output_name [ OUTPUT_PREPROC ] = output ;
-
 
891
	output_tdf = 0 ;
-
 
892
	output_capsule = 0 ;
-
 
893
	action = 1 ;
-
 
894
    } else {
-
 
895
	init_capsule () ;
-
 
896
	action = 0 ;
917
	action = 0;
897
    }
918
    }
898
 
919
 
899
    /* Check number of input files */
920
    /* Check number of input files */
900
    len = LENGTH_list ( files ) ;
921
    len = LENGTH_list(files);
901
    if ( max_len && len > max_len ) {
922
    if (max_len && len > max_len) {
902
	CONST char *err = "Too many arguments (should have %u)" ;
923
	CONST char *err = "Too many arguments (should have %u)";
903
	error ( ERROR_WARNING, err, max_len ) ;
924
	error(ERROR_WARNING, err, max_len);
904
	len = max_len ;
925
	len = max_len;
905
    }
926
    }
906
 
927
 
907
    /* Process start-up files in spec linker mode */
928
    /* Process start-up files in spec linker mode */
908
    if ( action == 2 ) {
929
    if (action == 2) {
909
	if ( have_startup ) {
930
	if (have_startup) {
910
	    IGNORE open_input ( mode ) ;
931
	    IGNORE open_input(mode);
911
	    crt_loc = builtin_loc ;
932
	    crt_loc = builtin_loc;
912
	    input_name = NULL ;
933
	    input_name = NULL;
913
	    input_file = NULL ;
934
	    input_file = NULL;
914
	    process_file () ;
935
	    process_file();
915
	    close_input () ;
936
	    close_input();
916
	}
937
	}
917
	mode = binary_mode ;
938
	mode = binary_mode;
918
    }
939
    }
919
 
940
 
920
    /* Scan through input files */
941
    /* Scan through input files */
921
    while ( len >= 2 ) {
942
    while (len >= 2) {
922
	/* Open input file */
943
	/* Open input file */
923
	input_name = DEREF_string ( HEAD_list ( input ) ) ;
944
	input_name = DEREF_string(HEAD_list(input));
924
	if ( !open_input ( mode ) ) {
945
	if (!open_input(mode)) {
925
	    fail ( ERR_fail_input ( input_name ) ) ;
946
	    fail(ERR_fail_input(input_name));
926
	    term_error ( 0 ) ;
947
	    term_error(0);
927
	    return ;
948
	    return;
928
	}
949
	}
929
	init_diag () ;
950
	init_diag();
930
 
951
 
931
	/* Process input file */
952
	/* Process input file */
932
	switch ( action ) {
953
	switch (action) {
933
	    case 0 : {
954
	    case 0: {
934
		/* Parsing action */
955
		/* Parsing action */
935
		process_file () ;
956
		process_file();
936
		break ;
957
		break;
937
	    }
958
	    }
938
	    case 1 : {
959
	    case 1: {
939
		/* Preprocessing action */
960
		/* Preprocessing action */
940
		preprocess_file () ;
961
		preprocess_file();
941
		break ;
962
		break;
942
	    }
963
	    }
943
	    case 2 : {
964
	    case 2: {
944
		/* Spec linker action */
965
		/* Spec linker action */
945
		if ( read_spec () ) have_syntax_error = 1 ;
966
		if (read_spec()) have_syntax_error = 1;
946
		no_declarations++ ;
967
		no_declarations++;
947
		break ;
968
		break;
948
	    }
969
	    }
949
	}
970
	}
950
 
971
 
951
	/* Close input file */
972
	/* Close input file */
952
	clear_decl_blocks () ;
973
	clear_decl_blocks();
953
	close_input () ;
974
	close_input();
954
	input = TAIL_list ( input ) ;
975
	input = TAIL_list(input);
955
	len-- ;
976
	len--;
956
    }
977
    }
957
 
978
 
958
    /* Write output file */
979
    /* Write output file */
959
    if ( have_syntax_error ) {
980
    if (have_syntax_error) {
960
	suppress_variable = 2 ;
981
	suppress_variable = 2;
961
	no_declarations++ ;
982
	no_declarations++;
962
    }
983
    }
963
    init_diag () ;
984
    init_diag();
964
    preproc_loc = crt_loc ;
985
    preproc_loc = crt_loc;
965
    restore_state ( &st ) ;
986
    restore_state(&st);
966
    if ( action == 1 ) {
987
    if (action == 1) {
967
	/* Preprocessing action */
988
	/* Preprocessing action */
968
	term_option () ;
989
	term_option();
969
    } else {
990
    } else {
970
	/* Compilation actions */
991
	/* Compilation actions */
971
	external_declaration ( NULL_exp, 0 ) ;
992
	external_declaration(NULL_exp, 0);
972
	clear_templates ( 2 ) ;
993
	clear_templates(2);
973
	term_main () ;
994
	term_main();
974
	IGNORE check_global ( complete_program ) ;
995
	IGNORE check_global(complete_program);
975
	term_option () ;
996
	term_option();
976
	compile_pending () ;
997
	compile_pending();
977
	write_capsule () ;
998
	write_capsule();
978
    }
999
    }
979
    return ;
1000
    return;
980
}
1001
}
981
 
1002
 
982
 
1003
 
983
/*
1004
/*
984
    MAIN ROUTINE
1005
 * MAIN ROUTINE
985
 
1006
 *
986
    This is the main routine.  It processes the command-line options,
1007
 * This is the main routine. It processes the command-line options, calls the
987
    calls the initialisation routines and calls the main processing
1008
 * initialisation routines and calls the main processing routine.
988
    routine.
-
 
989
*/
1009
 */
990
 
1010
 
991
int main
1011
int
992
    PROTO_N ( ( argc, argv ) )
-
 
993
    PROTO_T ( int argc X char **argv )
1012
main(int argc, char **argv)
994
{
1013
{
995
    LIST ( string ) files ;
1014
    LIST(string)files;
996
    set_progname ( argv [0], PROG_VERSION ) ;
1015
    set_progname(argv[0], PROG_VERSION);
997
    IGNORE set_machine ( FS_MACHINE ) ;
1016
    IGNORE set_machine(FS_MACHINE);
998
    init_loc () ;
1017
    init_loc();
999
    files = process_args ( argc - 1, argv + 1 ) ;
1018
    files = process_args(argc - 1, argv + 1);
1000
    builtin_startup () ;
1019
    builtin_startup();
1001
    if ( !quit_immediately ) {
1020
    if (!quit_immediately) {
1002
	/* Process files */
1021
	/* Process files */
1003
	init_main () ;
1022
	init_main();
1004
	if ( unmangle_names ) {
1023
	if (unmangle_names) {
1005
	    unmangle_list ( files, stdout, 1 ) ;
1024
	    unmangle_list(files, stdout, 1);
1006
	} else {
1025
	} else {
1007
	    process_files ( files ) ;
1026
	    process_files(files);
1008
	    term_error ( 0 ) ;
1027
	    term_error(0);
1009
	}
1028
	}
1010
    }
1029
    }
1011
    return ( exit_status ) ;
1030
    return(exit_status);
1012
}
1031
}