Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
5 /*
6 * The code makes two assumptions: strlen(ld) is 1 or 2; latintab[i].ld can be a
7 * prefix of latintab[j].ld only when j<i.
8 */
9 static struct cvlist
10 {
11 char *ld; /* must be seen before using this conversion */
12 char *si; /* options for last input characters */
13 Rune so[60]; /* the corresponding Rune for each si entry */
14 } latintab[] = {
15 #include "latin1.h"
16 0, 0, { 0 }
17 };
19 /*
20 * Given 5 characters k[0]..k[n], find the rune or return -1 for failure.
21 */
22 static long
23 unicode(Rune *k, int n)
24 {
25 long i, c;
27 c = 0;
28 for(i=0; i<n; i++,k++){
29 c <<= 4;
30 if('0'<=*k && *k<='9')
31 c += *k-'0';
32 else if('a'<=*k && *k<='f')
33 c += 10 + *k-'a';
34 else if('A'<=*k && *k<='F')
35 c += 10 + *k-'A';
36 else
37 return -1;
38 if(c > Runemax)
39 return -1;
40 }
41 return c;
42 }
44 /*
45 * Given n characters k[0]..k[n-1], find the corresponding rune or return -1 for
46 * failure, or something < -1 if n is too small. In the latter case, the result
47 * is minus the required n.
48 */
49 int
50 latin1(Rune *k, int n)
51 {
52 struct cvlist *l;
53 int c;
54 char* p;
56 if(k[0] == 'X'){
57 if(n < 2)
58 return -2;
59 if(k[1] == 'X') {
60 if(n < 3)
61 return -3;
62 if(k[2] == 'X') {
63 if(n < 9) {
64 if(unicode(k+3, n-3) < 0)
65 return -1;
66 return -(n+1);
67 }
68 return unicode(k+3, 6);
69 }
70 if(n < 7) {
71 if(unicode(k+2, n-2) < 0)
72 return -1;
73 return -(n+1);
74 }
75 return unicode(k+2, 5);
76 }
77 if(n < 5) {
78 if(unicode(k+1, n-1) < 0)
79 return -1;
80 return -(n+1);
81 }
82 return unicode(k+1, 4);
83 }
85 for(l=latintab; l->ld!=0; l++)
86 if(k[0] == l->ld[0]){
87 if(n == 1)
88 return -2;
89 if(l->ld[1] == 0)
90 c = k[1];
91 else if(l->ld[1] != k[1])
92 continue;
93 else if(n == 2)
94 return -3;
95 else
96 c = k[2];
97 for(p=l->si; *p!=0; p++)
98 if(*p == c)
99 return l->so[p - l->si];
100 return -1;
102 return -1;