Subversion Repositories DevTools

Rev

Rev 227 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
/*
2
 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3
 * unrestricted use provided that this legend is included on all tape
4
 * media and as a part of the software program in whole or part.  Users
5
 * may copy or modify Sun RPC without charge, but are not authorized
6
 * to license or distribute it to anyone else except as part of a product or
7
 * program developed by the user or with the express written consent of
8
 * Sun Microsystems, Inc.
9
 *
10
 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11
 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12
 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13
 *
14
 * Sun RPC is provided with no support and without any obligation on the
15
 * part of Sun Microsystems, Inc. to assist in its use, correction,
16
 * modification or enhancement.
17
 *
18
 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19
 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20
 * OR ANY PART THEREOF.
21
 *
22
 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23
 * or profits or other special, indirect and consequential damages, even if
24
 * Sun has been advised of the possibility of such damages.
25
 *
26
 * Sun Microsystems, Inc.
27
 * 2550 Garcia Avenue
28
 * Mountain View, California  94043
29
 */
30
 
31
#ifndef lint
32
static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
33
#endif
34
 
35
/*
36
 * rpc_scan.c, Scanner for the RPC protocol compiler 
37
 * Copyright (C) 1987, Sun Microsystems, Inc. 
38
 */
39
#include <stdio.h>
40
#include <ctype.h>
41
#include <string.h>
42
#include "rpc_scan.h"
43
#include "rpc_parse.h"
44
#include "rpc_util.h"
45
 
46
#define startcomment(where) (where[0] == '/' && where[1] == '*')
47
#define endcomment(where) (where[-1] == '*' && where[0] == '/')
48
 
49
static int pushed = 0;	/* is a token pushed */
50
static token lasttok;	/* last token, if pushed */
51
 
52
/*
53
 * scan expecting 1 given token 
54
 */
55
void
56
scan(expect, tokp)
57
	tok_kind expect;
58
	token *tokp;
59
{
60
	get_token(tokp);
61
	if (tokp->kind != expect) {
62
		expected1(expect);
63
	}
64
}
65
 
66
/*
67
 * scan expecting any of the 2 given tokens 
68
 */
69
void
70
scan2(expect1, expect2, tokp)
71
	tok_kind expect1;
72
	tok_kind expect2;
73
	token *tokp;
74
{
75
	get_token(tokp);
76
	if (tokp->kind != expect1 && tokp->kind != expect2) {
77
		expected2(expect1, expect2);
78
	}
79
}
80
 
81
/*
82
 * scan expecting any of the 3 given token 
83
 */
84
void
85
scan3(expect1, expect2, expect3, tokp)
86
	tok_kind expect1;
87
	tok_kind expect2;
88
	tok_kind expect3;
89
	token *tokp;
90
{
91
	get_token(tokp);
92
	if (tokp->kind != expect1 && tokp->kind != expect2
93
	    && tokp->kind != expect3) {
94
		expected3(expect1, expect2, expect3);
95
	}
96
}
97
 
98
/*
99
 * scan expecting a constant, possibly symbolic 
100
 */
101
void
102
scan_num(tokp)
103
	token *tokp;
104
{
105
	get_token(tokp);
106
	switch (tokp->kind) {
107
	case TOK_IDENT:
108
		break;
109
	default:
110
		error("constant or identifier expected");
111
	}
112
}
113
 
114
/*
115
 * Peek at the next token 
116
 */
117
void
118
peek(tokp)
119
	token *tokp;
120
{
121
	get_token(tokp);
122
	unget_token(tokp);
123
}
124
 
125
/*
126
 * Peek at the next token and scan it if it matches what you expect 
127
 */
128
int
129
peekscan(expect, tokp)
130
	tok_kind expect;
131
	token *tokp;
132
{
133
	peek(tokp);
134
	if (tokp->kind == expect) {
135
		get_token(tokp);
136
		return (1);
137
	}
138
	return (0);
139
}
140
 
141
/*
142
 * Get the next token, printing out any directive that are encountered. 
143
 */
144
void
145
get_token(tokp)
146
	token *tokp;
147
{
148
	int commenting;
149
 
150
	if (pushed) {
151
		pushed = 0;
152
		*tokp = lasttok;
153
		return;
154
	}
155
	commenting = 0;
156
	for (;;) {
157
		if (*where == 0) {
158
			for (;;) {
159
				if (!fgets(curline, MAXLINESIZE, fin)) {
160
					tokp->kind = TOK_EOF;
161
					*where = 0;
162
					return;
163
				}
164
				linenum++;
165
				if (commenting) {
166
					break;
167
				} else if (cppline(curline)) {
168
					docppline(curline, &linenum, 
169
						  &infilename);
170
				} else if (directive(curline)) {
171
					printdirective(curline);
172
				} else {
173
					break;
174
				}
175
			}
176
			where = curline;
177
		} else if (isspace(*where)) {
178
			while (isspace(*where)) {
179
				where++;	/* eat */
180
			}
181
		} else if (commenting) {
182
			for (where++; *where; where++) {
183
				if (endcomment(where)) {
184
					where++;
185
					commenting--;
186
					break;
187
				}
188
			}
189
		} else if (startcomment(where)) {
190
			where += 2;
191
			commenting++;
192
		} else {
193
			break;
194
		}
195
	}
196
 
197
	/*
198
	 * 'where' is not whitespace, comment or directive Must be a token! 
199
	 */
200
	switch (*where) {
201
	case ':':
202
		tokp->kind = TOK_COLON;
203
		where++;
204
		break;
205
	case ';':
206
		tokp->kind = TOK_SEMICOLON;
207
		where++;
208
		break;
209
	case ',':
210
		tokp->kind = TOK_COMMA;
211
		where++;
212
		break;
213
	case '=':
214
		tokp->kind = TOK_EQUAL;
215
		where++;
216
		break;
217
	case '*':
218
		tokp->kind = TOK_STAR;
219
		where++;
220
		break;
221
	case '[':
222
		tokp->kind = TOK_LBRACKET;
223
		where++;
224
		break;
225
	case ']':
226
		tokp->kind = TOK_RBRACKET;
227
		where++;
228
		break;
229
	case '{':
230
		tokp->kind = TOK_LBRACE;
231
		where++;
232
		break;
233
	case '}':
234
		tokp->kind = TOK_RBRACE;
235
		where++;
236
		break;
237
	case '(':
238
		tokp->kind = TOK_LPAREN;
239
		where++;
240
		break;
241
	case ')':
242
		tokp->kind = TOK_RPAREN;
243
		where++;
244
		break;
245
	case '<':
246
		tokp->kind = TOK_LANGLE;
247
		where++;
248
		break;
249
	case '>':
250
		tokp->kind = TOK_RANGLE;
251
		where++;
252
		break;
253
 
254
	case '"':
255
		tokp->kind = TOK_STRCONST;
256
		findstrconst(&where, &tokp->str);
257
		break;
258
	case '\'':
259
		tokp->kind = TOK_CHARCONST;
260
		findchrconst(&where, &tokp->str);
261
		break;
262
 
263
	case '-':
264
	case '0':
265
	case '1':
266
	case '2':
267
	case '3':
268
	case '4':
269
	case '5':
270
	case '6':
271
	case '7':
272
	case '8':
273
	case '9':
274
		tokp->kind = TOK_IDENT;
275
		findconst(&where, &tokp->str);
276
		break;
277
 
278
	default:
279
		if (!(isalpha(*where) || *where == '_')) {
280
			char buf[100];
281
			char *p;
282
 
283
			s_print(buf, "illegal character in file: ");
284
			p = buf + strlen(buf);
285
			if (isprint(*where)) {
286
				s_print(p, "%c", *where);
287
			} else {
288
				s_print(p, "%d", *where);
289
			}
290
			error(buf);
291
		}
292
		findkind(&where, tokp);
293
		break;
294
	}
295
}
296
 
297
static
298
unget_token(tokp)
299
	token *tokp;
300
{
301
	lasttok = *tokp;
302
	pushed = 1;
303
}
304
 
305
static
306
findstrconst(str, val)
307
	char **str;
308
	char **val;
309
{
310
	char *p;
311
	int size;
312
 
313
	p = *str;
314
	do {
315
		*p++;
316
	} while (*p && *p != '"');
317
	if (*p == 0) {
318
		error("unterminated string constant");
319
	}
320
	p++;
321
	size = p - *str;
322
	*val = alloc(size + 1);
323
	(void) strncpy(*val, *str, size);
324
	(*val)[size] = 0;
325
	*str = p;
326
}
327
 
328
static
329
findchrconst(str, val)
330
	char **str;
331
	char **val;
332
{
333
	char *p;
334
	int size;
335
 
336
	p = *str;
337
	do {
338
		*p++;
339
	} while (*p && *p != '\'');
340
	if (*p == 0) {
341
		error("unterminated string constant");
342
	}
343
	p++;
344
	size = p - *str;
345
	if (size != 3) {
346
		error("empty char string");
347
	}
348
	*val = alloc(size + 1);
349
	(void) strncpy(*val, *str, size);
350
	(*val)[size] = 0;
351
	*str = p;
352
}
353
 
354
static
355
findconst(str, val)
356
	char **str;
357
	char **val;
358
{
359
	char *p;
360
	int size;
361
 
362
	p = *str;
363
	if (*p == '0' && *(p + 1) == 'x') {
364
		p++;
365
		do {
366
			p++;
367
		} while (isxdigit(*p));
368
	} else {
369
		do {
370
			p++;
371
		} while (isdigit(*p));
372
	}
373
	size = p - *str;
374
	*val = alloc(size + 1);
375
	(void) strncpy(*val, *str, size);
376
	(*val)[size] = 0;
377
	*str = p;
378
}
379
 
380
static token symbols[] = {
381
			  {TOK_CONST, "const"},
382
			  {TOK_UNION, "union"},
383
			  {TOK_SWITCH, "switch"},
384
			  {TOK_CASE, "case"},
385
			  {TOK_DEFAULT, "default"},
386
			  {TOK_STRUCT, "struct"},
387
			  {TOK_TYPEDEF, "typedef"},
388
			  {TOK_ENUM, "enum"},
389
			  {TOK_OPAQUE, "opaque"},
390
			  {TOK_BOOL, "bool"},
391
			  {TOK_VOID, "void"},
392
			  {TOK_CHAR, "char"},
393
			  {TOK_INT, "int"},
394
			  {TOK_UNSIGNED, "unsigned"},
395
			  {TOK_SHORT, "short"},
396
			  {TOK_LONG, "long"},
397
			  {TOK_FLOAT, "float"},
398
			  {TOK_DOUBLE, "double"},
399
			  {TOK_STRING, "string"},
400
			  {TOK_PROGRAM, "program"},
401
			  {TOK_VERSION, "version"},
402
			  {TOK_EOF, "??????"},
403
};
404
 
405
static
406
findkind(mark, tokp)
407
	char **mark;
408
	token *tokp;
409
{
410
	int len;
411
	token *s;
412
	char *str;
413
 
414
	str = *mark;
415
	for (s = symbols; s->kind != TOK_EOF; s++) {
416
		len = strlen(s->str);
417
		if (strncmp(str, s->str, len) == 0) {
418
			if (!isalnum(str[len]) && str[len] != '_') {
419
				tokp->kind = s->kind;
420
				tokp->str = s->str;
421
				*mark = str + len;
422
				return;
423
			}
424
		}
425
	}
426
	tokp->kind = TOK_IDENT;
427
	for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
428
	tokp->str = alloc(len + 1);
429
	(void) strncpy(tokp->str, str, len);
430
	tokp->str[len] = 0;
431
	*mark = str + len;
432
}
433
 
434
static
435
cppline(line)
436
	char *line;
437
{
438
	return (line == curline && *line == '#');
439
}
440
 
441
static
442
directive(line)
443
	char *line;
444
{
445
	return (line == curline && *line == '%');
446
}
447
 
448
static
449
printdirective(line)
450
	char *line;
451
{
452
	f_print(fout, "%s", line + 1);
453
}
454
 
455
static
456
docppline(line, lineno, fname)
457
	char *line;
458
	int *lineno;
459
	char **fname;
460
{
461
	char *file;
462
	int num;
463
	char *p;
464
 
465
	line++;
466
	while (isspace(*line)) {
467
		line++;
468
	}
469
	num = atoi(line);
470
	while (isdigit(*line)) {
471
		line++;
472
	}
473
	while (isspace(*line)) {
474
		line++;
475
	}
476
	if (*line != '"') {
477
		error("preprocessor error");
478
	}
479
	line++;
5659 dpurdie 480
	p = alloc(strlen(line) + 1);
481
	file = p;
227 dpurdie 482
	while (*line && *line != '"') {
483
		*p++ = *line++;
484
	}
485
	if (*line == 0) {
486
		error("preprocessor error");
487
	}
488
	*p = 0;
489
	if (*file == 0) {
490
		*fname = NULL;
491
	} else {
492
		*fname = file;
493
	}
494
	*lineno = num - 1;
495
}