xref: /titanic_54/usr/src/cmd/rpcgen/rpc_scan.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  *
22*7c478bd9Sstevel@tonic-gate  * Copyright 2001 Sun Microsystems, Inc.  All rights reserved.
23*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24*7c478bd9Sstevel@tonic-gate  */
25*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
26*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */
27*7c478bd9Sstevel@tonic-gate /*
28*7c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
29*7c478bd9Sstevel@tonic-gate  * The Regents of the University of California
30*7c478bd9Sstevel@tonic-gate  * All Rights Reserved
31*7c478bd9Sstevel@tonic-gate  *
32*7c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
33*7c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
34*7c478bd9Sstevel@tonic-gate  * contributors.
35*7c478bd9Sstevel@tonic-gate  */
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
38*7c478bd9Sstevel@tonic-gate 
39*7c478bd9Sstevel@tonic-gate /*
40*7c478bd9Sstevel@tonic-gate  * rpc_scan.c, Scanner for the RPC protocol compiler
41*7c478bd9Sstevel@tonic-gate  */
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate #include <sys/wait.h>
44*7c478bd9Sstevel@tonic-gate #include <stdio.h>
45*7c478bd9Sstevel@tonic-gate #include <ctype.h>
46*7c478bd9Sstevel@tonic-gate #include <string.h>
47*7c478bd9Sstevel@tonic-gate #include "rpc_scan.h"
48*7c478bd9Sstevel@tonic-gate #include "rpc_parse.h"
49*7c478bd9Sstevel@tonic-gate #include "rpc_util.h"
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate #define startcomment(where) (where[0] == '/' && where[1] == '*')
52*7c478bd9Sstevel@tonic-gate #define endcomment(where) (where[-1] == '*' && where[0] == '/')
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate static int pushed = 0;	/* is a token pushed */
55*7c478bd9Sstevel@tonic-gate static token lasttok;	/* last token, if pushed */
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate /*
58*7c478bd9Sstevel@tonic-gate  * scan expecting 1 given token
59*7c478bd9Sstevel@tonic-gate  */
60*7c478bd9Sstevel@tonic-gate void
61*7c478bd9Sstevel@tonic-gate scan(expect, tokp)
62*7c478bd9Sstevel@tonic-gate 	tok_kind expect;
63*7c478bd9Sstevel@tonic-gate 	token *tokp;
64*7c478bd9Sstevel@tonic-gate {
65*7c478bd9Sstevel@tonic-gate 	get_token(tokp);
66*7c478bd9Sstevel@tonic-gate 	if (tokp->kind != expect) {
67*7c478bd9Sstevel@tonic-gate 		expected1(expect);
68*7c478bd9Sstevel@tonic-gate 	}
69*7c478bd9Sstevel@tonic-gate }
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate /*
72*7c478bd9Sstevel@tonic-gate  * scan expecting any of the 2 given tokens
73*7c478bd9Sstevel@tonic-gate  */
74*7c478bd9Sstevel@tonic-gate void
75*7c478bd9Sstevel@tonic-gate scan2(expect1, expect2, tokp)
76*7c478bd9Sstevel@tonic-gate 	tok_kind expect1;
77*7c478bd9Sstevel@tonic-gate 	tok_kind expect2;
78*7c478bd9Sstevel@tonic-gate 	token *tokp;
79*7c478bd9Sstevel@tonic-gate {
80*7c478bd9Sstevel@tonic-gate 	get_token(tokp);
81*7c478bd9Sstevel@tonic-gate 	if (tokp->kind != expect1 && tokp->kind != expect2) {
82*7c478bd9Sstevel@tonic-gate 		expected2(expect1, expect2);
83*7c478bd9Sstevel@tonic-gate 	}
84*7c478bd9Sstevel@tonic-gate }
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate /*
87*7c478bd9Sstevel@tonic-gate  * scan expecting any of the 3 given token
88*7c478bd9Sstevel@tonic-gate  */
89*7c478bd9Sstevel@tonic-gate void
90*7c478bd9Sstevel@tonic-gate scan3(expect1, expect2, expect3, tokp)
91*7c478bd9Sstevel@tonic-gate 	tok_kind expect1;
92*7c478bd9Sstevel@tonic-gate 	tok_kind expect2;
93*7c478bd9Sstevel@tonic-gate 	tok_kind expect3;
94*7c478bd9Sstevel@tonic-gate 	token *tokp;
95*7c478bd9Sstevel@tonic-gate {
96*7c478bd9Sstevel@tonic-gate 	get_token(tokp);
97*7c478bd9Sstevel@tonic-gate 	if (tokp->kind != expect1 && tokp->kind != expect2
98*7c478bd9Sstevel@tonic-gate 	    && tokp->kind != expect3) {
99*7c478bd9Sstevel@tonic-gate 		expected3(expect1, expect2, expect3);
100*7c478bd9Sstevel@tonic-gate 	}
101*7c478bd9Sstevel@tonic-gate }
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate /*
104*7c478bd9Sstevel@tonic-gate  * scan expecting a constant, possibly symbolic
105*7c478bd9Sstevel@tonic-gate  */
106*7c478bd9Sstevel@tonic-gate void
107*7c478bd9Sstevel@tonic-gate scan_num(tokp)
108*7c478bd9Sstevel@tonic-gate 	token *tokp;
109*7c478bd9Sstevel@tonic-gate {
110*7c478bd9Sstevel@tonic-gate 	get_token(tokp);
111*7c478bd9Sstevel@tonic-gate 	switch (tokp->kind) {
112*7c478bd9Sstevel@tonic-gate 	case TOK_IDENT:
113*7c478bd9Sstevel@tonic-gate 		break;
114*7c478bd9Sstevel@tonic-gate 	default:
115*7c478bd9Sstevel@tonic-gate 		error("constant or identifier expected");
116*7c478bd9Sstevel@tonic-gate 	}
117*7c478bd9Sstevel@tonic-gate }
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate /*
120*7c478bd9Sstevel@tonic-gate  * Peek at the next token
121*7c478bd9Sstevel@tonic-gate  */
122*7c478bd9Sstevel@tonic-gate void
123*7c478bd9Sstevel@tonic-gate peek(tokp)
124*7c478bd9Sstevel@tonic-gate 	token *tokp;
125*7c478bd9Sstevel@tonic-gate {
126*7c478bd9Sstevel@tonic-gate 	get_token(tokp);
127*7c478bd9Sstevel@tonic-gate 	unget_token(tokp);
128*7c478bd9Sstevel@tonic-gate }
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate /*
131*7c478bd9Sstevel@tonic-gate  * Peek at the next token and scan it if it matches what you expect
132*7c478bd9Sstevel@tonic-gate  */
133*7c478bd9Sstevel@tonic-gate int
134*7c478bd9Sstevel@tonic-gate peekscan(expect, tokp)
135*7c478bd9Sstevel@tonic-gate 	tok_kind expect;
136*7c478bd9Sstevel@tonic-gate 	token *tokp;
137*7c478bd9Sstevel@tonic-gate {
138*7c478bd9Sstevel@tonic-gate 	peek(tokp);
139*7c478bd9Sstevel@tonic-gate 	if (tokp->kind == expect) {
140*7c478bd9Sstevel@tonic-gate 		get_token(tokp);
141*7c478bd9Sstevel@tonic-gate 		return (1);
142*7c478bd9Sstevel@tonic-gate 	}
143*7c478bd9Sstevel@tonic-gate 	return (0);
144*7c478bd9Sstevel@tonic-gate }
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate /*
147*7c478bd9Sstevel@tonic-gate  * Get the next token, printing out any directive that are encountered.
148*7c478bd9Sstevel@tonic-gate  */
149*7c478bd9Sstevel@tonic-gate void
150*7c478bd9Sstevel@tonic-gate get_token(tokp)
151*7c478bd9Sstevel@tonic-gate 	token *tokp;
152*7c478bd9Sstevel@tonic-gate {
153*7c478bd9Sstevel@tonic-gate 	int commenting;
154*7c478bd9Sstevel@tonic-gate 	int stat = 0;
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate 
157*7c478bd9Sstevel@tonic-gate 	if (pushed) {
158*7c478bd9Sstevel@tonic-gate 		pushed = 0;
159*7c478bd9Sstevel@tonic-gate 		*tokp = lasttok;
160*7c478bd9Sstevel@tonic-gate 		return;
161*7c478bd9Sstevel@tonic-gate 	}
162*7c478bd9Sstevel@tonic-gate 	commenting = 0;
163*7c478bd9Sstevel@tonic-gate 	for (;;) {
164*7c478bd9Sstevel@tonic-gate 		if (*where == 0) {
165*7c478bd9Sstevel@tonic-gate 			for (;;) {
166*7c478bd9Sstevel@tonic-gate 				if (!fgets(curline, MAXLINESIZE, fin)) {
167*7c478bd9Sstevel@tonic-gate 					tokp->kind = TOK_EOF;
168*7c478bd9Sstevel@tonic-gate 					/* now check if cpp returned non NULL value */
169*7c478bd9Sstevel@tonic-gate 					waitpid(childpid, &stat, WUNTRACED);
170*7c478bd9Sstevel@tonic-gate 					if (stat > 0) {
171*7c478bd9Sstevel@tonic-gate 					/* Set return value from rpcgen */
172*7c478bd9Sstevel@tonic-gate 						nonfatalerrors = stat >> 8;
173*7c478bd9Sstevel@tonic-gate 					}
174*7c478bd9Sstevel@tonic-gate 					*where = 0;
175*7c478bd9Sstevel@tonic-gate 					return;
176*7c478bd9Sstevel@tonic-gate 				}
177*7c478bd9Sstevel@tonic-gate 				linenum++;
178*7c478bd9Sstevel@tonic-gate 				if (commenting) {
179*7c478bd9Sstevel@tonic-gate 					break;
180*7c478bd9Sstevel@tonic-gate 				} else if (cppline(curline)) {
181*7c478bd9Sstevel@tonic-gate 					docppline(curline, &linenum,
182*7c478bd9Sstevel@tonic-gate 						  &infilename);
183*7c478bd9Sstevel@tonic-gate 				} else if (directive(curline)) {
184*7c478bd9Sstevel@tonic-gate 					printdirective(curline);
185*7c478bd9Sstevel@tonic-gate 				} else {
186*7c478bd9Sstevel@tonic-gate 					break;
187*7c478bd9Sstevel@tonic-gate 				}
188*7c478bd9Sstevel@tonic-gate 			}
189*7c478bd9Sstevel@tonic-gate 			where = curline;
190*7c478bd9Sstevel@tonic-gate 		} else if (isspace(*where)) {
191*7c478bd9Sstevel@tonic-gate 			while (isspace(*where)) {
192*7c478bd9Sstevel@tonic-gate 				where++;	/* eat */
193*7c478bd9Sstevel@tonic-gate 			}
194*7c478bd9Sstevel@tonic-gate 		} else if (commenting) {
195*7c478bd9Sstevel@tonic-gate 			for (where++; *where; where++) {
196*7c478bd9Sstevel@tonic-gate 				if (endcomment(where)) {
197*7c478bd9Sstevel@tonic-gate 					where++;
198*7c478bd9Sstevel@tonic-gate 					commenting--;
199*7c478bd9Sstevel@tonic-gate 					break;
200*7c478bd9Sstevel@tonic-gate 				}
201*7c478bd9Sstevel@tonic-gate 			}
202*7c478bd9Sstevel@tonic-gate 		} else if (startcomment(where)) {
203*7c478bd9Sstevel@tonic-gate 			where += 2;
204*7c478bd9Sstevel@tonic-gate 			commenting++;
205*7c478bd9Sstevel@tonic-gate 		} else {
206*7c478bd9Sstevel@tonic-gate 			break;
207*7c478bd9Sstevel@tonic-gate 		}
208*7c478bd9Sstevel@tonic-gate 	}
209*7c478bd9Sstevel@tonic-gate 
210*7c478bd9Sstevel@tonic-gate 	/*
211*7c478bd9Sstevel@tonic-gate 	 * 'where' is not whitespace, comment or directive Must be a token!
212*7c478bd9Sstevel@tonic-gate 	 */
213*7c478bd9Sstevel@tonic-gate 	switch (*where) {
214*7c478bd9Sstevel@tonic-gate 	case ':':
215*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_COLON;
216*7c478bd9Sstevel@tonic-gate 		where++;
217*7c478bd9Sstevel@tonic-gate 		break;
218*7c478bd9Sstevel@tonic-gate 	case ';':
219*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_SEMICOLON;
220*7c478bd9Sstevel@tonic-gate 		where++;
221*7c478bd9Sstevel@tonic-gate 		break;
222*7c478bd9Sstevel@tonic-gate 	case ',':
223*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_COMMA;
224*7c478bd9Sstevel@tonic-gate 		where++;
225*7c478bd9Sstevel@tonic-gate 		break;
226*7c478bd9Sstevel@tonic-gate 	case '=':
227*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_EQUAL;
228*7c478bd9Sstevel@tonic-gate 		where++;
229*7c478bd9Sstevel@tonic-gate 		break;
230*7c478bd9Sstevel@tonic-gate 	case '*':
231*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_STAR;
232*7c478bd9Sstevel@tonic-gate 		where++;
233*7c478bd9Sstevel@tonic-gate 		break;
234*7c478bd9Sstevel@tonic-gate 	case '[':
235*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_LBRACKET;
236*7c478bd9Sstevel@tonic-gate 		where++;
237*7c478bd9Sstevel@tonic-gate 		break;
238*7c478bd9Sstevel@tonic-gate 	case ']':
239*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_RBRACKET;
240*7c478bd9Sstevel@tonic-gate 		where++;
241*7c478bd9Sstevel@tonic-gate 		break;
242*7c478bd9Sstevel@tonic-gate 	case '{':
243*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_LBRACE;
244*7c478bd9Sstevel@tonic-gate 		where++;
245*7c478bd9Sstevel@tonic-gate 		break;
246*7c478bd9Sstevel@tonic-gate 	case '}':
247*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_RBRACE;
248*7c478bd9Sstevel@tonic-gate 		where++;
249*7c478bd9Sstevel@tonic-gate 		break;
250*7c478bd9Sstevel@tonic-gate 	case '(':
251*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_LPAREN;
252*7c478bd9Sstevel@tonic-gate 		where++;
253*7c478bd9Sstevel@tonic-gate 		break;
254*7c478bd9Sstevel@tonic-gate 	case ')':
255*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_RPAREN;
256*7c478bd9Sstevel@tonic-gate 		where++;
257*7c478bd9Sstevel@tonic-gate 		break;
258*7c478bd9Sstevel@tonic-gate 	case '<':
259*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_LANGLE;
260*7c478bd9Sstevel@tonic-gate 		where++;
261*7c478bd9Sstevel@tonic-gate 		break;
262*7c478bd9Sstevel@tonic-gate 	case '>':
263*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_RANGLE;
264*7c478bd9Sstevel@tonic-gate 		where++;
265*7c478bd9Sstevel@tonic-gate 		break;
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 	case '"':
268*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_STRCONST;
269*7c478bd9Sstevel@tonic-gate 		findstrconst(&where, &tokp->str);
270*7c478bd9Sstevel@tonic-gate 		break;
271*7c478bd9Sstevel@tonic-gate 	case '\'':
272*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_CHARCONST;
273*7c478bd9Sstevel@tonic-gate 		findchrconst(&where, &tokp->str);
274*7c478bd9Sstevel@tonic-gate 		break;
275*7c478bd9Sstevel@tonic-gate 
276*7c478bd9Sstevel@tonic-gate 	case '-':
277*7c478bd9Sstevel@tonic-gate 	case '0':
278*7c478bd9Sstevel@tonic-gate 	case '1':
279*7c478bd9Sstevel@tonic-gate 	case '2':
280*7c478bd9Sstevel@tonic-gate 	case '3':
281*7c478bd9Sstevel@tonic-gate 	case '4':
282*7c478bd9Sstevel@tonic-gate 	case '5':
283*7c478bd9Sstevel@tonic-gate 	case '6':
284*7c478bd9Sstevel@tonic-gate 	case '7':
285*7c478bd9Sstevel@tonic-gate 	case '8':
286*7c478bd9Sstevel@tonic-gate 	case '9':
287*7c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_IDENT;
288*7c478bd9Sstevel@tonic-gate 		findconst(&where, &tokp->str);
289*7c478bd9Sstevel@tonic-gate 		break;
290*7c478bd9Sstevel@tonic-gate 
291*7c478bd9Sstevel@tonic-gate 	default:
292*7c478bd9Sstevel@tonic-gate 		if (!(isalpha(*where) || *where == '_')) {
293*7c478bd9Sstevel@tonic-gate 			char buf[100];
294*7c478bd9Sstevel@tonic-gate 			char *p;
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 			s_print(buf, "illegal character in file: ");
297*7c478bd9Sstevel@tonic-gate 			p = buf + strlen(buf);
298*7c478bd9Sstevel@tonic-gate 			if (isprint(*where)) {
299*7c478bd9Sstevel@tonic-gate 				s_print(p, "%c", *where);
300*7c478bd9Sstevel@tonic-gate 			} else {
301*7c478bd9Sstevel@tonic-gate 				s_print(p, "%d", *where);
302*7c478bd9Sstevel@tonic-gate 			}
303*7c478bd9Sstevel@tonic-gate 			error(buf);
304*7c478bd9Sstevel@tonic-gate 		}
305*7c478bd9Sstevel@tonic-gate 		findkind(&where, tokp);
306*7c478bd9Sstevel@tonic-gate 		break;
307*7c478bd9Sstevel@tonic-gate 	}
308*7c478bd9Sstevel@tonic-gate }
309*7c478bd9Sstevel@tonic-gate 
310*7c478bd9Sstevel@tonic-gate static
311*7c478bd9Sstevel@tonic-gate unget_token(tokp)
312*7c478bd9Sstevel@tonic-gate 	token *tokp;
313*7c478bd9Sstevel@tonic-gate {
314*7c478bd9Sstevel@tonic-gate 	lasttok = *tokp;
315*7c478bd9Sstevel@tonic-gate 	pushed = 1;
316*7c478bd9Sstevel@tonic-gate }
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate static
319*7c478bd9Sstevel@tonic-gate findstrconst(str, val)
320*7c478bd9Sstevel@tonic-gate 	char **str;
321*7c478bd9Sstevel@tonic-gate 	char **val;
322*7c478bd9Sstevel@tonic-gate {
323*7c478bd9Sstevel@tonic-gate 	char *p;
324*7c478bd9Sstevel@tonic-gate 	int size;
325*7c478bd9Sstevel@tonic-gate 
326*7c478bd9Sstevel@tonic-gate 	p = *str;
327*7c478bd9Sstevel@tonic-gate 	do {
328*7c478bd9Sstevel@tonic-gate 		*p++;
329*7c478bd9Sstevel@tonic-gate 	} while (*p && *p != '"');
330*7c478bd9Sstevel@tonic-gate 	if (*p == 0) {
331*7c478bd9Sstevel@tonic-gate 		error("unterminated string constant");
332*7c478bd9Sstevel@tonic-gate 	}
333*7c478bd9Sstevel@tonic-gate 	p++;
334*7c478bd9Sstevel@tonic-gate 	size = p - *str;
335*7c478bd9Sstevel@tonic-gate 	*val = alloc(size + 1);
336*7c478bd9Sstevel@tonic-gate 	(void) strncpy(*val, *str, size);
337*7c478bd9Sstevel@tonic-gate 	(*val)[size] = 0;
338*7c478bd9Sstevel@tonic-gate 	*str = p;
339*7c478bd9Sstevel@tonic-gate }
340*7c478bd9Sstevel@tonic-gate 
341*7c478bd9Sstevel@tonic-gate static
342*7c478bd9Sstevel@tonic-gate findchrconst(str, val)
343*7c478bd9Sstevel@tonic-gate 	char **str;
344*7c478bd9Sstevel@tonic-gate 	char **val;
345*7c478bd9Sstevel@tonic-gate {
346*7c478bd9Sstevel@tonic-gate 	char *p;
347*7c478bd9Sstevel@tonic-gate 	int size;
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate 	p = *str;
350*7c478bd9Sstevel@tonic-gate 	do {
351*7c478bd9Sstevel@tonic-gate 		*p++;
352*7c478bd9Sstevel@tonic-gate 	} while (*p && *p != '\'');
353*7c478bd9Sstevel@tonic-gate 	if (*p == 0) {
354*7c478bd9Sstevel@tonic-gate 		error("unterminated string constant");
355*7c478bd9Sstevel@tonic-gate 	}
356*7c478bd9Sstevel@tonic-gate 	p++;
357*7c478bd9Sstevel@tonic-gate 	size = p - *str;
358*7c478bd9Sstevel@tonic-gate 	if (size != 3) {
359*7c478bd9Sstevel@tonic-gate 		error("empty char string");
360*7c478bd9Sstevel@tonic-gate 	}
361*7c478bd9Sstevel@tonic-gate 	*val = alloc(size + 1);
362*7c478bd9Sstevel@tonic-gate 	(void) strncpy(*val, *str, size);
363*7c478bd9Sstevel@tonic-gate 	(*val)[size] = 0;
364*7c478bd9Sstevel@tonic-gate 	*str = p;
365*7c478bd9Sstevel@tonic-gate }
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate static
368*7c478bd9Sstevel@tonic-gate findconst(str, val)
369*7c478bd9Sstevel@tonic-gate 	char **str;
370*7c478bd9Sstevel@tonic-gate 	char **val;
371*7c478bd9Sstevel@tonic-gate {
372*7c478bd9Sstevel@tonic-gate 	char *p;
373*7c478bd9Sstevel@tonic-gate 	int size;
374*7c478bd9Sstevel@tonic-gate 
375*7c478bd9Sstevel@tonic-gate 	p = *str;
376*7c478bd9Sstevel@tonic-gate 	if (*p == '0' && *(p + 1) == 'x') {
377*7c478bd9Sstevel@tonic-gate 		p++;
378*7c478bd9Sstevel@tonic-gate 		do {
379*7c478bd9Sstevel@tonic-gate 			p++;
380*7c478bd9Sstevel@tonic-gate 		} while (isxdigit(*p));
381*7c478bd9Sstevel@tonic-gate 	} else {
382*7c478bd9Sstevel@tonic-gate 		do {
383*7c478bd9Sstevel@tonic-gate 			p++;
384*7c478bd9Sstevel@tonic-gate 		} while (isdigit(*p));
385*7c478bd9Sstevel@tonic-gate 	}
386*7c478bd9Sstevel@tonic-gate 	size = p - *str;
387*7c478bd9Sstevel@tonic-gate 	*val = alloc(size + 1);
388*7c478bd9Sstevel@tonic-gate 	(void) strncpy(*val, *str, size);
389*7c478bd9Sstevel@tonic-gate 	(*val)[size] = 0;
390*7c478bd9Sstevel@tonic-gate 	*str = p;
391*7c478bd9Sstevel@tonic-gate }
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate static token symbols[] = {
394*7c478bd9Sstevel@tonic-gate 			  {TOK_CONST, "const"},
395*7c478bd9Sstevel@tonic-gate 			  {TOK_UNION, "union"},
396*7c478bd9Sstevel@tonic-gate 			  {TOK_SWITCH, "switch"},
397*7c478bd9Sstevel@tonic-gate 			  {TOK_CASE, "case"},
398*7c478bd9Sstevel@tonic-gate 			  {TOK_DEFAULT, "default"},
399*7c478bd9Sstevel@tonic-gate 			  {TOK_STRUCT, "struct"},
400*7c478bd9Sstevel@tonic-gate 			  {TOK_TYPEDEF, "typedef"},
401*7c478bd9Sstevel@tonic-gate 			  {TOK_ENUM, "enum"},
402*7c478bd9Sstevel@tonic-gate 			  {TOK_OPAQUE, "opaque"},
403*7c478bd9Sstevel@tonic-gate 			  {TOK_BOOL, "bool"},
404*7c478bd9Sstevel@tonic-gate 			  {TOK_VOID, "void"},
405*7c478bd9Sstevel@tonic-gate 			  {TOK_ONEWAY, "oneway"},
406*7c478bd9Sstevel@tonic-gate 			  {TOK_CHAR, "char"},
407*7c478bd9Sstevel@tonic-gate 			  {TOK_INT, "int"},
408*7c478bd9Sstevel@tonic-gate 			  {TOK_UNSIGNED, "unsigned"},
409*7c478bd9Sstevel@tonic-gate 			  {TOK_SHORT, "short"},
410*7c478bd9Sstevel@tonic-gate 			  {TOK_LONG, "long"},
411*7c478bd9Sstevel@tonic-gate 			  {TOK_HYPER, "hyper"},
412*7c478bd9Sstevel@tonic-gate 			  {TOK_FLOAT, "float"},
413*7c478bd9Sstevel@tonic-gate 			  {TOK_DOUBLE, "double"},
414*7c478bd9Sstevel@tonic-gate 			  {TOK_QUAD, "quadruple"},
415*7c478bd9Sstevel@tonic-gate 			  {TOK_STRING, "string"},
416*7c478bd9Sstevel@tonic-gate 			  {TOK_PROGRAM, "program"},
417*7c478bd9Sstevel@tonic-gate 			  {TOK_VERSION, "version"},
418*7c478bd9Sstevel@tonic-gate 			  {TOK_EOF, "??????"},
419*7c478bd9Sstevel@tonic-gate };
420*7c478bd9Sstevel@tonic-gate 
421*7c478bd9Sstevel@tonic-gate static
422*7c478bd9Sstevel@tonic-gate findkind(mark, tokp)
423*7c478bd9Sstevel@tonic-gate 	char **mark;
424*7c478bd9Sstevel@tonic-gate 	token *tokp;
425*7c478bd9Sstevel@tonic-gate {
426*7c478bd9Sstevel@tonic-gate 	int len;
427*7c478bd9Sstevel@tonic-gate 	token *s;
428*7c478bd9Sstevel@tonic-gate 	char *str;
429*7c478bd9Sstevel@tonic-gate 
430*7c478bd9Sstevel@tonic-gate 	str = *mark;
431*7c478bd9Sstevel@tonic-gate 	for (s = symbols; s->kind != TOK_EOF; s++) {
432*7c478bd9Sstevel@tonic-gate 		len = strlen(s->str);
433*7c478bd9Sstevel@tonic-gate 		if (strncmp(str, s->str, len) == 0) {
434*7c478bd9Sstevel@tonic-gate 			if (!isalnum(str[len]) && str[len] != '_') {
435*7c478bd9Sstevel@tonic-gate 				tokp->kind = s->kind;
436*7c478bd9Sstevel@tonic-gate 				tokp->str = s->str;
437*7c478bd9Sstevel@tonic-gate 				*mark = str + len;
438*7c478bd9Sstevel@tonic-gate 				return;
439*7c478bd9Sstevel@tonic-gate 			}
440*7c478bd9Sstevel@tonic-gate 		}
441*7c478bd9Sstevel@tonic-gate 	}
442*7c478bd9Sstevel@tonic-gate 	tokp->kind = TOK_IDENT;
443*7c478bd9Sstevel@tonic-gate 	for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
444*7c478bd9Sstevel@tonic-gate 	tokp->str = alloc(len + 1);
445*7c478bd9Sstevel@tonic-gate 	(void) strncpy(tokp->str, str, len);
446*7c478bd9Sstevel@tonic-gate 	tokp->str[len] = 0;
447*7c478bd9Sstevel@tonic-gate 	*mark = str + len;
448*7c478bd9Sstevel@tonic-gate }
449*7c478bd9Sstevel@tonic-gate 
450*7c478bd9Sstevel@tonic-gate static
451*7c478bd9Sstevel@tonic-gate cppline(line)
452*7c478bd9Sstevel@tonic-gate 	char *line;
453*7c478bd9Sstevel@tonic-gate {
454*7c478bd9Sstevel@tonic-gate 	return (line == curline && *line == '#');
455*7c478bd9Sstevel@tonic-gate }
456*7c478bd9Sstevel@tonic-gate 
457*7c478bd9Sstevel@tonic-gate static
458*7c478bd9Sstevel@tonic-gate directive(line)
459*7c478bd9Sstevel@tonic-gate 	char *line;
460*7c478bd9Sstevel@tonic-gate {
461*7c478bd9Sstevel@tonic-gate 	return (line == curline && *line == '%');
462*7c478bd9Sstevel@tonic-gate }
463*7c478bd9Sstevel@tonic-gate 
464*7c478bd9Sstevel@tonic-gate static
465*7c478bd9Sstevel@tonic-gate printdirective(line)
466*7c478bd9Sstevel@tonic-gate 	char *line;
467*7c478bd9Sstevel@tonic-gate {
468*7c478bd9Sstevel@tonic-gate 	f_print(fout, "%s", line + 1);
469*7c478bd9Sstevel@tonic-gate }
470*7c478bd9Sstevel@tonic-gate 
471*7c478bd9Sstevel@tonic-gate static
472*7c478bd9Sstevel@tonic-gate docppline(line, lineno, fname)
473*7c478bd9Sstevel@tonic-gate 	char *line;
474*7c478bd9Sstevel@tonic-gate 	int *lineno;
475*7c478bd9Sstevel@tonic-gate 	char **fname;
476*7c478bd9Sstevel@tonic-gate {
477*7c478bd9Sstevel@tonic-gate 	char *file;
478*7c478bd9Sstevel@tonic-gate 	int num;
479*7c478bd9Sstevel@tonic-gate 	char *p;
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate 	line++;
482*7c478bd9Sstevel@tonic-gate 	while (isspace(*line)) {
483*7c478bd9Sstevel@tonic-gate 		line++;
484*7c478bd9Sstevel@tonic-gate 	}
485*7c478bd9Sstevel@tonic-gate 	num = atoi(line);
486*7c478bd9Sstevel@tonic-gate 	while (isdigit(*line)) {
487*7c478bd9Sstevel@tonic-gate 		line++;
488*7c478bd9Sstevel@tonic-gate 	}
489*7c478bd9Sstevel@tonic-gate 	while (isspace(*line)) {
490*7c478bd9Sstevel@tonic-gate 		line++;
491*7c478bd9Sstevel@tonic-gate 	}
492*7c478bd9Sstevel@tonic-gate 	if (*line != '"') {
493*7c478bd9Sstevel@tonic-gate 		error("preprocessor error");
494*7c478bd9Sstevel@tonic-gate 	}
495*7c478bd9Sstevel@tonic-gate 	line++;
496*7c478bd9Sstevel@tonic-gate 	p = file = alloc(strlen(line) + 1);
497*7c478bd9Sstevel@tonic-gate 	while (*line && *line != '"') {
498*7c478bd9Sstevel@tonic-gate 		*p++ = *line++;
499*7c478bd9Sstevel@tonic-gate 	}
500*7c478bd9Sstevel@tonic-gate 	if (*line == 0) {
501*7c478bd9Sstevel@tonic-gate 		error("preprocessor error");
502*7c478bd9Sstevel@tonic-gate 	}
503*7c478bd9Sstevel@tonic-gate 	*p = 0;
504*7c478bd9Sstevel@tonic-gate 	if (*file == 0) {
505*7c478bd9Sstevel@tonic-gate 		*fname = NULL;
506*7c478bd9Sstevel@tonic-gate 	} else {
507*7c478bd9Sstevel@tonic-gate 		*fname = file;
508*7c478bd9Sstevel@tonic-gate 	}
509*7c478bd9Sstevel@tonic-gate 	*lineno = num - 1;
510*7c478bd9Sstevel@tonic-gate }
511