claws-mail/libkcc/out.c
2001-04-19 12:21:46 +00:00

188 lines
4.8 KiB
C

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "kcc.h"
#include "libkcc.h"
/**********************************************************************
* *
* Output Routines *
* *
**********************************************************************/
extern void (*outascii)(), (*outkanji)(), (*outgaiji)(), (*outkana)();
/*---------------------------------------------------------------------
NAME
outsjis
---------------------------------------------------------------------*/
void Kcc_outsjis(ddd, c1, c2)
register int c1, c2;
char **ddd;
{
register int c;
c = c1 * 2 - (c1 <= 0x9f ? 0x00e1 : (c1 < 0xf0 ? 0x0161 : 0x01bf));
if (c2 < 0x9f)
c2 = c2 - (c2 > 0x7f ? 0x20 : 0x1f);
else {
c2 = c2 - 0x7e;
c++;
}
(*(c1 <= 0xef ? outkanji : outgaiji))(ddd, c, c2);
}
/*---------------------------------------------------------------------
NAME
out
---------------------------------------------------------------------*/
unsigned Kcc_out(ddd, str, len, code, outcode, inmode, insi, inso, innj, ingj)
char *str, **ddd;
int len;
register unsigned code;
enum mode *inmode;
unsigned long *insi, *inso, *innj, *ingj;
unsigned outcode;
{
register char *s;
register int i;
for (s = str; s < str + len; s += i) {
i = 1;
switch (*(u_char *) s) {
case ESC:
if (*inmode == M_SO)
break;
if (Kcc_compare("$B", s + 1) || Kcc_compare("$@", s + 1)) {
*inmode = M_KANJI; /* kanji */
*insi |= bitflag(((u_char *) s)[2]);
i = 3;
} else if (Kcc_compare("&@\033$B", s + 1)) {
*inmode = M_KANJI; /* kanji 1990 */
*innj |= bitflag('B');
i = 6;
} else if (Kcc_compare("(B", s + 1) || Kcc_compare("(J", s + 1) ||
Kcc_compare("(H", s + 1)) {
*inmode = M_ASCII; /* kanji end */
*inso |= bitflag(((u_char *) s)[2]);
i = 3;
} else if (Kcc_compare("(I", s + 1)) {
*inmode = M_ESCI; /* "ESC(I" */
*inso |= bitflag('I');
i = 3;
} else if (Kcc_compare("$(D", s + 1)) {
*inmode = M_GAIJI; /* gaiji */
*ingj |= bitflag('D');
i = 4;
} else
break;
code |= JIS;
continue;
case SO:
if (*inmode == M_ASCII) {
code |= JIS;
*inmode = M_SO;
continue;
}
break;
case SI:
if (*inmode == M_SO) {
*inmode = M_ASCII;
continue;
}
break;
}
if (*inmode != M_ASCII) {
if (0x20 < ((u_char *) s)[0] && ((u_char *) s)[0] < 0x7f)
switch (*inmode) {
case M_KANJI:
(*outkanji)(ddd, ((u_char *) s)[0], ((u_char *) s)[1] & 0x7f);
i = 2;
continue;
case M_GAIJI:
(*outgaiji)(ddd, ((u_char *) s)[0], ((u_char *) s)[1] & 0x7f);
i = 2;
continue;
case M_SO:
case M_ESCI:
(*outkana)(ddd, ((u_char *) s)[0]);
continue;
default:
continue;
}
} else if (((u_char *) s)[0] & 0x80) {
if (code & (EUC | DEC)) {
/*
* EUC or DEC:
*/
if (0xa0 < ((u_char *) s)[0] &&
((u_char *) s)[0] < 0xff) {
if (!(((u_char *) s)[1] & 0x80) && code & DEC) {
/*
* DEC gaiji:
*/
code &= ~EUC; /* definitely DEC */
(*outgaiji)(ddd, ((u_char *) s)[0] & 0x7f, ((u_char *) s)[1]);
} else
/*
* EUC code set 1 (kanji), DEC kanji:
*/
(*outkanji)(ddd, ((u_char *) s)[0] & 0x7f, ((u_char *) s)[1] & 0x7f);
} else if (((u_char *) s)[0] == SS2 && code & EUC &&
0xa0 < ((u_char *) s)[1] &&
((u_char *) s)[1] < 0xff) {
/*
* EUC code set 2 (hankaku kana):
*/
code &= ~DEC; /* probably EUC */
(*outkana)(ddd, ((u_char *) s)[1] & 0x7f);
} else if (((u_char *) s)[0] == SS3 && code & EUC &&
0xa0 < ((u_char *) s)[1] &&
((u_char *) s)[1] < 0xff &&
0xa0 < ((u_char *) s)[2] &&
((u_char *) s)[2] < 0xff) {
/*
* EUC code set 3 (gaiji):
*/
code &= ~DEC; /* probably EUC */
(*outgaiji)(ddd, ((u_char *) s)[1] & 0x7f, ((u_char *) s)[2] & 0x7f);
i = 3;
continue;
} else {
/*
* Control character (C1):
*/
if (outcode != SJIS && (outcode != EUC ||
(((u_char *) s)[0] != SS2 &&
((u_char *) s)[0] != SS3)))
**ddd = ((u_char *) s)[0]; (*ddd)++;
continue;
}
i = 2;
continue;
} else if (code & (SJIS | JIS8)) {
/*
* Shift-JIS or JIS8:
*/
if (!(code & SJIS) || (0xa0 < ((u_char *) s)[0] &&
((u_char *) s)[0] < 0xe0))
/*
* Hankaku kana:
*/
(*outkana)(ddd, ((u_char *) s)[0] & 0x7f);
else {
/*
* Shift-JIS kanji:
*/
code &= ~JIS8; /* definitely shift-JIS */
Kcc_outsjis(ddd, ((u_char *) s)[0], ((u_char *) s)[1]);
i = 2;
}
continue;
}
}
(*outascii)(ddd, ((u_char *) s)[0]);
}
return (code);
}