Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – //branches/tendra4/src/utilities/make_mf/include.c – Rev 2

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 "types.h"
33
#include "depend.h"
34
#include "error.h"
35
#include "include.h"
36
#include "option.h"
37
#include "path.h"
38
#include "tokens.h"
39
 
40
 
41
/*
42
    CURRENT PATHNAME
43
 
44
    This variable gives the pathname structure corresponding to the
45
    current input file.
46
*/
47
 
48
PATHNAME *crt_pathname = NULL ;
49
 
50
 
51
/*
52
    READ AN INCLUSION STRING
53
 
54
    This routine reads and analyses the string following a '#include' in
55
    the file f.  qo is true for quoted strings and false for angle bracket
56
    strings.
57
*/
58
 
59
static void read_incl_string
60
    PROTO_N ( ( f, qo ) )
61
    PROTO_T ( FILE *f X int qo )
62
{
63
    int c ;
64
    PATHNAME *p ;
65
    char buff [1000] ;
66
    char *s = buff ;
67
    int qc = ( qo ? '"' : '>' ) ;
68
 
69
    /* Read the string */
70
    while ( c = getc ( f ), c != qc ) {
71
	if ( c == EOF ) {
72
	    error ( ERROR_WARNING, "End of file in string" ) ;
73
	    break ;
74
	} else if ( c == '\n' ) {
75
	    error ( ERROR_WARNING, "End of line in string" ) ;
76
	    IGNORE ungetc ( c, f ) ;
77
	    break ;
78
	}
79
	*( s++ ) = ( char ) c ;
80
    }
81
    *s = 0 ;
82
 
83
    /* Create the dependency */
84
    p = search_pathname ( incl_dirs, buff, qo ) ;
85
    if ( p ) {
86
	add_dependency ( crt_pathname, p ) ;
87
	add_dependency ( h_files, p ) ;
88
    }
89
    return ;
90
}
91
 
92
 
93
/*
94
    MACHINE STATES
95
 
96
    These values give the various states for the machine used to scan for
97
    '#include' directives.
98
*/
99
 
100
#define STATE_NONE			0
101
#define STATE_NEWLINE			1
102
#define STATE_PREPROC			2
103
#define STATE_INCLUDE_I			3
104
#define STATE_INCLUDE_N			4
105
#define STATE_INCLUDE_C			5
106
#define STATE_INCLUDE_L			6
107
#define STATE_INCLUDE_U			7
108
#define STATE_INCLUDE_D			8
109
#define STATE_INCLUDE_E			9
110
#define STATE_STRING			10
111
 
112
 
113
/*
114
    PROCESS C SOURCE FILE
115
 
116
    This routine analyses the dependencies for the C source, or similar,
117
    file given by p.  The file parsing algorithms are rather simple.
118
*/
119
 
120
void process_file
121
    PROTO_N ( ( p ) )
122
    PROTO_T ( PATHNAME *p )
123
{
124
    int c ;
125
    FILE *f ;
126
    char *nm = p->full ;
127
    int state = STATE_NEWLINE ;
128
 
129
    /* Open the input file */
130
    crt_line_no = 1 ;
131
    crt_file_name = nm ;
132
    f = fopen ( nm, "r" ) ;
133
    if ( f == NULL ) {
134
	if ( p->exists == 0 ) {
135
	    error ( ERROR_SERIOUS, "Can't open input file, '%s'", nm ) ;
136
	    p->exists = 1 ;
137
	}
138
	crt_file_name = NULL ;
139
	return ;
140
    }
141
    crt_pathname = p ;
142
 
143
    while ( c = getc ( f ), c != EOF ) {
144
 
145
	switch ( c ) {
146
 
147
	    case ' ' :
148
	    case '\t' :
149
	    case '\f' :
150
	    case '\v' : {
151
		/* White space */
152
		if ( state >= STATE_INCLUDE_I &&
153
		     state < STATE_INCLUDE_E ) {
154
		    state = STATE_NONE ;
155
		} else {
156
		    /* state unchanged */
157
		}
158
		break ;
159
	    }
160
 
161
	    case '\n' : {
162
		/* New lines */
163
		state = STATE_NEWLINE ;
164
		crt_line_no++ ;
165
		break ;
166
	    }
167
 
168
	    case '\\' : {
169
		/* Escaped newlines */
170
		c = getc ( f ) ;
171
		if ( c == '\n' ) {
172
		    /* state unchanged */
173
		    crt_line_no++ ;
174
		} else {
175
		    IGNORE ungetc ( c, f ) ;
176
		    goto default_lab ;
177
		}
178
		break ;
179
	    }
180
 
181
	    case '/' : {
182
		/* Comments */
183
		c = getc ( f ) ;
184
		if ( c == '*' ) {
185
		    int comment = 0 ;
186
		    while ( comment != 2 ) {
187
			c = getc ( f ) ;
188
			if ( c == EOF ) {
189
			    error ( ERROR_WARNING, "End of file in comment" ) ;
190
			    break ;
191
			} else if ( c == '\n' ) {
192
			    crt_line_no++ ;
193
			    comment = 0 ;
194
			} else if ( c == '*' ) {
195
			    comment = 1 ;
196
			} else if ( comment == 1 && c == '/' ) {
197
			    comment = 2 ;
198
			} else {
199
			    comment = 0 ;
200
			}
201
		    }
202
		} else if ( c == '/' ) {
203
		    do {
204
			c = getc ( f ) ;
205
			if ( c == EOF ) {
206
			    error ( ERROR_WARNING, "End of file in comment" ) ;
207
			    break ;
208
			}
209
		    } while ( c != '\n' ) ;
210
		    crt_line_no++ ;
211
		} else {
212
		    IGNORE ungetc ( c, f ) ;
213
		    goto default_lab ;
214
		}
215
		if ( state >= STATE_INCLUDE_I && state < STATE_INCLUDE_E ) {
216
		    state = STATE_NONE ;
217
		} else {
218
		    /* state unchanged */
219
		}
220
		break ;
221
	    }
222
 
223
	    case '#' : {
224
		/* Hash symbol */
225
		if ( state != STATE_NEWLINE ) goto default_lab ;
226
		state = STATE_PREPROC ;
227
		break ;
228
	    }
229
 
230
	    case 'i' : {
231
		/* The i of include */
232
		if ( state != STATE_PREPROC ) goto default_lab ;
233
		state = STATE_INCLUDE_I ;
234
		break ;
235
	    }
236
 
237
	    case 'n' : {
238
		/* The n of include */
239
		if ( state != STATE_INCLUDE_I ) goto default_lab ;
240
		state = STATE_INCLUDE_N ;
241
		break ;
242
	    }
243
 
244
	    case 'c' : {
245
		/* The c of include */
246
		if ( state != STATE_INCLUDE_N ) goto default_lab ;
247
		state = STATE_INCLUDE_C ;
248
		break ;
249
	    }
250
 
251
	    case 'l' : {
252
		/* The l of include */
253
		if ( state != STATE_INCLUDE_C ) goto default_lab ;
254
		state = STATE_INCLUDE_L ;
255
		break ;
256
	    }
257
 
258
	    case 'u' : {
259
		/* The u of include */
260
		if ( state != STATE_INCLUDE_L ) goto default_lab ;
261
		state = STATE_INCLUDE_U ;
262
		break ;
263
	    }
264
 
265
	    case 'd' : {
266
		/* The d of include */
267
		if ( state != STATE_INCLUDE_U ) goto default_lab ;
268
		state = STATE_INCLUDE_D ;
269
		break ;
270
	    }
271
 
272
	    case 'e' : {
273
		/* The e of include */
274
		if ( state != STATE_INCLUDE_D ) goto default_lab ;
275
		state = STATE_INCLUDE_E ;
276
		break ;
277
	    }
278
 
279
	    case '<' : {
280
		if ( state != STATE_INCLUDE_E ) goto default_lab ;
281
		read_incl_string ( f, 0 ) ;
282
		state = STATE_STRING ;
283
		break ;
284
	    }
285
 
286
	    case '"' : {
287
		if ( state != STATE_INCLUDE_E ) goto skip_string_lab ;
288
		read_incl_string ( f, 1 ) ;
289
		state = STATE_STRING ;
290
		break ;
291
	    }
292
 
293
	    case '\'' :
294
	    skip_string_lab : {
295
		/* Normal string literals */
296
		int escaped = 0 ;
297
		int qo = c ;
298
		do {
299
		    c = getc ( f ) ;
300
		    if ( c == EOF ) {
301
			error ( ERROR_WARNING, "End of file in string" ) ;
302
			break ;
303
		    }
304
		    if ( escaped ) {
305
			escaped = 0 ;
306
			if ( c == '\n' ) crt_line_no++ ;
307
			c = 'x' ;
308
		    } else {
309
			if ( c == '\\' ) escaped = 1 ;
310
			if ( c == '\n' ) {
311
			    error ( ERROR_WARNING, "End of line in string" ) ;
312
			    IGNORE ungetc ( c, f ) ;
313
			    break ;
314
			}
315
		    }
316
		} while ( c != qo ) ;
317
		goto default_lab ;
318
	    }
319
 
320
	    default :
321
	    default_lab : {
322
		if ( state == STATE_INCLUDE_E ) {
323
		    error ( ERROR_WARNING,
324
			    "Unrecognised '#include' directive" ) ;
325
		} else if ( state == STATE_STRING ) {
326
		    error ( ERROR_WARNING,
327
			    "End of '#include' directive expected" ) ;
328
		}
329
		state = STATE_NONE ;
330
		break ;
331
	    }
332
	}
333
    }
334
 
335
    /* Close the input file */
336
    fclose_v ( f ) ;
337
    crt_file_name = NULL ;
338
    crt_pathname = NULL ;
339
    return ;
340
}
341
 
342
 
343
/*
344
    TEST WHETHER A FILE EXISTS
345
 
346
    This routine tests whether the file given by the pathname p exists.
347
*/
348
 
349
void test_file
350
    PROTO_N ( ( p ) )
351
    PROTO_T ( PATHNAME *p )
352
{
353
    if ( p->exists == 0 ) {
354
	char *nm = p->full ;
355
	FILE *f = fopen ( nm, "r" ) ;
356
	if ( f == NULL ) {
357
	    crt_line_no = 1 ;
358
	    crt_file_name = nm ;
359
	    error ( ERROR_SERIOUS, "Can't open input file, '%s'", nm ) ;
360
	    crt_file_name = NULL ;
361
	    p->exists = 1 ;
362
	    return ;
363
	}
364
	fclose_v ( f ) ;
365
    }
366
    return ;
367
}