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