Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | 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 "calculus.h"
33
#include "check.h"
34
#include "common.h"
35
#include "error.h"
36
#include "output.h"
37
#include "type_ops.h"
38
#include "xalloc.h"
39
 
40
 
41
/*
42
    LIST OF ALL NAMES
43
 
44
    This variable contains a list of all the names defined within the algebra.
45
*/
46
 
47
static NAME *all_names = NULL ;
48
 
49
 
50
/*
51
    ARRAY OF NAME ERRORS
52
 
53
    This array gives all the errors associated with the various name types.
54
*/
55
 
56
static char *name_error [] = {
57
    "Type name %s",
58
    "Auxilliary type name %s",
59
    "Enumeration constant %s.%s",
60
    "Structure component %s.%s",
61
    "Union component %s.%s",
62
    "Union field component %s.%s.%s",
63
    "Union map %s.%s",
64
    "Union map argument %s.%s"
65
} ;
66
 
67
 
68
/*
69
    LOOK UP A NAME
70
 
71
    This routine looks up the name with type n and components a, b and c in
72
    the list of all names.
73
*/
74
 
75
static NAME *find_name
76
    PROTO_N ( ( n, a, b, c ) )
77
    PROTO_T ( int n X char *a X char *b X char *c )
78
{
79
    NAME *p ;
80
    for ( p = all_names ; p != NULL ; p = p->next ) {
81
	if ( p->type == n && streq ( p->text [0], a ) &&
82
	     streq ( p->text [1], b ) && streq ( p->text [2], c ) ) {
83
	    return ( p ) ; ;
84
	}
85
    }
86
    return ( NULL ) ;
87
}
88
 
89
 
90
/*
91
    CREATE A NAME
92
 
93
    This routine adds the name with type n and components a, b and c to the
94
    list of all names.
95
*/
96
 
97
static void make_name
98
    PROTO_N ( ( n, a, b, c ) )
99
    PROTO_T ( int n X char *a X char *b X char *c )
100
{
101
    static int names_left = 0 ;
102
    static NAME *names_free = NULL ;
103
    NAME *p = find_name ( n, a, b, c ) ;
104
    if ( p ) {
105
	char buffer [1000] ;
106
	sprintf_v ( buffer, name_error [n], a, b, c ) ;
107
	error ( ERROR_SERIOUS, "%s already defined (at %s, line %d)",
108
		buffer, p->file, p->line ) ;
109
	return ;
110
    }
111
    if ( names_left == 0 ) {
112
	names_left = 1000 ;
113
	names_free = xmalloc_nof ( NAME, names_left ) ;
114
    }
115
    p = names_free + ( --names_left ) ;
116
    p->type = n ;
117
    p->text [0] = a ;
118
    p->text [1] = b ;
119
    p->text [2] = c ;
120
    p->file = crt_file_name ;
121
    p->line = crt_line_no ;
122
    p->next = all_names ;
123
    all_names = p ;
124
    return ;
125
}
126
 
127
 
128
/*
129
    EXTRACT NAMES FROM AN IDENTIFIER
130
 
131
    This routine assigns the names from the identifier id into na and nb.
132
    It also sets the current file position to the location of id.
133
*/
134
 
135
static void split_id
136
    PROTO_N ( ( id, na, nb ) )
137
    PROTO_T ( CLASS_ID_P id X char **na X char **nb )
138
{
139
    *na = DEREF_string ( cid_name ( id ) ) ;
140
    *nb = DEREF_string ( cid_name_aux ( id ) ) ;
141
    crt_file_name = DEREF_string ( cid_file ( id ) ) ;
142
    crt_line_no = DEREF_int ( cid_line ( id ) ) ;
143
    return ;
144
}
145
 
146
 
147
/*
148
    CHECK FOR NAME CLASHES
149
 
150
    This routine scans through the entire algebra definition checking for
151
    name clashes.  Type names are only checked if c is true.
152
*/
153
 
154
void check_names
155
    PROTO_N ( ( c ) )
156
    PROTO_T ( int c )
157
{
158
    CLASS_ID_P id ;
159
    char *na, *nb ;
160
    char *empty = "" ;
161
    int line = crt_line_no ;
162
    CONST char *file = crt_file_name ;
163
    all_names = NULL ;
164
 
165
    LOOP_PRIMITIVE {
166
	id = DEREF_ptr ( prim_id ( CRT_PRIMITIVE ) ) ;
167
	split_id ( id, &na, &nb ) ;
168
	if ( c ) make_name ( NAME_TYPE, na, empty, empty ) ;
169
	make_name ( NAME_TYPE_AUX, nb, empty, empty ) ;
170
    }
171
 
172
    LOOP_IDENTITY {
173
	id = DEREF_ptr ( ident_id ( CRT_IDENTITY ) ) ;
174
	split_id ( id, &na, &nb ) ;
175
	if ( c ) make_name ( NAME_TYPE, na, empty, empty ) ;
176
	make_name ( NAME_TYPE_AUX, nb, empty, empty ) ;
177
    }
178
 
179
    LOOP_ENUM {
180
	id = DEREF_ptr ( en_id ( CRT_ENUM ) ) ;
181
	split_id ( id, &na, &nb ) ;
182
	if ( c ) make_name ( NAME_TYPE, na, empty, empty ) ;
183
	make_name ( NAME_TYPE_AUX, nb, empty, empty ) ;
184
	LOOP_ENUM_CONST {
185
	    char *ne = DEREF_string ( ec_name ( CRT_ECONST ) ) ;
186
	    make_name ( NAME_ENUM_CONST, na, ne, empty ) ;
187
	}
188
    }
189
 
190
    LOOP_STRUCTURE {
191
	id = DEREF_ptr ( str_id ( CRT_STRUCTURE ) ) ;
192
	split_id ( id, &na, &nb ) ;
193
	if ( c ) make_name ( NAME_TYPE, na, empty, empty ) ;
194
	make_name ( NAME_TYPE_AUX, nb, empty, empty ) ;
195
	LOOP_STRUCTURE_COMPONENT {
196
	    char *nc = DEREF_string ( cmp_name ( CRT_COMPONENT ) ) ;
197
	    make_name ( NAME_STRUCT_CMP, na, nc, empty ) ;
198
	}
199
    }
200
 
201
    LOOP_UNION {
202
	id = DEREF_ptr ( un_id ( CRT_UNION ) ) ;
203
	split_id ( id, &na, &nb ) ;
204
	if ( c ) make_name ( NAME_TYPE, na, empty, empty ) ;
205
	make_name ( NAME_TYPE_AUX, nb, empty, empty ) ;
206
	LOOP_UNION_COMPONENT {
207
	    char *nc = DEREF_string ( cmp_name ( CRT_COMPONENT ) ) ;
208
	    make_name ( NAME_UNION_CMP, na, nc, empty ) ;
209
	}
210
	LOOP_UNION_FIELD {
211
	    char *nf = DEREF_string ( fld_name ( CRT_FIELD ) ) ;
212
	    make_name ( NAME_UNION_CMP, na, nf, empty ) ;
213
	    LOOP_FIELD_COMPONENT {
214
		char *nc = DEREF_string ( cmp_name ( CRT_COMPONENT ) ) ;
215
		make_name ( NAME_FIELD_CMP, na, nf, nc ) ;
216
	    }
217
	}
218
	LOOP_UNION_MAP {
219
	    char *nm = DEREF_string ( map_name ( CRT_MAP ) ) ;
220
	    make_name ( NAME_MAP, na, nm, empty ) ;
221
	    LOOP_MAP_ARGUMENT {
222
		char *np = DEREF_string ( arg_name ( CRT_ARGUMENT ) ) ;
223
		make_name ( NAME_MAP_ARG, na, nm, np ) ;
224
	    }
225
	}
226
    }
227
 
228
    crt_file_name = file ;
229
    crt_line_no = line ;
230
    return ;
231
}