latin1.c - vx32 - Local 9vx git repository for patches.
(HTM) git clone git://r-36.net/vx32
(DIR) Log
(DIR) Files
(DIR) Refs
---
latin1.c (1952B)
---
1 #include "u.h"
2 #include "lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "keyboard.h"
7
8
9 /*
10 * The code makes two assumptions: strlen(ld) is 1 or 2; latintab[i].ld can be a
11 * prefix of latintab[j].ld only when j<i.
12 */
13 struct cvlist
14 {
15 char *ld; /* must be seen before using this conversion */
16 char *si; /* options for last input characters */
17 Rune so[64]; /* the corresponding Rune for each si entry */
18 } latintab[] = {
19 #include "latin1.h"
20 0, 0, 0
21 };
22
23 /*
24 * Given 5 characters k[0]..k[4], find the rune or return -1 for failure.
25 */
26 long
27 unicode(Rune *k)
28 {
29 long i, c;
30
31 k++; /* skip 'X' */
32 c = 0;
33 for(i=0; i<4; i++,k++){
34 c <<= 4;
35 if('0'<=*k && *k<='9')
36 c += *k-'0';
37 else if('a'<=*k && *k<='f')
38 c += 10 + *k-'a';
39 else if('A'<=*k && *k<='F')
40 c += 10 + *k-'A';
41 else
42 return -1;
43 }
44 return c;
45 }
46
47 /*
48 * Given n characters k[0]..k[n-1], find the corresponding rune or return -1 for
49 * failure, or something < -1 if n is too small. In the latter case, the result
50 * is minus the required n.
51 */
52 long
53 latin1(Rune *k, int n)
54 {
55 struct cvlist *l;
56 int c;
57 char* p;
58
59 if(k[0] == 'X'){
60 if(n>=5)
61 return unicode(k);
62 else
63 return -5;
64 }
65 for(l=latintab; l->ld!=0; l++)
66 if(k[0] == l->ld[0]){
67 if(n == 1)
68 return -2;
69 if(l->ld[1] == 0)
70 c = k[1];
71 else if(l->ld[1] != k[1])
72 continue;
73 else if(n == 2)
74 return -3;
75 else
76 c = k[2];
77 for(p=l->si; *p!=0; p++)
78 if(*p == c)
79 return l->so[p - l->si];
80 return -1;
81 }
82 return -1;
83 }
84
85 // Plan 9 VX
86 void
87 latin1putc(int c, void (*kputc)(int))
88 {
89 int i;
90 static int collecting, nk;
91 static Rune kc[5];
92
93 if(c == Kalt){
94 collecting = !collecting;
95 nk = 0;
96 return;
97 }
98
99 if(!collecting){
100 kputc(c);
101 return;
102 }
103
104 kc[nk++] = c;
105 c = latin1(kc, nk);
106 if(c < -1) /* need more keystrokes */
107 return;
108 if(c != -1) /* valid sequence */
109 kputc(c);
110 else
111 for(i=0; i<nk; i++)
112 kputc(kc[i]);
113 nk = 0;
114 collecting = 0;
115 }
116