This commit was manufactured by cvs2svn to create tag 'LAST_STABLE'.
[claws.git] / libkcc / out.c
blob86e3dcb78bc20f329a5eb7b2983de3417843f830
1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
6 #include "kcc.h"
7 #include "libkcc.h"
9 /**********************************************************************
10 * *
11 * Output Routines *
12 * *
13 **********************************************************************/
14 extern void (*outascii)(), (*outkanji)(), (*outgaiji)(), (*outkana)();
16 /*---------------------------------------------------------------------
17 NAME
18 outsjis
19 ---------------------------------------------------------------------*/
20 void Kcc_outsjis(ddd, c1, c2)
21 register int c1, c2;
22 char **ddd;
24 register int c;
26 c = c1 * 2 - (c1 <= 0x9f ? 0x00e1 : (c1 < 0xf0 ? 0x0161 : 0x01bf));
27 if (c2 < 0x9f)
28 c2 = c2 - (c2 > 0x7f ? 0x20 : 0x1f);
29 else {
30 c2 = c2 - 0x7e;
31 c++;
33 (*(c1 <= 0xef ? outkanji : outgaiji))(ddd, c, c2);
36 /*---------------------------------------------------------------------
37 NAME
38 out
39 ---------------------------------------------------------------------*/
40 unsigned Kcc_out(ddd, str, len, code, outcode, inmode, insi, inso, innj, ingj)
41 char *str, **ddd;
42 int len;
43 register unsigned code;
44 enum mode *inmode;
45 unsigned long *insi, *inso, *innj, *ingj;
46 unsigned outcode;
48 register char *s;
49 register int i;
51 for (s = str; s < str + len; s += i) {
52 i = 1;
53 switch (*(u_char *) s) {
54 case ESC:
55 if (*inmode == M_SO)
56 break;
57 if (Kcc_compare("$B", s + 1) || Kcc_compare("$@", s + 1)) {
58 *inmode = M_KANJI; /* kanji */
59 *insi |= bitflag(((u_char *) s)[2]);
60 i = 3;
61 } else if (Kcc_compare("&@\033$B", s + 1)) {
62 *inmode = M_KANJI; /* kanji 1990 */
63 *innj |= bitflag('B');
64 i = 6;
65 } else if (Kcc_compare("(B", s + 1) || Kcc_compare("(J", s + 1) ||
66 Kcc_compare("(H", s + 1)) {
67 *inmode = M_ASCII; /* kanji end */
68 *inso |= bitflag(((u_char *) s)[2]);
69 i = 3;
70 } else if (Kcc_compare("(I", s + 1)) {
71 *inmode = M_ESCI; /* "ESC(I" */
72 *inso |= bitflag('I');
73 i = 3;
74 } else if (Kcc_compare("$(D", s + 1)) {
75 *inmode = M_GAIJI; /* gaiji */
76 *ingj |= bitflag('D');
77 i = 4;
78 } else
79 break;
80 code |= JIS;
81 continue;
82 case SO:
83 if (*inmode == M_ASCII) {
84 code |= JIS;
85 *inmode = M_SO;
86 continue;
88 break;
89 case SI:
90 if (*inmode == M_SO) {
91 *inmode = M_ASCII;
92 continue;
94 break;
96 if (*inmode != M_ASCII) {
97 if (0x20 < ((u_char *) s)[0] && ((u_char *) s)[0] < 0x7f)
98 switch (*inmode) {
99 case M_KANJI:
100 (*outkanji)(ddd, ((u_char *) s)[0], ((u_char *) s)[1] & 0x7f);
101 i = 2;
102 continue;
103 case M_GAIJI:
104 (*outgaiji)(ddd, ((u_char *) s)[0], ((u_char *) s)[1] & 0x7f);
105 i = 2;
106 continue;
107 case M_SO:
108 case M_ESCI:
109 (*outkana)(ddd, ((u_char *) s)[0]);
110 continue;
111 default:
112 continue;
114 } else if (((u_char *) s)[0] & 0x80) {
115 if (code & (EUC | DEC)) {
117 * EUC or DEC:
119 if (0xa0 < ((u_char *) s)[0] &&
120 ((u_char *) s)[0] < 0xff) {
121 if (!(((u_char *) s)[1] & 0x80) && code & DEC) {
123 * DEC gaiji:
125 code &= ~EUC; /* definitely DEC */
126 (*outgaiji)(ddd, ((u_char *) s)[0] & 0x7f, ((u_char *) s)[1]);
127 } else
129 * EUC code set 1 (kanji), DEC kanji:
131 (*outkanji)(ddd, ((u_char *) s)[0] & 0x7f, ((u_char *) s)[1] & 0x7f);
132 } else if (((u_char *) s)[0] == SS2 && code & EUC &&
133 0xa0 < ((u_char *) s)[1] &&
134 ((u_char *) s)[1] < 0xff) {
136 * EUC code set 2 (hankaku kana):
138 code &= ~DEC; /* probably EUC */
139 (*outkana)(ddd, ((u_char *) s)[1] & 0x7f);
140 } else if (((u_char *) s)[0] == SS3 && code & EUC &&
141 0xa0 < ((u_char *) s)[1] &&
142 ((u_char *) s)[1] < 0xff &&
143 0xa0 < ((u_char *) s)[2] &&
144 ((u_char *) s)[2] < 0xff) {
146 * EUC code set 3 (gaiji):
148 code &= ~DEC; /* probably EUC */
149 (*outgaiji)(ddd, ((u_char *) s)[1] & 0x7f, ((u_char *) s)[2] & 0x7f);
150 i = 3;
151 continue;
152 } else {
154 * Control character (C1):
156 if (outcode != SJIS && (outcode != EUC ||
157 (((u_char *) s)[0] != SS2 &&
158 ((u_char *) s)[0] != SS3)))
159 **ddd = ((u_char *) s)[0]; (*ddd)++;
160 continue;
162 i = 2;
163 continue;
164 } else if (code & (SJIS | JIS8)) {
166 * Shift-JIS or JIS8:
168 if (!(code & SJIS) || (0xa0 < ((u_char *) s)[0] &&
169 ((u_char *) s)[0] < 0xe0))
171 * Hankaku kana:
173 (*outkana)(ddd, ((u_char *) s)[0] & 0x7f);
174 else {
176 * Shift-JIS kanji:
178 code &= ~JIS8; /* definitely shift-JIS */
179 Kcc_outsjis(ddd, ((u_char *) s)[0], ((u_char *) s)[1]);
180 i = 2;
182 continue;
185 (*outascii)(ddd, ((u_char *) s)[0]);
187 return (code);