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