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