xref: /freebsd/usr.bin/rpcgen/rpc_scan.c (revision 5b31cc94b10d4bb7109c6b27940a0fc76a44a331)
14e115012SGarrett Wollman /*
24e115012SGarrett Wollman  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
34e115012SGarrett Wollman  * unrestricted use provided that this legend is included on all tape
44e115012SGarrett Wollman  * media and as a part of the software program in whole or part.  Users
54e115012SGarrett Wollman  * may copy or modify Sun RPC without charge, but are not authorized
64e115012SGarrett Wollman  * to license or distribute it to anyone else except as part of a product or
74e115012SGarrett Wollman  * program developed by the user.
84e115012SGarrett Wollman  *
94e115012SGarrett Wollman  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
104e115012SGarrett Wollman  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
114e115012SGarrett Wollman  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
124e115012SGarrett Wollman  *
134e115012SGarrett Wollman  * Sun RPC is provided with no support and without any obligation on the
144e115012SGarrett Wollman  * part of Sun Microsystems, Inc. to assist in its use, correction,
154e115012SGarrett Wollman  * modification or enhancement.
164e115012SGarrett Wollman  *
174e115012SGarrett Wollman  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
184e115012SGarrett Wollman  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
194e115012SGarrett Wollman  * OR ANY PART THEREOF.
204e115012SGarrett Wollman  *
214e115012SGarrett Wollman  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
224e115012SGarrett Wollman  * or profits or other special, indirect and consequential damages, even if
234e115012SGarrett Wollman  * Sun has been advised of the possibility of such damages.
244e115012SGarrett Wollman  *
254e115012SGarrett Wollman  * Sun Microsystems, Inc.
264e115012SGarrett Wollman  * 2550 Garcia Avenue
274e115012SGarrett Wollman  * Mountain View, California  94043
284e115012SGarrett Wollman  */
29ff49530fSBill Paul 
304e115012SGarrett Wollman /*
314e115012SGarrett Wollman  * rpc_scan.c, Scanner for the RPC protocol compiler
324e115012SGarrett Wollman  * Copyright (C) 1987, Sun Microsystems, Inc.
334e115012SGarrett Wollman  */
34ff49530fSBill Paul 
35bff9e230SBrian Somers #include <sys/types.h>
36bff9e230SBrian Somers 
37ff49530fSBill Paul #include <sys/wait.h>
384e115012SGarrett Wollman #include <stdio.h>
394e115012SGarrett Wollman #include <ctype.h>
40ff49530fSBill Paul #include <string.h>
41ff49530fSBill Paul #include "rpc_parse.h"
42e390e3afSDavid Malone #include "rpc_scan.h"
434e115012SGarrett Wollman #include "rpc_util.h"
444e115012SGarrett Wollman 
454e115012SGarrett Wollman #define startcomment(where) (where[0] == '/' && where[1] == '*')
464e115012SGarrett Wollman #define endcomment(where) (where[-1] == '*' && where[0] == '/')
474e115012SGarrett Wollman 
484e115012SGarrett Wollman static int pushed = 0;	/* is a token pushed */
494e115012SGarrett Wollman static token lasttok;	/* last token, if pushed */
504e115012SGarrett Wollman 
51d3cb5dedSWarner Losh static void unget_token( token * );
52e390e3afSDavid Malone static void findstrconst(char **, const char **);
53e390e3afSDavid Malone static void findchrconst(char **, const char **);
54e390e3afSDavid Malone static void findconst(char **, const char **);
55d3cb5dedSWarner Losh static void findkind( char **, token * );
56d3cb5dedSWarner Losh static int cppline( char * );
57d3cb5dedSWarner Losh static int directive( char * );
58d3cb5dedSWarner Losh static void printdirective( char * );
59e390e3afSDavid Malone static void docppline(char *, int *, const char **);
60ff49530fSBill Paul 
614e115012SGarrett Wollman /*
624e115012SGarrett Wollman  * scan expecting 1 given token
634e115012SGarrett Wollman  */
644e115012SGarrett Wollman void
scan(tok_kind expect,token * tokp)65e390e3afSDavid Malone scan(tok_kind expect, token *tokp)
664e115012SGarrett Wollman {
674e115012SGarrett Wollman 	get_token(tokp);
684e115012SGarrett Wollman 	if (tokp->kind != expect) {
694e115012SGarrett Wollman 		expected1(expect);
704e115012SGarrett Wollman 	}
714e115012SGarrett Wollman }
724e115012SGarrett Wollman 
734e115012SGarrett Wollman /*
74ff49530fSBill Paul  * scan expecting any of the 2 given tokens
754e115012SGarrett Wollman  */
764e115012SGarrett Wollman void
scan2(tok_kind expect1,tok_kind expect2,token * tokp)77e390e3afSDavid Malone scan2(tok_kind expect1, tok_kind expect2, token *tokp)
784e115012SGarrett Wollman {
794e115012SGarrett Wollman 	get_token(tokp);
804e115012SGarrett Wollman 	if (tokp->kind != expect1 && tokp->kind != expect2) {
814e115012SGarrett Wollman 		expected2(expect1, expect2);
824e115012SGarrett Wollman 	}
834e115012SGarrett Wollman }
844e115012SGarrett Wollman 
854e115012SGarrett Wollman /*
86ff49530fSBill Paul  * scan expecting any of the 3 given token
874e115012SGarrett Wollman  */
884e115012SGarrett Wollman void
scan3(tok_kind expect1,tok_kind expect2,tok_kind expect3,token * tokp)89e390e3afSDavid Malone scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp)
904e115012SGarrett Wollman {
914e115012SGarrett Wollman 	get_token(tokp);
924e115012SGarrett Wollman 	if (tokp->kind != expect1 && tokp->kind != expect2
934e115012SGarrett Wollman 	    && tokp->kind != expect3) {
944e115012SGarrett Wollman 		expected3(expect1, expect2, expect3);
954e115012SGarrett Wollman 	}
964e115012SGarrett Wollman }
974e115012SGarrett Wollman 
984e115012SGarrett Wollman /*
994e115012SGarrett Wollman  * scan expecting a constant, possibly symbolic
1004e115012SGarrett Wollman  */
1014e115012SGarrett Wollman void
scan_num(token * tokp)102e390e3afSDavid Malone scan_num(token *tokp)
1034e115012SGarrett Wollman {
1044e115012SGarrett Wollman 	get_token(tokp);
1054e115012SGarrett Wollman 	switch (tokp->kind) {
1064e115012SGarrett Wollman 	case TOK_IDENT:
1074e115012SGarrett Wollman 		break;
1084e115012SGarrett Wollman 	default:
1094e115012SGarrett Wollman 		error("constant or identifier expected");
1104e115012SGarrett Wollman 	}
1114e115012SGarrett Wollman }
1124e115012SGarrett Wollman 
1134e115012SGarrett Wollman /*
1144e115012SGarrett Wollman  * Peek at the next token
1154e115012SGarrett Wollman  */
1164e115012SGarrett Wollman void
peek(token * tokp)117e390e3afSDavid Malone peek(token *tokp)
1184e115012SGarrett Wollman {
1194e115012SGarrett Wollman 	get_token(tokp);
1204e115012SGarrett Wollman 	unget_token(tokp);
1214e115012SGarrett Wollman }
1224e115012SGarrett Wollman 
1234e115012SGarrett Wollman /*
1244e115012SGarrett Wollman  * Peek at the next token and scan it if it matches what you expect
1254e115012SGarrett Wollman  */
1264e115012SGarrett Wollman int
peekscan(tok_kind expect,token * tokp)127e390e3afSDavid Malone peekscan(tok_kind expect, token *tokp)
1284e115012SGarrett Wollman {
1294e115012SGarrett Wollman 	peek(tokp);
1304e115012SGarrett Wollman 	if (tokp->kind == expect) {
1314e115012SGarrett Wollman 		get_token(tokp);
1324e115012SGarrett Wollman 		return (1);
1334e115012SGarrett Wollman 	}
1344e115012SGarrett Wollman 	return (0);
1354e115012SGarrett Wollman }
1364e115012SGarrett Wollman 
1374e115012SGarrett Wollman /*
1384e115012SGarrett Wollman  * Get the next token, printing out any directive that are encountered.
1394e115012SGarrett Wollman  */
1404e115012SGarrett Wollman void
get_token(token * tokp)141e390e3afSDavid Malone get_token(token *tokp)
1424e115012SGarrett Wollman {
1434e115012SGarrett Wollman 	int commenting;
144ff49530fSBill Paul 	int stat = 0;
145ff49530fSBill Paul 
1464e115012SGarrett Wollman 
1474e115012SGarrett Wollman 	if (pushed) {
1484e115012SGarrett Wollman 		pushed = 0;
1494e115012SGarrett Wollman 		*tokp = lasttok;
1504e115012SGarrett Wollman 		return;
1514e115012SGarrett Wollman 	}
1524e115012SGarrett Wollman 	commenting = 0;
1534e115012SGarrett Wollman 	for (;;) {
1544e115012SGarrett Wollman 		if (*where == 0) {
1554e115012SGarrett Wollman 			for (;;) {
1564e115012SGarrett Wollman 				if (!fgets(curline, MAXLINESIZE, fin)) {
1574e115012SGarrett Wollman 					tokp->kind = TOK_EOF;
158ff49530fSBill Paul 					/* now check if cpp returned non NULL value */
159ff49530fSBill Paul 					waitpid(childpid, &stat, WUNTRACED);
160ff49530fSBill Paul 					if (stat > 0) {
161ff49530fSBill Paul 					/* Set return value from rpcgen */
162ff49530fSBill Paul 						nonfatalerrors = stat >> 8;
163ff49530fSBill Paul 					}
1644e115012SGarrett Wollman 					*where = 0;
1654e115012SGarrett Wollman 					return;
1664e115012SGarrett Wollman 				}
1674e115012SGarrett Wollman 				linenum++;
1684e115012SGarrett Wollman 				if (commenting) {
1694e115012SGarrett Wollman 					break;
1704e115012SGarrett Wollman 				} else if (cppline(curline)) {
1714e115012SGarrett Wollman 					docppline(curline, &linenum,
1724e115012SGarrett Wollman 						  &infilename);
1734e115012SGarrett Wollman 				} else if (directive(curline)) {
1744e115012SGarrett Wollman 					printdirective(curline);
1754e115012SGarrett Wollman 				} else {
1764e115012SGarrett Wollman 					break;
1774e115012SGarrett Wollman 				}
1784e115012SGarrett Wollman 			}
1794e115012SGarrett Wollman 			where = curline;
1804e115012SGarrett Wollman 		} else if (isspace(*where)) {
1814e115012SGarrett Wollman 			while (isspace(*where)) {
1824e115012SGarrett Wollman 				where++;	/* eat */
1834e115012SGarrett Wollman 			}
1844e115012SGarrett Wollman 		} else if (commenting) {
185ff49530fSBill Paul 			for (where++; *where; where++) {
1864e115012SGarrett Wollman 				if (endcomment(where)) {
1874e115012SGarrett Wollman 					where++;
1884e115012SGarrett Wollman 					commenting--;
189ff49530fSBill Paul 					break;
190ff49530fSBill Paul 				}
1914e115012SGarrett Wollman 			}
1924e115012SGarrett Wollman 		} else if (startcomment(where)) {
1934e115012SGarrett Wollman 			where += 2;
1944e115012SGarrett Wollman 			commenting++;
1954e115012SGarrett Wollman 		} else {
1964e115012SGarrett Wollman 			break;
1974e115012SGarrett Wollman 		}
1984e115012SGarrett Wollman 	}
1994e115012SGarrett Wollman 
2004e115012SGarrett Wollman 	/*
2014e115012SGarrett Wollman 	 * 'where' is not whitespace, comment or directive Must be a token!
2024e115012SGarrett Wollman 	 */
2034e115012SGarrett Wollman 	switch (*where) {
2044e115012SGarrett Wollman 	case ':':
2054e115012SGarrett Wollman 		tokp->kind = TOK_COLON;
2064e115012SGarrett Wollman 		where++;
2074e115012SGarrett Wollman 		break;
2084e115012SGarrett Wollman 	case ';':
2094e115012SGarrett Wollman 		tokp->kind = TOK_SEMICOLON;
2104e115012SGarrett Wollman 		where++;
2114e115012SGarrett Wollman 		break;
2124e115012SGarrett Wollman 	case ',':
2134e115012SGarrett Wollman 		tokp->kind = TOK_COMMA;
2144e115012SGarrett Wollman 		where++;
2154e115012SGarrett Wollman 		break;
2164e115012SGarrett Wollman 	case '=':
2174e115012SGarrett Wollman 		tokp->kind = TOK_EQUAL;
2184e115012SGarrett Wollman 		where++;
2194e115012SGarrett Wollman 		break;
2204e115012SGarrett Wollman 	case '*':
2214e115012SGarrett Wollman 		tokp->kind = TOK_STAR;
2224e115012SGarrett Wollman 		where++;
2234e115012SGarrett Wollman 		break;
2244e115012SGarrett Wollman 	case '[':
2254e115012SGarrett Wollman 		tokp->kind = TOK_LBRACKET;
2264e115012SGarrett Wollman 		where++;
2274e115012SGarrett Wollman 		break;
2284e115012SGarrett Wollman 	case ']':
2294e115012SGarrett Wollman 		tokp->kind = TOK_RBRACKET;
2304e115012SGarrett Wollman 		where++;
2314e115012SGarrett Wollman 		break;
2324e115012SGarrett Wollman 	case '{':
2334e115012SGarrett Wollman 		tokp->kind = TOK_LBRACE;
2344e115012SGarrett Wollman 		where++;
2354e115012SGarrett Wollman 		break;
2364e115012SGarrett Wollman 	case '}':
2374e115012SGarrett Wollman 		tokp->kind = TOK_RBRACE;
2384e115012SGarrett Wollman 		where++;
2394e115012SGarrett Wollman 		break;
2404e115012SGarrett Wollman 	case '(':
2414e115012SGarrett Wollman 		tokp->kind = TOK_LPAREN;
2424e115012SGarrett Wollman 		where++;
2434e115012SGarrett Wollman 		break;
2444e115012SGarrett Wollman 	case ')':
2454e115012SGarrett Wollman 		tokp->kind = TOK_RPAREN;
2464e115012SGarrett Wollman 		where++;
2474e115012SGarrett Wollman 		break;
2484e115012SGarrett Wollman 	case '<':
2494e115012SGarrett Wollman 		tokp->kind = TOK_LANGLE;
2504e115012SGarrett Wollman 		where++;
2514e115012SGarrett Wollman 		break;
2524e115012SGarrett Wollman 	case '>':
2534e115012SGarrett Wollman 		tokp->kind = TOK_RANGLE;
2544e115012SGarrett Wollman 		where++;
2554e115012SGarrett Wollman 		break;
2564e115012SGarrett Wollman 
2574e115012SGarrett Wollman 	case '"':
2584e115012SGarrett Wollman 		tokp->kind = TOK_STRCONST;
2594e115012SGarrett Wollman 		findstrconst(&where, &tokp->str);
2604e115012SGarrett Wollman 		break;
261ff49530fSBill Paul 	case '\'':
262ff49530fSBill Paul 		tokp->kind = TOK_CHARCONST;
263ff49530fSBill Paul 		findchrconst(&where, &tokp->str);
264ff49530fSBill Paul 		break;
2654e115012SGarrett Wollman 
2664e115012SGarrett Wollman 	case '-':
2674e115012SGarrett Wollman 	case '0':
2684e115012SGarrett Wollman 	case '1':
2694e115012SGarrett Wollman 	case '2':
2704e115012SGarrett Wollman 	case '3':
2714e115012SGarrett Wollman 	case '4':
2724e115012SGarrett Wollman 	case '5':
2734e115012SGarrett Wollman 	case '6':
2744e115012SGarrett Wollman 	case '7':
2754e115012SGarrett Wollman 	case '8':
2764e115012SGarrett Wollman 	case '9':
2774e115012SGarrett Wollman 		tokp->kind = TOK_IDENT;
2784e115012SGarrett Wollman 		findconst(&where, &tokp->str);
2794e115012SGarrett Wollman 		break;
2804e115012SGarrett Wollman 
2814e115012SGarrett Wollman 	default:
2824e115012SGarrett Wollman 		if (!(isalpha(*where) || *where == '_')) {
2834e115012SGarrett Wollman 			char buf[100];
2844e115012SGarrett Wollman 			char *p;
2854e115012SGarrett Wollman 
2864e115012SGarrett Wollman 			s_print(buf, "illegal character in file: ");
2874e115012SGarrett Wollman 			p = buf + strlen(buf);
2884e115012SGarrett Wollman 			if (isprint(*where)) {
2894e115012SGarrett Wollman 				s_print(p, "%c", *where);
2904e115012SGarrett Wollman 			} else {
2914e115012SGarrett Wollman 				s_print(p, "%d", *where);
2924e115012SGarrett Wollman 			}
2934e115012SGarrett Wollman 			error(buf);
2944e115012SGarrett Wollman 		}
2954e115012SGarrett Wollman 		findkind(&where, tokp);
2964e115012SGarrett Wollman 		break;
2974e115012SGarrett Wollman 	}
2984e115012SGarrett Wollman }
2994e115012SGarrett Wollman 
300526195adSJordan K. Hubbard static void
unget_token(token * tokp)301e390e3afSDavid Malone unget_token(token *tokp)
3024e115012SGarrett Wollman {
3034e115012SGarrett Wollman 	lasttok = *tokp;
3044e115012SGarrett Wollman 	pushed = 1;
3054e115012SGarrett Wollman }
3064e115012SGarrett Wollman 
307526195adSJordan K. Hubbard static void
findstrconst(char ** str,const char ** val)308e390e3afSDavid Malone findstrconst(char **str, const char **val)
3094e115012SGarrett Wollman {
3104e115012SGarrett Wollman 	char *p;
311e390e3afSDavid Malone 	char *tmp;
3124e115012SGarrett Wollman 	int size;
3134e115012SGarrett Wollman 
3144e115012SGarrett Wollman 	p = *str;
3154e115012SGarrett Wollman 	do {
316526195adSJordan K. Hubbard 		p++;
3174e115012SGarrett Wollman 	} while (*p && *p != '"');
3184e115012SGarrett Wollman 	if (*p == 0) {
3194e115012SGarrett Wollman 		error("unterminated string constant");
3204e115012SGarrett Wollman 	}
3214e115012SGarrett Wollman 	p++;
322682b6483SXin LI 	size = p - *str + 1;
323682b6483SXin LI 	tmp = xmalloc(size);
324682b6483SXin LI 	(void) strlcpy(tmp, *str, size);
325e390e3afSDavid Malone 	*val = tmp;
3264e115012SGarrett Wollman 	*str = p;
3274e115012SGarrett Wollman }
3284e115012SGarrett Wollman 
329526195adSJordan K. Hubbard static void
findchrconst(char ** str,const char ** val)330e390e3afSDavid Malone findchrconst(char **str, const char **val)
331ff49530fSBill Paul {
332ff49530fSBill Paul 	char *p;
333e390e3afSDavid Malone 	char *tmp;
334ff49530fSBill Paul 	int size;
335ff49530fSBill Paul 
336ff49530fSBill Paul 	p = *str;
337ff49530fSBill Paul 	do {
338526195adSJordan K. Hubbard 		p++;
339ff49530fSBill Paul 	} while (*p && *p != '\'');
340ff49530fSBill Paul 	if (*p == 0) {
341ff49530fSBill Paul 		error("unterminated string constant");
342ff49530fSBill Paul 	}
343ff49530fSBill Paul 	p++;
344682b6483SXin LI 	size = p - *str + 1;
345682b6483SXin LI 	if (size != 4) {
346ff49530fSBill Paul 		error("empty char string");
347ff49530fSBill Paul 	}
348682b6483SXin LI 	tmp = xmalloc(size);
349682b6483SXin LI 	(void) strlcpy(tmp, *str, size);
350e390e3afSDavid Malone 	*val = tmp;
351ff49530fSBill Paul 	*str = p;
352ff49530fSBill Paul }
353ff49530fSBill Paul 
354526195adSJordan K. Hubbard static void
findconst(char ** str,const char ** val)355e390e3afSDavid Malone findconst(char **str, const char **val)
3564e115012SGarrett Wollman {
3574e115012SGarrett Wollman 	char *p;
358e390e3afSDavid Malone 	char *tmp;
3594e115012SGarrett Wollman 	int size;
3604e115012SGarrett Wollman 
3614e115012SGarrett Wollman 	p = *str;
3624e115012SGarrett Wollman 	if (*p == '0' && *(p + 1) == 'x') {
3634e115012SGarrett Wollman 		p++;
3644e115012SGarrett Wollman 		do {
3654e115012SGarrett Wollman 			p++;
3664e115012SGarrett Wollman 		} while (isxdigit(*p));
3674e115012SGarrett Wollman 	} else {
3684e115012SGarrett Wollman 		do {
3694e115012SGarrett Wollman 			p++;
3704e115012SGarrett Wollman 		} while (isdigit(*p));
3714e115012SGarrett Wollman 	}
372682b6483SXin LI 	size = p - *str + 1;
373682b6483SXin LI 	tmp = xmalloc(size);
374682b6483SXin LI 	(void) strlcpy(tmp, *str, size);
375e390e3afSDavid Malone 	*val = tmp;
3764e115012SGarrett Wollman 	*str = p;
3774e115012SGarrett Wollman }
3784e115012SGarrett Wollman 
3794e115012SGarrett Wollman static token symbols[] = {
3804e115012SGarrett Wollman 			  {TOK_CONST, "const"},
3814e115012SGarrett Wollman 			  {TOK_UNION, "union"},
3824e115012SGarrett Wollman 			  {TOK_SWITCH, "switch"},
3834e115012SGarrett Wollman 			  {TOK_CASE, "case"},
3844e115012SGarrett Wollman 			  {TOK_DEFAULT, "default"},
3854e115012SGarrett Wollman 			  {TOK_STRUCT, "struct"},
3864e115012SGarrett Wollman 			  {TOK_TYPEDEF, "typedef"},
3874e115012SGarrett Wollman 			  {TOK_ENUM, "enum"},
3884e115012SGarrett Wollman 			  {TOK_OPAQUE, "opaque"},
3894e115012SGarrett Wollman 			  {TOK_BOOL, "bool"},
3904e115012SGarrett Wollman 			  {TOK_VOID, "void"},
3914e115012SGarrett Wollman 			  {TOK_CHAR, "char"},
3924e115012SGarrett Wollman 			  {TOK_INT, "int"},
3934e115012SGarrett Wollman 			  {TOK_UNSIGNED, "unsigned"},
3944e115012SGarrett Wollman 			  {TOK_SHORT, "short"},
3954e115012SGarrett Wollman 			  {TOK_LONG, "long"},
396ff49530fSBill Paul 			  {TOK_HYPER, "hyper"},
3974e115012SGarrett Wollman 			  {TOK_FLOAT, "float"},
3984e115012SGarrett Wollman 			  {TOK_DOUBLE, "double"},
399ff49530fSBill Paul 			  {TOK_QUAD, "quadruple"},
4004e115012SGarrett Wollman 			  {TOK_STRING, "string"},
4014e115012SGarrett Wollman 			  {TOK_PROGRAM, "program"},
4024e115012SGarrett Wollman 			  {TOK_VERSION, "version"},
4034e115012SGarrett Wollman 			  {TOK_EOF, "??????"},
4044e115012SGarrett Wollman };
4054e115012SGarrett Wollman 
406526195adSJordan K. Hubbard static void
findkind(char ** mark,token * tokp)407e390e3afSDavid Malone findkind(char **mark, token *tokp)
4084e115012SGarrett Wollman {
4094e115012SGarrett Wollman 	int len;
4104e115012SGarrett Wollman 	token *s;
411e390e3afSDavid Malone 	char *str, *tmp;
4124e115012SGarrett Wollman 
4134e115012SGarrett Wollman 	str = *mark;
4144e115012SGarrett Wollman 	for (s = symbols; s->kind != TOK_EOF; s++) {
4154e115012SGarrett Wollman 		len = strlen(s->str);
4164e115012SGarrett Wollman 		if (strncmp(str, s->str, len) == 0) {
4174e115012SGarrett Wollman 			if (!isalnum(str[len]) && str[len] != '_') {
4184e115012SGarrett Wollman 				tokp->kind = s->kind;
4194e115012SGarrett Wollman 				tokp->str = s->str;
4204e115012SGarrett Wollman 				*mark = str + len;
4214e115012SGarrett Wollman 				return;
4224e115012SGarrett Wollman 			}
4234e115012SGarrett Wollman 		}
4244e115012SGarrett Wollman 	}
4254e115012SGarrett Wollman 	tokp->kind = TOK_IDENT;
4264e115012SGarrett Wollman 	for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
427e390e3afSDavid Malone 	tmp = xmalloc(len + 1);
428682b6483SXin LI 	(void) strlcpy(tmp, str, len + 1);
429e390e3afSDavid Malone 	tokp->str = tmp;
4304e115012SGarrett Wollman 	*mark = str + len;
4314e115012SGarrett Wollman }
4324e115012SGarrett Wollman 
433526195adSJordan K. Hubbard static int
cppline(char * line)434e390e3afSDavid Malone cppline(char *line)
4354e115012SGarrett Wollman {
4364e115012SGarrett Wollman 	return (line == curline && *line == '#');
4374e115012SGarrett Wollman }
4384e115012SGarrett Wollman 
439526195adSJordan K. Hubbard static int
directive(char * line)440e390e3afSDavid Malone directive(char *line)
4414e115012SGarrett Wollman {
4424e115012SGarrett Wollman 	return (line == curline && *line == '%');
4434e115012SGarrett Wollman }
4444e115012SGarrett Wollman 
445526195adSJordan K. Hubbard static void
printdirective(char * line)446e390e3afSDavid Malone printdirective(char *line)
4474e115012SGarrett Wollman {
4484e115012SGarrett Wollman 	f_print(fout, "%s", line + 1);
4494e115012SGarrett Wollman }
4504e115012SGarrett Wollman 
451526195adSJordan K. Hubbard static void
docppline(char * line,int * lineno,const char ** fname)452e390e3afSDavid Malone docppline(char *line, int *lineno, const char **fname)
4534e115012SGarrett Wollman {
4544e115012SGarrett Wollman 	char *file;
4554e115012SGarrett Wollman 	int num;
4564e115012SGarrett Wollman 	char *p;
4574e115012SGarrett Wollman 
4584e115012SGarrett Wollman 	line++;
4594e115012SGarrett Wollman 	while (isspace(*line)) {
4604e115012SGarrett Wollman 		line++;
4614e115012SGarrett Wollman 	}
4624e115012SGarrett Wollman 	num = atoi(line);
4634e115012SGarrett Wollman 	while (isdigit(*line)) {
4644e115012SGarrett Wollman 		line++;
4654e115012SGarrett Wollman 	}
4664e115012SGarrett Wollman 	while (isspace(*line)) {
4674e115012SGarrett Wollman 		line++;
4684e115012SGarrett Wollman 	}
4694e115012SGarrett Wollman 	if (*line != '"') {
4704e115012SGarrett Wollman 		error("preprocessor error");
4714e115012SGarrett Wollman 	}
4724e115012SGarrett Wollman 	line++;
47375863a6dSPhilippe Charnier 	p = file = xmalloc(strlen(line) + 1);
4744e115012SGarrett Wollman 	while (*line && *line != '"') {
4754e115012SGarrett Wollman 		*p++ = *line++;
4764e115012SGarrett Wollman 	}
4774e115012SGarrett Wollman 	if (*line == 0) {
4784e115012SGarrett Wollman 		error("preprocessor error");
4794e115012SGarrett Wollman 	}
4804e115012SGarrett Wollman 	*p = 0;
4814e115012SGarrett Wollman 	if (*file == 0) {
4824e115012SGarrett Wollman 		*fname = NULL;
483*e893031dSWarner Losh 		free(file);
4844e115012SGarrett Wollman 	} else {
4854e115012SGarrett Wollman 		*fname = file;
4864e115012SGarrett Wollman 	}
4874e115012SGarrett Wollman 	*lineno = num - 1;
4884e115012SGarrett Wollman }
489