home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / os2 / less / charset.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-27  |  3.7 KB  |  211 lines

  1. /*
  2.  * Functions to define the character set
  3.  * and do things specific to the character set.
  4.  */
  5.  
  6. #include "less.h"
  7.  
  8. /*
  9.  * Predefined character sets,
  10.  * selected by the LESSCHARSET environment variable.
  11.  */
  12. struct charset {
  13.     char *name;
  14.     char *desc;
  15. } charsets[] = {
  16.     { "ascii",    "8bcccbcc18b95.b"    },
  17.     { "latin1",    "8bcccbcc18b95.33b."    },
  18.     { "pc8",    "8bcccbcc18b95.b128."    },
  19.     { NULL }
  20. };
  21.  
  22. #define    IS_BINARY_CHAR    01
  23. #define    IS_CONTROL_CHAR    02
  24.  
  25. static char chardef[256];
  26. static char *binfmt = "\\%o";
  27. public int binattr = BLINK;
  28.  
  29. extern char *getenv();
  30.  
  31. /*
  32.  * Define a charset, given a description string.
  33.  * The string consists of 256 letters,
  34.  * one for each character in the charset.
  35.  * If the string is shorter than 256 letters, missing letters
  36.  * are taken to be identical to the last one.
  37.  * A decimal number followed by a letter is taken to be a
  38.  * repetition of the letter.
  39.  *
  40.  * Each letter is one of:
  41.  *    . normal character
  42.  *    b binary character
  43.  *    c control character
  44.  */
  45.     static void
  46. ichardef(s)
  47.     char *s;
  48. {
  49.     register char *cp;
  50.     register int n;
  51.     register char v;
  52.  
  53.     n = 0;
  54.     cp = chardef;
  55.     while (*s != '\0')
  56.     {
  57.         switch (*s++)
  58.         {
  59.         case '.':
  60.             v = 0;
  61.             break;
  62.         case 'c':
  63.             v = IS_CONTROL_CHAR;
  64.             break;
  65.         case 'b':
  66.             v = IS_BINARY_CHAR|IS_CONTROL_CHAR;
  67.             break;
  68.  
  69.         case '0': case '1': case '2': case '3': case '4':
  70.         case '5': case '6': case '7': case '8': case '9':
  71.             n = (10 * n) + (s[-1] - '0');
  72.             continue;
  73.  
  74.         default:
  75.             error("invalid chardef", NULL_PARG);
  76.             quit(1);
  77.             /*NOTREACHED*/
  78.         }
  79.  
  80.         do
  81.         {
  82.             if (cp >= chardef + sizeof(chardef))
  83.             {
  84.                 error("chardef longer than 256", NULL_PARG);
  85.                 quit(1);
  86.                 /*NOTREACHED*/
  87.             }
  88.             *cp++ = v;
  89.         } while (--n > 0);
  90.         n = 0;
  91.     }
  92.  
  93.     while (cp < chardef + sizeof(chardef))
  94.         *cp++ = v;
  95. }
  96.  
  97. /*
  98.  * Define a charset, given a charset name.
  99.  * The valid charset names are listed in the "charsets" array.
  100.  */
  101.     static int
  102. icharset(name)
  103.     register char *name;
  104. {
  105.     register struct charset *p;
  106.  
  107.     if (name == NULL || *name == '\0')
  108.         return (0);
  109.  
  110.     for (p = charsets;  p->name != NULL;  p++)
  111.     {
  112.         if (strcmp(name, p->name) == 0)
  113.         {
  114.             ichardef(p->desc);
  115.             return (1);
  116.         }
  117.     }
  118.  
  119.     error("invalid charset name", NULL_PARG);
  120.     quit(1);
  121.     /*NOTREACHED*/
  122. }
  123.  
  124. /*
  125.  * Initialize charset data structures.
  126.  */
  127.     public void
  128. init_charset()
  129. {
  130.     register char *s;
  131.  
  132.     /*
  133.      * Try environment variable LESSCHARSET.
  134.      * If LESSCHARSET is not set, try LESSCHARDEF.
  135.      * If LESSCHARDEF is not set, default to "ascii" charset.
  136.      */
  137.     s = getenv("LESSCHARSET");
  138.     if (icharset(s))
  139.         return;
  140.  
  141.     s = getenv("LESSCHARDEF");
  142.     if (s != NULL && *s != '\0')
  143.     {
  144.         ichardef(s);
  145.         return;
  146.     }
  147.  
  148. #ifdef OS2
  149.     (void) icharset("pc8");
  150. #else
  151.     (void) icharset("ascii");
  152. #endif
  153.  
  154.     s = getenv("LESSBINFMT");
  155.     if (s != NULL && *s != '\0')
  156.     {
  157.         if (*s == '*')
  158.         {
  159.             switch (s[1])
  160.             {
  161.             case 'd':  binattr = BOLD;      break;
  162.             case 'k':  binattr = BLINK;     break;
  163.             case 'u':  binattr = UNDERLINE; break;
  164.             default:   binattr = NORMAL;    break;
  165.             }
  166.             s += 2;
  167.         }
  168.         if (*s != '\0')
  169.             binfmt = s;
  170.     }
  171. }
  172.  
  173. /*
  174.  * Is a given character a "binary" character?
  175.  */
  176.     public int
  177. binary_char(c)
  178.     int c;
  179. {
  180.     return (chardef[c] & IS_BINARY_CHAR);
  181. }
  182.  
  183. /*
  184.  * Is a given character a "control" character?
  185.  */
  186.     public int
  187. control_char(c)
  188.     int c;
  189. {
  190.     return (chardef[c] & IS_CONTROL_CHAR);
  191. }
  192.  
  193. /*
  194.  * Return the printable form of a character.
  195.  * For example, in the "ascii" charset '\3' is printed as "^C".
  196.  */
  197.     public char *
  198. prchar(c)
  199.     int c;
  200. {
  201.     static char buf[8];
  202.  
  203.     if (!control_char(c))
  204.         sprintf(buf, "%c", c);
  205.     else if (!control_char(c ^ 0100))
  206.         sprintf(buf, "^%c", c ^ 0100);
  207.     else
  208.         sprintf(buf, binfmt, c);
  209.     return (buf);
  210. }
  211.