]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/miscellany/less-177/charset.c
ap: Fix write past end of addrs[] array.
[nmh] / docs / historical / mh-6.8.5 / miscellany / less-177 / charset.c
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 { NULL }
19 };
20
21 #define IS_BINARY_CHAR 01
22 #define IS_CONTROL_CHAR 02
23
24 static char chardef[256];
25 static char *binfmt = "\\%o";
26 public int binattr = BLINK;
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 (void) icharset("ascii");
148
149 s = getenv("LESSBINFMT");
150 if (s != NULL && *s != '\0')
151 {
152 if (*s == '*')
153 {
154 switch (s[1])
155 {
156 case 'd': binattr = BOLD; break;
157 case 'k': binattr = BLINK; break;
158 case 'u': binattr = UNDERLINE; break;
159 default: binattr = NORMAL; break;
160 }
161 s += 2;
162 }
163 if (*s != '\0')
164 binfmt = s;
165 }
166 }
167
168 /*
169 * Is a given character a "binary" character?
170 */
171 public int
172 binary_char(c)
173 int c;
174 {
175 return (chardef[c] & IS_BINARY_CHAR);
176 }
177
178 /*
179 * Is a given character a "control" character?
180 */
181 public int
182 control_char(c)
183 int c;
184 {
185 return (chardef[c] & IS_CONTROL_CHAR);
186 }
187
188 /*
189 * Return the printable form of a character.
190 * For example, in the "ascii" charset '\3' is printed as "^C".
191 */
192 public char *
193 prchar(c)
194 int c;
195 {
196 static char buf[8];
197
198 if (!control_char(c))
199 sprintf(buf, "%c", c);
200 else if (!control_char(c ^ 0100))
201 sprintf(buf, "^%c", c ^ 0100);
202 else
203 sprintf(buf, binfmt, c);
204 return (buf);
205 }