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.new / rpc_scan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-12  |  8.6 KB  |  495 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. #define startcomment(where) (where[0] == '/' && where[1] == '*')
  47. #define endcomment(where) (where[-1] == '*' && where[0] == '/')
  48.  
  49. static int pushed = 0;    /* is a token pushed */
  50. static token lasttok;    /* last token, if pushed */
  51.  
  52. /*
  53.  * scan expecting 1 given token 
  54.  */
  55. void
  56. scan(expect, tokp)
  57.     tok_kind expect;
  58.     token *tokp;
  59. {
  60.     get_token(tokp);
  61.     if (tokp->kind != expect) {
  62.         expected1(expect);
  63.     }
  64. }
  65.  
  66. /*
  67.  * scan expecting any of the 2 given tokens 
  68.  */
  69. void
  70. scan2(expect1, expect2, tokp)
  71.     tok_kind expect1;
  72.     tok_kind expect2;
  73.     token *tokp;
  74. {
  75.     get_token(tokp);
  76.     if (tokp->kind != expect1 && tokp->kind != expect2) {
  77.         expected2(expect1, expect2);
  78.     }
  79. }
  80.  
  81. /*
  82.  * scan expecting any of the 3 given token 
  83.  */
  84. void
  85. scan3(expect1, expect2, expect3, tokp)
  86.     tok_kind expect1;
  87.     tok_kind expect2;
  88.     tok_kind expect3;
  89.     token *tokp;
  90. {
  91.     get_token(tokp);
  92.     if (tokp->kind != expect1 && tokp->kind != expect2
  93.         && tokp->kind != expect3) {
  94.         expected3(expect1, expect2, expect3);
  95.     }
  96. }
  97.  
  98. /*
  99.  * scan expecting a constant, possibly symbolic 
  100.  */
  101. void
  102. scan_num(tokp)
  103.     token *tokp;
  104. {
  105.     get_token(tokp);
  106.     switch (tokp->kind) {
  107.     case TOK_IDENT:
  108.         break;
  109.     default:
  110.         error("constant or identifier expected");
  111.     }
  112. }
  113.  
  114. /*
  115.  * Peek at the next token 
  116.  */
  117. void
  118. peek(tokp)
  119.     token *tokp;
  120. {
  121.     get_token(tokp);
  122.     unget_token(tokp);
  123. }
  124.  
  125. /*
  126.  * Peek at the next token and scan it if it matches what you expect 
  127.  */
  128. int
  129. peekscan(expect, tokp)
  130.     tok_kind expect;
  131.     token *tokp;
  132. {
  133.     peek(tokp);
  134.     if (tokp->kind == expect) {
  135.         get_token(tokp);
  136.         return (1);
  137.     }
  138.     return (0);
  139. }
  140.  
  141. /*
  142.  * Get the next token, printing out any directive that are encountered. 
  143.  */
  144. void
  145. get_token(tokp)
  146.     token *tokp;
  147. {
  148.     int commenting;
  149.  
  150.     if (pushed) {
  151.         pushed = 0;
  152.         *tokp = lasttok;
  153.         return;
  154.     }
  155.     commenting = 0;
  156.     for (;;) {
  157.         if (*where == 0) {
  158.             for (;;) {
  159.                 if (!fgets(curline, MAXLINESIZE, fin)) {
  160.                     tokp->kind = TOK_EOF;
  161.                     *where = 0;
  162.                     return;
  163.                 }
  164.                 linenum++;
  165.                 if (commenting) {
  166.                     break;
  167.                 } else if (cppline(curline)) {
  168.                     docppline(curline, &linenum, 
  169.                           &infilename);
  170.                 } else if (directive(curline)) {
  171.                     printdirective(curline);
  172.                 } else {
  173.                     break;
  174.                 }
  175.             }
  176.             where = curline;
  177.         } else if (isspace(*where)) {
  178.             while (isspace(*where)) {
  179.                 where++;    /* eat */
  180.             }
  181.         } else if (commenting) {
  182.             for (where++; *where; where++) {
  183.                 if (endcomment(where)) {
  184.                     where++;
  185.                     commenting--;
  186.                     break;
  187.                 }
  188.             }
  189.         } else if (startcomment(where)) {
  190.             where += 2;
  191.             commenting++;
  192.         } else {
  193.             break;
  194.         }
  195.     }
  196.  
  197.     /*
  198.      * 'where' is not whitespace, comment or directive Must be a token! 
  199.      */
  200.     switch (*where) {
  201.     case ':':
  202.         tokp->kind = TOK_COLON;
  203.         where++;
  204.         break;
  205.     case ';':
  206.         tokp->kind = TOK_SEMICOLON;
  207.         where++;
  208.         break;
  209.     case ',':
  210.         tokp->kind = TOK_COMMA;
  211.         where++;
  212.         break;
  213.     case '=':
  214.         tokp->kind = TOK_EQUAL;
  215.         where++;
  216.         break;
  217.     case '*':
  218.         tokp->kind = TOK_STAR;
  219.         where++;
  220.         break;
  221.     case '[':
  222.         tokp->kind = TOK_LBRACKET;
  223.         where++;
  224.         break;
  225.     case ']':
  226.         tokp->kind = TOK_RBRACKET;
  227.         where++;
  228.         break;
  229.     case '{':
  230.         tokp->kind = TOK_LBRACE;
  231.         where++;
  232.         break;
  233.     case '}':
  234.         tokp->kind = TOK_RBRACE;
  235.         where++;
  236.         break;
  237.     case '(':
  238.         tokp->kind = TOK_LPAREN;
  239.         where++;
  240.         break;
  241.     case ')':
  242.         tokp->kind = TOK_RPAREN;
  243.         where++;
  244.         break;
  245.     case '<':
  246.         tokp->kind = TOK_LANGLE;
  247.         where++;
  248.         break;
  249.     case '>':
  250.         tokp->kind = TOK_RANGLE;
  251.         where++;
  252.         break;
  253.  
  254.     case '"':
  255.         tokp->kind = TOK_STRCONST;
  256.         findstrconst(&where, &tokp->str);
  257.         break;
  258.     case '\'':
  259.         tokp->kind = TOK_CHARCONST;
  260.         findchrconst(&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.     default:
  279.         if (!(isalpha(*where) || *where == '_')) {
  280.             char buf[100];
  281.             char *p;
  282.  
  283.             s_print(buf, "illegal character in file: ");
  284.             p = buf + strlen(buf);
  285.             if (isprint(*where)) {
  286.                 s_print(p, "%c", *where);
  287.             } else {
  288.                 s_print(p, "%d", *where);
  289.             }
  290.             error(buf);
  291.         }
  292.         findkind(&where, tokp);
  293.         break;
  294.     }
  295. }
  296.  
  297. static
  298. unget_token(tokp)
  299.     token *tokp;
  300. {
  301.     lasttok = *tokp;
  302.     pushed = 1;
  303. }
  304.  
  305. static
  306. findstrconst(str, val)
  307.     char **str;
  308.     char **val;
  309. {
  310.     char *p;
  311.     int size;
  312.  
  313.     p = *str;
  314.     do {
  315.         *p++;
  316.     } while (*p && *p != '"');
  317.     if (*p == 0) {
  318.         error("unterminated string constant");
  319.     }
  320.     p++;
  321.     size = p - *str;
  322.     *val = alloc(size + 1);
  323.     (void) strncpy(*val, *str, size);
  324.     (*val)[size] = 0;
  325.     *str = p;
  326. }
  327.  
  328. static
  329. findchrconst(str, val)
  330.     char **str;
  331.     char **val;
  332. {
  333.     char *p;
  334.     int size;
  335.  
  336.     p = *str;
  337.     do {
  338.         *p++;
  339.     } while (*p && *p != '\'');
  340.     if (*p == 0) {
  341.         error("unterminated string constant");
  342.     }
  343.     p++;
  344.     size = p - *str;
  345.     if (size != 3) {
  346.         error("empty char string");
  347.     }
  348.     *val = alloc(size + 1);
  349.     (void) strncpy(*val, *str, size);
  350.     (*val)[size] = 0;
  351.     *str = p;
  352. }
  353.  
  354. static
  355. findconst(str, val)
  356.     char **str;
  357.     char **val;
  358. {
  359.     char *p;
  360.     int size;
  361.  
  362.     p = *str;
  363.     if (*p == '0' && *(p + 1) == 'x') {
  364.         p++;
  365.         do {
  366.             p++;
  367.         } while (isxdigit(*p));
  368.     } else {
  369.         do {
  370.             p++;
  371.         } while (isdigit(*p));
  372.     }
  373.     size = p - *str;
  374.     *val = alloc(size + 1);
  375.     (void) strncpy(*val, *str, size);
  376.     (*val)[size] = 0;
  377.     *str = p;
  378. }
  379.  
  380. static token symbols[] = {
  381.               {TOK_CONST, "const"},
  382.               {TOK_UNION, "union"},
  383.               {TOK_SWITCH, "switch"},
  384.               {TOK_CASE, "case"},
  385.               {TOK_DEFAULT, "default"},
  386.               {TOK_STRUCT, "struct"},
  387.               {TOK_TYPEDEF, "typedef"},
  388.               {TOK_ENUM, "enum"},
  389.               {TOK_OPAQUE, "opaque"},
  390.               {TOK_BOOL, "bool"},
  391.               {TOK_VOID, "void"},
  392.               {TOK_CHAR, "char"},
  393.               {TOK_INT, "int"},
  394.               {TOK_UNSIGNED, "unsigned"},
  395.               {TOK_SHORT, "short"},
  396.               {TOK_LONG, "long"},
  397.               {TOK_FLOAT, "float"},
  398.               {TOK_DOUBLE, "double"},
  399.               {TOK_STRING, "string"},
  400.               {TOK_PROGRAM, "program"},
  401.               {TOK_VERSION, "version"},
  402.               {TOK_EOF, "??????"},
  403. };
  404.  
  405. static
  406. findkind(mark, tokp)
  407.     char **mark;
  408.     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
  435. cppline(line)
  436.     char *line;
  437. {
  438.     return (line == curline && *line == '#');
  439. }
  440.  
  441. static
  442. directive(line)
  443.     char *line;
  444. {
  445.     return (line == curline && *line == '%');
  446. }
  447.  
  448. static
  449. printdirective(line)
  450.     char *line;
  451. {
  452.     f_print(fout, "%s", line + 1);
  453. }
  454.  
  455. static
  456. docppline(line, lineno, fname)
  457.     char *line;
  458.     int *lineno;
  459.     char **fname;
  460. {
  461.     char *file;
  462.     int num;
  463.     char *p;
  464.  
  465.     line++;
  466.     while (isspace(*line)) {
  467.         line++;
  468.     }
  469.     num = atoi(line);
  470.     while (isdigit(*line)) {
  471.         line++;
  472.     }
  473.     while (isspace(*line)) {
  474.         line++;
  475.     }
  476.     if (*line != '"') {
  477.         error("preprocessor error");
  478.     }
  479.     line++;
  480.     p = file = alloc(strlen(line) + 1);
  481.     while (*line && *line != '"') {
  482.         *p++ = *line++;
  483.     }
  484.     if (*line == 0) {
  485.         error("preprocessor error");
  486.     }
  487.     *p = 0;
  488.     if (*file == 0) {
  489.         *fname = NULL;
  490.     } else {
  491.         *fname = file;
  492.     }
  493.     *lineno = num - 1;
  494. }
  495.