]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/tcs/conv_gb.c
fix ref822 again: remove uniqarray(), fix case with many entries in 'n'.
[plan9front.git] / sys / src / cmd / tcs / conv_gb.c
1 #include        <u.h>
2 #include        <libc.h>
3 #include        <bio.h>
4 #include        "hdr.h"
5 #include        "conv.h"
6 #include        "gb.h"
7
8 /*
9         a state machine for interpreting gb.
10 */
11 void
12 gbproc(int c, Rune **r, long input_loc)
13 {
14         static enum { state0, state1 } state = state0;
15         static int lastc;
16         long n, ch, cold = c;
17
18         switch(state)
19         {
20         case state0:    /* idle state */
21                 if(c < 0)
22                         return;
23                 if(c >= 0xA1){
24                         lastc = c;
25                         state = state1;
26                         return;
27                 }
28                 emit(c);
29                 return;
30
31         case state1:    /* seen a font spec */
32                 if(c >= 0xA1)
33                         n = (lastc-0xA0)*100 + (c-0xA0);
34                 else {
35                         nerrors++;
36                         if(squawk)
37                                 warn("bad gb glyph %d (from 0x%x,0x%lx) near byte %ld in %s", c-0xA0, lastc, cold, input_loc, file);
38                         if(!clean)
39                                 emit(BADMAP);
40                         state = state0;
41                         return;
42                 }
43                 ch = tabgb[n];
44                 if(ch < 0){
45                         nerrors++;
46                         if(squawk)
47                                 warn("unknown gb %ld (from 0x%x,0x%lx) near byte %ld in %s", n, lastc, cold, input_loc, file);
48                         if(!clean)
49                                 emit(BADMAP);
50                 } else
51                         emit(ch);
52                 state = state0;
53         }
54 }
55
56 void
57 gb_in(int fd, long *, struct convert *out)
58 {
59         Rune ob[N];
60         Rune *r, *re;
61         uchar ibuf[N];
62         int n, i;
63         long nin;
64
65         r = ob;
66         re = ob+N-3;
67         nin = 0;
68         while((n = read(fd, ibuf, sizeof ibuf)) > 0){
69                 for(i = 0; i < n; i++){
70                         gbproc(ibuf[i], &r, nin++);
71                         if(r >= re){
72                                 OUT(out, ob, r-ob);
73                                 r = ob;
74                         }
75                 }
76                 if(r > ob){
77                         OUT(out, ob, r-ob);
78                         r = ob;
79                 }
80         }
81         gbproc(-1, &r, nin);
82         if(r > ob)
83                 OUT(out, ob, r-ob);
84         OUT(out, ob, 0);
85 }
86
87 void
88 gb_out(Rune *base, int n, long *)
89 {
90         char *p;
91         int i;
92         Rune r;
93         static int first = 1;
94
95         if(first){
96                 first = 0;
97                 for(i = 0; i < NRUNE; i++)
98                         tab[i] = -1;
99                 for(i = 0; i < GBMAX; i++)
100                         if(tabgb[i] != -1)
101                                 tab[tabgb[i]] = i;
102         }
103         nrunes += n;
104         p = obuf;
105         for(i = 0; i < n; i++){
106                 r = base[i];
107                 if(r < 128)
108                         *p++ = r;
109                 else {
110                         if(r < NRUNE && tab[r] != -1){
111                                 r = tab[r];
112                                 *p++ = 0xA0 + (r/100);
113                                 *p++ = 0xA0 + (r%100);
114                                 continue;
115                         }
116                         if(squawk)
117                                 warn("rune 0x%x not in output cs", r);
118                         nerrors++;
119                         if(clean)
120                                 continue;
121                         *p++ = BYTEBADMAP;
122                 }
123         }
124         noutput += p-obuf;
125         if(p > obuf)
126                 write(1, obuf, p-obuf);
127 }