summaryrefslogtreecommitdiff
path: root/emu/port/latin1.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /emu/port/latin1.c
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'emu/port/latin1.c')
-rw-r--r--emu/port/latin1.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/emu/port/latin1.c b/emu/port/latin1.c
new file mode 100644
index 00000000..9e8abf43
--- /dev/null
+++ b/emu/port/latin1.c
@@ -0,0 +1,83 @@
+#include "dat.h"
+
+/*
+ * The code makes two assumptions: strlen(ld) is 1 or 2; latintab[i].ld can be a
+ * prefix of latintab[j].ld only when j<i.
+ */
+static
+struct cvlist
+{
+ char *ld; /* must be seen before using this conversion */
+ char *si; /* options for last input characters */
+ char *so; /* the corresponding Rune for each si entry */
+} latintab[] = {
+#include "latin1.h"
+ 0, 0, 0
+};
+
+/*
+ * Given 5 characters k[0]..k[4], find the rune or return -1 for failure.
+ */
+static long
+unicode(uchar *k)
+{
+ long i, c;
+
+ k++; /* skip 'X' */
+ c = 0;
+ for(i=0; i<4; i++,k++){
+ c <<= 4;
+ if('0'<=*k && *k<='9')
+ c += *k-'0';
+ else if('a'<=*k && *k<='f')
+ c += 10 + *k-'a';
+ else if('A'<=*k && *k<='F')
+ c += 10 + *k-'A';
+ else
+ return -1;
+ }
+ return c;
+}
+
+/*
+ * Given n characters k[0]..k[n-1], find the corresponding rune or return -1 for
+ * failure, or something < -1 if n is too small. In the latter case, the result
+ * is minus the required n.
+ */
+long
+latin1(uchar *k, int n)
+{
+ struct cvlist *l;
+ int c;
+ char* p;
+
+ if(k[0] == 'X')
+ if(n>=5)
+ return unicode(k);
+ else
+ return -5;
+ for(l=latintab; l->ld!=0; l++)
+ if(k[0] == l->ld[0]){
+ if(n == 1)
+ return -2;
+ if(l->ld[1] == 0)
+ c = k[1];
+ else if(l->ld[1] != k[1])
+ continue;
+ else if(n == 2)
+ return -3;
+ else
+ c = k[2];
+ for(p=l->si; *p!=0; p++)
+ if(*p == c) {
+ Rune r;
+ int i = p - l->si;
+ p = l->so;
+ for(; i >= 0; i--)
+ p += chartorune(&r, p);
+ return r;
+ }
+ return -1;
+ }
+ return -1;
+}