latin1.c (1874B)
1 #include <u.h> 2 #include <libc.h> 3 #include <draw.h> 4 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 }; 18 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; 26 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 } 43 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; 55 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 } 84 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; 101 } 102 return -1; 103 }