home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-B.05 / NETKIT-B / NetKit-B-0.05 / rpcgen / rpc_scan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-17  |  8.3 KB  |  477 lines

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