plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }