vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

latin1.c (1952B)


      1 #include "u.h"
      2 #include "lib.h"
      3 #include "mem.h"
      4 #include "dat.h"
      5 #include "fns.h"
      6 #include "keyboard.h"
      7 
      8 
      9 /*
     10  * The code makes two assumptions: strlen(ld) is 1 or 2; latintab[i].ld can be a
     11  * prefix of latintab[j].ld only when j<i.
     12  */
     13 struct cvlist
     14 {
     15 	char	*ld;		/* must be seen before using this conversion */
     16 	char	*si;		/* options for last input characters */
     17 	Rune so[64];		/* the corresponding Rune for each si entry */
     18 } latintab[] = {
     19 #include "latin1.h"
     20 	0,	0,		0
     21 };
     22 
     23 /*
     24  * Given 5 characters k[0]..k[4], find the rune or return -1 for failure.
     25  */
     26 long
     27 unicode(Rune *k)
     28 {
     29 	long i, c;
     30 
     31 	k++;	/* skip 'X' */
     32 	c = 0;
     33 	for(i=0; i<4; i++,k++){
     34 		c <<= 4;
     35 		if('0'<=*k && *k<='9')
     36 			c += *k-'0';
     37 		else if('a'<=*k && *k<='f')
     38 			c += 10 + *k-'a';
     39 		else if('A'<=*k && *k<='F')
     40 			c += 10 + *k-'A';
     41 		else
     42 			return -1;
     43 	}
     44 	return c;
     45 }
     46 
     47 /*
     48  * Given n characters k[0]..k[n-1], find the corresponding rune or return -1 for
     49  * failure, or something < -1 if n is too small.  In the latter case, the result
     50  * is minus the required n.
     51  */
     52 long
     53 latin1(Rune *k, int n)
     54 {
     55 	struct cvlist *l;
     56 	int c;
     57 	char* p;
     58 
     59 	if(k[0] == 'X'){
     60 		if(n>=5)
     61 			return unicode(k);
     62 		else
     63 			return -5;
     64 	}
     65 	for(l=latintab; l->ld!=0; l++)
     66 		if(k[0] == l->ld[0]){
     67 			if(n == 1)
     68 				return -2;
     69 			if(l->ld[1] == 0)
     70 				c = k[1];
     71 			else if(l->ld[1] != k[1])
     72 				continue;
     73 			else if(n == 2)
     74 				return -3;
     75 			else
     76 				c = k[2];
     77 			for(p=l->si; *p!=0; p++)
     78 				if(*p == c)
     79 					return l->so[p - l->si];
     80 			return -1;
     81 		}
     82 	return -1;
     83 }
     84 
     85 // Plan 9 VX
     86 void
     87 latin1putc(int c, void (*kputc)(int))
     88 {
     89 	int i;
     90 	static int collecting, nk;
     91 	static Rune kc[5];
     92 
     93 	 if(c == Kalt){
     94 		 collecting = !collecting;
     95 		 nk = 0;
     96 		 return;
     97 	 }
     98 
     99 	 if(!collecting){
    100 		 kputc(c);
    101 		 return;
    102 	 }
    103 
    104 	kc[nk++] = c;
    105 	c = latin1(kc, nk);
    106 	if(c < -1)  /* need more keystrokes */
    107 		return;
    108 	if(c != -1) /* valid sequence */
    109 		kputc(c);
    110 	else
    111 		for(i=0; i<nk; i++)
    112 		 	kputc(kc[i]);
    113 	nk = 0;
    114 	collecting = 0;
    115 }
    116