home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v92.tgz / v92.tar / v92 / src / common / literals.c < prev    next >
C/C++ Source or Header  |  1996-03-22  |  5KB  |  195 lines

  1. #include "::h:gsupport.h"
  2. #include "::h:esctab.h"
  3.  
  4. #if (MVS || VM) && SASC
  5. #include <lctype.h>
  6. #else                                   /* SASC */
  7. #include <ctype.h>
  8. #endif                                  /* SASC */
  9.  
  10. /*
  11.  * Prototype.
  12.  */
  13. unsigned short    *bitvect    Params((char *image,int len));
  14.  
  15. /*
  16.  * Within translators, csets are internally implemented as a bit vector made
  17.  *  from an array of unsigned shorts. For portability, only the lower 16
  18.  *  bits of these shorts are used.
  19.  */
  20. #define BVectIndx(c) (((unsigned char)c >> 4) & 0xf)
  21. #define BitInShrt(c) (1 << ((unsigned char)c & 0xf))
  22.  
  23. /*
  24.  * Macros used by escape() to advance to the next character and to
  25.  *  test the kind of character.
  26.  */
  27. #define NextChar(c) ((*nchars_ptr)--, c = *(*str_ptr)++)
  28. #define isoctal(c) ((c)>='0'&&(c)<='7')    /* macro to test for octal digit */
  29.  
  30.  
  31.  
  32. /*
  33.  * escape - translate the character sequence following a '\' into the
  34.  *   single character it represents.
  35.  */
  36. static int escape(str_ptr, nchars_ptr)
  37. char **str_ptr;
  38. int *nchars_ptr;
  39.    {
  40.    register int c, nc, i;
  41.  
  42.    /*
  43.     * Note, it is impossible to have a character string ending with a '\',
  44.     *  something must be here.
  45.     */
  46.    NextChar(c);
  47.    if (isoctal(c)) {
  48.       /*
  49.        * translate an octal escape -- backslash followed by one, two, or three
  50.        *  octal digits.
  51.        */
  52.       c -= '0';
  53.       for (i = 2; *nchars_ptr > 0 && isoctal(**str_ptr) && i <= 3; ++i) {
  54.          NextChar(nc);
  55.          c = (c << 3) | (nc - '0');
  56.          }
  57.       return (c & 0377);
  58.       }
  59.    else if (c == 'x') {
  60.       /*
  61.        * translate a hexadecimal escape -- backslash-x followed by one or
  62.        *  two hexadecimal digits.
  63.        */
  64.       c = 0;
  65.       for (i = 1; *nchars_ptr > 0 && isxdigit(**str_ptr) && i <= 2; ++i) {
  66.          NextChar(nc);
  67.          if (nc >= 'a' && nc <= 'f')
  68.              nc -= 'a' - 10;
  69.          else if (nc >= 'A' && nc <= 'F')
  70.             nc -= 'A' - 10;
  71.          else if (isdigit(nc))
  72.              nc -= '0';
  73.          c = (c << 4) | nc;
  74.          }
  75.       return c;
  76.       }
  77.    else if (c == '^') {
  78.       /*
  79.        * translate a control escape -- backslash followed by caret and one
  80.        *  character.
  81.        */
  82.       if (*nchars_ptr <= 0)
  83.          return 0;           /* could only happen in a keyword */
  84.       NextChar(c);
  85.       return (c & 037);
  86.       }
  87.    else
  88.       return esctab[c];
  89.    }
  90.  
  91.  
  92. /*
  93.  * bitvect - convert cset literal into a bitvector
  94.  */
  95. unsigned short *bitvect(image, len)
  96. char *image;
  97. int len;
  98.    {
  99.    register int c;
  100.    register unsigned short *bv;
  101.    register int i;
  102.  
  103.    bv =
  104.     (unsigned short *)alloc((unsigned int)((BVectSize)*sizeof(unsigned short)));
  105.    for (i = 0; i < BVectSize; ++i)
  106.        bv[i] = 0;
  107.    while (len-- > 0) {
  108.       c = *image++;
  109.       if (c == '\\')
  110.          c = escape(&image, &len);
  111.       bv[BVectIndx(c)] |= BitInShrt(c);
  112.       }
  113.    return bv;
  114.    }
  115.  
  116. /*
  117.  * cset_init - use bitvector for a cset to write an initialization for
  118.  *    a cset block.
  119.  */
  120. novalue cset_init(f, bv)
  121. FILE *f;
  122. unsigned short *bv;
  123.    {
  124.    int size;
  125.    unsigned short n;
  126.    register int j;
  127.  
  128.    size = 0;
  129.    for (j = 0; j < BVectSize; ++j)
  130.       for (n = bv[j]; n != 0; n >>= 1)
  131.          size += n & 1;
  132.    fprintf(f, "{T_Cset, %d,\n", size);
  133.    fprintf(f, "   cset_display(0x%x", bv[0]);
  134.    for (j = 1; j < BVectSize; ++j)
  135.       fprintf(f, ",0x%x", bv[j]);
  136.    fprintf(f, ")\n    };\n");
  137.    }
  138.  
  139. /*
  140.  * prtstr - print an Icon string literal as a C string literal.
  141.  */
  142. int prt_i_str(f, s, len)
  143. FILE *f;
  144. char *s;
  145. int len;
  146.    {
  147.    int c;
  148.    int n_chars;
  149.  
  150.    n_chars = 0;
  151.    while (len-- > 0) {
  152.       ++n_chars;
  153.       c = *s++;
  154.       if (c == '\\')
  155.          c = escape(&s, &len);
  156.       switch (c) {
  157.          case '\n':
  158.             fprintf(f, "\\n");
  159.             break;
  160.          case '\t':
  161.             fprintf(f, "\\t");
  162.             break;
  163.          case '\v':
  164.             fprintf(f, "\\v");
  165.             break;
  166.          case '\b':
  167.             fprintf(f, "\\b");
  168.             break;
  169.          case '\r':
  170.             fprintf(f, "\\r");
  171.             break;
  172.          case '\f':
  173.             fprintf(f, "\\f");
  174.             break;
  175.          case '\\':
  176.             fprintf(f, "\\\\");
  177.             break;
  178.          case '\"':
  179.             fprintf(f, "\\\"");
  180.             break;
  181.          default:
  182.  
  183. #if (MVS || VM) && SASC
  184.             if (isascii(c) && !iscntrl(c))
  185. #else                                   /* SASC */
  186.             if (isprint(c))
  187. #endif                                  /* SASC */
  188.                fprintf(f, "%c", c);
  189.             else
  190.                fprintf(f, "\\%03o", (int)c);
  191.          }
  192.       }
  193.    return n_chars;
  194.    }
  195.