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