sync with sylpheed 0.6.1cvs2
[claws.git] / libkcc / filter.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5
6 #include "kcc.h"
7 #include "libkcc.h"
8
9 unsigned incode, outcode;
10 char shiftin[7] = "\033$B";
11 char shiftout[4] = "\033(J";
12
13 /**********************************************************************
14  *                                                                    *
15  *  Filter                                                            *
16  *                                                                    *
17  **********************************************************************/
18 enum mode gsmode;               /* guess:  M_ASCII M_KANJI M_SO */
19 enum mode inmode;               /* input:  M_ASCII M_KANJI M_GAIJI
20                                  * M_SO M_ESCI */
21 enum mode outmode;              /* output: M_ASCII M_KANJI M_GAIJI
22                                  * M_SO M_ESCI */
23
24 unsigned long insi;             /* JIS shift-in sequence flag */
25 unsigned long inso;             /* JIS shift-out sequence flag
26                                  * including "ESC(I" */
27 unsigned long innj;             /* JIS 1990 sequence flag */
28 unsigned long ingj;             /* JIS 1990 aux flag */
29
30 bool nogaiji = 0;
31 /*---------------------------------------------------------------------
32     NAME
33         filter - filtering routine
34  ---------------------------------------------------------------------*/
35 int KCC_filter(ddd, outcode_name, sss, incode_name, extend, zenkaku, gaiji)
36     char *sss, *ddd;
37     int extend, zenkaku;
38     char *incode_name, *outcode_name;
39     int gaiji;
40 {
41     register bool hold;
42     register unsigned code, c = ASCII;
43     register int len;
44     char str[LENLINE];
45     char *dummy, *dst;
46     unsigned incode, outcode;
47     unsigned size = HOLDBUFSIZ;
48     char s[3];
49     s[0]='\0'; s[1]='\0'; s[2]='\0';
50
51     nogaiji = gaiji;
52     if (extend<0) {extend=0;} ;     if (extend>1) {extend=1;}
53     if (zenkaku<0) {zenkaku=0;};    if (zenkaku>1) {zenkaku=1;}
54     if (nogaiji<0) {nogaiji=0;};    if (nogaiji>1) {nogaiji=1;}
55
56     /* allocate hold buf */
57     if (Kcc_buffalloc(size) == NULL)  return (-1);
58
59     incode =0; outcode = EUC;
60     if (!strcasecmp(incode_name,"AUTO")) { incode=0; }
61     if (!strcasecmp(incode_name,"SJIS")) { incode=SJIS; }
62     if (!strcasecmp(incode_name,"DEC"))  { incode=DEC; }
63     if (!strcasecmp(incode_name,"JIS"))  { incode=JIS; }
64     if (!strcasecmp(incode_name,"JIS8")) { incode=JIS8; }
65     if (!strcasecmp(incode_name,"JISI")) { incode=ESCI; }
66
67     if (!strcasecmp(outcode_name,"EUC"))  { outcode=EUC; }
68     if (!strcasecmp(outcode_name,"SJIS")) { outcode=SJIS; }
69     if (!strcasecmp(outcode_name,"DEC"))  { outcode=DEC; }
70     if (!strncasecmp(outcode_name,"JIS", 3))
71       { outcode=JIS;
72         if (outcode_name[3]!='\0' && outcode_name[3]!='8' && outcode_name[3]!='I' )
73           { s[0]=outcode_name[3] ; s[1]=outcode_name[4]; }
74       }
75     if (!strncasecmp(outcode_name,"JIS8",4))
76       { outcode=JIS8;
77         if (outcode_name[4]!='\0')
78           { s[0]=outcode_name[4] ; s[1]=outcode_name[5]; }
79       }
80     if (!strncasecmp(outcode_name,"JISI",4))
81       { outcode=ESCI;
82         if (outcode_name[4]!='\0')
83           { s[0]=outcode_name[4] ; s[1]=outcode_name[5]; }
84       }
85     if ((s[0] == 'B' || s[0] == '@' || s[0] == '+') &&
86         (s[1] == 'B' || s[1] == 'J' || s[1] == 'H'))
87       {
88         if (s[0] == '+')
89           sprintf(shiftin, "\033&@\033$B");
90         else
91           sprintf(shiftin, "\033$%c", s[0]);
92         sprintf(shiftout, "\033(%c", s[1]);
93       }
94
95     Kcc_setfunc(outcode);
96
97     dummy = sss;
98     dst = ddd;
99
100     code = incode ? incode : extend ? BIT8 : BIT8 & ~DEC;
101     gsmode = inmode = outmode = M_ASCII;
102     insi = inso = innj = ingj = 0;
103     hold = 0;
104     while ((len = Kcc_getstr(str, sizeof str, &dummy)) != 0) {
105         if ((!(code & NONASCII) && code & BIT8) ||
106                 (code & (EUC | DEC) && code & SJIS && !(code & ASSUME))) {
107             /*
108              * So far, no kanji has been seen, or ambiguous.
109              */
110             c = Kcc_guess(str, len, extend, zenkaku, &gsmode, &insi, &inso, &innj, &ingj);
111             code |= c & (JIS | NONASCII), code &= c | ~BIT8;
112             if (code & NONASCII && code & (EUC | DEC) && code & SJIS) {
113                 /*
114                  * If ambiguous, store the line in hold buffer.
115                  */
116                 if (Kcc_append(str, len)) {
117                     hold = 1;
118                     continue;
119                 }
120                 /*
121                  * When buffer is full, assume EUC/DEC.
122                  */
123                 code |= ASSUME;
124             }
125         }
126         if (hold) {
127             /*
128              * Flush hold buffer.
129              */
130             Kcc_flush(code,  &dst, outcode, &inmode, &insi, &inso, &innj, &ingj);
131             hold = 0;
132         }
133         c = Kcc_out(&dst,   str, len, code,   outcode, &inmode, &insi, &inso, &innj, &ingj);
134         code |= c & JIS, code &= c | ~BIT8;
135     }
136     if (hold)
137         /*
138          * Assume EUC.
139          */
140         Kcc_flush(code |= ASSUME,   &dst, outcode, &inmode, &insi, &inso, &innj, &ingj);
141
142     *dst = '\0';
143     Kcc_bufffree();
144     return (Kcc_showcode(c));
145 }