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