Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
#include "config.h"
32
#include <limits.h>
33
#include "system.h"
34
#include "c_types.h"
35
#include "hashid_ops.h"
36
#include "error.h"
37
#include "catalog.h"
38
#include "option.h"
39
#include "char.h"
40
#include "file.h"
41
#include "inttype.h"
42
#include "lex.h"
43
#include "literal.h"
44
#include "macro.h"
45
#include "preproc.h"
46
#include "syntax.h"
47
#include "table.h"
48
#include "ustring.h"
49
 
50
 
51
/*
52
    PORTABILITY TABLE ENTRIES
53
 
54
    This table describes the portability table entries.  The entries need
55
    to be keep in one-to-one correspondence with the PORT_* macros defined
56
    in table.h.
57
*/
58
 
59
PORT_ENTRY port_entry [] = {
60
    { "char_bits", 0, 0, btype_none },			/* 0 */
61
    { "short_bits", 0, 0, btype_none },			/* 1 */
62
    { "int_bits", 0, 0, btype_none },			/* 2 */
63
    { "long_bits", 0, 0, btype_none },			/* 3 */
64
    { "longlong_bits", 1, 0, btype_none },		/* 4 */
65
    { "max_bits", 1, UINT_MAX, btype_none },		/* 5 */
66
    { "signed_range", 0, 0, btype_none },		/* 6 */
67
    { "char_type", 0, 0, btype_none },			/* 7 */
68
    { "exact_range", 1, 0, btype_none },		/* 8 */
69
    { "ptr_int", 1, 0, btype_none },			/* 9 */
70
    { "ptr_fn", 1, 0, btype_none },			/* 10 */
71
    { "non_prototype_checks", 1, 0, btype_none },	/* 11 */
72
    { "multibyte", 1, 0, btype_none }			/* 12 */
73
} ;
74
 
75
 
76
/*
77
    PARSE A PORTABILITY TABLE
78
 
79
    This routine parses and processes the portability table.  It returns
80
    the last token read.
81
*/
82
 
83
static int parse_table
84
    PROTO_Z ()
85
{
86
    int t ;
87
    PORT_ENTRY *p = port_entry ;
88
    while ( t = read_token (), t == lex_identifier ) {
89
	int i ;
90
	unsigned n = 0 ;
91
	HASHID nm = token_hashid ;
92
	BASE_TYPE bt = btype_none ;
93
	string us = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
94
	update_column () ;
95
 
96
	/* Check through table entries */
97
	for ( i = 0 ; i < PORT_size ; i++ ) {
98
	    string ut = ustrlit ( p [i].name ) ;
99
	    if ( ustreq ( us, ut ) ) {
100
		/* Entry found */
101
		if ( p [i].set == 2 ) {
102
		    report ( crt_loc, ERR_port_entry_redef ( ut ) ) ;
103
		}
104
		p [i].set = 2 ;
105
		break ;
106
	    }
107
	}
108
 
109
	/* Perform appropriate action */
110
	switch ( i ) {
111
 
112
	    case PORT_char_bits :
113
	    case PORT_short_bits :
114
	    case PORT_int_bits :
115
	    case PORT_long_bits :
116
	    case PORT_llong_bits :
117
	    case PORT_max_bits :
118
	    case PORT_multibyte : {
119
		/* Deal with integral values */
120
		unsigned err = 0 ;
121
		t = read_token () ;
122
		update_column () ;
123
		if ( t != lex_integer_Hlit ) return ( t ) ;
124
		us = token_buff.start ;
125
		n = ( unsigned ) eval_line_digits ( us, &err ) ;
126
		if ( err ) report ( crt_loc, ERR_lex_literal_bad ( us ) ) ;
127
		break ;
128
	    }
129
 
130
	    case PORT_signed_range : {
131
		/* Deal with range values */
132
		t = read_token () ;
133
		update_column () ;
134
		if ( t != lex_identifier ) return ( t ) ;
135
		nm = token_hashid ;
136
		us = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
137
		if ( ustrseq ( us, "maximum" ) ) {
138
		    bt = ( btype_signed | btype_long ) ;
139
		} else if ( ustrseq ( us, "symmetric" ) ) {
140
		    bt = btype_signed ;
141
		} else {
142
		    return ( t ) ;
143
		}
144
		break ;
145
	    }
146
 
147
	    case PORT_char_type : {
148
		/* Deal with sign values */
149
		t = read_token () ;
150
		update_column () ;
151
		if ( t != lex_identifier ) return ( t ) ;
152
		nm = token_hashid ;
153
		us = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
154
		if ( ustrseq ( us, "signed" ) ) {
155
		    bt = btype_signed ;
156
		} else if ( ustrseq ( us, "unsigned" ) ) {
157
		    bt = btype_unsigned ;
158
		} else if ( ustrseq ( us, "either" ) ) {
159
		    bt = btype_none ;
160
		} else {
161
		    return ( t ) ;
162
		}
163
		break ;
164
	    }
165
 
166
	    case PORT_ptr_int : {
167
		/* Deal with type values */
168
		t = read_token () ;
169
		update_column () ;
170
		if ( t != lex_identifier ) return ( t ) ;
171
		nm = token_hashid ;
172
		us = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
173
		if ( ustrseq ( us, "char" ) ) {
174
		    bt = btype_char ;
175
		} else if ( ustrseq ( us, "short" ) ) {
176
		    bt = btype_short ;
177
		} else if ( ustrseq ( us, "int" ) ) {
178
		    bt = btype_int ;
179
		} else if ( ustrseq ( us, "long" ) ) {
180
		    bt = btype_long ;
181
		} else if ( ustrseq ( us, "none" ) ) {
182
		    bt = btype_none ;
183
		} else {
184
		    return ( t ) ;
185
		}
186
		break ;
187
	    }
188
 
189
	    case PORT_exact_range :
190
	    case PORT_ptr_fn :
191
	    case PORT_non_proto : {
192
		/* Deal with boolean values */
193
		t = read_token () ;
194
		update_column () ;
195
		if ( t != lex_identifier ) return ( t ) ;
196
		nm = token_hashid ;
197
		us = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
198
		if ( ustrseq ( us, "no" ) ) {
199
		    n = 0 ;
200
		} else if ( ustrseq ( us, "yes" ) ) {
201
		    n = 1 ;
202
		} else {
203
		    return ( t ) ;
204
		}
205
		break ;
206
	    }
207
 
208
	    default : {
209
		/* Unknown entry identifier */
210
		return ( t ) ;
211
	    }
212
	}
213
	p [i].value = n ;
214
	p [i].type = bt ;
215
    }
216
    return ( t ) ;
217
}
218
 
219
 
220
/*
221
    READ THE PORTABILITY TABLE
222
 
223
    This routine reads and processes the portability table given by nm.
224
*/
225
 
226
void read_table
227
    PROTO_N ( ( nm ) )
228
    PROTO_T ( string nm )
229
{
230
    int set = 0 ;
231
    PORT_ENTRY *p = port_entry ;
232
 
233
    /* Read table */
234
    if ( nm ) {
235
	int i, t ;
236
	input_name = nm ;
237
	if ( !open_input ( text_mode ) ) {
238
	    /* Can't open portability table */
239
	    fail ( ERR_fail_port ( nm ) ) ;
240
	} else {
241
	    /* Read portability table */
242
	    set = 1 ;
243
	    pragma_number = 1 ;
244
	    no_preproc_dir = 1 ;
245
	    crt_buff_no = 0 ;
246
	    IGNORE init_buffer ( crt_buff_no ) ;
247
	    unread_char ( char_newline ) ;
248
	    crt_loc.line-- ;
249
	    t = parse_table () ;
250
	    update_column () ;
251
	    if ( t != lex_eof ) {
252
		/* Parse error in portability table */
253
		PPTOKEN *r = new_pptok () ;
254
		r->tok = t ;
255
		token_parts ( t, r ) ;
256
		report ( crt_loc, ERR_lex_parse ( r ) ) ;
257
		set = 0 ;
258
	    } else {
259
		/* Check for undefined values */
260
		for ( i = 0 ; i < PORT_size ; i++ ) {
261
		    if ( p [i].set == 0 ) {
262
			string nt = ustrlit ( p [i].name ) ;
263
			report ( crt_loc, ERR_port_entry_undef ( nt ) ) ;
264
			set = 0 ;
265
		    }
266
		}
267
	    }
268
	    no_preproc_dir = 0 ;
269
	    pragma_number = 0 ;
270
	    close_input () ;
271
	}
272
    }
273
 
274
    /* Set values from table */
275
    if ( set ) {
276
	unsigned m ;
277
	unsigned long n ;
278
	BASE_INFO *q = basetype_info ;
279
	set_char_sign ( p [ PORT_char_type ].type ) ;
280
	if ( p [ PORT_llong_bits ].set == 2 ) {
281
	    /* 'long long' types are allowed */
282
	    set_option ( OPT_longlong, ( unsigned ) OPTION_ALLOW ) ;
283
	    m = p [ PORT_llong_bits ].value ;
284
	} else {
285
	    /* 'long long' types are not allowed */
286
	    m = p [ PORT_long_bits ].value ;
287
	    p [ PORT_llong_bits ].value = m ;
288
	}
289
	if ( p [ PORT_exact_range ].value == 0 ) {
290
	    /* Find maximum number of bits in an integer */
291
	    m = p [ PORT_max_bits ].value ;
292
	}
293
	for ( n = 0 ; n < ORDER_ntype ; n++ ) {
294
	    unsigned exact = p [ PORT_exact_range ].value ;
295
	    switch ( n ) {
296
		case ntype_char :
297
		case ntype_schar :
298
		case ntype_uchar : {
299
		    q [n].min_bits = p [ PORT_char_bits ].value ;
300
		    q [n].max_bits = m ;
301
		    break ;
302
		}
303
		case ntype_sshort :
304
		case ntype_ushort : {
305
		    q [n].min_bits = p [ PORT_short_bits ].value ;
306
		    q [n].max_bits = m ;
307
		    break ;
308
		}
309
		case ntype_sint :
310
		case ntype_uint :
311
		case ntype_none : {
312
		    q [n].min_bits = p [ PORT_int_bits ].value ;
313
		    q [n].max_bits = m ;
314
		    break ;
315
		}
316
		case ntype_slong :
317
		case ntype_ulong : {
318
		    q [n].min_bits = p [ PORT_long_bits ].value ;
319
		    q [n].max_bits = m ;
320
		    break ;
321
		}
322
		case ntype_sllong :
323
		case ntype_ullong : {
324
		    q [n].min_bits = p [ PORT_llong_bits ].value ;
325
		    q [n].max_bits = m ;
326
		    break ;
327
		}
328
		case ntype_ptrdiff_t :
329
		case ntype_size_t : {
330
		    q [n].min_bits = p [ PORT_int_bits ].value ;
331
		    q [n].max_bits = m ;
332
		    exact = 0 ;
333
		    break ;
334
		}
335
		case ntype_wchar_t :
336
		case ntype_ellipsis : {
337
		    q [n].min_bits = p [ PORT_char_bits ].value ;
338
		    q [n].max_bits = m ;
339
		    exact = 0 ;
340
		    break ;
341
		}
342
	    }
343
	    if ( exact ) {
344
		/* Exact integer range known */
345
		q [n].max_bits = q [n].min_bits ;
346
	    }
347
	    if ( q [n].sign & btype_signed ) {
348
		/* Set signed type range */
349
		q [n].sign = p [ PORT_signed_range ].type ;
350
	    }
351
	}
352
	if ( p [ PORT_exact_range ].value ) {
353
	    /* Set exact type ranges */
354
	    set_exact_types () ;
355
	}
356
    }
357
    return ;
358
}