xref: /onnv-gate/usr/src/cmd/rpcgen/rpc_scan.c (revision 9497:b07c573232c0)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*9497SJordan.Brown@Sun.COM  * Common Development and Distribution License (the "License").
6*9497SJordan.Brown@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
20132Srobinson  */
21132Srobinson 
22132Srobinson /*
23*9497SJordan.Brown@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
270Sstevel@tonic-gate /* All Rights Reserved */
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
300Sstevel@tonic-gate  * The Regents of the University of California
310Sstevel@tonic-gate  * All Rights Reserved
320Sstevel@tonic-gate  *
330Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
340Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
350Sstevel@tonic-gate  * contributors.
360Sstevel@tonic-gate  */
370Sstevel@tonic-gate 
380Sstevel@tonic-gate /*
39132Srobinson  * rpc_scan.c, Scanner for the RPC protocol compiler
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #include <sys/wait.h>
430Sstevel@tonic-gate #include <stdio.h>
440Sstevel@tonic-gate #include <ctype.h>
450Sstevel@tonic-gate #include <string.h>
46132Srobinson #include <strings.h>
470Sstevel@tonic-gate #include "rpc_scan.h"
480Sstevel@tonic-gate #include "rpc_parse.h"
490Sstevel@tonic-gate #include "rpc_util.h"
500Sstevel@tonic-gate 
51132Srobinson #define	startcomment(where)	(where[0] == '/' && where[1] == '*')
52132Srobinson #define	endcomment(where)	(where[-1] == '*' && where[0] == '/')
530Sstevel@tonic-gate 
540Sstevel@tonic-gate static int pushed = 0;	/* is a token pushed */
550Sstevel@tonic-gate static token lasttok;	/* last token, if pushed */
560Sstevel@tonic-gate 
57132Srobinson static void unget_token(token *);
58132Srobinson static void findstrconst(char **, char **);
59132Srobinson static void findchrconst(char **, char **);
60132Srobinson static void findconst(char **, char **);
61132Srobinson static void findkind(char **, token *);
62132Srobinson static int cppline(char *);
63132Srobinson static int directive(char *);
64132Srobinson static void printdirective(char *);
65132Srobinson static void docppline(char *, int *, char **);
66132Srobinson 
670Sstevel@tonic-gate /*
68132Srobinson  * scan expecting 1 given token
690Sstevel@tonic-gate  */
700Sstevel@tonic-gate void
scan(tok_kind expect,token * tokp)71132Srobinson scan(tok_kind expect, token *tokp)
720Sstevel@tonic-gate {
730Sstevel@tonic-gate 	get_token(tokp);
74132Srobinson 	if (tokp->kind != expect)
750Sstevel@tonic-gate 		expected1(expect);
760Sstevel@tonic-gate }
770Sstevel@tonic-gate 
780Sstevel@tonic-gate /*
79132Srobinson  * scan expecting any of the 2 given tokens
800Sstevel@tonic-gate  */
810Sstevel@tonic-gate void
scan2(tok_kind expect1,tok_kind expect2,token * tokp)82132Srobinson scan2(tok_kind expect1, tok_kind expect2, token *tokp)
830Sstevel@tonic-gate {
840Sstevel@tonic-gate 	get_token(tokp);
85132Srobinson 	if (tokp->kind != expect1 && tokp->kind != expect2)
860Sstevel@tonic-gate 		expected2(expect1, expect2);
870Sstevel@tonic-gate }
880Sstevel@tonic-gate 
890Sstevel@tonic-gate /*
90132Srobinson  * scan expecting any of the 3 given token
910Sstevel@tonic-gate  */
920Sstevel@tonic-gate void
scan3(tok_kind expect1,tok_kind expect2,tok_kind expect3,token * tokp)93132Srobinson scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp)
940Sstevel@tonic-gate {
950Sstevel@tonic-gate 	get_token(tokp);
96132Srobinson 	if (tokp->kind != expect1 && tokp->kind != expect2 &&
97*9497SJordan.Brown@Sun.COM 	    tokp->kind != expect3)
980Sstevel@tonic-gate 		expected3(expect1, expect2, expect3);
990Sstevel@tonic-gate }
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate /*
102132Srobinson  * scan expecting a constant, possibly symbolic
1030Sstevel@tonic-gate  */
1040Sstevel@tonic-gate void
scan_num(token * tokp)105132Srobinson scan_num(token *tokp)
1060Sstevel@tonic-gate {
1070Sstevel@tonic-gate 	get_token(tokp);
1080Sstevel@tonic-gate 	switch (tokp->kind) {
1090Sstevel@tonic-gate 	case TOK_IDENT:
1100Sstevel@tonic-gate 		break;
1110Sstevel@tonic-gate 	default:
1120Sstevel@tonic-gate 		error("constant or identifier expected");
1130Sstevel@tonic-gate 	}
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate /*
117132Srobinson  * Peek at the next token
1180Sstevel@tonic-gate  */
1190Sstevel@tonic-gate void
peek(token * tokp)120132Srobinson peek(token *tokp)
1210Sstevel@tonic-gate {
1220Sstevel@tonic-gate 	get_token(tokp);
1230Sstevel@tonic-gate 	unget_token(tokp);
1240Sstevel@tonic-gate }
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate /*
127132Srobinson  * Peek at the next token and scan it if it matches what you expect
1280Sstevel@tonic-gate  */
1290Sstevel@tonic-gate int
peekscan(tok_kind expect,token * tokp)130132Srobinson peekscan(tok_kind expect, token *tokp)
1310Sstevel@tonic-gate {
1320Sstevel@tonic-gate 	peek(tokp);
1330Sstevel@tonic-gate 	if (tokp->kind == expect) {
1340Sstevel@tonic-gate 		get_token(tokp);
1350Sstevel@tonic-gate 		return (1);
1360Sstevel@tonic-gate 	}
1370Sstevel@tonic-gate 	return (0);
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate /*
141132Srobinson  * Get the next token, printing out any directive that are encountered.
1420Sstevel@tonic-gate  */
1430Sstevel@tonic-gate void
get_token(token * tokp)144132Srobinson get_token(token *tokp)
1450Sstevel@tonic-gate {
1460Sstevel@tonic-gate 	int commenting;
1470Sstevel@tonic-gate 	int stat = 0;
148132Srobinson 
1490Sstevel@tonic-gate 	if (pushed) {
1500Sstevel@tonic-gate 		pushed = 0;
1510Sstevel@tonic-gate 		*tokp = lasttok;
1520Sstevel@tonic-gate 		return;
1530Sstevel@tonic-gate 	}
1540Sstevel@tonic-gate 	commenting = 0;
1550Sstevel@tonic-gate 	for (;;) {
1560Sstevel@tonic-gate 		if (*where == 0) {
1570Sstevel@tonic-gate 			for (;;) {
1580Sstevel@tonic-gate 				if (!fgets(curline, MAXLINESIZE, fin)) {
1590Sstevel@tonic-gate 					tokp->kind = TOK_EOF;
160132Srobinson 					/*
161132Srobinson 					 * now check if cpp returned
162132Srobinson 					 * non NULL value
163132Srobinson 					 */
164132Srobinson 					(void) waitpid(childpid, &stat,
165*9497SJordan.Brown@Sun.COM 					    WUNTRACED);
1660Sstevel@tonic-gate 					if (stat > 0) {
1670Sstevel@tonic-gate 					/* Set return value from rpcgen */
1680Sstevel@tonic-gate 						nonfatalerrors = stat >> 8;
1690Sstevel@tonic-gate 					}
1700Sstevel@tonic-gate 					*where = 0;
1710Sstevel@tonic-gate 					return;
1720Sstevel@tonic-gate 				}
1730Sstevel@tonic-gate 				linenum++;
1740Sstevel@tonic-gate 				if (commenting) {
1750Sstevel@tonic-gate 					break;
1760Sstevel@tonic-gate 				} else if (cppline(curline)) {
177132Srobinson 					docppline(curline, &linenum,
178*9497SJordan.Brown@Sun.COM 					    &infilename);
1790Sstevel@tonic-gate 				} else if (directive(curline)) {
1800Sstevel@tonic-gate 					printdirective(curline);
1810Sstevel@tonic-gate 				} else {
1820Sstevel@tonic-gate 					break;
1830Sstevel@tonic-gate 				}
1840Sstevel@tonic-gate 			}
1850Sstevel@tonic-gate 			where = curline;
1860Sstevel@tonic-gate 		} else if (isspace(*where)) {
1870Sstevel@tonic-gate 			while (isspace(*where)) {
1880Sstevel@tonic-gate 				where++;	/* eat */
1890Sstevel@tonic-gate 			}
1900Sstevel@tonic-gate 		} else if (commenting) {
1910Sstevel@tonic-gate 			for (where++; *where; where++) {
1920Sstevel@tonic-gate 				if (endcomment(where)) {
1930Sstevel@tonic-gate 					where++;
1940Sstevel@tonic-gate 					commenting--;
1950Sstevel@tonic-gate 					break;
1960Sstevel@tonic-gate 				}
1970Sstevel@tonic-gate 			}
1980Sstevel@tonic-gate 		} else if (startcomment(where)) {
1990Sstevel@tonic-gate 			where += 2;
2000Sstevel@tonic-gate 			commenting++;
2010Sstevel@tonic-gate 		} else {
2020Sstevel@tonic-gate 			break;
2030Sstevel@tonic-gate 		}
2040Sstevel@tonic-gate 	}
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 	/*
207132Srobinson 	 * 'where' is not whitespace, comment or directive Must be a token!
2080Sstevel@tonic-gate 	 */
2090Sstevel@tonic-gate 	switch (*where) {
2100Sstevel@tonic-gate 	case ':':
2110Sstevel@tonic-gate 		tokp->kind = TOK_COLON;
2120Sstevel@tonic-gate 		where++;
2130Sstevel@tonic-gate 		break;
2140Sstevel@tonic-gate 	case ';':
2150Sstevel@tonic-gate 		tokp->kind = TOK_SEMICOLON;
2160Sstevel@tonic-gate 		where++;
2170Sstevel@tonic-gate 		break;
2180Sstevel@tonic-gate 	case ',':
2190Sstevel@tonic-gate 		tokp->kind = TOK_COMMA;
2200Sstevel@tonic-gate 		where++;
2210Sstevel@tonic-gate 		break;
2220Sstevel@tonic-gate 	case '=':
2230Sstevel@tonic-gate 		tokp->kind = TOK_EQUAL;
2240Sstevel@tonic-gate 		where++;
2250Sstevel@tonic-gate 		break;
2260Sstevel@tonic-gate 	case '*':
2270Sstevel@tonic-gate 		tokp->kind = TOK_STAR;
2280Sstevel@tonic-gate 		where++;
2290Sstevel@tonic-gate 		break;
2300Sstevel@tonic-gate 	case '[':
2310Sstevel@tonic-gate 		tokp->kind = TOK_LBRACKET;
2320Sstevel@tonic-gate 		where++;
2330Sstevel@tonic-gate 		break;
2340Sstevel@tonic-gate 	case ']':
2350Sstevel@tonic-gate 		tokp->kind = TOK_RBRACKET;
2360Sstevel@tonic-gate 		where++;
2370Sstevel@tonic-gate 		break;
2380Sstevel@tonic-gate 	case '{':
2390Sstevel@tonic-gate 		tokp->kind = TOK_LBRACE;
2400Sstevel@tonic-gate 		where++;
2410Sstevel@tonic-gate 		break;
2420Sstevel@tonic-gate 	case '}':
2430Sstevel@tonic-gate 		tokp->kind = TOK_RBRACE;
2440Sstevel@tonic-gate 		where++;
2450Sstevel@tonic-gate 		break;
2460Sstevel@tonic-gate 	case '(':
2470Sstevel@tonic-gate 		tokp->kind = TOK_LPAREN;
2480Sstevel@tonic-gate 		where++;
2490Sstevel@tonic-gate 		break;
2500Sstevel@tonic-gate 	case ')':
2510Sstevel@tonic-gate 		tokp->kind = TOK_RPAREN;
2520Sstevel@tonic-gate 		where++;
2530Sstevel@tonic-gate 		break;
2540Sstevel@tonic-gate 	case '<':
2550Sstevel@tonic-gate 		tokp->kind = TOK_LANGLE;
2560Sstevel@tonic-gate 		where++;
2570Sstevel@tonic-gate 		break;
2580Sstevel@tonic-gate 	case '>':
2590Sstevel@tonic-gate 		tokp->kind = TOK_RANGLE;
2600Sstevel@tonic-gate 		where++;
2610Sstevel@tonic-gate 		break;
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate 	case '"':
2640Sstevel@tonic-gate 		tokp->kind = TOK_STRCONST;
2650Sstevel@tonic-gate 		findstrconst(&where, &tokp->str);
2660Sstevel@tonic-gate 		break;
2670Sstevel@tonic-gate 	case '\'':
2680Sstevel@tonic-gate 		tokp->kind = TOK_CHARCONST;
2690Sstevel@tonic-gate 		findchrconst(&where, &tokp->str);
2700Sstevel@tonic-gate 		break;
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate 	case '-':
2730Sstevel@tonic-gate 	case '0':
2740Sstevel@tonic-gate 	case '1':
2750Sstevel@tonic-gate 	case '2':
2760Sstevel@tonic-gate 	case '3':
2770Sstevel@tonic-gate 	case '4':
2780Sstevel@tonic-gate 	case '5':
2790Sstevel@tonic-gate 	case '6':
2800Sstevel@tonic-gate 	case '7':
2810Sstevel@tonic-gate 	case '8':
2820Sstevel@tonic-gate 	case '9':
2830Sstevel@tonic-gate 		tokp->kind = TOK_IDENT;
2840Sstevel@tonic-gate 		findconst(&where, &tokp->str);
2850Sstevel@tonic-gate 		break;
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate 	default:
2880Sstevel@tonic-gate 		if (!(isalpha(*where) || *where == '_')) {
2890Sstevel@tonic-gate 			char buf[100];
2900Sstevel@tonic-gate 			char *p;
291132Srobinson 			size_t blen;
2920Sstevel@tonic-gate 
293132Srobinson 			(void) snprintf(buf, sizeof (buf),
294*9497SJordan.Brown@Sun.COM 			    "illegal character in file: ");
295132Srobinson 			blen = strlen(buf);
296132Srobinson 			p = buf + blen;
2970Sstevel@tonic-gate 			if (isprint(*where)) {
298132Srobinson 				(void) snprintf(p, sizeof (buf) - blen,
299*9497SJordan.Brown@Sun.COM 				    "%c", *where);
3000Sstevel@tonic-gate 			} else {
301132Srobinson 				(void) snprintf(p, sizeof (buf) - blen,
302*9497SJordan.Brown@Sun.COM 				    "%d", *where);
3030Sstevel@tonic-gate 			}
3040Sstevel@tonic-gate 			error(buf);
3050Sstevel@tonic-gate 		}
3060Sstevel@tonic-gate 		findkind(&where, tokp);
3070Sstevel@tonic-gate 		break;
3080Sstevel@tonic-gate 	}
3090Sstevel@tonic-gate }
3100Sstevel@tonic-gate 
311132Srobinson static void
unget_token(token * tokp)312132Srobinson unget_token(token *tokp)
3130Sstevel@tonic-gate {
3140Sstevel@tonic-gate 	lasttok = *tokp;
3150Sstevel@tonic-gate 	pushed = 1;
3160Sstevel@tonic-gate }
3170Sstevel@tonic-gate 
318132Srobinson static void
findstrconst(char ** str,char ** val)319132Srobinson findstrconst(char **str, char **val)
3200Sstevel@tonic-gate {
3210Sstevel@tonic-gate 	char *p;
3220Sstevel@tonic-gate 	int size;
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 	p = *str;
3250Sstevel@tonic-gate 	do {
326132Srobinson 		p++;
3270Sstevel@tonic-gate 	} while (*p && *p != '"');
3280Sstevel@tonic-gate 	if (*p == 0) {
3290Sstevel@tonic-gate 		error("unterminated string constant");
3300Sstevel@tonic-gate 	}
3310Sstevel@tonic-gate 	p++;
3320Sstevel@tonic-gate 	size = p - *str;
333132Srobinson 	*val = malloc(size + 1);
3340Sstevel@tonic-gate 	(void) strncpy(*val, *str, size);
3350Sstevel@tonic-gate 	(*val)[size] = 0;
3360Sstevel@tonic-gate 	*str = p;
3370Sstevel@tonic-gate }
3380Sstevel@tonic-gate 
339132Srobinson static void
findchrconst(char ** str,char ** val)340132Srobinson findchrconst(char **str, char **val)
3410Sstevel@tonic-gate {
3420Sstevel@tonic-gate 	char *p;
3430Sstevel@tonic-gate 	int size;
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate 	p = *str;
3460Sstevel@tonic-gate 	do {
347132Srobinson 		p++;
3480Sstevel@tonic-gate 	} while (*p && *p != '\'');
349132Srobinson 	if (*p == 0)
3500Sstevel@tonic-gate 		error("unterminated string constant");
3510Sstevel@tonic-gate 	p++;
3520Sstevel@tonic-gate 	size = p - *str;
353132Srobinson 	if (size != 3)
3540Sstevel@tonic-gate 		error("empty char string");
355132Srobinson 	*val = malloc(size + 1);
3560Sstevel@tonic-gate 	(void) strncpy(*val, *str, size);
3570Sstevel@tonic-gate 	(*val)[size] = 0;
3580Sstevel@tonic-gate 	*str = p;
3590Sstevel@tonic-gate }
3600Sstevel@tonic-gate 
361132Srobinson static void
findconst(char ** str,char ** val)362132Srobinson findconst(char **str, char **val)
3630Sstevel@tonic-gate {
3640Sstevel@tonic-gate 	char *p;
3650Sstevel@tonic-gate 	int size;
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate 	p = *str;
3680Sstevel@tonic-gate 	if (*p == '0' && *(p + 1) == 'x') {
3690Sstevel@tonic-gate 		p++;
3700Sstevel@tonic-gate 		do {
3710Sstevel@tonic-gate 			p++;
3720Sstevel@tonic-gate 		} while (isxdigit(*p));
3730Sstevel@tonic-gate 	} else {
3740Sstevel@tonic-gate 		do {
3750Sstevel@tonic-gate 			p++;
3760Sstevel@tonic-gate 		} while (isdigit(*p));
3770Sstevel@tonic-gate 	}
3780Sstevel@tonic-gate 	size = p - *str;
379132Srobinson 	*val = malloc(size + 1);
3800Sstevel@tonic-gate 	(void) strncpy(*val, *str, size);
3810Sstevel@tonic-gate 	(*val)[size] = 0;
3820Sstevel@tonic-gate 	*str = p;
3830Sstevel@tonic-gate }
3840Sstevel@tonic-gate 
3850Sstevel@tonic-gate static token symbols[] = {
386132Srobinson 			{TOK_CONST, "const"},
387132Srobinson 			{TOK_UNION, "union"},
388132Srobinson 			{TOK_SWITCH, "switch"},
389132Srobinson 			{TOK_CASE, "case"},
390132Srobinson 			{TOK_DEFAULT, "default"},
391132Srobinson 			{TOK_STRUCT, "struct"},
392132Srobinson 			{TOK_TYPEDEF, "typedef"},
393132Srobinson 			{TOK_ENUM, "enum"},
394132Srobinson 			{TOK_OPAQUE, "opaque"},
395132Srobinson 			{TOK_BOOL, "bool"},
396132Srobinson 			{TOK_VOID, "void"},
397132Srobinson 			{TOK_ONEWAY, "oneway"},
398132Srobinson 			{TOK_CHAR, "char"},
399132Srobinson 			{TOK_INT, "int"},
400132Srobinson 			{TOK_UNSIGNED, "unsigned"},
401132Srobinson 			{TOK_SHORT, "short"},
402132Srobinson 			{TOK_LONG, "long"},
403132Srobinson 			{TOK_HYPER, "hyper"},
404132Srobinson 			{TOK_FLOAT, "float"},
405132Srobinson 			{TOK_DOUBLE, "double"},
406132Srobinson 			{TOK_QUAD, "quadruple"},
407132Srobinson 			{TOK_STRING, "string"},
408132Srobinson 			{TOK_PROGRAM, "program"},
409132Srobinson 			{TOK_VERSION, "version"},
410132Srobinson 			{TOK_EOF, "??????"},
4110Sstevel@tonic-gate };
4120Sstevel@tonic-gate 
413132Srobinson static void
findkind(char ** mark,token * tokp)414132Srobinson findkind(char **mark, token *tokp)
4150Sstevel@tonic-gate {
4160Sstevel@tonic-gate 	int len;
4170Sstevel@tonic-gate 	token *s;
4180Sstevel@tonic-gate 	char *str;
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate 	str = *mark;
4210Sstevel@tonic-gate 	for (s = symbols; s->kind != TOK_EOF; s++) {
4220Sstevel@tonic-gate 		len = strlen(s->str);
4230Sstevel@tonic-gate 		if (strncmp(str, s->str, len) == 0) {
4240Sstevel@tonic-gate 			if (!isalnum(str[len]) && str[len] != '_') {
4250Sstevel@tonic-gate 				tokp->kind = s->kind;
4260Sstevel@tonic-gate 				tokp->str = s->str;
4270Sstevel@tonic-gate 				*mark = str + len;
4280Sstevel@tonic-gate 				return;
4290Sstevel@tonic-gate 			}
4300Sstevel@tonic-gate 		}
4310Sstevel@tonic-gate 	}
4320Sstevel@tonic-gate 	tokp->kind = TOK_IDENT;
433*9497SJordan.Brown@Sun.COM 	for (len = 0; isalnum(str[len]) || str[len] == '_'; len++)
434*9497SJordan.Brown@Sun.COM 		/* LOOP */;
435132Srobinson 	tokp->str = malloc(len + 1);
4360Sstevel@tonic-gate 	(void) strncpy(tokp->str, str, len);
4370Sstevel@tonic-gate 	tokp->str[len] = 0;
4380Sstevel@tonic-gate 	*mark = str + len;
4390Sstevel@tonic-gate }
4400Sstevel@tonic-gate 
441132Srobinson static int
cppline(char * line)442132Srobinson cppline(char *line)
4430Sstevel@tonic-gate {
4440Sstevel@tonic-gate 	return (line == curline && *line == '#');
4450Sstevel@tonic-gate }
4460Sstevel@tonic-gate 
447132Srobinson static int
directive(char * line)448132Srobinson directive(char *line)
4490Sstevel@tonic-gate {
4500Sstevel@tonic-gate 	return (line == curline && *line == '%');
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate 
453132Srobinson static void
printdirective(char * line)454132Srobinson printdirective(char *line)
4550Sstevel@tonic-gate {
4560Sstevel@tonic-gate 	f_print(fout, "%s", line + 1);
4570Sstevel@tonic-gate }
4580Sstevel@tonic-gate 
459132Srobinson static void
docppline(char * line,int * lineno,char ** fname)460132Srobinson docppline(char *line, int *lineno, char **fname)
4610Sstevel@tonic-gate {
4620Sstevel@tonic-gate 	char *file;
4630Sstevel@tonic-gate 	int num;
4640Sstevel@tonic-gate 	char *p;
4650Sstevel@tonic-gate 
4660Sstevel@tonic-gate 	line++;
467132Srobinson 	while (isspace(*line))
4680Sstevel@tonic-gate 		line++;
4690Sstevel@tonic-gate 	num = atoi(line);
470132Srobinson 	while (isdigit(*line))
4710Sstevel@tonic-gate 		line++;
472132Srobinson 	while (isspace(*line))
4730Sstevel@tonic-gate 		line++;
474132Srobinson 	if (*line != '"')
4750Sstevel@tonic-gate 		error("preprocessor error");
4760Sstevel@tonic-gate 	line++;
477132Srobinson 	p = file = malloc(strlen(line) + 1);
478132Srobinson 	while (*line && *line != '"')
4790Sstevel@tonic-gate 		*p++ = *line++;
480132Srobinson 	if (*line == 0)
4810Sstevel@tonic-gate 		error("preprocessor error");
4820Sstevel@tonic-gate 	*p = 0;
483132Srobinson 	if (*file == 0)
4840Sstevel@tonic-gate 		*fname = NULL;
485132Srobinson 	else
4860Sstevel@tonic-gate 		*fname = file;
4870Sstevel@tonic-gate 	*lineno = num - 1;
4880Sstevel@tonic-gate }
489