123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- /*
- * From: @(#)rpc_scan.c 1.11 89/02/22
- *
- * Copyright (c) 2010, Oracle America, Inc.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- * * Neither the name of the "Oracle America, Inc." nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /*
- * rpc_scan.c, Scanner for the RPC protocol compiler
- * Copyright (C) 1987, Sun Microsystems, Inc.
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <libintl.h>
- #include "rpc_scan.h"
- #include "rpc_parse.h"
- #include "rpc_util.h"
- #include "proto.h"
- #define startcomment(where) (where[0] == '/' && where[1] == '*')
- #define endcomment(where) (where[-1] == '*' && where[0] == '/')
- static int pushed = 0; /* is a token pushed */
- static token lasttok; /* last token, if pushed */
- static void unget_token (token * tokp);
- static void findstrconst (const char **str, const char **val);
- static void findchrconst (const char **str, const char **val);
- static void findconst (const char **str, const char **val);
- static void findkind (const char **mark, token * tokp);
- static int cppline (const char *line);
- static int directive (const char *line);
- static void printdirective (const char *line);
- static void docppline (const char *line, int *lineno, const char **fname);
- /*
- * scan expecting 1 given token
- */
- void
- scan (tok_kind expect, token * tokp)
- {
- get_token (tokp);
- if (tokp->kind != expect)
- expected1 (expect);
- }
- /*
- * scan expecting any of the 2 given tokens
- */
- void
- scan2 (tok_kind expect1, tok_kind expect2, token * tokp)
- {
- get_token (tokp);
- if (tokp->kind != expect1 && tokp->kind != expect2)
- {
- expected2 (expect1, expect2);
- }
- }
- /*
- * scan expecting any of the 3 given token
- */
- void
- scan3 (tok_kind expect1, tok_kind expect2, tok_kind expect3, token * tokp)
- {
- get_token (tokp);
- if (tokp->kind != expect1 && tokp->kind != expect2
- && tokp->kind != expect3)
- {
- expected3 (expect1, expect2, expect3);
- }
- }
- /*
- * scan expecting a constant, possibly symbolic
- */
- void
- scan_num (token *tokp)
- {
- get_token (tokp);
- switch (tokp->kind)
- {
- case TOK_IDENT:
- break;
- default:
- error (_("constant or identifier expected"));
- }
- }
- /*
- * Peek at the next token
- */
- void
- peek (token *tokp)
- {
- get_token (tokp);
- unget_token (tokp);
- }
- /*
- * Peek at the next token and scan it if it matches what you expect
- */
- int
- peekscan (tok_kind expect, token *tokp)
- {
- peek (tokp);
- if (tokp->kind == expect)
- {
- get_token (tokp);
- return 1;
- }
- return 0;
- }
- /*
- * Get the next token, printing out any directive that are encountered.
- */
- void
- get_token (token *tokp)
- {
- int commenting;
- if (pushed)
- {
- pushed = 0;
- *tokp = lasttok;
- return;
- }
- commenting = 0;
- for (;;)
- {
- if (*where == 0)
- {
- for (;;)
- {
- if (!fgets (curline, MAXLINESIZE, fin))
- {
- tokp->kind = TOK_EOF;
- *curline = 0;
- where = curline;
- return;
- }
- linenum++;
- if (commenting)
- {
- break;
- }
- else if (cppline (curline))
- {
- docppline (curline, &linenum,
- &infilename);
- }
- else if (directive (curline))
- {
- printdirective (curline);
- }
- else
- {
- break;
- }
- }
- where = curline;
- }
- else if (isspace (*where))
- {
- while (isspace (*where))
- {
- where++; /* eat */
- }
- }
- else if (commenting)
- {
- for (where++; *where; where++)
- {
- if (endcomment (where))
- {
- where++;
- commenting--;
- break;
- }
- }
- }
- else if (startcomment (where))
- {
- where += 2;
- commenting++;
- }
- else
- {
- break;
- }
- }
- /*
- * 'where' is not whitespace, comment or directive Must be a token!
- */
- switch (*where)
- {
- case ':':
- tokp->kind = TOK_COLON;
- where++;
- break;
- case ';':
- tokp->kind = TOK_SEMICOLON;
- where++;
- break;
- case ',':
- tokp->kind = TOK_COMMA;
- where++;
- break;
- case '=':
- tokp->kind = TOK_EQUAL;
- where++;
- break;
- case '*':
- tokp->kind = TOK_STAR;
- where++;
- break;
- case '[':
- tokp->kind = TOK_LBRACKET;
- where++;
- break;
- case ']':
- tokp->kind = TOK_RBRACKET;
- where++;
- break;
- case '{':
- tokp->kind = TOK_LBRACE;
- where++;
- break;
- case '}':
- tokp->kind = TOK_RBRACE;
- where++;
- break;
- case '(':
- tokp->kind = TOK_LPAREN;
- where++;
- break;
- case ')':
- tokp->kind = TOK_RPAREN;
- where++;
- break;
- case '<':
- tokp->kind = TOK_LANGLE;
- where++;
- break;
- case '>':
- tokp->kind = TOK_RANGLE;
- where++;
- break;
- case '"':
- tokp->kind = TOK_STRCONST;
- findstrconst (&where, &tokp->str);
- break;
- case '\'':
- tokp->kind = TOK_CHARCONST;
- findchrconst (&where, &tokp->str);
- break;
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- tokp->kind = TOK_IDENT;
- findconst (&where, &tokp->str);
- break;
- default:
- if (!(isalpha (*where) || *where == '_'))
- {
- char buf[100];
- char *p;
- s_print (buf, _("illegal character in file: "));
- p = buf + strlen (buf);
- if (isprint (*where))
- {
- s_print (p, "%c", *where);
- }
- else
- {
- s_print (p, "%d", *where);
- }
- error (buf);
- }
- findkind (&where, tokp);
- break;
- }
- }
- static void
- unget_token (token * tokp)
- {
- lasttok = *tokp;
- pushed = 1;
- }
- static void
- findstrconst (const char **str, const char **val)
- {
- const char *p;
- char *tmp;
- int size;
- p = *str;
- do
- {
- p++;
- }
- while (*p && *p != '"');
- if (*p == 0)
- {
- error (_("unterminated string constant"));
- }
- p++;
- size = p - *str;
- tmp = alloc (size + 1);
- strncpy (tmp, *str, size);
- tmp[size] = 0;
- *val = tmp;
- *str = p;
- }
- static void
- findchrconst (const char **str, const char **val)
- {
- const char *p;
- char *tmp;
- int size;
- p = *str;
- do
- {
- p++;
- }
- while (*p && *p != '\'');
- if (*p == 0)
- {
- error (_("unterminated string constant"));
- }
- p++;
- size = p - *str;
- if (size != 3)
- {
- error (_("empty char string"));
- }
- tmp = alloc (size + 1);
- strncpy (tmp, *str, size);
- tmp[size] = 0;
- *val = tmp;
- *str = p;
- }
- static void
- findconst (const char **str, const char **val)
- {
- const char *p;
- char *tmp;
- int size;
- p = *str;
- if (*p == '0' && *(p + 1) == 'x')
- {
- p++;
- do
- {
- p++;
- }
- while (isxdigit (*p));
- }
- else
- {
- do
- {
- p++;
- }
- while (isdigit (*p));
- }
- size = p - *str;
- tmp = alloc (size + 1);
- strncpy (tmp, *str, size);
- tmp[size] = 0;
- *val = tmp;
- *str = p;
- }
- static const token symbols[] =
- {
- {TOK_CONST, "const"},
- {TOK_UNION, "union"},
- {TOK_SWITCH, "switch"},
- {TOK_CASE, "case"},
- {TOK_DEFAULT, "default"},
- {TOK_STRUCT, "struct"},
- {TOK_TYPEDEF, "typedef"},
- {TOK_ENUM, "enum"},
- {TOK_OPAQUE, "opaque"},
- {TOK_BOOL, "bool"},
- {TOK_VOID, "void"},
- {TOK_CHAR, "char"},
- {TOK_INT, "int"},
- {TOK_UNSIGNED, "unsigned"},
- {TOK_SHORT, "short"},
- {TOK_LONG, "long"},
- {TOK_HYPER, "hyper"},
- {TOK_FLOAT, "float"},
- {TOK_DOUBLE, "double"},
- {TOK_STRING, "string"},
- {TOK_PROGRAM, "program"},
- {TOK_VERSION, "version"},
- {TOK_EOF, "??????"},
- };
- static void
- findkind (const char **mark, token *tokp)
- {
- int len;
- const token *s;
- const char *str;
- char *tmp;
- str = *mark;
- for (s = symbols; s->kind != TOK_EOF; s++)
- {
- len = strlen (s->str);
- if (strncmp (str, s->str, len) == 0)
- {
- if (!isalnum (str[len]) && str[len] != '_')
- {
- tokp->kind = s->kind;
- tokp->str = s->str;
- *mark = str + len;
- return;
- }
- }
- }
- tokp->kind = TOK_IDENT;
- for (len = 0; isalnum (str[len]) || str[len] == '_'; len++);
- tmp = alloc (len + 1);
- strncpy (tmp, str, len);
- tmp[len] = 0;
- tokp->str = tmp;
- *mark = str + len;
- }
- static int
- cppline (const char *line)
- {
- return line == curline && *line == '#';
- }
- static int
- directive (const char *line)
- {
- return line == curline && *line == '%';
- }
- static void
- printdirective (const char *line)
- {
- f_print (fout, "%s", line + 1);
- }
- static void
- docppline (const char *line, int *lineno, const char **fname)
- {
- char *file;
- int num;
- char *p;
- line++;
- while (isspace (*line))
- {
- line++;
- }
- num = atoi (line);
- while (isdigit (*line))
- {
- line++;
- }
- while (isspace (*line))
- {
- line++;
- }
- if (*line != '"')
- {
- error (_("preprocessor error"));
- }
- line++;
- p = file = alloc (strlen (line) + 1);
- while (*line && *line != '"')
- {
- *p++ = *line++;
- }
- if (*line == 0)
- {
- error (_("preprocessor error"));
- }
- *p = 0;
- if (*file == 0)
- {
- free (file);
- *fname = NULL;
- }
- else
- {
- *fname = file;
- }
- *lineno = num - 1;
- }
|