home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / src / common / literals.c < prev    next >
C/C++ Source or Header  |  2002-01-18  |  4KB  |  181 lines

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