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