Subversion Repositories tendra.SVN

Rev

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

Rev 5 Rev 6
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
32
    		 Crown Copyright (c) 1997
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 42... Line 72...
42
 
72
 
43
    The current line in the file is recorded.  The previous line (where
73
    The current line in the file is recorded.  The previous line (where
44
    any errors were likely to have been) is also saved.
74
    any errors were likely to have been) is also saved.
45
*/
75
*/
46
 
76
 
47
long crt_line_no = 1 ;
77
long crt_line_no = 1;
48
long line_no = 1 ;
78
long line_no = 1;
49
 
79
 
50
 
80
 
51
/*
81
/*
52
    FORM OF INPUT
82
    FORM OF INPUT
53
 
83
 
54
    This flag controls whether the input should be lisp-like (default)
84
    This flag controls whether the input should be lisp-like (default)
55
    or c-like.
85
    or c-like.
56
*/
86
*/
57
 
87
 
58
boolean func_input = 0 ;
88
boolean func_input = 0;
59
 
89
 
60
 
90
 
61
/*
91
/*
62
    ANALYSE FLAGS
92
    ANALYSE FLAGS
63
 
93
 
64
    The looked_ahead flag is true to indicate that the next word has
94
    The looked_ahead flag is true to indicate that the next word has
65
    already been read.  The really_analyse flag is false to indicate
95
    already been read.  The really_analyse flag is false to indicate
66
    that the next word may be ignored.
96
    that the next word may be ignored.
67
*/
97
*/
68
 
98
 
69
boolean looked_ahead = 0 ;
99
boolean looked_ahead = 0;
70
static boolean really_analyse = 1 ;
100
static boolean really_analyse = 1;
71
 
101
 
72
 
102
 
73
/*
103
/*
74
    INPUT BUFFER
104
    INPUT BUFFER
75
 
105
 
76
    The input is read into a buffer.
106
    The input is read into a buffer.
77
*/
107
*/
78
 
108
 
79
#define BUFFSIZE	5000
109
#define BUFFSIZE	5000
80
static char word_buff [ BUFFSIZE ] ;
110
static char word_buff[BUFFSIZE];
81
 
111
 
82
 
112
 
83
/*
113
/*
84
    LAST WORD READ
114
    LAST WORD READ
85
 
115
 
86
    The word just read from the input file is word.  It has length
116
    The word just read from the input file is word.  It has length
87
    word_length and input type word_type.
117
    word_length and input type word_type.
88
*/
118
*/
89
 
119
 
90
char *word = "" ;
120
char *word = "";
91
long word_length ;
121
long word_length;
92
int word_type = INPUT_EOF ;
122
int word_type = INPUT_EOF;
93
 
123
 
94
 
124
 
95
/*
125
/*
96
    PENDING CHARACTER
126
    PENDING CHARACTER
97
 
127
 
98
    In reading a word we almost always read one too many character.
128
    In reading a word we almost always read one too many character.
99
    This is stored in pending.  A value of 0 indicates that there is
129
    This is stored in pending.  A value of 0 indicates that there is
100
    no pending character.
130
    no pending character.
101
*/
131
*/
102
 
132
 
103
static int pending = 0 ;
133
static int pending = 0;
104
 
134
 
105
 
135
 
106
/*
136
/*
107
    READ THE NEXT WORD
137
    READ THE NEXT WORD
108
 
138
 
109
    The next word is read from the input file.
139
    The next word is read from the input file.
110
*/
140
*/
111
 
141
 
112
void read_word
142
void
113
    PROTO_Z ()
143
read_word(void)
114
{
144
{
115
    int c ;
145
    int c;
116
    char *p ;
146
    char *p;
117
    int negate = 0 ;
147
    int negate = 0;
118
    unsigned base = 10 ;
148
    unsigned base = 10;
119
 
149
 
120
    /* If we have looked ahead one, return last value */
150
    /* If we have looked ahead one, return last value */
121
    if ( looked_ahead ) {
151
    if (looked_ahead) {
122
	looked_ahead = 0 ;
152
	looked_ahead = 0;
123
	return ;
153
	return;
124
    }
154
    }
125
 
155
 
126
    /* Get the first letter */
156
    /* Get the first letter */
127
    if ( pending ) {
157
    if (pending) {
128
	c = pending ;
158
	c = pending;
129
	if ( c == EOF ) {
159
	if (c == EOF) {
130
	    word_type = INPUT_EOF ;
160
	    word_type = INPUT_EOF;
131
	    return ;
161
	    return;
132
	}
162
	}
133
	pending = 0 ;
163
	pending = 0;
134
    } else {
164
    } else {
135
	c = getc ( input ) ;
165
	c = getc(input);
136
	if ( c == '\n' ) crt_line_no++ ;
166
	if (c == '\n')crt_line_no++;
137
    }
167
    }
138
 
168
 
139
    /* Step over any white space and comments */
169
    /* Step over any white space and comments */
140
    while ( white_space ( c ) || c == '#' ) {
170
    while (white_space(c) || c == '#') {
141
	if ( c == '#' ) {
171
	if (c == '#') {
142
	    /* Comments go to the end of the line */
172
	    /* Comments go to the end of the line */
143
	    while ( c = getc ( input ), c != '\n' ) {
173
	    while (c = getc(input), c != '\n') {
144
		if ( c == EOF ) {
174
		if (c == EOF) {
145
		    is_fatal = 0 ;
175
		    is_fatal = 0;
146
		    input_error ( "End of file in comment" ) ;
176
		    input_error("End of file in comment");
147
		    word_type = INPUT_EOF ;
177
		    word_type = INPUT_EOF;
148
		    pending = EOF ;
178
		    pending = EOF;
149
		    return ;
179
		    return;
150
		}
180
		}
151
	    }
181
	    }
152
	    crt_line_no++ ;
182
	    crt_line_no++;
153
	} else {
183
	} else {
154
	    c = getc ( input ) ;
184
	    c = getc(input);
155
	    if ( c == '\n' ) crt_line_no++ ;
185
	    if (c == '\n')crt_line_no++;
156
	}
186
	}
157
    }
187
    }
158
    line_no = crt_line_no ;
188
    line_no = crt_line_no;
159
 
189
 
160
    /* Check for end of file */
190
    /* Check for end of file */
161
    if ( c == EOF ) {
191
    if (c == EOF) {
162
	word_type = INPUT_EOF ;
192
	word_type = INPUT_EOF;
163
	pending = EOF ;
193
	pending = EOF;
164
	return ;
194
	return;
165
    }
195
    }
166
 
196
 
167
    /* Check for open brackets */
197
    /* Check for open brackets */
168
    if ( c == '(' ) {
198
    if (c == '(') {
169
	word = "(" ;
199
	word = "(";
170
	word_type = INPUT_OPEN ;
200
	word_type = INPUT_OPEN;
171
	return ;
201
	return;
172
    }
202
    }
173
 
203
 
174
    /* Check for close brackets */
204
    /* Check for close brackets */
175
    if ( c == ')' ) {
205
    if (c == ')') {
176
	word = ")" ;
206
	word = ")";
177
	word_type = INPUT_CLOSE ;
207
	word_type = INPUT_CLOSE;
178
	return ;
208
	return;
179
    }
209
    }
180
 
210
 
181
    if ( func_input ) {
211
    if (func_input) {
182
	/* Check for commas (c-like input only) */
212
	/* Check for commas (c-like input only) */
183
	if ( c == ',' ) {
213
	if (c == ',') {
184
	    word = "," ;
214
	    word = ",";
185
	    word_type = INPUT_COMMA ;
215
	    word_type = INPUT_COMMA;
186
	    return ;
216
	    return;
187
	}
217
	}
188
 
218
 
189
	/* Check for semicolons (c-like input only) */
219
	/* Check for semicolons (c-like input only) */
190
	if ( c == ';' ) {
220
	if (c == ';') {
191
	    word = ";" ;
221
	    word = ";";
192
	    word_type = INPUT_SEMICOLON ;
222
	    word_type = INPUT_SEMICOLON;
193
	    return ;
223
	    return;
194
	}
224
	}
195
    }
225
    }
196
 
226
 
197
    /* Check for strings */
227
    /* Check for strings */
198
    if ( c == '"' ) {
228
    if (c == '"') {
199
	boolean escaped ;
229
	boolean escaped;
200
	p = word_buff ;
230
	p = word_buff;
201
	do {
231
	do {
202
	    boolean ignore = 0 ;
232
	    boolean ignore = 0;
203
	    escaped = 0 ;
233
	    escaped = 0;
204
	    c = getc ( input ) ;
234
	    c = getc(input);
205
	    if ( c == '\n' ) {
235
	    if (c == '\n') {
206
		is_fatal = 0 ;
236
		is_fatal = 0;
207
		input_error ( "New line in string" ) ;
237
		input_error("New line in string");
208
		crt_line_no++ ;
238
		crt_line_no++;
209
		line_no = crt_line_no ;
239
		line_no = crt_line_no;
210
		ignore = 1 ;
240
		ignore = 1;
211
	    }
241
	    }
212
	    if ( c == '\\' ) {
242
	    if (c == '\\') {
213
		escaped = 1 ;
243
		escaped = 1;
214
		c = getc ( input ) ;
244
		c = getc(input);
215
		if ( c == '\n' ) {
245
		if (c == '\n') {
216
		    crt_line_no++ ;
246
		    crt_line_no++;
217
		    line_no = crt_line_no ;
247
		    line_no = crt_line_no;
218
		    ignore = 1 ;
248
		    ignore = 1;
219
		} else if ( c == 'n' ) {
249
		} else if (c == 'n') {
220
		    c = '\n' ;
250
		    c = '\n';
221
		} else if ( c == 't' ) {
251
		} else if (c == 't') {
222
		    c = '\t' ;
252
		    c = '\t';
223
		} else if ( octal_digit ( c ) ) {
253
		} else if (octal_digit(c)) {
224
		    int e = ( c - '0' ) ;
254
		    int e = (c - '0');
225
		    c = getc ( input ) ;
255
		    c = getc(input);
226
		    if ( !octal_digit ( c ) ) {
256
		    if (!octal_digit(c)) {
227
			is_fatal = 0 ;
257
			is_fatal = 0;
228
			input_error ( "Invalid escape sequence" ) ;
258
			input_error("Invalid escape sequence");
229
			c = '0' ;
259
			c = '0';
230
		    }
260
		    }
231
		    e = 8 * e + ( c - '0' ) ;
261
		    e = 8 * e + (c - '0');
232
		    c = getc ( input ) ;
262
		    c = getc(input);
233
		    if ( !octal_digit ( c ) ) {
263
		    if (!octal_digit(c)) {
234
			is_fatal = 0 ;
264
			is_fatal = 0;
235
			input_error ( "Invalid escape sequence" ) ;
265
			input_error("Invalid escape sequence");
236
			c = '0' ;
266
			c = '0';
237
		    }
267
		    }
238
		    e = 8 * e + ( c - '0' ) ;
268
		    e = 8 * e + (c - '0');
239
		    c = e ;
269
		    c = e;
240
		    if ( c >= 256 ) {
270
		    if (c >= 256) {
241
			is_fatal = 0 ;
271
			is_fatal = 0;
242
			input_error ( "Invalid escape sequence" ) ;
272
			input_error("Invalid escape sequence");
243
			c = 0 ;
273
			c = 0;
244
		    }
274
		    }
245
		}
275
		}
246
	    }
276
	    }
247
	    if ( c == EOF ) {
277
	    if (c == EOF) {
248
		is_fatal = 0 ;
278
		is_fatal = 0;
249
		input_error ( "End of file in string" ) ;
279
		input_error("End of file in string");
250
		word_type = INPUT_EOF ;
280
		word_type = INPUT_EOF;
251
		pending = EOF ;
281
		pending = EOF;
252
		return ;
282
		return;
253
	    }
283
	    }
254
	    if ( !ignore ) *( p++ ) = ( char ) c ;
284
	    if (!ignore)*(p++) = (char)c;
255
	} while ( c != '"' || escaped ) ;
285
	} while (c != '"' || escaped);
256
	*( --p ) = 0 ;
286
	*(--p) = 0;
257
#if 0
287
#if 0
258
	c = getc ( input ) ;
288
	c = getc(input);
259
	if ( c == '\n' ) crt_line_no++ ;
289
	if (c == '\n')crt_line_no++;
260
	if ( !terminator ( c ) ) {
290
	if (!terminator(c)) {
261
	    is_fatal = 0 ;
291
	    is_fatal = 0;
262
	    input_error ( "Terminator character expected" ) ;
292
	    input_error("Terminator character expected");
263
	}
293
	}
264
	pending = c ;
294
	pending = c;
265
#endif
295
#endif
266
	word = word_buff ;
296
	word = word_buff;
267
	word_length = ( int ) ( p - word ) ;
297
	word_length = (int)(p - word);
268
	word_type = INPUT_STRING ;
298
	word_type = INPUT_STRING;
269
	return ;
299
	return;
270
    }
300
    }
271
 
301
 
272
    /* Check for words */
302
    /* Check for words */
273
    if ( alpha ( c ) ) {
303
    if (alpha(c)) {
274
	p = word_buff ;
304
	p = word_buff;
275
	do {
305
	do {
276
	    *( p++ ) = ( char ) c ;
306
	    *(p++) = (char)c;
277
	    c = getc ( input ) ;
307
	    c = getc(input);
278
	    if ( c == '\n' ) crt_line_no++ ;
308
	    if (c == '\n')crt_line_no++;
279
	} while ( alphanum ( c ) ) ;
309
	} while (alphanum(c));
280
	*p = 0 ;
310
	*p = 0;
281
	if ( !terminator ( c ) ) {
311
	if (!terminator(c)) {
282
	    is_fatal = 0 ;
312
	    is_fatal = 0;
283
	    input_error ( "Terminator character expected" ) ;
313
	    input_error("Terminator character expected");
284
	}
314
	}
285
	pending = c ;
315
	pending = c;
286
	word = word_buff ;
316
	word = word_buff;
287
	word_type = INPUT_WORD ;
317
	word_type = INPUT_WORD;
288
	return ;
318
	return;
289
    }
319
    }
290
 
320
 
291
    /* Check for bars */
321
    /* Check for bars */
292
    if ( c == '|' ) {
322
    if (c == '|') {
293
	c = getc ( input ) ;
323
	c = getc(input);
294
	if ( c == '\n' ) crt_line_no++ ;
324
	if (c == '\n')crt_line_no++;
295
	if ( !terminator ( c ) ) {
325
	if (!terminator(c)) {
296
	    is_fatal = 0 ;
326
	    is_fatal = 0;
297
	    input_error ( "Terminator character expected" ) ;
327
	    input_error("Terminator character expected");
298
	}
328
	}
299
	pending = c ;
329
	pending = c;
300
	word = "|"  ;
330
	word = "|" ;
301
	word_type = INPUT_BAR ;
331
	word_type = INPUT_BAR;
302
	return ;
332
	return;
303
    }
333
    }
304
 
334
 
305
    /* Check for a single dash and arrow */
335
    /* Check for a single dash and arrow */
306
    if ( c == '-' ) {
336
    if (c == '-') {
307
	c = getc ( input ) ;
337
	c = getc(input);
308
	if ( c == '\n' ) crt_line_no++ ;
338
	if (c == '\n')crt_line_no++;
309
	if ( terminator ( c ) ) {
339
	if (terminator(c)) {
310
	    pending = c ;
340
	    pending = c;
311
	    word = "-"  ;
341
	    word = "-" ;
312
	    word_type = INPUT_BLANK ;
342
	    word_type = INPUT_BLANK;
313
	    return ;
343
	    return;
314
	}
344
	}
315
	if ( func_input && c == '>' ) {
345
	if (func_input && c == '>') {
316
	    pending = 0 ;
346
	    pending = 0;
317
	    word = "->" ;
347
	    word = "->";
318
	    word_type = INPUT_ARROW ;
348
	    word_type = INPUT_ARROW;
319
	    return ;
349
	    return;
320
	}
350
	}
321
	negate = 1 ;
351
	negate = 1;
322
    }
352
    }
323
 
353
 
324
    /* Step over any signs */
354
    /* Step over any signs */
325
    while ( c == '-' || c == '+' ) {
355
    while (c == '-' || c == '+') {
326
	if ( c == '-' ) negate = 1 - negate ;
356
	if (c == '-')negate = 1 - negate;
327
	c = getc ( input ) ;
357
	c = getc(input);
328
	if ( c == '\n' ) crt_line_no++ ;
358
	if (c == '\n')crt_line_no++;
329
    }
359
    }
330
 
360
 
331
    /* Check for numbers */
361
    /* Check for numbers */
332
    if ( c == '0' ) {
362
    if (c == '0') {
333
	base = 8 ;
363
	base = 8;
334
	c = getc ( input ) ;
364
	c = getc(input);
335
	if ( c == '\n' ) crt_line_no++ ;
365
	if (c == '\n')crt_line_no++;
336
	if ( terminator ( c ) ) {
366
	if (terminator(c)) {
337
	    pending = c ;
367
	    pending = c;
338
	    word = "0" ;
368
	    word = "0";
339
	    word_type = INPUT_NUMBER ;
369
	    word_type = INPUT_NUMBER;
340
	    return ;
370
	    return;
341
	}
371
	}
342
	if ( c == 'x' || c == 'X' ) {
372
	if (c == 'x' || c == 'X') {
343
	    base = 16 ;
373
	    base = 16;
344
	    c = getc ( input ) ;
374
	    c = getc(input);
345
	    if ( c == '\n' ) crt_line_no++ ;
375
	    if (c == '\n')crt_line_no++;
346
	}
376
	}
347
    } else if ( !dec_digit ( c ) ) {
377
    } else if (!dec_digit(c)) {
348
	is_fatal = 0 ;
378
	is_fatal = 0;
349
	input_error ( "Illegal character, %c", ( unsigned char ) c ) ;
379
	input_error("Illegal character, %c",(unsigned char)c);
350
	pending = 0 ;
380
	pending = 0;
351
	read_word () ;
381
	read_word();
352
	return ;
382
	return;
353
    }
383
    }
354
 
384
 
355
    /* Set up buffer */
385
    /* Set up buffer */
356
    p = word_buff + BUFFSIZE ;
386
    p = word_buff + BUFFSIZE;
357
    *( --p ) = 0 ;
387
    *(--p) = 0;
358
    *( --p ) = '0' ;
388
    *(--p) = '0';
359
    *( --p ) = 0 ;
389
    *(--p) = 0;
360
 
390
 
361
    /* Read the number */
391
    /* Read the number */
362
    do {
392
    do {
363
	unsigned n ;
393
	unsigned n;
364
	if ( dec_digit ( c ) ) {
394
	if (dec_digit(c)) {
365
	    n = ( unsigned ) ( c - '0' ) ;
395
	    n = (unsigned)(c - '0');
366
	} else if ( c >= 'A' && c <= 'F' ) {
396
	} else if (c >= 'A' && c <= 'F') {
367
	    n = 10 + ( unsigned ) ( c - 'A' ) ;
397
	    n = 10 + (unsigned)(c - 'A');
368
	} else if ( c >= 'a' && c <= 'f' ) {
398
	} else if (c >= 'a' && c <= 'f') {
369
	    n = 10 + ( unsigned ) ( c - 'a' ) ;
399
	    n = 10 + (unsigned)(c - 'a');
370
	} else {
400
	} else {
371
	    is_fatal = 0 ;
401
	    is_fatal = 0;
372
	    input_error ( "Illegal digit, %c", ( unsigned char ) c ) ;
402
	    input_error("Illegal digit, %c",(unsigned char)c);
373
	    n = 0 ;
403
	    n = 0;
374
	}
404
	}
375
	if ( n >= base ) {
405
	if (n >= base) {
376
	    is_fatal = 0 ;
406
	    is_fatal = 0;
377
	    input_error ( "Illegal digit, %c", ( unsigned char ) c ) ;
407
	    input_error("Illegal digit, %c",(unsigned char)c);
378
	    n = 0 ;
408
	    n = 0;
379
	}
409
	}
380
	if ( really_analyse ) {
410
	if (really_analyse) {
381
	    p = word_buff + ( BUFFSIZE - 2 ) ;
411
	    p = word_buff + (BUFFSIZE - 2);
382
	    do {
412
	    do {
383
		if ( *p == 0 ) {
413
		if (*p == 0) {
384
		    *( p - 1 ) = 0 ;
414
		    *(p - 1) = 0;
385
		} else {
415
		} else {
386
		    n += base * ( unsigned ) ( *p - '0' ) ;
416
		    n += base *(unsigned)(*p - '0');
387
		}
417
		}
388
		*p = ( char ) ( '0' + ( n & 7 ) ) ;
418
		*p = (char)('0' + (n & 7));
389
		n >>= 3 ;
419
		n >>= 3;
390
		p-- ;
420
		p--;
391
	    } while ( n || *p ) ;
421
	    } while (n || *p);
392
	}
422
	}
393
	c = getc ( input ) ;
423
	c = getc(input);
394
	if ( c == '\n' ) crt_line_no++ ;
424
	if (c == '\n')crt_line_no++;
395
    } while ( !terminator ( c ) ) ;
425
    } while (!terminator(c));
396
 
426
 
397
    /* Find the start of the number */
427
    /* Find the start of the number */
398
    if ( really_analyse ) {
428
    if (really_analyse) {
399
	for ( p = word_buff + ( BUFFSIZE - 2 ) ; *p ; p-- ) /* empty */ ;
429
	for ( p = word_buff + ( BUFFSIZE - 2 ) ; *p ; p-- ) /* empty */ ;
400
	if ( negate ) *( p-- ) = '-' ;
430
	if (negate)*(p--) = '-';
401
    }
431
    }
402
    pending = c ;
432
    pending = c;
403
    word = p + 1 ;
433
    word = p + 1;
404
    if ( streq ( word, "-0" ) ) word = "0" ;
434
    if (streq(word, "-0"))word = "0";
405
    word_type = INPUT_NUMBER ;
435
    word_type = INPUT_NUMBER;
406
    return ;
436
    return;
407
}
437
}
408
 
438
 
409
 
439
 
410
/*
440
/*
411
    HOW MANY WORDS TO THE NEXT CLOSE BRACKET?
441
    HOW MANY WORDS TO THE NEXT CLOSE BRACKET?
Line 414... Line 444...
414
    unmatched by an open bracket is read.  The routine returns the
444
    unmatched by an open bracket is read.  The routine returns the
415
    number of word read at the highest bracket level.  (Not currently
445
    number of word read at the highest bracket level.  (Not currently
416
    used.)
446
    used.)
417
*/
447
*/
418
 
448
 
419
long skip_words
449
long
420
    PROTO_Z ()
450
skip_words(void)
421
{
451
{
422
    long n = 0 ;
452
    long n = 0;
423
    int level = 1 ;
453
    int level = 1;
424
    really_analyse = 0 ;
454
    really_analyse = 0;
425
    while ( level ) {
455
    while (level) {
426
	read_word () ;
456
	read_word();
427
	switch ( word_type ) {
457
	switch (word_type) {
428
	    case INPUT_OPEN : level++ ; break ;
458
	    case INPUT_OPEN: level++; break;
429
	    case INPUT_CLOSE : level-- ; break ;
459
	    case INPUT_CLOSE: level--; break;
430
	    case INPUT_EOF : {
460
	    case INPUT_EOF: {
431
		input_error ( "Unexpected end of file" ) ;
461
		input_error("Unexpected end of file");
432
		return ( n ) ;
462
		return(n);
433
	    }
463
	    }
434
	}
464
	}
435
	if ( level == 1 ) n++ ;
465
	if (level == 1)n++;
436
    }
466
    }
437
    really_analyse = 1 ;
467
    really_analyse = 1;
438
    return ( n ) ;
468
    return(n);
439
}
469
}
440
 
470
 
441
 
471
 
442
/*
472
/*
443
    STORE THE CURRENT POSITION
473
    STORE THE CURRENT POSITION
444
 
474
 
445
    The current position in the input file is stored in p.
475
    The current position in the input file is stored in p.
446
*/
476
*/
447
 
477
 
448
void store_position
478
void
449
    PROTO_N ( ( p ) )
-
 
450
    PROTO_T ( position *p )
479
store_position(position *p)
451
{
480
{
452
    p->line = crt_line_no ;
481
    p->line = crt_line_no;
453
    p->posn = ftell ( input ) ;
482
    p->posn = ftell(input);
454
    p->pending = pending ;
483
    p->pending = pending;
455
    p->ahead = looked_ahead ;
484
    p->ahead = looked_ahead;
456
    return ;
485
    return;
457
}
486
}
458
 
487
 
459
 
488
 
460
/*
489
/*
461
    SET THE CURRENT POSITION
490
    SET THE CURRENT POSITION
462
 
491
 
463
    The position in the input file is set from p.
492
    The position in the input file is set from p.
464
*/
493
*/
465
 
494
 
466
void set_position
495
void
467
    PROTO_N ( ( p ) )
-
 
468
    PROTO_T ( position *p )
496
set_position(position *p)
469
{
497
{
470
    crt_line_no = p->line ;
498
    crt_line_no = p->line;
471
    pending = p->pending ;
499
    pending = p->pending;
472
    looked_ahead = p->ahead ;
500
    looked_ahead = p->ahead;
473
    if ( fseek ( input, p->posn, SEEK_SET ) ) {
501
    if (fseek(input, p->posn, SEEK_SET)) {
474
	fatal_error ( "Illegal seek command" ) ;
502
	fatal_error("Illegal seek command");
475
    }
503
    }
476
    return ;
504
    return;
477
}
505
}