latin1.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) 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