Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 343 lines (310 sloc) 9.151 kb
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
1 /* digraph.c */
2 /* Copyright 1995 by Steve Kirkendall */
3
4
5 #include "elvis.h"
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
6 #ifdef FEATURE_RCSID
2fe6e17 @mbert Import Elvis 2.2_1 (written by Steve Kirkendall)
authored
7 char id_digraph[] = "$Id: digraph.c,v 2.13 2004/03/21 23:24:41 steve Exp $";
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
8 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
9 #ifndef NO_DIGRAPH
10
11 static void adjustctype P_((_CHAR_ ch));
12
13 /* This structure is used to store digraphs. Note that "in1" is always less
14 * than or equal to "in2".
15 */
16 typedef struct dig_s
17 {
18 struct dig_s *next; /* another digraph */
19 CHAR in1, in2; /* the input characters of this digraph */
20 CHAR out; /* the character they form */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
21 ELVBOOL save; /* user-defined? */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
22 } DIGRAPH;
23
24
25 /* This is a list of all defined digraphs */
26 DIGRAPH *digs;
27
28
29 #ifdef NEED_CTYPE
30 CHAR elvct_upper[256] =
31 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
32 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
33 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
34 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
35 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
36 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
37 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
38 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
39 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
40 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
41 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
42 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
43 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
44 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
45 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
46 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
47 };
48 CHAR elvct_lower[256] =
49 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
50 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
51 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
52 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
53 64, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
54 112,113,114,115,116,117,118,119,120,121,122, 91, 92, 93, 94, 95,
55 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
56 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
57 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
58 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
59 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
60 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
61 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
62 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
63 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
64 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
65 };
66 #define U ELVCT_UPPER
67 #define L ELVCT_LOWER
68 #define XU ELVCT_UPPER|ELVCT_XDIGIT
69 #define XL ELVCT_LOWER|ELVCT_XDIGIT
70 #define XD ELVCT_DIGIT|ELVCT_XDIGIT
71 #define P ELVCT_PUNCT
72 #define S ELVCT_SPACE
73 #define C ELVCT_CNTRL
74 #define SC ELVCT_SPACE|ELVCT_CNTRL
75 CHAR elvct_class[256] =
76 {
77 C, C, C, C, C, C, C, C, C, SC, SC, C, SC, SC, C, C,
78 C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
79 S, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
80 XD, XD, XD, XD, XD, XD, XD, XD, XD, XD, P, P, P, P, P, P,
81 P, XU, XU, XU, XU, XU, XU, U, U, U, U, U, U, U, U, U,
82 U, U, U, U, U, U, U, U, U, U, U, P, P, P, P, P,
83 P, XL, XL, XL, XL, XL, XL, L, L, L, L, L, L, L, L, L,
84 L, L, L, L, L, L, L, L, L, L, L, P, P, P, P, C,
85 P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
86 P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
87 P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
88 P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
89 P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
90 P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
91 P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
92 P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P
93 };
94 #undef U
95 #undef L
96 #undef XU
97 #undef XL
98 #undef XD
99 #undef P
100 #undef S
101 #undef C
102 #undef SC
103
104 static void adjustctype(ch)
105 _CHAR_ ch; /* a digraph character that changed */
106 {
107 DIGRAPH *dp; /* the changed digraph, or NULL if deleted */
108 CHAR tmp;
109
110 /* if ASCII, leave it alone */
111 if (ch < 0x80)
112 return;
113
114 /* try to find a digraph that results in this character */
115 for (dp = digs; dp && dp->out != ch; dp = dp->next)
116 {
117 }
118
119 /* what kind of change? */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
120 if (dp && ((elvupper(dp->in1) && !elvlower(dp->in2)) || elvupper(dp->in2)))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
121 {
122 /* making it uppercase */
123 setupper(ch);
124 clrlower(ch);
125 clrpunct(ch);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
126 tmp = digraph(elvtolower(dp->in1), elvtolower(dp->in2));
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
127 if (tmp >= 0x80)
128 {
129 /* we can make an uppercase/lowercase pair */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
130 elvtoupper(tmp) = ch;
131 elvtolower(ch) = tmp;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
132 }
133 }
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
134 else if (dp && ((!elvupper(dp->in1) && elvlower(dp->in2)) || elvlower(dp->in1)))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
135 {
136 /* making it lowercase */
137 setlower(ch);
138 clrupper(ch);
139 clrpunct(ch);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
140 tmp = digraph(elvtoupper(dp->in1), elvtoupper(dp->in2));
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
141 if (tmp >= 0x80)
142 {
143 /* we can make an uppercase/lowercase pair */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
144 elvtolower(tmp) = ch;
145 elvtoupper(ch) = tmp;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
146 }
147 }
148 else
149 {
150 /* deleting it, or making it punctuation */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
151 if (elvupper(ch))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
152 {
153 clrupper(ch);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
154 tmp = elvtolower(ch);
155 elvtolower(ch) = ch;
156 elvtoupper(tmp) = tmp;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
157 clrupper(ch);
158 }
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
159 else if (elvtolower(ch))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
160 {
161 clrlower(ch);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
162 tmp = elvtoupper(ch);
163 elvtoupper(ch) = ch;
164 elvtolower(tmp) = tmp;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
165 clrlower(ch);
166 }
167 setpunct(ch);
168 }
169 }
170 #endif
171
172
173
174 /* This function looks up a digraph. If it finds the digraph, it returns
175 * the non-ASCII character; otherwise it returns the second parameter character.
176 */
177 CHAR digraph(in1, in2)
178 _CHAR_ in1; /* the underlying character */
179 _CHAR_ in2; /* the second character */
180 {
181 CHAR newkey;
182 DIGRAPH *dp;
183
184 /* remember the new key, so we can return it if this isn't a digraph */
185 newkey = in2;
186
187 /* sort in1 and in2, so that their original order won't matter */
188 if (in1 > in2)
189 {
190 in2 = in1;
191 in1 = newkey;
192 }
193
194 /* scan through the digraph chart */
195 for (dp = digs;
196 dp && (dp->in1 != in1 || dp->in2 != in2);
197 dp = dp->next)
198 {
199 }
200
201 /* if this combination isn't in there, just use the new key */
202 if (!dp)
203 {
204 return newkey;
205 }
206
207 /* else use the digraph key */
208 return dp->out;
209 }
210
211
212 /* This function lists, defines, or deletes digraphs. If passed a NULL
213 * pointer it will list the user-defined digraphs or all digraphs, depending
214 * on the value of "bang." If passed a 2-character string, it will delete
215 * a digraph. If passed a 3-character string, it will define a digraph.
216 */
217 void digaction(win, bang, extra)
218 WINDOW win; /* window to write to, if listing */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
219 ELVBOOL bang; /* list all, or define non-ASCII */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
220 CHAR *extra; /* NULL to list, "xx" to delete, "xxy" to add */
221 {
222 int dig;
223 DIGRAPH *dp;
224 DIGRAPH *prev;
225 CHAR listbuf[8];
226
227 /* if no args, then display the existing digraphs */
228 if (!extra)
229 {
230 listbuf[0] = listbuf[1] = listbuf[2] = listbuf[5] = ' ';
231 listbuf[7] = '\0';
232 for (dig = 0, dp = digs; dp; dp = dp->next)
233 {
234 if (dp->save || bang)
235 {
236 dig += 7;
237 if (dig >= o_columns(win))
238 {
239 drawextext(win, toCHAR("\n"), 1);
240 dig = 7;
241 }
242 listbuf[3] = dp->in1;
243 listbuf[4] = dp->in2;
244 listbuf[6] = dp->out;
245 drawextext(win, listbuf, 7);
246 }
247 }
248 drawextext(win, toCHAR("\n"), 1);
249 return;
250 }
251
252 /* make sure we have at least two characters */
253 if (!extra[1])
254 {
255 msg(MSG_ERROR, "digraphs must be composed of two characters");
256 return;
257 }
258
259 /* sort in1 and in2, so that their original order won't matter */
260 if (extra[0] > extra[1])
261 {
262 dig = extra[0];
263 extra[0] = extra[1];
264 extra[1] = dig;
265 }
266
267 /* locate the new digraph character */
268 for (dig = 2; extra[dig] == ' ' || extra[dig] == '\t'; dig++)
269 {
270 }
271 dig = extra[dig];
272 if (!bang && dig)
273 {
274 dig |= 0x80;
275 }
276
277 /* search for the digraph */
278 for (prev = (DIGRAPH *)0, dp = digs;
279 dp && (dp->in1 != extra[0] || dp->in2 != extra[1]);
280 prev = dp, dp = dp->next)
281 {
282 }
283
284 /* deleting the digraph? */
285 if (!dig)
286 {
287 if (!dp)
288 {
289 return;
290 }
291 if (prev)
292 prev->next = dp->next;
293 else
294 digs = dp->next;
295 #ifdef NEED_CTYPE
296 adjustctype(dp->out);
297 #endif
298 safefree(dp);
299 return;
300 }
301
302 /* if necessary, create a new digraph struct for the new digraph */
303 if (dig && !dp)
304 {
305 dp = (DIGRAPH *)safekept(1, sizeof *dp);
306 if (prev)
307 prev->next = dp;
308 else
309 digs = dp;
310 dp->next = (DIGRAPH *)0;
311 }
312
313 /* assign it the new digraph value */
314 dp->in1 = extra[0];
315 dp->in2 = extra[1];
316 dp->out = dig;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
317 dp->save = (ELVBOOL)(win != (WINDOW)0);
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
318 # ifdef NEED_CTYPE
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
319 adjustctype(dig);
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
320 # endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
321 }
322
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
323 # ifdef FEATURE_MKEXRC
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
324 void digsave(buf)
325 BUFFER buf; /* the buffer to append commands onto */
326 {
327 static CHAR text[] = "digraph! XX Y\n";
328 DIGRAPH *dp;
329
330 for (dp = digs; dp; dp = dp->next)
331 {
332 if (dp->save)
333 {
334 text[9] = dp->in1;
335 text[10] = dp->in2;
336 text[12] = dp->out;
2fe6e17 @mbert Import Elvis 2.2_1 (written by Steve Kirkendall)
authored
337 bufappend(buf, text, QTY(text) - 1);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
338 }
339 }
340 }
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
341 # endif /* FEATURE_MKEXRC */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
342 #endif
Something went wrong with that request. Please try again.