4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
29 * University Copyright- Copyright (c) 1982, 1986, 1988
30 * The Regents of the University of California
33 * University Acknowledgment- Portions of this document are derived from
34 * software developed by the University of California, Berkeley, and its
39 * rpc_scan.c, Scanner for the RPC protocol compiler
48 #include "rpc_parse.h"
51 #define startcomment(where) (where[0] == '/' && where[1] == '*')
52 #define endcomment(where) (where[-1] == '*' && where[0] == '/')
54 static int pushed
= 0; /* is a token pushed */
55 static token lasttok
; /* last token, if pushed */
57 static void unget_token(token
*);
58 static void findstrconst(char **, char **);
59 static void findchrconst(char **, char **);
60 static void findconst(char **, char **);
61 static void findkind(char **, token
*);
62 static int cppline(char *);
63 static int directive(char *);
64 static void printdirective(char *);
65 static void docppline(char *, int *, char **);
68 * scan expecting 1 given token
71 scan(tok_kind expect
, token
*tokp
)
74 if (tokp
->kind
!= expect
)
79 * scan expecting any of the 2 given tokens
82 scan2(tok_kind expect1
, tok_kind expect2
, token
*tokp
)
85 if (tokp
->kind
!= expect1
&& tokp
->kind
!= expect2
)
86 expected2(expect1
, expect2
);
90 * scan expecting any of the 3 given token
93 scan3(tok_kind expect1
, tok_kind expect2
, tok_kind expect3
, token
*tokp
)
96 if (tokp
->kind
!= expect1
&& tokp
->kind
!= expect2
&&
97 tokp
->kind
!= expect3
)
98 expected3(expect1
, expect2
, expect3
);
102 * scan expecting a constant, possibly symbolic
105 scan_num(token
*tokp
)
108 switch (tokp
->kind
) {
112 error("constant or identifier expected");
117 * Peek at the next token
127 * Peek at the next token and scan it if it matches what you expect
130 peekscan(tok_kind expect
, token
*tokp
)
133 if (tokp
->kind
== expect
) {
141 * Get the next token, printing out any directive that are encountered.
144 get_token(token
*tokp
)
158 if (!fgets(curline
, MAXLINESIZE
, fin
)) {
159 tokp
->kind
= TOK_EOF
;
161 * now check if cpp returned
164 (void) waitpid(childpid
, &stat
,
167 /* Set return value from rpcgen */
168 nonfatalerrors
= stat
>> 8;
176 } else if (cppline(curline
)) {
177 docppline(curline
, &linenum
,
179 } else if (directive(curline
)) {
180 printdirective(curline
);
186 } else if (isspace(*where
)) {
187 while (isspace(*where
)) {
190 } else if (commenting
) {
191 for (where
++; *where
; where
++) {
192 if (endcomment(where
)) {
198 } else if (startcomment(where
)) {
207 * 'where' is not whitespace, comment or directive Must be a token!
211 tokp
->kind
= TOK_COLON
;
215 tokp
->kind
= TOK_SEMICOLON
;
219 tokp
->kind
= TOK_COMMA
;
223 tokp
->kind
= TOK_EQUAL
;
227 tokp
->kind
= TOK_STAR
;
231 tokp
->kind
= TOK_LBRACKET
;
235 tokp
->kind
= TOK_RBRACKET
;
239 tokp
->kind
= TOK_LBRACE
;
243 tokp
->kind
= TOK_RBRACE
;
247 tokp
->kind
= TOK_LPAREN
;
251 tokp
->kind
= TOK_RPAREN
;
255 tokp
->kind
= TOK_LANGLE
;
259 tokp
->kind
= TOK_RANGLE
;
264 tokp
->kind
= TOK_STRCONST
;
265 findstrconst(&where
, &tokp
->str
);
268 tokp
->kind
= TOK_CHARCONST
;
269 findchrconst(&where
, &tokp
->str
);
283 tokp
->kind
= TOK_IDENT
;
284 findconst(&where
, &tokp
->str
);
288 if (!(isalpha(*where
) || *where
== '_')) {
293 (void) snprintf(buf
, sizeof (buf
),
294 "illegal character in file: ");
297 if (isprint(*where
)) {
298 (void) snprintf(p
, sizeof (buf
) - blen
,
301 (void) snprintf(p
, sizeof (buf
) - blen
,
306 findkind(&where
, tokp
);
312 unget_token(token
*tokp
)
319 findstrconst(char **str
, char **val
)
327 } while (*p
&& *p
!= '"');
329 error("unterminated string constant");
333 *val
= malloc(size
+ 1);
334 (void) strncpy(*val
, *str
, size
);
340 findchrconst(char **str
, char **val
)
348 } while (*p
&& *p
!= '\'');
350 error("unterminated string constant");
354 error("empty char string");
355 *val
= malloc(size
+ 1);
356 (void) strncpy(*val
, *str
, size
);
362 findconst(char **str
, char **val
)
368 if (*p
== '0' && *(p
+ 1) == 'x') {
372 } while (isxdigit(*p
));
376 } while (isdigit(*p
));
379 *val
= malloc(size
+ 1);
380 (void) strncpy(*val
, *str
, size
);
385 static token symbols
[] = {
386 {TOK_CONST
, "const"},
387 {TOK_UNION
, "union"},
388 {TOK_SWITCH
, "switch"},
390 {TOK_DEFAULT
, "default"},
391 {TOK_STRUCT
, "struct"},
392 {TOK_TYPEDEF
, "typedef"},
394 {TOK_OPAQUE
, "opaque"},
397 {TOK_ONEWAY
, "oneway"},
400 {TOK_UNSIGNED
, "unsigned"},
401 {TOK_SHORT
, "short"},
403 {TOK_HYPER
, "hyper"},
404 {TOK_FLOAT
, "float"},
405 {TOK_DOUBLE
, "double"},
406 {TOK_QUAD
, "quadruple"},
407 {TOK_STRING
, "string"},
408 {TOK_PROGRAM
, "program"},
409 {TOK_VERSION
, "version"},
414 findkind(char **mark
, token
*tokp
)
421 for (s
= symbols
; s
->kind
!= TOK_EOF
; s
++) {
422 len
= strlen(s
->str
);
423 if (strncmp(str
, s
->str
, len
) == 0) {
424 if (!isalnum(str
[len
]) && str
[len
] != '_') {
425 tokp
->kind
= s
->kind
;
432 tokp
->kind
= TOK_IDENT
;
433 for (len
= 0; isalnum(str
[len
]) || str
[len
] == '_'; len
++)
435 tokp
->str
= malloc(len
+ 1);
436 (void) strncpy(tokp
->str
, str
, len
);
444 return (line
== curline
&& *line
== '#');
448 directive(char *line
)
450 return (line
== curline
&& *line
== '%');
454 printdirective(char *line
)
456 f_print(fout
, "%s", line
+ 1);
460 docppline(char *line
, int *lineno
, char **fname
)
467 while (isspace(*line
))
470 while (isdigit(*line
))
472 while (isspace(*line
))
475 error("preprocessor error");
477 p
= file
= malloc(strlen(line
) + 1);
478 while (*line
&& *line
!= '"')
481 error("preprocessor error");