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