home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / comm / tcp / amitcp / src / devtools / rpcgen / rpc_scan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-09  |  9.2 KB  |  489 lines

  1. /*
  2.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  3.  * unrestricted use provided that this legend is included on all tape
  4.  * media and as a part of the software program in whole or part.  Users
  5.  * may copy or modify Sun RPC without charge, but are not authorized
  6.  * to license or distribute it to anyone else except as part of a product or
  7.  * program developed by the user or with the express written consent of
  8.  * Sun Microsystems, Inc.
  9.  *
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  *
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  *
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  *
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  *
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30.  
  31. #ifndef lint
  32. static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
  33. #endif
  34.  
  35. /*
  36.  * rpc_scan.c, Scanner for the RPC protocol compiler 
  37.  * Copyright (C) 1987, Sun Microsystems, Inc. 
  38.  */
  39. #include <stdio.h>
  40. #include <ctype.h>
  41. #include <string.h>
  42. #include "rpc_scan.h"
  43. #include "rpc_parse.h"
  44. #include "rpc_util.h"
  45.  
  46. #ifdef __STDC__
  47. #include <string.h>
  48. #include "protos.h"
  49.  
  50. void scan ( tok_kind expect , token *tokp );
  51. void scan2 ( tok_kind expect1 , tok_kind expect2 , token *tokp );
  52. void scan3 ( tok_kind expect1 , tok_kind expect2 , tok_kind expect3 , token *tokp );
  53. void scan_num ( token *tokp );
  54. void peek ( token *tokp );
  55. int peekscan ( tok_kind expect , token *tokp );
  56. void get_token ( token *tokp );
  57. static void unget_token ( token *tokp );
  58. static void findstrconst ( char **str , char **val );
  59. static void findchrconst ( char **str , char **val );
  60. static void findconst ( char **str , char **val );
  61. static void findkind ( char **mark , token *tokp );
  62. static int cppline ( char *line );
  63. static int directive ( char *line );
  64. static void printdirective ( char *line );
  65. static void docppline ( char *line , int *lineno , char **fname );
  66. #endif
  67.  
  68. #define startcomment(where) (where[0] == '/' && where[1] == '*')
  69. #define endcomment(where) (where[-1] == '*' && where[0] == '/')
  70.  
  71. static int pushed = 0;    /* is a token pushed */
  72. static token lasttok;    /* last token, if pushed */
  73.  
  74. /*
  75.  * scan expecting 1 given token 
  76.  */
  77.  
  78. void
  79. scan(tok_kind expect, token *tokp)
  80. {
  81.     get_token(tokp);
  82.     if (tokp->kind != expect) {
  83.         expected1(expect);
  84.     }
  85. }
  86.  
  87. /*
  88.  * scan expecting any of the 2 given tokens 
  89.  */
  90. void
  91. scan2(tok_kind expect1, tok_kind expect2, token *tokp)
  92. {
  93.     get_token(tokp);
  94.     if (tokp->kind != expect1 && tokp->kind != expect2) {
  95.         expected2(expect1, expect2);
  96.     }
  97. }
  98.  
  99. /*
  100.  * scan expecting any of the 3 given token 
  101.  */
  102. void
  103. scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp)
  104. {
  105.     get_token(tokp);
  106.     if (tokp->kind != expect1 && tokp->kind != expect2
  107.         && tokp->kind != expect3) {
  108.         expected3(expect1, expect2, expect3);
  109.     }
  110. }
  111.  
  112. /*
  113.  * scan expecting a constant, possibly symbolic 
  114.  */
  115. void
  116. scan_num(token *tokp)
  117. {
  118.     get_token(tokp);
  119.     switch (tokp->kind) {
  120.     case TOK_IDENT:
  121.         break;
  122.     default:
  123.         error("constant or identifier expected");
  124.     }
  125. }
  126.  
  127. /*
  128.  * Peek at the next token 
  129.  */
  130. void
  131. peek(token *tokp)
  132. {
  133.     get_token(tokp);
  134.     unget_token(tokp);
  135. }
  136.  
  137. /*
  138.  * Peek at the next token and scan it if it matches what you expect 
  139.  */
  140. int
  141. peekscan(tok_kind expect, token *tokp)
  142. {
  143.     peek(tokp);
  144.     if (tokp->kind == expect) {
  145.         get_token(tokp);
  146.         return (1);
  147.     }
  148.     return (0);
  149. }
  150.  
  151. /*
  152.  * Get the next token, printing out any directive that are encountered. 
  153.  */
  154. void
  155. get_token(token *tokp)
  156. {
  157.     int commenting;
  158.  
  159.     if (pushed) {
  160.         pushed = 0;
  161.         *tokp = lasttok;
  162.         return;
  163.     }
  164.     commenting = 0;
  165.     for (;;) {
  166.         if (*where == 0) {
  167.             for (;;) {
  168.                 if (!fgets(curline, MAXLINESIZE, fin)) {
  169.                     tokp->kind = TOK_EOF;
  170.                     *where = 0;
  171.                     return;
  172.                 }
  173.                 linenum++;
  174.                 if (commenting) {
  175.                     break;
  176.                 } else if (cppline(curline)) {
  177.                     docppline(curline, &linenum, 
  178.                           &infilename);
  179.                 } else if (directive(curline)) {
  180.                     printdirective(curline);
  181.                 } else {
  182.                     break;
  183.                 }
  184.             }
  185.             where = curline;
  186.         } else if (isspace(*where)) {
  187.             while (isspace(*where)) {
  188.                 where++;    /* eat */
  189.             }
  190.         } else if (commenting) {
  191.             for (where++; *where; where++) {
  192.                 if (endcomment(where)) {
  193.                     where++;
  194.                     commenting--;
  195.                     break;
  196.                 }
  197.             }
  198.         } else if (startcomment(where)) {
  199.             where += 2;
  200.             commenting++;
  201.         } else {
  202.             break;
  203.         }
  204.     }
  205.  
  206.     /*
  207.      * 'where' is not whitespace, comment or directive Must be a token! 
  208.      */
  209.     switch (*where) {
  210.     case ':':
  211.         tokp->kind = TOK_COLON;
  212.         where++;
  213.         break;
  214.     case ';':
  215.         tokp->kind = TOK_SEMICOLON;
  216.         where++;
  217.         break;
  218.     case ',':
  219.         tokp->kind = TOK_COMMA;
  220.         where++;
  221.         break;
  222.     case '=':
  223.         tokp->kind = TOK_EQUAL;
  224.         where++;
  225.         break;
  226.     case '*':
  227.         tokp->kind = TOK_STAR;
  228.         where++;
  229.         break;
  230.     case '[':
  231.         tokp->kind = TOK_LBRACKET;
  232.         where++;
  233.         break;
  234.     case ']':
  235.         tokp->kind = TOK_RBRACKET;
  236.         where++;
  237.         break;
  238.     case '{':
  239.         tokp->kind = TOK_LBRACE;
  240.         where++;
  241.         break;
  242.     case '}':
  243.         tokp->kind = TOK_RBRACE;
  244.         where++;
  245.         break;
  246.     case '(':
  247.         tokp->kind = TOK_LPAREN;
  248.         where++;
  249.         break;
  250.     case ')':
  251.         tokp->kind = TOK_RPAREN;
  252.         where++;
  253.         break;
  254.     case '<':
  255.         tokp->kind = TOK_LANGLE;
  256.         where++;
  257.         break;
  258.     case '>':
  259.         tokp->kind = TOK_RANGLE;
  260.         where++;
  261.         break;
  262.  
  263.     case '"':
  264.         tokp->kind = TOK_STRCONST;
  265.         findstrconst(&where, &tokp->str);
  266.         break;
  267.     case '\'':
  268.         tokp->kind = TOK_CHARCONST;
  269.         findchrconst(&where, &tokp->str);
  270.         break;
  271.  
  272.     case '-':
  273.     case '0':
  274.     case '1':
  275.     case '2':
  276.     case '3':
  277.     case '4':
  278.     case '5':
  279.     case '6':
  280.     case '7':
  281.     case '8':
  282.     case '9':
  283.         tokp->kind = TOK_IDENT;
  284.         findconst(&where, &tokp->str);
  285.         break;
  286.  
  287.     default:
  288.         if (!(isalpha(*where) || *where == '_')) {
  289.             char buf[100];
  290.             char *p;
  291.  
  292.             s_print(buf, "illegal character in file: ");
  293.             p = buf + strlen(buf);
  294.             if (isprint(*where)) {
  295.                 s_print(p, "%c", *where);
  296.             } else {
  297.                 s_print(p, "%d", *where);
  298.             }
  299.             error(buf);
  300.         }
  301.         findkind(&where, tokp);
  302.         break;
  303.     }
  304. }
  305.  
  306. static void
  307. unget_token(token *tokp)
  308. {
  309.     lasttok = *tokp;
  310.     pushed = 1;
  311. }
  312.  
  313. static void
  314. findstrconst(char **str, char **val)
  315. {
  316.     char *p;
  317.     int size;
  318.  
  319.     p = *str;
  320.     do {
  321.         *p++;
  322.     } while (*p && *p != '"');
  323.     if (*p == 0) {
  324.         error("unterminated string constant");
  325.     }
  326.     p++;
  327.     size = p - *str;
  328.     *val = alloc(size + 1);
  329.     (void) strncpy(*val, *str, size);
  330.     (*val)[size] = 0;
  331.     *str = p;
  332. }
  333.  
  334. static void
  335. findchrconst(char **str, char **val)
  336. {
  337.     char *p;
  338.     int size;
  339.  
  340.     p = *str;
  341.     do {
  342.         *p++;
  343.     } while (*p && *p != '\'');
  344.     if (*p == 0) {
  345.         error("unterminated string constant");
  346.     }
  347.     p++;
  348.     size = p - *str;
  349.     if (size != 3) {
  350.         error("empty char string");
  351.     }
  352.     *val = alloc(size + 1);
  353.     (void) strncpy(*val, *str, size);
  354.     (*val)[size] = 0;
  355.     *str = p;
  356. }
  357.  
  358. static void
  359. findconst(char **str, char **val)
  360. {
  361.     char *p;
  362.     int size;
  363.  
  364.     p = *str;
  365.     if (*p == '0' && *(p + 1) == 'x') {
  366.         p++;
  367.         do {
  368.             p++;
  369.         } while (isxdigit(*p));
  370.     } else {
  371.         do {
  372.             p++;
  373.         } while (isdigit(*p));
  374.     }
  375.     size = p - *str;
  376.     *val = alloc(size + 1);
  377.     (void) strncpy(*val, *str, size);
  378.     (*val)[size] = 0;
  379.     *str = p;
  380. }
  381.  
  382. static token symbols[] = {
  383.               {TOK_CONST, "const"},
  384.               {TOK_UNION, "union"},
  385.               {TOK_SWITCH, "switch"},
  386.               {TOK_CASE, "case"},
  387.               {TOK_DEFAULT, "default"},
  388.               {TOK_STRUCT, "struct"},
  389.               {TOK_TYPEDEF, "typedef"},
  390.               {TOK_ENUM, "enum"},
  391.               {TOK_OPAQUE, "opaque"},
  392.               {TOK_BOOL, "bool"},
  393.               {TOK_VOID, "void"},
  394.               {TOK_CHAR, "char"},
  395.               {TOK_INT, "int"},
  396.               {TOK_UNSIGNED, "unsigned"},
  397.               {TOK_SHORT, "short"},
  398.               {TOK_LONG, "long"},
  399.               {TOK_FLOAT, "float"},
  400.               {TOK_DOUBLE, "double"},
  401.               {TOK_STRING, "string"},
  402.               {TOK_PROGRAM, "program"},
  403.               {TOK_VERSION, "version"},
  404.               {TOK_EOF, "??????"},
  405. };
  406.  
  407. static void
  408. findkind(char **mark, token *tokp)
  409. {
  410.     int len;
  411.     token *s;
  412.     char *str;
  413.  
  414.     str = *mark;
  415.     for (s = symbols; s->kind != TOK_EOF; s++) {
  416.         len = strlen(s->str);
  417.         if (strncmp(str, s->str, len) == 0) {
  418.             if (!isalnum(str[len]) && str[len] != '_') {
  419.                 tokp->kind = s->kind;
  420.                 tokp->str = s->str;
  421.                 *mark = str + len;
  422.                 return;
  423.             }
  424.         }
  425.     }
  426.     tokp->kind = TOK_IDENT;
  427.     for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
  428.     tokp->str = alloc(len + 1);
  429.     (void) strncpy(tokp->str, str, len);
  430.     tokp->str[len] = 0;
  431.     *mark = str + len;
  432. }
  433.  
  434. static int
  435. cppline(char *line)
  436. {
  437.     return (line == curline && *line == '#');
  438. }
  439.  
  440. static int
  441. directive(char *line)
  442. {
  443.     return (line == curline && *line == '%');
  444. }
  445.  
  446. static void
  447. printdirective(char *line)
  448. {
  449.     f_print(fout, "%s", line + 1);
  450. }
  451.  
  452. static void
  453. docppline(char *line, int *lineno, char **fname)
  454. {
  455.     char *file;
  456.     int num;
  457.     char *p;
  458.  
  459.     line++;
  460.     while (isspace(*line)) {
  461.         line++;
  462.     }
  463.     num = atoi(line);
  464.     while (isdigit(*line)) {
  465.         line++;
  466.     }
  467.     while (isspace(*line)) {
  468.         line++;
  469.     }
  470.     if (*line != '"') {
  471.         error("preprocessor error");
  472.     }
  473.     line++;
  474.     p = file = alloc(strlen(line) + 1);
  475.     while (*line && *line != '"') {
  476.         *p++ = *line++;
  477.     }
  478.     if (*line == 0) {
  479.         error("preprocessor error");
  480.     }
  481.     *p = 0;
  482.     if (*file == 0) {
  483.         *fname = NULL;
  484.     } else {
  485.         *fname = file;
  486.     }
  487.     *lineno = num - 1;
  488. }
  489.