xref: /titanic_53/usr/src/cmd/rpcgen/rpc_scan.c (revision 61961e0f20c7637a3846bb39786bb9dffa91dfb9)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*61961e0fSrobinson  */
22*61961e0fSrobinson 
23*61961e0fSrobinson /*
24*61961e0fSrobinson  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
257c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
287c478bd9Sstevel@tonic-gate /* All Rights Reserved */
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
317c478bd9Sstevel@tonic-gate  * The Regents of the University of California
327c478bd9Sstevel@tonic-gate  * All Rights Reserved
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
357c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
367c478bd9Sstevel@tonic-gate  * contributors.
377c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * rpc_scan.c, Scanner for the RPC protocol compiler
437c478bd9Sstevel@tonic-gate  */
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #include <sys/wait.h>
467c478bd9Sstevel@tonic-gate #include <stdio.h>
477c478bd9Sstevel@tonic-gate #include <ctype.h>
487c478bd9Sstevel@tonic-gate #include <string.h>
49*61961e0fSrobinson #include <strings.h>
507c478bd9Sstevel@tonic-gate #include "rpc_scan.h"
517c478bd9Sstevel@tonic-gate #include "rpc_parse.h"
527c478bd9Sstevel@tonic-gate #include "rpc_util.h"
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #define	startcomment(where)	(where[0] == '/' && where[1] == '*')
557c478bd9Sstevel@tonic-gate #define	endcomment(where)	(where[-1] == '*' && where[0] == '/')
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate static int pushed = 0;	/* is a token pushed */
587c478bd9Sstevel@tonic-gate static token lasttok;	/* last token, if pushed */
597c478bd9Sstevel@tonic-gate 
60*61961e0fSrobinson static void unget_token(token *);
61*61961e0fSrobinson static void findstrconst(char **, char **);
62*61961e0fSrobinson static void findchrconst(char **, char **);
63*61961e0fSrobinson static void findconst(char **, char **);
64*61961e0fSrobinson static void findkind(char **, token *);
65*61961e0fSrobinson static int cppline(char *);
66*61961e0fSrobinson static int directive(char *);
67*61961e0fSrobinson static void printdirective(char *);
68*61961e0fSrobinson static void docppline(char *, int *, char **);
69*61961e0fSrobinson 
707c478bd9Sstevel@tonic-gate /*
717c478bd9Sstevel@tonic-gate  * scan expecting 1 given token
727c478bd9Sstevel@tonic-gate  */
737c478bd9Sstevel@tonic-gate void
74*61961e0fSrobinson scan(tok_kind expect, token *tokp)
757c478bd9Sstevel@tonic-gate {
767c478bd9Sstevel@tonic-gate 	get_token(tokp);
77*61961e0fSrobinson 	if (tokp->kind != expect)
787c478bd9Sstevel@tonic-gate 		expected1(expect);
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate /*
827c478bd9Sstevel@tonic-gate  * scan expecting any of the 2 given tokens
837c478bd9Sstevel@tonic-gate  */
847c478bd9Sstevel@tonic-gate void
85*61961e0fSrobinson scan2(tok_kind expect1, tok_kind expect2, token *tokp)
867c478bd9Sstevel@tonic-gate {
877c478bd9Sstevel@tonic-gate 	get_token(tokp);
88*61961e0fSrobinson 	if (tokp->kind != expect1 && tokp->kind != expect2)
897c478bd9Sstevel@tonic-gate 		expected2(expect1, expect2);
907c478bd9Sstevel@tonic-gate }
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate /*
937c478bd9Sstevel@tonic-gate  * scan expecting any of the 3 given token
947c478bd9Sstevel@tonic-gate  */
957c478bd9Sstevel@tonic-gate void
96*61961e0fSrobinson scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp)
977c478bd9Sstevel@tonic-gate {
987c478bd9Sstevel@tonic-gate 	get_token(tokp);
99*61961e0fSrobinson 	if (tokp->kind != expect1 && tokp->kind != expect2 &&
100*61961e0fSrobinson 						tokp->kind != expect3)
1017c478bd9Sstevel@tonic-gate 		expected3(expect1, expect2, expect3);
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate /*
1057c478bd9Sstevel@tonic-gate  * scan expecting a constant, possibly symbolic
1067c478bd9Sstevel@tonic-gate  */
1077c478bd9Sstevel@tonic-gate void
108*61961e0fSrobinson scan_num(token *tokp)
1097c478bd9Sstevel@tonic-gate {
1107c478bd9Sstevel@tonic-gate 	get_token(tokp);
1117c478bd9Sstevel@tonic-gate 	switch (tokp->kind) {
1127c478bd9Sstevel@tonic-gate 	case TOK_IDENT:
1137c478bd9Sstevel@tonic-gate 		break;
1147c478bd9Sstevel@tonic-gate 	default:
1157c478bd9Sstevel@tonic-gate 		error("constant or identifier expected");
1167c478bd9Sstevel@tonic-gate 	}
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate /*
1207c478bd9Sstevel@tonic-gate  * Peek at the next token
1217c478bd9Sstevel@tonic-gate  */
1227c478bd9Sstevel@tonic-gate void
123*61961e0fSrobinson peek(token *tokp)
1247c478bd9Sstevel@tonic-gate {
1257c478bd9Sstevel@tonic-gate 	get_token(tokp);
1267c478bd9Sstevel@tonic-gate 	unget_token(tokp);
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate /*
1307c478bd9Sstevel@tonic-gate  * Peek at the next token and scan it if it matches what you expect
1317c478bd9Sstevel@tonic-gate  */
1327c478bd9Sstevel@tonic-gate int
133*61961e0fSrobinson peekscan(tok_kind expect, token *tokp)
1347c478bd9Sstevel@tonic-gate {
1357c478bd9Sstevel@tonic-gate 	peek(tokp);
1367c478bd9Sstevel@tonic-gate 	if (tokp->kind == expect) {
1377c478bd9Sstevel@tonic-gate 		get_token(tokp);
1387c478bd9Sstevel@tonic-gate 		return (1);
1397c478bd9Sstevel@tonic-gate 	}
1407c478bd9Sstevel@tonic-gate 	return (0);
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate /*
1447c478bd9Sstevel@tonic-gate  * Get the next token, printing out any directive that are encountered.
1457c478bd9Sstevel@tonic-gate  */
1467c478bd9Sstevel@tonic-gate void
147*61961e0fSrobinson get_token(token *tokp)
1487c478bd9Sstevel@tonic-gate {
1497c478bd9Sstevel@tonic-gate 	int commenting;
1507c478bd9Sstevel@tonic-gate 	int stat = 0;
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	if (pushed) {
1537c478bd9Sstevel@tonic-gate 		pushed = 0;
1547c478bd9Sstevel@tonic-gate 		*tokp = lasttok;
1557c478bd9Sstevel@tonic-gate 		return;
1567c478bd9Sstevel@tonic-gate 	}
1577c478bd9Sstevel@tonic-gate 	commenting = 0;
1587c478bd9Sstevel@tonic-gate 	for (;;) {
1597c478bd9Sstevel@tonic-gate 		if (*where == 0) {
1607c478bd9Sstevel@tonic-gate 			for (;;) {
1617c478bd9Sstevel@tonic-gate 				if (!fgets(curline, MAXLINESIZE, fin)) {
1627c478bd9Sstevel@tonic-gate 					tokp->kind = TOK_EOF;
163*61961e0fSrobinson 					/*
164*61961e0fSrobinson 					 * now check if cpp returned
165*61961e0fSrobinson 					 * non NULL value
166*61961e0fSrobinson 					 */
167*61961e0fSrobinson 					(void) waitpid(childpid, &stat,
168*61961e0fSrobinson 								WUNTRACED);
1697c478bd9Sstevel@tonic-gate 					if (stat > 0) {
1707c478bd9Sstevel@tonic-gate 					/* Set return value from rpcgen */
1717c478bd9Sstevel@tonic-gate 						nonfatalerrors = stat >> 8;
1727c478bd9Sstevel@tonic-gate 					}
1737c478bd9Sstevel@tonic-gate 					*where = 0;
1747c478bd9Sstevel@tonic-gate 					return;
1757c478bd9Sstevel@tonic-gate 				}
1767c478bd9Sstevel@tonic-gate 				linenum++;
1777c478bd9Sstevel@tonic-gate 				if (commenting) {
1787c478bd9Sstevel@tonic-gate 					break;
1797c478bd9Sstevel@tonic-gate 				} else if (cppline(curline)) {
1807c478bd9Sstevel@tonic-gate 					docppline(curline, &linenum,
1817c478bd9Sstevel@tonic-gate 						&infilename);
1827c478bd9Sstevel@tonic-gate 				} else if (directive(curline)) {
1837c478bd9Sstevel@tonic-gate 					printdirective(curline);
1847c478bd9Sstevel@tonic-gate 				} else {
1857c478bd9Sstevel@tonic-gate 					break;
1867c478bd9Sstevel@tonic-gate 				}
1877c478bd9Sstevel@tonic-gate 			}
1887c478bd9Sstevel@tonic-gate 			where = curline;
1897c478bd9Sstevel@tonic-gate 		} else if (isspace(*where)) {
1907c478bd9Sstevel@tonic-gate 			while (isspace(*where)) {
1917c478bd9Sstevel@tonic-gate 				where++;	/* eat */
1927c478bd9Sstevel@tonic-gate 			}
1937c478bd9Sstevel@tonic-gate 		} else if (commenting) {
1947c478bd9Sstevel@tonic-gate 			for (where++; *where; where++) {
1957c478bd9Sstevel@tonic-gate 				if (endcomment(where)) {
1967c478bd9Sstevel@tonic-gate 					where++;
1977c478bd9Sstevel@tonic-gate 					commenting--;
1987c478bd9Sstevel@tonic-gate 					break;
1997c478bd9Sstevel@tonic-gate 				}
2007c478bd9Sstevel@tonic-gate 			}
2017c478bd9Sstevel@tonic-gate 		} else if (startcomment(where)) {
2027c478bd9Sstevel@tonic-gate 			where += 2;
2037c478bd9Sstevel@tonic-gate 			commenting++;
2047c478bd9Sstevel@tonic-gate 		} else {
2057c478bd9Sstevel@tonic-gate 			break;
2067c478bd9Sstevel@tonic-gate 		}
2077c478bd9Sstevel@tonic-gate 	}
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	/*
2107c478bd9Sstevel@tonic-gate 	 * 'where' is not whitespace, comment or directive Must be a token!
2117c478bd9Sstevel@tonic-gate 	 */
2127c478bd9Sstevel@tonic-gate 	switch (*where) {
2137c478bd9Sstevel@tonic-gate 	case ':':
2147c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_COLON;
2157c478bd9Sstevel@tonic-gate 		where++;
2167c478bd9Sstevel@tonic-gate 		break;
2177c478bd9Sstevel@tonic-gate 	case ';':
2187c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_SEMICOLON;
2197c478bd9Sstevel@tonic-gate 		where++;
2207c478bd9Sstevel@tonic-gate 		break;
2217c478bd9Sstevel@tonic-gate 	case ',':
2227c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_COMMA;
2237c478bd9Sstevel@tonic-gate 		where++;
2247c478bd9Sstevel@tonic-gate 		break;
2257c478bd9Sstevel@tonic-gate 	case '=':
2267c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_EQUAL;
2277c478bd9Sstevel@tonic-gate 		where++;
2287c478bd9Sstevel@tonic-gate 		break;
2297c478bd9Sstevel@tonic-gate 	case '*':
2307c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_STAR;
2317c478bd9Sstevel@tonic-gate 		where++;
2327c478bd9Sstevel@tonic-gate 		break;
2337c478bd9Sstevel@tonic-gate 	case '[':
2347c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_LBRACKET;
2357c478bd9Sstevel@tonic-gate 		where++;
2367c478bd9Sstevel@tonic-gate 		break;
2377c478bd9Sstevel@tonic-gate 	case ']':
2387c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_RBRACKET;
2397c478bd9Sstevel@tonic-gate 		where++;
2407c478bd9Sstevel@tonic-gate 		break;
2417c478bd9Sstevel@tonic-gate 	case '{':
2427c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_LBRACE;
2437c478bd9Sstevel@tonic-gate 		where++;
2447c478bd9Sstevel@tonic-gate 		break;
2457c478bd9Sstevel@tonic-gate 	case '}':
2467c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_RBRACE;
2477c478bd9Sstevel@tonic-gate 		where++;
2487c478bd9Sstevel@tonic-gate 		break;
2497c478bd9Sstevel@tonic-gate 	case '(':
2507c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_LPAREN;
2517c478bd9Sstevel@tonic-gate 		where++;
2527c478bd9Sstevel@tonic-gate 		break;
2537c478bd9Sstevel@tonic-gate 	case ')':
2547c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_RPAREN;
2557c478bd9Sstevel@tonic-gate 		where++;
2567c478bd9Sstevel@tonic-gate 		break;
2577c478bd9Sstevel@tonic-gate 	case '<':
2587c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_LANGLE;
2597c478bd9Sstevel@tonic-gate 		where++;
2607c478bd9Sstevel@tonic-gate 		break;
2617c478bd9Sstevel@tonic-gate 	case '>':
2627c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_RANGLE;
2637c478bd9Sstevel@tonic-gate 		where++;
2647c478bd9Sstevel@tonic-gate 		break;
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	case '"':
2677c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_STRCONST;
2687c478bd9Sstevel@tonic-gate 		findstrconst(&where, &tokp->str);
2697c478bd9Sstevel@tonic-gate 		break;
2707c478bd9Sstevel@tonic-gate 	case '\'':
2717c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_CHARCONST;
2727c478bd9Sstevel@tonic-gate 		findchrconst(&where, &tokp->str);
2737c478bd9Sstevel@tonic-gate 		break;
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 	case '-':
2767c478bd9Sstevel@tonic-gate 	case '0':
2777c478bd9Sstevel@tonic-gate 	case '1':
2787c478bd9Sstevel@tonic-gate 	case '2':
2797c478bd9Sstevel@tonic-gate 	case '3':
2807c478bd9Sstevel@tonic-gate 	case '4':
2817c478bd9Sstevel@tonic-gate 	case '5':
2827c478bd9Sstevel@tonic-gate 	case '6':
2837c478bd9Sstevel@tonic-gate 	case '7':
2847c478bd9Sstevel@tonic-gate 	case '8':
2857c478bd9Sstevel@tonic-gate 	case '9':
2867c478bd9Sstevel@tonic-gate 		tokp->kind = TOK_IDENT;
2877c478bd9Sstevel@tonic-gate 		findconst(&where, &tokp->str);
2887c478bd9Sstevel@tonic-gate 		break;
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	default:
2917c478bd9Sstevel@tonic-gate 		if (!(isalpha(*where) || *where == '_')) {
2927c478bd9Sstevel@tonic-gate 			char buf[100];
2937c478bd9Sstevel@tonic-gate 			char *p;
294*61961e0fSrobinson 			size_t blen;
2957c478bd9Sstevel@tonic-gate 
296*61961e0fSrobinson 			(void) snprintf(buf, sizeof (buf),
297*61961e0fSrobinson 						"illegal character in file: ");
298*61961e0fSrobinson 			blen = strlen(buf);
299*61961e0fSrobinson 			p = buf + blen;
3007c478bd9Sstevel@tonic-gate 			if (isprint(*where)) {
301*61961e0fSrobinson 				(void) snprintf(p, sizeof (buf) - blen,
302*61961e0fSrobinson 								"%c", *where);
3037c478bd9Sstevel@tonic-gate 			} else {
304*61961e0fSrobinson 				(void) snprintf(p, sizeof (buf) - blen,
305*61961e0fSrobinson 								"%d", *where);
3067c478bd9Sstevel@tonic-gate 			}
3077c478bd9Sstevel@tonic-gate 			error(buf);
3087c478bd9Sstevel@tonic-gate 		}
3097c478bd9Sstevel@tonic-gate 		findkind(&where, tokp);
3107c478bd9Sstevel@tonic-gate 		break;
3117c478bd9Sstevel@tonic-gate 	}
3127c478bd9Sstevel@tonic-gate }
3137c478bd9Sstevel@tonic-gate 
314*61961e0fSrobinson static void
315*61961e0fSrobinson unget_token(token *tokp)
3167c478bd9Sstevel@tonic-gate {
3177c478bd9Sstevel@tonic-gate 	lasttok = *tokp;
3187c478bd9Sstevel@tonic-gate 	pushed = 1;
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate 
321*61961e0fSrobinson static void
322*61961e0fSrobinson findstrconst(char **str, char **val)
3237c478bd9Sstevel@tonic-gate {
3247c478bd9Sstevel@tonic-gate 	char *p;
3257c478bd9Sstevel@tonic-gate 	int size;
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate 	p = *str;
3287c478bd9Sstevel@tonic-gate 	do {
329*61961e0fSrobinson 		p++;
3307c478bd9Sstevel@tonic-gate 	} while (*p && *p != '"');
3317c478bd9Sstevel@tonic-gate 	if (*p == 0) {
3327c478bd9Sstevel@tonic-gate 		error("unterminated string constant");
3337c478bd9Sstevel@tonic-gate 	}
3347c478bd9Sstevel@tonic-gate 	p++;
3357c478bd9Sstevel@tonic-gate 	size = p - *str;
336*61961e0fSrobinson 	*val = malloc(size + 1);
3377c478bd9Sstevel@tonic-gate 	(void) strncpy(*val, *str, size);
3387c478bd9Sstevel@tonic-gate 	(*val)[size] = 0;
3397c478bd9Sstevel@tonic-gate 	*str = p;
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate 
342*61961e0fSrobinson static void
343*61961e0fSrobinson findchrconst(char **str, char **val)
3447c478bd9Sstevel@tonic-gate {
3457c478bd9Sstevel@tonic-gate 	char *p;
3467c478bd9Sstevel@tonic-gate 	int size;
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate 	p = *str;
3497c478bd9Sstevel@tonic-gate 	do {
350*61961e0fSrobinson 		p++;
3517c478bd9Sstevel@tonic-gate 	} while (*p && *p != '\'');
352*61961e0fSrobinson 	if (*p == 0)
3537c478bd9Sstevel@tonic-gate 		error("unterminated string constant");
3547c478bd9Sstevel@tonic-gate 	p++;
3557c478bd9Sstevel@tonic-gate 	size = p - *str;
356*61961e0fSrobinson 	if (size != 3)
3577c478bd9Sstevel@tonic-gate 		error("empty char string");
358*61961e0fSrobinson 	*val = malloc(size + 1);
3597c478bd9Sstevel@tonic-gate 	(void) strncpy(*val, *str, size);
3607c478bd9Sstevel@tonic-gate 	(*val)[size] = 0;
3617c478bd9Sstevel@tonic-gate 	*str = p;
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate 
364*61961e0fSrobinson static void
365*61961e0fSrobinson findconst(char **str, char **val)
3667c478bd9Sstevel@tonic-gate {
3677c478bd9Sstevel@tonic-gate 	char *p;
3687c478bd9Sstevel@tonic-gate 	int size;
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	p = *str;
3717c478bd9Sstevel@tonic-gate 	if (*p == '0' && *(p + 1) == 'x') {
3727c478bd9Sstevel@tonic-gate 		p++;
3737c478bd9Sstevel@tonic-gate 		do {
3747c478bd9Sstevel@tonic-gate 			p++;
3757c478bd9Sstevel@tonic-gate 		} while (isxdigit(*p));
3767c478bd9Sstevel@tonic-gate 	} else {
3777c478bd9Sstevel@tonic-gate 		do {
3787c478bd9Sstevel@tonic-gate 			p++;
3797c478bd9Sstevel@tonic-gate 		} while (isdigit(*p));
3807c478bd9Sstevel@tonic-gate 	}
3817c478bd9Sstevel@tonic-gate 	size = p - *str;
382*61961e0fSrobinson 	*val = malloc(size + 1);
3837c478bd9Sstevel@tonic-gate 	(void) strncpy(*val, *str, size);
3847c478bd9Sstevel@tonic-gate 	(*val)[size] = 0;
3857c478bd9Sstevel@tonic-gate 	*str = p;
3867c478bd9Sstevel@tonic-gate }
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate static token symbols[] = {
3897c478bd9Sstevel@tonic-gate 			{TOK_CONST, "const"},
3907c478bd9Sstevel@tonic-gate 			{TOK_UNION, "union"},
3917c478bd9Sstevel@tonic-gate 			{TOK_SWITCH, "switch"},
3927c478bd9Sstevel@tonic-gate 			{TOK_CASE, "case"},
3937c478bd9Sstevel@tonic-gate 			{TOK_DEFAULT, "default"},
3947c478bd9Sstevel@tonic-gate 			{TOK_STRUCT, "struct"},
3957c478bd9Sstevel@tonic-gate 			{TOK_TYPEDEF, "typedef"},
3967c478bd9Sstevel@tonic-gate 			{TOK_ENUM, "enum"},
3977c478bd9Sstevel@tonic-gate 			{TOK_OPAQUE, "opaque"},
3987c478bd9Sstevel@tonic-gate 			{TOK_BOOL, "bool"},
3997c478bd9Sstevel@tonic-gate 			{TOK_VOID, "void"},
4007c478bd9Sstevel@tonic-gate 			{TOK_ONEWAY, "oneway"},
4017c478bd9Sstevel@tonic-gate 			{TOK_CHAR, "char"},
4027c478bd9Sstevel@tonic-gate 			{TOK_INT, "int"},
4037c478bd9Sstevel@tonic-gate 			{TOK_UNSIGNED, "unsigned"},
4047c478bd9Sstevel@tonic-gate 			{TOK_SHORT, "short"},
4057c478bd9Sstevel@tonic-gate 			{TOK_LONG, "long"},
4067c478bd9Sstevel@tonic-gate 			{TOK_HYPER, "hyper"},
4077c478bd9Sstevel@tonic-gate 			{TOK_FLOAT, "float"},
4087c478bd9Sstevel@tonic-gate 			{TOK_DOUBLE, "double"},
4097c478bd9Sstevel@tonic-gate 			{TOK_QUAD, "quadruple"},
4107c478bd9Sstevel@tonic-gate 			{TOK_STRING, "string"},
4117c478bd9Sstevel@tonic-gate 			{TOK_PROGRAM, "program"},
4127c478bd9Sstevel@tonic-gate 			{TOK_VERSION, "version"},
4137c478bd9Sstevel@tonic-gate 			{TOK_EOF, "??????"},
4147c478bd9Sstevel@tonic-gate };
4157c478bd9Sstevel@tonic-gate 
416*61961e0fSrobinson static void
417*61961e0fSrobinson findkind(char **mark, token *tokp)
4187c478bd9Sstevel@tonic-gate {
4197c478bd9Sstevel@tonic-gate 	int len;
4207c478bd9Sstevel@tonic-gate 	token *s;
4217c478bd9Sstevel@tonic-gate 	char *str;
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate 	str = *mark;
4247c478bd9Sstevel@tonic-gate 	for (s = symbols; s->kind != TOK_EOF; s++) {
4257c478bd9Sstevel@tonic-gate 		len = strlen(s->str);
4267c478bd9Sstevel@tonic-gate 		if (strncmp(str, s->str, len) == 0) {
4277c478bd9Sstevel@tonic-gate 			if (!isalnum(str[len]) && str[len] != '_') {
4287c478bd9Sstevel@tonic-gate 				tokp->kind = s->kind;
4297c478bd9Sstevel@tonic-gate 				tokp->str = s->str;
4307c478bd9Sstevel@tonic-gate 				*mark = str + len;
4317c478bd9Sstevel@tonic-gate 				return;
4327c478bd9Sstevel@tonic-gate 			}
4337c478bd9Sstevel@tonic-gate 		}
4347c478bd9Sstevel@tonic-gate 	}
4357c478bd9Sstevel@tonic-gate 	tokp->kind = TOK_IDENT;
4367c478bd9Sstevel@tonic-gate 	for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
437*61961e0fSrobinson 	tokp->str = malloc(len + 1);
4387c478bd9Sstevel@tonic-gate 	(void) strncpy(tokp->str, str, len);
4397c478bd9Sstevel@tonic-gate 	tokp->str[len] = 0;
4407c478bd9Sstevel@tonic-gate 	*mark = str + len;
4417c478bd9Sstevel@tonic-gate }
4427c478bd9Sstevel@tonic-gate 
443*61961e0fSrobinson static int
444*61961e0fSrobinson cppline(char *line)
4457c478bd9Sstevel@tonic-gate {
4467c478bd9Sstevel@tonic-gate 	return (line == curline && *line == '#');
4477c478bd9Sstevel@tonic-gate }
4487c478bd9Sstevel@tonic-gate 
449*61961e0fSrobinson static int
450*61961e0fSrobinson directive(char *line)
4517c478bd9Sstevel@tonic-gate {
4527c478bd9Sstevel@tonic-gate 	return (line == curline && *line == '%');
4537c478bd9Sstevel@tonic-gate }
4547c478bd9Sstevel@tonic-gate 
455*61961e0fSrobinson static void
456*61961e0fSrobinson printdirective(char *line)
4577c478bd9Sstevel@tonic-gate {
4587c478bd9Sstevel@tonic-gate 	f_print(fout, "%s", line + 1);
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate 
461*61961e0fSrobinson static void
462*61961e0fSrobinson docppline(char *line, int *lineno, char **fname)
4637c478bd9Sstevel@tonic-gate {
4647c478bd9Sstevel@tonic-gate 	char *file;
4657c478bd9Sstevel@tonic-gate 	int num;
4667c478bd9Sstevel@tonic-gate 	char *p;
4677c478bd9Sstevel@tonic-gate 
4687c478bd9Sstevel@tonic-gate 	line++;
469*61961e0fSrobinson 	while (isspace(*line))
4707c478bd9Sstevel@tonic-gate 		line++;
4717c478bd9Sstevel@tonic-gate 	num = atoi(line);
472*61961e0fSrobinson 	while (isdigit(*line))
4737c478bd9Sstevel@tonic-gate 		line++;
474*61961e0fSrobinson 	while (isspace(*line))
4757c478bd9Sstevel@tonic-gate 		line++;
476*61961e0fSrobinson 	if (*line != '"')
4777c478bd9Sstevel@tonic-gate 		error("preprocessor error");
4787c478bd9Sstevel@tonic-gate 	line++;
479*61961e0fSrobinson 	p = file = malloc(strlen(line) + 1);
480*61961e0fSrobinson 	while (*line && *line != '"')
4817c478bd9Sstevel@tonic-gate 		*p++ = *line++;
482*61961e0fSrobinson 	if (*line == 0)
4837c478bd9Sstevel@tonic-gate 		error("preprocessor error");
4847c478bd9Sstevel@tonic-gate 	*p = 0;
485*61961e0fSrobinson 	if (*file == 0)
4867c478bd9Sstevel@tonic-gate 		*fname = NULL;
487*61961e0fSrobinson 	else
4887c478bd9Sstevel@tonic-gate 		*fname = file;
4897c478bd9Sstevel@tonic-gate 	*lineno = num - 1;
4907c478bd9Sstevel@tonic-gate }
491