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