static char rcsid[] = "@(#)$Id: cs_iso2022.c,v 1.42 2006/04/09 07:37:08 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.42 $ $State: Exp $
*
* Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
*****************************************************************************/
#include "headers.h"
#include "s_me.h"
#include "cs_imp.h"
#include "cs_terminal.h"
DEBUG_VAR(Debug,__FILE__,"charset");
static unsigned char *s2us P_((char *str));
static unsigned char *s2us(str)
char *str;
{
return (unsigned char *)str;
}
static char *us2s P_((unsigned char *str));
static char *us2s(str)
unsigned char *str;
{
return(char *)str;
}
/* ------------------------------------------------------------------------- */
static void map_init_bad P_((struct map_info *map));
static void map_init_bad(map)
struct map_info *map;
{
panic("STRING PANIC",__FILE__,__LINE__,"map_init_bad",
"map_init_bad called",0);
}
/* ISO 2022 maps */
static struct map_info * open_iso2022_mapset P_((const char * map_name));
static struct map_info * open_iso2022_mapset(map_name)
CONST char * map_name;
{
/* Indexes to iso2022_map_list[] */
int setlist[ISO2022_SET_COUNT];
int count = 0;
static struct map_info * ret = NULL;
char * WALK = NULL;
int i;
char * X = safe_strdup(map_name), *X1;
for (X1 = mime_parse_content_opts(X, &WALK); X1 && *X1;
X1 = mime_parse_content_opts(NULL, &WALK)) {
if (count >= ISO2022_SET_COUNT) {
lib_error(CATGETS(elm_msg_cat, MeSet, MeTooManyMaps,
"Too many maps on %s"),
map_name);
break;
}
setlist[count] = find_iso2022_map_spec(X1);
if (-1 == setlist[count]) {
free(X);
return NULL;
}
count++;
}
free(X);
ret = safe_malloc(sizeof (struct map_info));
ret -> map_type = &cs_iso2022;
ret -> map_name = safe_strdup(map_name);
ret -> b.setlist = safe_malloc(sizeof (* (ret -> b.setlist)));
ret -> map_initialized = 1;
ret -> map_init_it = map_init_bad;
for (i = 0;
i < sizeof (ret->b.setlist->setlist) /
sizeof (ret->b.setlist->setlist[0]);
i++) {
ret->b.setlist->setlist[i] = i < count ? setlist[i] : -1;
}
return ret;
}
/* EUC maps */
static struct map_info * open_euc_mapset P_((const char * map_name));
static struct map_info * open_euc_mapset(map_name)
CONST char * map_name;
{
/* Indexes to iso2022_map_list[] */
int setlist[ISO2022_SET_COUNT];
int count = 0;
static struct map_info * ret = NULL;
char * WALK = NULL;
int i;
char * X = safe_strdup(map_name), *X1;
for (X1 = mime_parse_content_opts(X, &WALK); X1 && *X1;
X1 = mime_parse_content_opts(NULL, &WALK)) {
if (count >= ISO2022_SET_COUNT) {
lib_error(CATGETS(elm_msg_cat, MeSet, MeTooManyMaps,
"Too many maps on %s"),
map_name);
break;
}
setlist[count] = find_iso2022_map_spec(X1);
if (-1 == setlist[count])
return NULL;
count++;
}
free(X);
ret = safe_malloc(sizeof (struct map_info));
ret -> map_type = &cs_euc;
ret -> map_name = safe_strdup(map_name);
ret -> b.setlist = safe_malloc(sizeof (* (ret -> b.setlist)));
ret -> map_initialized = 1;
ret -> map_init_it = map_init_bad;
for (i = 0;
i < sizeof (ret->b.setlist->setlist) /
sizeof (ret->b.setlist->setlist[0]);
i++) {
ret->b.setlist->setlist[i] = i < count ? setlist[i] : -1;
}
return ret;
}
static void find_with_list P_((struct iso2022_setid **p,
struct map_info *map));
static void find_with_list(p,map)
struct iso2022_setid **p;
struct map_info *map;
{
int count = 0;
DPRINT(Debug,61,(&Debug,
"find_with_list iso2022 indexes for %s:",
map->map_name ? map->map_name : "???"));
for (count = 0; p[count]; count++) {
int i;
if (count >=
sizeof (map->b.setlist->setlist) /
sizeof (map->b.setlist->setlist[0]))
panic("STRING PANIC",__FILE__,__LINE__,"find_with_list",
"Too many maps",0);
for (i = 0; i < iso2022_map_list_count; i++) {
if (iso2022_map_list[i].setid == p[count])
break;
}
if (i >= iso2022_map_list_count)
panic("STRING PANIC",__FILE__,__LINE__,"find_with_list",
"Set not found",0);
if (!iso2022_map_list[i].map)
panic("STRING PANIC",__FILE__,__LINE__,"find_with_list",
"No map for set",0);
map->b.setlist->setlist[count] = i;
DPRINT(Debug,61,(&Debug," %d",map->b.setlist->setlist[count]));
}
DPRINT(Debug,61,(&Debug,"\n"));
while (count < sizeof (map->b.setlist->setlist) /
sizeof (map->b.setlist->setlist[0]))
map->b.setlist->setlist[count++] = -1;
}
/* ASCII -------------------------------------------------------------- */
static void map_init_ASCII P_((struct map_info *map));
static void map_init_ASCII(map)
struct map_info *map;
{
struct iso2022_setid *XX[2] = { NULL, NULL };
map -> b.setlist = safe_malloc(sizeof (* (map -> b.setlist)));
XX[0] = ASCII_BANK;
find_with_list(XX,map);
map->map_initialized = 1;
DPRINT(Debug,5,(&Debug,
"Map %s (%s) initialized\n",
map->map_name,map->map_type->type_name));
}
struct map_info map_ISO2022_ascii = {
&cs_iso2022, "US-ASCII", 0, map_init_ASCII, 0
};
struct map_info map_EUC_ascii = {
&cs_euc, "US-ASCII", 0, map_init_ASCII, 0
};
/* ASCII / ISO-8859-1 ---------------------------------------------------- */
static void map_init_ASCII_latin1 P_((struct map_info *map));
static void map_init_ASCII_latin1(map)
struct map_info *map;
{
struct iso2022_setid *XX[3] = { NULL, NULL,
NULL };
map -> b.setlist = safe_malloc(sizeof (* (map -> b.setlist)));
XX[0] = ASCII_BANK;
XX[1] = LATIN1_BANK;
find_with_list(XX,map);
map->map_initialized = 1;
DPRINT(Debug,5,(&Debug,
"Map %s (%s) initialized\n",
map->map_name,map->map_type->type_name));
}
struct map_info map_ISO2022_ascii_latin1 = {
&cs_iso2022, "ISO-8859-1", 0, map_init_ASCII_latin1, 0
};
struct map_info map_EUC_ascii_latin1 = {
&cs_euc, "ISO-8859-1", 0, map_init_ASCII_latin1, 0
};
/* ====================================================================== */
#define CS_ISO2022_magic 0xF301
struct charset_type cs_iso2022;
struct mb_data {
unsigned short magic; /* CS_ISO2022_magic */
struct mb_data_part {
int set_index; /* Refers to iso2022_info (struct setlist) ...
-1 if control characters
(also space with 94, 94x94 sets)
-2 if bad iso2022 bank
*/
int iso2022_map_index; /* index to iso2022_map_list[] */
enum iso2022_settype type; /* iso2022_other for controls */
uint16 *words; /* range: 1 - 94 (bank 94)
0 - 95 (bank 96)
0 == 'space'
1 - (96*96)-1 (bank 94x94)
0 - (96*96)-1 (bank 96x96)
0 - 32,128-160 (if control)
*/
int word_count;
} * parts;
int part_count;
};
#define STATE_ISO2022_magic 0xF302
/* NOTE: state_iso2022 is used for for input state
struct display_settings is used for for output state
*/
struct state_iso2022 {
unsigned short magic; /* STATE_ISO2022_magic */
enum iso2022_bank bank; /* initially bank_unspecified (-1),
also bank_unspecified if control
character (or perhaps space)
*/
struct {
enum iso2022_settype type;
int iso2022_info_index; /* index to iso2022_info (setlist)
of charset
-1 if not on list
*/
unsigned char bytes[ISO2022_SETID_LEN];
} banks[ISO2022_BANK_NUM];
enum iso2022_bank CL_bank; /* Bank for 32 - 127 */
enum iso2022_bank CR_bank; /* Bank for 160 - 255 */
/* raw_byte is used during parsing */
unsigned char raw_bytes[ISO2022_SETID_LEN + 4];
int raw_bytes_count;
uint16 word; /* code position on gived bank / type */
};
#if ANSI_C
#define S_(x) static x;
#else
#define S_(x)
#endif
static struct mb_data * alloc_mb_data P_((void));
static struct mb_data * alloc_mb_data()
{
struct mb_data *ret = safe_malloc(sizeof (* ret));
/* defined in hdrs/defs.h */
bzero((void *) ret, sizeof (* ret));
ret->magic = CS_ISO2022_magic;
ret->parts = NULL;
ret->part_count = 0;
return ret;
}
S_(cs_init_string cs_init_iso2022_gen)
static void cs_init_iso2022_gen(str)
struct string *str;
{
str->p->len = 0;
str->p->private_flag = 0;
str->p->a.data = alloc_mb_data();
}
static void free_parts P_((struct mb_data * X1));
static void free_parts(X1)
struct mb_data * X1;
{
if (X1->parts) {
int i;
for (i = 0; i < X1->part_count; i++) {
if (X1->parts[i].words) {
free (X1->parts[i].words);
X1->parts[i].words = NULL;
}
X1->parts[i].word_count = 0;
}
free(X1->parts);
X1->parts = NULL;
}
X1->part_count = 0;
}
static void free_mb_data P_((struct mb_data ** ptr));
static void free_mb_data(ptr)
struct mb_data **ptr;
{
if (*ptr) {
if (CS_ISO2022_magic != (*ptr)->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"free_mb_data",
"Bad magic number",0);
free_parts(*ptr);
(*ptr)->magic = 0; /* Invalidate magic */
/* defined in hdrs/defs.h */
bzero((void *) *ptr, sizeof (* (*ptr)));
free(*ptr);
*ptr = NULL;
}
}
S_(cs_free_string cs_free_iso2022_gen)
static void cs_free_iso2022_gen(str)
struct string *str;
{
free_mb_data ( & (str->p->a.data));
str->p->len = 0;
}
static struct mb_data_part * get_part P_((struct mb_data * X1,
int index,
enum iso2022_settype type));
static struct mb_data_part * get_part(X1,index,type)
struct mb_data * X1;
int index;
enum iso2022_settype type;
{
struct mb_data_part * X3 = NULL;
if (X1->part_count < 1 ||
X1->parts[X1->part_count-1].set_index != index ||
X1->parts[X1->part_count-1].type != type) {
X1->parts = safe_realloc(X1->parts,
( X1->part_count+1) *
sizeof (X1->parts[0]));
X1->parts[X1->part_count].set_index = index;
X1->parts[X1->part_count].iso2022_map_index = -1; /* Filled later */
X1->parts[X1->part_count].type = type;
X1->parts[X1->part_count].words = NULL;
X1->parts[X1->part_count].word_count = 0;
#ifdef DEBUG
DPRINT(Debug,59,(&Debug,
"get_part: %d: type=%d set_index=%d (new part)\n",
X1->part_count,type,index));
#endif
X1->part_count++;
}
X3 = & (X1->parts[X1->part_count-1] );
return X3;
}
static void fill_iso2022_map_index P_((struct setlist *iso2022_info,
struct mb_data *X1,
struct map_info *map));
static void fill_iso2022_map_index(iso2022_info,X1,map)
struct setlist * iso2022_info;
struct mb_data * X1;
struct map_info *map;
{
int i;
if (map -> map_type != &cs_iso2022 &&
map -> map_type != &cs_euc) {
panic("ISO2022 PANIC",__FILE__,__LINE__,"fill_iso2022_map_index",
"Bad map type",0);
}
if (!map->map_initialized)
map->map_init_it(map);
for (i = 0; i < X1->part_count; i++) {
if (X1->parts[i].set_index >= 0 &&
-1 == X1->parts[i].iso2022_map_index) {
if (X1->parts[i].set_index <
sizeof (iso2022_info->sets) /
sizeof (iso2022_info->sets[0]) &&
iso2022_info->sets[X1->parts[i].set_index]) {
X1->parts[i].iso2022_map_index =
give_iso2022_index(map->b.setlist->setlist,
sizeof (map->b.setlist->setlist) /
sizeof (map->b.setlist->setlist[0]),
iso2022_info->sets[X1->parts[i].
set_index]);
} else
panic("ISO2022 PANIC",__FILE__,__LINE__,
"fill_iso2022_map_index",
"Bad data set_index",0);
}
}
}
static int find_index P_((struct setlist *list,enum iso2022_settype type,
unsigned char bytes[ISO2022_SETID_LEN]));
static int find_index(list,type,bytes)
struct setlist *list;
enum iso2022_settype type;
unsigned char bytes[ISO2022_SETID_LEN];
{
int i;
for (i = 0; i < sizeof(list->sets) / sizeof(list->sets[0]); i++) {
if (! list->sets[i])
break;
if (type == list->sets[i]->type &&
0 == memcmp(bytes,list->sets[i]->bytes,sizeof (list->sets[i]->bytes)))
return i;
}
return -2; /* unknown */
}
static int convert_index P_((int d_index, struct setlist *d_list,
struct setlist *list,enum iso2022_settype type));
static int convert_index(d_index,d_list,list,type)
int d_index;
struct setlist *d_list;
struct setlist *list;
enum iso2022_settype type;
{
int index = -2;
if (d_index >= 0 &&
d_index < sizeof (d_list->sets) / sizeof (d_list->sets[0]) &&
d_list->sets[d_index]) {
unsigned char bytes[ISO2022_SETID_LEN];
if (type != d_list->sets[d_index]->type)
panic("ISO2022 PANIC",__FILE__,__LINE__,"convert_index",
"Bank type mismatch",0);
if (sizeof(bytes) !=
sizeof(d_list->sets[d_index]->bytes))
panic("ISO2022 PANIC",__FILE__,__LINE__,"convert_index",
"size mismatch on ISO2022_SETID",0);
memcpy(bytes,d_list->sets[d_index]->bytes,
sizeof(bytes));
index = find_index(list,type,bytes);
} else
panic("ISO2022 PANIC",__FILE__,__LINE__,"convert_index",
"Bad data set_index",0);
return index;
}
/* FIXME: This call should be replaced with more effective */
/* iso2022_word can not be uint16 becaus ethat causes error message
about promotion
*/
static void add_iso2022_word P_((struct mb_data_part * X3,
unsigned iso2022_word));
static void add_iso2022_word(X3,iso2022_word)
struct mb_data_part * X3;
unsigned iso2022_word;
{
X3->words = safe_realloc(X3->words, (X3->word_count+1) *
sizeof (X3->words[0]));
X3->words[X3->word_count++] = iso2022_word;
}
#ifdef DEBUG
static void debug_iso2022_info_index P_((int level,int index,
struct setlist *iso2022_info));
static void debug_iso2022_info_index(level,
index,iso2022_info)
int level;
int index;
struct setlist *iso2022_info;
{
if (index >= 0 &&
index < sizeof (iso2022_info->sets) /
sizeof (iso2022_info->sets[0]) &&
iso2022_info->sets[index]) {
char *x = iso2022_codestr(iso2022_info->sets[index]->bytes,
sizeof (iso2022_info->sets[index]));
DPRINT(Debug,level,(&Debug,
"bank=%d type=%d",
iso2022_info->sets[index]->bank,
iso2022_info->sets[index]->type));
if (x) {
DPRINT(Debug,level,(&Debug," bytes=%s",x));
free(x);
}
}
}
#endif
static void iso2022_add_char P_((struct string *str,
struct charset_state *state));
static void iso2022_add_char(str,state)
struct string *str;
struct charset_state *state;
{
int index = -1;
enum iso2022_settype type = iso2022_other;
struct state_iso2022 * X = state->p->a.iso2022;
struct mb_data * X1 = str->p->a.data;
struct mb_data_part * X3 = NULL, *debug_ptr;
if (STATE_ISO2022_magic != X->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"iso2022_add_char",
"Bad magic number (state)",0);
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"iso2022_add_char",
"Bad magic number (string)",0);
if (bank_unspecified == X->bank) {
index = -1;
type = iso2022_other;
} else if (X->bank >= 0 && X->bank < ISO2022_BANK_NUM) {
if (-1 == X->banks[X->bank].iso2022_info_index) {
index = -2; /* BAD */
type = X->banks[X->bank].type;
} else if (str->string_type->iso2022_info) {
if (str->string_type != state->charset) {
/* If different character set then we must search about bank */
if (state->charset->iso2022_info) {
int d_index = X->banks[X->bank].iso2022_info_index;
if (str->string_type->iso2022_info)
index = convert_index (d_index,
state->charset->iso2022_info,
str->string_type->iso2022_info,
type);
else
index = -2; /* Bad bank */
} else
index = -2; /* Bad set */
} else {
index = X->banks[X->bank].iso2022_info_index; /* Assume correct index */
if (index >= 0 &&
index < sizeof (str->string_type->iso2022_info->sets) /
sizeof (str->string_type->iso2022_info->sets[0]) &&
str->string_type->iso2022_info->sets[index]) {
type = X->banks[X->bank].type;
if (str->string_type->iso2022_info->sets[index]->type !=
X->banks[X->bank].type)
panic("ISO2022 PANIC",__FILE__,__LINE__,"iso2022_add_char",
"Bank type mismatch",0);
} else
panic("ISO2022 PANIC",__FILE__,__LINE__,"iso2022_add_char",
"Bad iso2022_info_index",0);
}
} else {
index = -2; /* Default: Bad bank */
type = X->banks[X->bank].type;
}
} else
panic("ISO2022 PANIC",__FILE__,__LINE__,"iso2022_add_char",
"Bad bank number",0);
debug_ptr = NULL;
if (X1->part_count > 0)
debug_ptr = & (X1->parts[X1->part_count-1]);
X3 = get_part(X1,index,type);
#ifdef DEBUG
if (Debug.active > 58 && X3 != debug_ptr) {
DPRINT(Debug,59,(&Debug,
"iso2022_add_char: %d: type=%d set_index=%d <",
X1->part_count-1,
type, index));
if (str->string_type->iso2022_info)
debug_iso2022_info_index(59,index,
str->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,">\n"));
}
#endif
add_iso2022_word(X3, X->word);
str->p->len++;
}
/* sets state to be ready and pops raw_byte, 1 if popped
does not parse escape sequences
*/
static int streambyte_make_code_1 P_((struct charset_state *st,
enum iso2022_bank single_shift_bank));
static int streambyte_make_code_1(st,single_shift_bank)
struct charset_state *st;
enum iso2022_bank single_shift_bank;
{
struct state_iso2022 * X = st->p->a.iso2022;
unsigned char ch1;
int upper;
enum iso2022_bank bank;
if (X->raw_bytes_count < 1)
return 0;
/* raw_bytes is unsigned */
if (X->raw_bytes[0] < 32) {
goto add_control;
}
upper = X->raw_bytes[0] & 128;
ch1 = X->raw_bytes[0] & 127;
if (single_shift_bank >= 0) /* Normally left, but EUC uses rigth bank */
bank = single_shift_bank;
else
bank = upper ? X->CR_bank : X->CL_bank;
if (ch1 > 32 && ch1 < 127 &&
bank >= 0 && bank < ISO2022_BANK_NUM &&
iso2022_94 == X->banks[bank].type) {
X->bank = bank;
X->word = ISO2022_1byte_to_word(ch1);
X->raw_bytes_count--;
if (X->raw_bytes_count > 0)
memmove(X->raw_bytes, X->raw_bytes+1, X->raw_bytes_count);
DPRINT(Debug,61,(&Debug,
"got [94] bank=%d ISO2022 word=%02x ch=%c upper=%d\n",
X->bank,X->word, ch1,upper));
st->p->ready = 1;
return 1;
}
if (ch1 >= 32 &&
bank >= 0 && bank < ISO2022_BANK_NUM &&
iso2022_96 == X->banks[bank].type) {
X->bank = bank;
X->word = ISO2022_1byte_to_word(ch1);
X->raw_bytes_count--;
if (X->raw_bytes_count > 0)
memmove(X->raw_bytes, X->raw_bytes+1, X->raw_bytes_count);
DPRINT(Debug,61,(&Debug,
"got [96] bank=%d ISO2022 word=%02x ch=%c upper=%d\n",
X->bank,X->word, ch1,upper));
st->p->ready = 1;
return 1;
}
if (X->raw_bytes_count > 1) {
unsigned char ch2;
if (upper != X->raw_bytes[1] & 128) {
/* BAD */
goto add_control;
}
ch2 = X->raw_bytes[1] & 127;
if (ch1 > 32 && ch1 < 127 &&
ch2 > 32 && ch2 < 127 &&
bank >= 0 && bank < ISO2022_BANK_NUM &&
iso2022_94x94 == X->banks[bank].type) {
X->bank = bank;
X->word = ISO2022_2byte_to_word(ch1,ch2);
X->raw_bytes_count -= 2;
if (X->raw_bytes_count > 0)
memmove(X->raw_bytes, X->raw_bytes+2, X->raw_bytes_count);
DPRINT(Debug,61,(&Debug,
"got [94x94] bank=%d ISO2022 word=%04x ch=%c%c upper=%d\n",
X->bank,X->word, ch1,ch2,upper));
st->p->ready = 1;
return 1;
}
if (ch1 >= 32 &&
ch2 >= 32 &&
bank >= 0 && bank < ISO2022_BANK_NUM &&
iso2022_96x96 == X->banks[bank].type) {
X->bank = bank;
X->word = ISO2022_2byte_to_word(ch1,ch2);
X->raw_bytes_count -= 2;
if (X->raw_bytes_count > 0)
memmove(X->raw_bytes, X->raw_bytes+2, X->raw_bytes_count);
DPRINT(Debug,61,(&Debug,
"got [96x96] bank=%d ISO2022 word=%04x ch=%c%c upper=%d\n",
X->bank,X->word, ch1,ch2,upper));
st->p->ready = 1;
return 1;
}
}
if (bank >= 0 && bank < ISO2022_BANK_NUM &&
(iso2022_96x96 == X->banks[bank].type ||
iso2022_94x94 == X->banks[bank].type) &&
X->raw_bytes_count < 2) {
return 0;
}
/* This is not really supported because we do not know
number of bytes per characters
*/
if (bank >= 0 && bank < ISO2022_BANK_NUM &&
iso2022_other == X->banks[bank].type) {
/* Like controls */
X->bank = bank;
X->word = X->raw_bytes[0];
X->raw_bytes_count--;
if (X->raw_bytes_count > 0)
memmove(X->raw_bytes, X->raw_bytes+1, X->raw_bytes_count);
DPRINT(Debug,61,(&Debug,
"got [other] bank=%d ISO2022 word=%02x\n",
X->bank,X->word));
st->p->ready = 1;
return 1;
}
add_control:
X->bank = bank_unspecified;
X->word = X->raw_bytes[0];
X->raw_bytes_count--;
if (X->raw_bytes_count > 0)
memmove(X->raw_bytes, X->raw_bytes+1, X->raw_bytes_count);
DPRINT(Debug,61,(&Debug,
"got [ctrl] bank=%d ISO2022 word=%02x\n",
X->bank,X->word));
st->p->ready = 1;
return 1;
}
/* 0 == overflow or bad char, 1 == OK */
static int state_add_raw P_((struct state_iso2022 * X , int ch));
static int state_add_raw(X,ch)
struct state_iso2022 * X;
int ch;
{
if (ch < 0 || ch > 0xFF)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"state_add_raw",
"Value not in range 0-255",0);
if (X->raw_bytes_count >= sizeof (X->raw_bytes)) {
DPRINT(Debug,4,(&Debug,
"state_add_raw: Overlow (already %d bytes)\n",
X->raw_bytes_count));
return 0; /* Overflow */
}
X->raw_bytes[X->raw_bytes_count++] = ch; /* store it */
return 1;
}
/* -1 == not enough
0 == not ok
1 == processed
*/
static int streambyte_make_code_2 P_((struct charset_state *st,
struct state_iso2022 * X));
static int streambyte_make_code_2(st,X)
struct charset_state *st;
struct state_iso2022 * X;
{
int T;
if (X->raw_bytes_count < 1) {
DPRINT(Debug,1,(&Debug,
"streambyte_make_code_2: len=%d\n",
X->raw_bytes_count));
return -1;
}
T = X->raw_bytes[0] & 127;
if (T < 32) { /* Is on control area ... ( 0 - 31 or 128 - 159) */
enum iso2022_bank Bank;
enum shift_mode LR;
struct iso2022_setid Setid;
int l;
/* Try then if this is bank switch */
l = eat_iso2022_bank_switch(&Bank,&LR,
X->raw_bytes,
X->raw_bytes_count);
if (l > 0) {
char buffer[sizeof (X->raw_bytes)];
int buffer_len;
/* For backup of single-shift */
memcpy(buffer,X->raw_bytes,X->raw_bytes_count);
buffer_len = X->raw_bytes_count;
X->raw_bytes_count -= l;
if (X->raw_bytes_count > 0)
memmove(X->raw_bytes, X->raw_bytes+l, X->raw_bytes_count);
switch (LR) {
case lock_shift_left:
X->CL_bank = Bank;
DPRINT(Debug,61,(&Debug,
"got bank shift lower bank=%d\n",
X->CL_bank));
break;
case lock_shift_right:
X->CR_bank = Bank;
DPRINT(Debug,61,(&Debug,
"got bank shift upper bank=%d\n",
X->CR_bank));
break;
case single_shift:
DPRINT(Debug,61,(&Debug,
"looking for single shift .. bank=%d\n",
Bank));
if (streambyte_make_code_1(st,Bank) > 0)
break; /* OK */
memcpy(X->raw_bytes,buffer,buffer_len);
X->raw_bytes_count = buffer_len;
DPRINT(Debug,8,(&Debug,
"streambyte_make_code_2: single shift not complete (len=%d)\n",
buffer_len));
return -1;
}
return 1; /* try eat next code */
}
if (l < 0) {
DPRINT(Debug,8,(&Debug,
"streambyte_make_code_2: incomplete bank switch (len=%d)\n",
X->raw_bytes_count));
return -1;
}
/* Try then if this is setid */
l = eat_iso2022_setid(&Setid,X->raw_bytes,X->raw_bytes_count);
if (l > 0) {
if (Setid.bank >= 0 && Setid.bank < ISO2022_BANK_NUM) {
X->banks[Setid.bank].type = Setid.type;
memcpy(X->banks[Setid.bank].bytes,
Setid.bytes,sizeof X->banks[Setid.bank].bytes);
DPRINT(Debug,61,(&Debug,
"got bank %d type=%d bytes=%.*s\n",
Setid.bank,
X->banks[Setid.bank].type,
sizeof X->banks[Setid.bank].bytes,
X->banks[Setid.bank].bytes));
X->banks[Setid.bank].iso2022_info_index =
find_index(st->charset->iso2022_info,
X->banks[Setid.bank].type,
X->banks[Setid.bank].bytes);
if ( X->banks[Setid.bank].iso2022_info_index < 0) {
X->banks[Setid.bank].iso2022_info_index = -1;
DPRINT(Debug,8,(&Debug,
"streambyte_make_code_2: setid is not part of charset\n"));
}
DPRINT(Debug,61,(&Debug,
" ... iso2022_info_index %d\n",
X->banks[Setid.bank].iso2022_info_index));
X->raw_bytes_count -= l;
if (X->raw_bytes_count > 0)
memmove(X->raw_bytes, X->raw_bytes+l, X->raw_bytes_count);
return 1; /* try eat next code */
}
DPRINT(Debug,8,(&Debug,
"streambyte_make_code_2: bad bank %d on setid\n",
Setid.bank));
}
if (l < 0) {
DPRINT(Debug,8,(&Debug,
"streambyte_make_code_2: incomplete setting of bank (setid, len=%d)\n",
X->raw_bytes_count));
return -1;
}
}
if (!streambyte_make_code_1(st,bank_unspecified)) {
DPRINT(Debug,8,(&Debug,
"streambyte_make_code_2: Incomplete character (len=%d)\n",
X->raw_bytes_count));
return -1;
}
return 1;
}
static void cs_soft_reset_s_iso2022_gen P_((struct charset_state *str));
S_(cs_add_streambyte_to_string cs_add_streambyte_to_iso2022_gen)
static int cs_add_streambyte_to_iso2022_gen(str,ch)
struct string *str;
int ch;
{
int c;
struct state_iso2022 * X ;
if (!str->p->state)
str->p->state = new_state_1(str->string_type);
if (str->p->state->charset != str->string_type)
panic("STRING PANIC",__FILE__,__LINE__,"cs_add_streambyte_to_iso2022_gen",
"Bad state",0);
X = str->p->state->p->a.iso2022;
if (STATE_ISO2022_magic != X->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_add_streambyte_to_iso2022_gen",
"Bad magic number (state)",0);
if (X->raw_bytes_count > 0) {
DPRINT(Debug,8,(&Debug,
"cs_add_streambyte_to_iso2022: %d bytes already\n",
X->raw_bytes_count));
/* Try first read extra characters from buffer */
if (streambyte_make_code_2(str->p->state,X) > 0) {
if (str->p->state->p->ready) {
/* Got it */
iso2022_add_char(str,str->p->state);
cs_soft_reset_s_iso2022_gen(str->p->state);
}
}
}
if (!state_add_raw(X,ch)) {
DPRINT(Debug,8,(&Debug,
"cs_add_streambyte_to_iso2022_gen: failed to add code\n"));
return 0;
}
while ((c = streambyte_make_code_2(str->p->state,X)) > 0) {
/* Handle case where several characters generated */
if (str->p->state->p->ready) {
/* Got it */
iso2022_add_char(str,str->p->state);
cs_soft_reset_s_iso2022_gen(str->p->state);
}
}
if (0 == c) {
DPRINT(Debug,8,(&Debug,
"cs_add_streambyte_to_iso2022_gen: failed to parse code\n"));
return 0;
}
return 1;
}
S_(cs_add_intdata_to_string cs_add_intdata_to_iso2022_gen)
static void cs_add_intdata_to_iso2022_gen(str,data)
struct string *str;
CONST struct string *data;
{
int i;
struct mb_data * X1 = str->p->a.data;
struct mb_data * Xd = data->p->a.data;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_add_intdata_to_iso2022_gen",
"Bad magic number (string)",0);
if (CS_ISO2022_magic != Xd->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_add_intdata_to_iso2022_gen",
"Bad magic number (data string)",0);
for (i = 0; i < Xd->part_count; i++) {
int index = -1;
enum iso2022_settype type = Xd->parts[i].type;
struct mb_data_part * X3 = NULL, *debug_ptr;
int j;
#ifdef DEBUG
DPRINT(Debug,59,(&Debug,
"cs_add_intdata_to_iso2022_gen: %d: type=%d set_index=%d <",
i,type, Xd->parts[i].set_index));
if (Debug.active > 58 && data->string_type->iso2022_info)
debug_iso2022_info_index(59,Xd->parts[i].set_index,
data->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,"> (source)\n"));
#endif
if (-1 == Xd->parts[i].set_index) {
index = -1;
if (iso2022_other != type)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_add_intdata_to_iso2022_gen",
"Bad type for control data",0);
} else if (-2 == Xd->parts[i].set_index) {
index = -2; /* bad iso2022 bank */
} else {
index = -2; /* bad iso2022 bank */
if (data->string_type->iso2022_info) {
int d_index = Xd->parts[i].set_index;
if (str->string_type->iso2022_info)
index = convert_index(d_index,data->string_type->iso2022_info,
str->string_type->iso2022_info,type);
else
index = -2; /* Bad bank */
} else
index = -2; /* bad iso2022 bank */
}
if (Xd->parts[i].word_count < 1)
continue; /* OOPS -- nothing to do */
debug_ptr = NULL;
if (X1->part_count > 0)
debug_ptr = & (X1->parts[X1->part_count-1]);
X3 = get_part(X1,index,type);
#ifdef DEBUG
if (Debug.active > 58 && X3 != debug_ptr) {
DPRINT(Debug,59,(&Debug,
"cs_add_intdata_to_iso2022_gen: %d: type=%d set_index=%d <",
X1->part_count-1,
type, index));
if (str->string_type->iso2022_info)
debug_iso2022_info_index(59,index,
str->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,"> (target)\n"));
}
#endif
X3->words = safe_realloc(X3->words,
(X3->word_count + Xd->parts[i].word_count) *
sizeof (X3->words[0]));
for (j = 0; j < Xd->parts[i].word_count; j++)
X3->words[X3->word_count++] = Xd->parts[i].words[j];
str->p->len += Xd->parts[i].word_count;
}
}
/* Does compression, recalculation and so on ...
so 'const' is not very const
*/
S_(cs_check_length_string cs_check_length_iso2022_gen)
static void cs_check_length_iso2022_gen(str)
CONST struct string *str;
{
int len = 0;
int i;
struct mb_data * X1 = str->p->a.data;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_check_length_iso2022_gen",
"Bad magic number (string)",0);
for (i = 0; i < X1->part_count; i++) {
len += X1->parts[i].word_count;
}
if (len != str->p->len) {
DPRINT(Debug,6,(&Debug,
"cs_check_length_iso2022_gen: Fixing length %d => %d\n",
str->p->len,len));
str->p->len = len;
}
}
/* Returns 1 if position exists */
static int pos_to_block P_((struct mb_data * X1, int pos,
int *block_number,
int *block_index));
static int pos_to_block(X1,pos,block_number,block_index)
struct mb_data * X1;
int pos;
int *block_number;
int *block_index;
{
*block_number = 0;
*block_index = pos;
while (*block_number < X1->part_count &&
X1->parts[*block_number].word_count <= *block_index) {
*block_index -= X1->parts[*block_number].word_count;
(*block_number)++;
}
if (*block_number >= X1->part_count ||
*block_index >= X1->parts[*block_number].word_count)
return 0;
DPRINT(Debug,61,(&Debug,
" pos=%d => block/index=%d/%d\n",
pos,*block_number,*block_index));
return 1;
}
S_(cs_give_unicode_from_string cs_give_unicode_from_iso2022_gen)
static uint16 cs_give_unicode_from_iso2022_gen(str,pos,found)
CONST struct string *str;
int pos;
int *found;
{
struct mb_data * X1 = str->p->a.data;
int block_number = 0;
int block_index = pos;
uint16 code;
int set_index; /* Refers to iso2022_info (struct setlist) ...
-1 if control characters
(also space with 94, 94x94 sets)
-2 if bad iso2022 bank
*/
enum iso2022_settype type; /* iso2022_other for controls */
uint16 ret;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_give_unicode_from_iso2022_gen",
"Bad magic number (string)",0);
if (pos < 0 || pos >= str->p->len)
panic("STRING PANIC",__FILE__,__LINE__,"cs_give_unicode_from_iso2022_gen",
"Index out of array",0);
if (!pos_to_block(X1,pos,&block_number,&block_index))
panic("STRING PANIC",__FILE__,__LINE__,"cs_give_unicode_from_iso2022_gen",
"Index position not found",0);
/* Fill indexes if current not filled */
if (-1 == X1->parts[block_number].iso2022_map_index &&
str->string_type->map_info && str->string_type->iso2022_info)
fill_iso2022_map_index(str->string_type->iso2022_info,
X1,
str->string_type->map_info);
code = X1->parts[block_number].words[block_index];
set_index = X1->parts[block_number].set_index;
type = X1->parts[block_number].type;
*found = 0;
ret = 0x003F; /* '?' */
if (-1 == set_index) { /* Controls maps to unicode directly */
if (iso2022_other != type)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_give_unicode_from_iso2022_gen",
"Type is not iso2022_other for controls",0);
ret = code;
*found = 1;
} else {
int iso2022_map_index; /* index to iso2022_map_list[] */
iso2022_map_index = X1->parts[block_number].iso2022_map_index;
if (-1 != iso2022_map_index)
*found = map_ISO2022_word_to_unicode(code,type,iso2022_map_index,
&ret);
else {
DPRINT(Debug,62,(&Debug,
"pos %d -- block/index=%d/%d (code %04x set_index %d type %d) -- no iso2022_map_index\n",
pos,block_number,block_index,code,set_index,type));
}
}
return ret;
}
static int map_unicode_to_ISO2022_word P_((unsigned unicode,
struct setlist * iso2022_info,
int * index,
enum iso2022_settype * type,
uint16 * iso2022_word,
struct map_info *map));
static int map_unicode_to_ISO2022_word(unicode,iso2022_info,
iso2022_info_index,
type,iso2022_word,
map)
unsigned unicode;
struct setlist * iso2022_info;
int * iso2022_info_index;
enum iso2022_settype * type;
uint16 * iso2022_word;
struct map_info * map;
{
int found = 0;
int i;
*iso2022_info_index = -3; /* MARKER !!!!!!! */
for (i = 0;
i < sizeof (iso2022_info->sets) / sizeof (iso2022_info->sets[0]);
i++) {
if (iso2022_info->sets[i]) {
/* (space (32) and del (127) with 94, 94x94 sets is
on control area ... */
if ((iso2022_94 == iso2022_info->sets[i]->type ||
iso2022_94x94 == iso2022_info->sets[i]->type) &&
( 32 == unicode || 127 == unicode)) {
*iso2022_info_index = -1; /* Control area */
*iso2022_word = unicode;
*type = iso2022_other; /* we do not use
iso2022_94 hre,
because we interpret
word as character
32-127 then
*/
found = 1;
break;
}
}
}
if (!found && map) {
int s;
if (map -> map_type != &cs_iso2022 &&
map -> map_type != &cs_euc)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_unicode_to_ISO2022_word",
"Bad map type",0);
if (!map->map_initialized)
map->map_init_it(map);
for (s = 0; s < sizeof (map->b.setlist->setlist) /
sizeof (map->b.setlist->setlist[0]);
s++) {
int iso2022_map_index = map->b.setlist->setlist[s];
if (-1 != iso2022_map_index &&
map_unicode_to_ISO2022_word_1(unicode,type,iso2022_map_index,
iso2022_word)) {
DPRINT(Debug,52,(&Debug,
"map_unicode_to_ISO2022_word: %04x => iso2022_map_index=%d (setlist %d), type=%d word=%04x\n",
unicode,iso2022_map_index,s,*type,*iso2022_word));
/* Search iso2022_info_index */
*iso2022_info_index = -2; /* bad iso2022 bank */
if (iso2022_info) {
unsigned char bytes[ISO2022_SETID_LEN];
fill_iso2022_map_setlist_bytes(iso2022_map_index,*type,bytes, sizeof bytes);
*iso2022_info_index = find_index(iso2022_info,*type,bytes);
}
found = 1;
break;
}
}
}
if (!found) { /* Not actually used ... */
*iso2022_info_index = -2; /* Bad bank */
*iso2022_word = unicode;
*type = iso2022_other; /* we do not use
iso2022_94 here,
because we interpret
word as character
32-127 then
*/
}
DPRINT(Debug,52,(&Debug,
"map_unicode_to_ISO2022_word=%d: %04x %s == iso2022_info_index %d, type=%d word=%04x\n",
found,
unicode,
found ? "FOUND" : "NOT FOUND",
*iso2022_info_index,
*type,
*iso2022_word));
return found;
}
S_(cs_add_unicodedata_to_string cs_add_unicodedata_to_iso2022_gen)
static void cs_add_unicodedata_to_iso2022_gen(str,len,data)
struct string *str;
int len;
CONST uint16 *data;
{
int i;
struct mb_data * X1 = str->p->a.data;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_add_unicodedata_to_iso2022_gen",
"Bad magic number (string)",0);
/* TODO: This should be optimized */
for (i = 0; i < len; i++) {
/* Values < 32 are on control block and
also correspond 8-bit values
*/
if (data[i] < 32 ||
data[i] > 127 && data[i] < 160 ) {
struct mb_data_part * X3 = get_part(X1,-1,iso2022_other);
add_iso2022_word(X3, data[i]);
str->p->len++;
} else {
int index;
enum iso2022_settype type;
uint16 iso2022_word;
struct mb_data_part * X3, *debug_ptr;
/* map_unicode_to_ISO2022_word() also puts 32 and 127
to control area if needed
*/
if (! str->string_type->iso2022_info ||
! map_unicode_to_ISO2022_word(data[i],
str->string_type->iso2022_info,
&index,&type,&iso2022_word,
str->string_type->map_info
)) {
/* Put as bad data ...
add_char1_stream() will print
that as question mark
*/
index = -2; /* Bad bank */
type = iso2022_other; /* Also controls */
iso2022_word = data[i];
}
debug_ptr = NULL;
if (X1->part_count > 0)
debug_ptr = & (X1->parts[X1->part_count-1]);
X3 = get_part(X1,index,type);
#ifdef DEBUG
if (Debug.active > 58 && X3 != debug_ptr) {
DPRINT(Debug,59,(&Debug,
"cs_add_unicodedata_to_iso2022_gen: %d: type=%d set_index=%d <",
X1->part_count-1,
type, index));
if (str->string_type->iso2022_info)
debug_iso2022_info_index(59,index,
str->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,">\n"));
}
#endif
add_iso2022_word(X3,iso2022_word);
str->p->len++;
}
}
}
S_(cs_cmp_string cs_cmp_iso2022_gen)
static int cs_cmp_iso2022_gen(str1,str2)
CONST struct string *str1;
CONST struct string *str2;
{
struct mb_data * X1 = str1->p->a.data;
struct mb_data * X2 = str1->p->a.data;
int i;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_cmp_iso2022_gen",
"Bad magic number (string 1)",0);
if (CS_ISO2022_magic != X2->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_cmp_iso2022_gen",
"Bad magic number (string 2)",0);
for (i = 0; i < X1->part_count && i < X2->part_count; i++) {
int j;
for (j = 0; j < X1->parts[i].word_count &&
j < X1->parts[i].word_count; j++) {
if (X1->parts[i].words[j] < X2->parts[i].words[j])
return -1;
if (X1->parts[i].words[j] > X2->parts[i].words[j])
return 1;
}
/* not necessary correct */
if (j < X1->parts[i].word_count)
return 1;
if (j < X2->parts[i].word_count)
return -1;
}
if (i < X1->part_count)
return 1;
if (i < X2->part_count)
return -1;
return 0;
}
static void add_bytes_stream P_((unsigned char **ret,
int *len,
int *alloced,
unsigned char *c,
int l));
static void add_bytes_stream(ret,len,alloced,c,l)
unsigned char **ret;
int *len;
int *alloced;
unsigned char *c;
int l;
{
if (*alloced < *len + l) {
*alloced = *len + l + 15;
*ret = safe_realloc(*ret,*alloced);
}
memcpy((*ret)+(*len),c,l);
*len += l;
}
static int select_upper_lower P_((unsigned char **ret,
int *len,
int *alloced,
struct iso2022_setid *ID,
screen_info_p output_state,
int *width));
static int select_upper_lower(ret,len,alloced,ID,output_state,width)
unsigned char **ret;
int *len;
int *alloced;
struct iso2022_setid *ID;
screen_info_p output_state;
int *width;
{
int is_upper = 0;
int setpos = iso2022_give_setpos(ID,output_state);
int printit = 0;
if (-1 == setpos) {
char * c;
if (output_state->set_count <
sizeof (output_state->sets) /
sizeof (output_state->sets[0])) {
setpos = output_state->set_count++;
} else if (iso2022_94 == ID->type) {
setpos = 0;
DPRINT(Debug,7,(&Debug,
"select_upper_lower: Too many sets on output state, replacing set %d\n",
setpos));
printit++;
} else {
setpos = 1;
DPRINT(Debug,7,(&Debug,
"select_upper_lower: Too many sets on output state, replacing set %d\n",
setpos));
printit++;
}
output_state->sets[setpos] = *ID;
output_state->width[setpos] = -1; /* No terminal information so no width */
DPRINT(Debug,58,(&Debug,
"select_upper_lower: set %d selected\n",
setpos));
/* iso2022_change_helper_1 does both
iso2022_setid_stream() and lock_shift(), but does nothing
if bank is already occupied.
This function sets
output_state->bank[ID->bank] = setpos;
*/
c = iso2022_change_helper_1(output_state,*ID,setpos,NULL,0);
if (c) {
int l = strlen(c);
add_bytes_stream(ret,len,alloced,s2us(c),l);
#ifdef DEBUG
{
int x;
DPRINT(Debug,58,(&Debug,
"select_upper_lower: Setting %d to bank %d: ",
setpos,ID->bank));
for (x = 0; x < l; x++) {
DPRINT(Debug,58,(&Debug," %02x",c[x]));
}
DPRINT(Debug,58,(&Debug,"\n"));
}
if (Debug.active > 57)
printit++;
#endif
free(c);
}
}
/* If on bank have currently other set selected, change it */
if (ID->bank != bank_unspecified
&& output_state->bank[ID->bank] != setpos) {
char * c;
output_state->bank[ID->bank] = -1; /* Forget previous assignment */
c = iso2022_setid_stream(*ID,NULL,0);
if (c) {
int l = strlen(c);
/* iso2022_setid_stream() does not set this */
output_state->bank[ID->bank] = setpos;
add_bytes_stream(ret,len,alloced,s2us(c),l);
#ifdef DEBUG
{
int x;
DPRINT(Debug,58,(&Debug,
"select_upper_lower: Changing %d to bank %d: ",
setpos,ID->bank));
for (x = 0; x < l; x++) {
DPRINT(Debug,58,(&Debug," %02x",c[x]));
}
DPRINT(Debug,58,(&Debug," (width %d)\n",
output_state->width[setpos]
));
if (Debug.active > 57)
printit++;
}
#endif
free(c);
}
}
if (output_state->current_L == ID->bank)
is_upper = 0;
else if (output_state->current_R == ID->bank)
is_upper = 1;
else { /* If either left nor right is selected for this
bank currently, select left bank because
iso2022 sets are usually 7-bit only
*/
char buffer1[10];
char * c;
is_upper = 0;
output_state->current_L = ID->bank;
c = lock_shift(is_upper,output_state->current_L,
buffer1,sizeof buffer1);
if (c) {
int l = strlen(c);
add_bytes_stream(ret,len,alloced,s2us(c),l);
#ifdef DEBUG
{
int x;
DPRINT(Debug,58,(&Debug,
"select_upper_lower: setting %s to bank %d: ",
is_upper ? "upper" : "lower",
setpos));
for (x = 0; x < l; x++) {
DPRINT(Debug,58,(&Debug," %02x",c[x]));
}
DPRINT(Debug,58,(&Debug,"\n"));
if (Debug.active > 57)
printit++;
}
#endif
}
}
if (printit)
debug_display_settings(output_state,0,1);
*width = output_state->width[setpos];
return is_upper;
}
static void add_char_stream_helper P_((unsigned char **ret,
int *len,
int *alloced,
unsigned char *temp,
int temp_l,
int temp_size,
enum iso2022_settype type,
unsigned iso2022_word,
int is_upper
));
static void add_char_stream_helper(ret,len,alloced,temp,temp_l,temp_size,type,
iso2022_word,is_upper)
unsigned char **ret;
int *len;
int *alloced;
unsigned char *temp;
int temp_l;
int temp_size;
enum iso2022_settype type;
unsigned iso2022_word;
int is_upper;
{
switch(type) {
case iso2022_94:
if (iso2022_word < 1 || iso2022_word > 94)
panic("STRING PANIC",__FILE__,__LINE__,"add_char_stream_helper",
"Bad iso2022_94 character",0);
/* FALLTHRU */
case iso2022_96:
if (iso2022_word > 95)
panic("STRING PANIC",__FILE__,__LINE__,"add_char_stream_helper",
"Bad iso2022_96 character",0);
if (temp_l+1 > temp_size)
panic("STRING PANIC",__FILE__,__LINE__,"add_char_stream_helper",
"Overflow",0);
temp[temp_l++] = iso2022_word + 32 + (is_upper ? 128 : 0);
DPRINT(Debug,63,(&Debug,
"add_char_stream_helper: Adding 1-byte: %02x (%s) [iso2022_word %04x]\n",
temp[temp_l-1],
is_upper ? "upper" : "lower",
iso2022_word
));
add_bytes_stream(ret,len,alloced,temp,temp_l);
break;
case iso2022_94x94:
case iso2022_96x96:
if (iso2022_word > 96*96-1)
panic("STRING PANIC",__FILE__,__LINE__,"add_char_stream_helper",
"Bad iso2022_94x94 or iso2022_96x96 character",0);
if (temp_l+2 > temp_size)
panic("STRING PANIC",__FILE__,__LINE__,"add_char_stream_helper",
"Overflow",0);
temp[temp_l++] = iso2022_word/96 + 32 + (is_upper ? 128 : 0);
temp[temp_l++] = iso2022_word%96 + 32 + (is_upper ? 128 : 0);
DPRINT(Debug,63,(&Debug,
"add_char_stream_helper: Adding 2-byte: %02x %02x (%s) [iso2022_word %04x]\n",
temp[temp_l-2],temp[temp_l-1],
is_upper ? "upper" : "lower",
iso2022_word));
add_bytes_stream(ret,len,alloced,temp,temp_l);
break;
case iso2022_other:
if (iso2022_word < 256) {
if (temp_l+1 > temp_size)
panic("STRING PANIC",__FILE__,__LINE__,"add_char_stream_helper",
"Overflow",0);
temp[temp_l++] = iso2022_word; /* Not actually work correctly */
DPRINT(Debug,63,(&Debug,
"add_char_stream_helper: Adding other: %02x [iso2022_word %04x]\n",
temp[temp_l-1],
iso2022_word));
add_bytes_stream(ret,len,alloced,temp,temp_l);
break;
}
/* FALLTHRU */
default:
panic("STRING PANIC",__FILE__,__LINE__,"add_char_stream_helper",
"Unsupported iso2022 settype",0);
}
}
/* iso2022_word can't be uint16 because that causes error
messages about promotion ...
*/
typedef int add_char_stream_t P_((unsigned char **ret,
int *len,
int *alloced,
struct iso2022_setid *set,
screen_info_p output_state,
unsigned iso2022_word,
struct iso2022_setid *ctrlset,
struct cs_printable_len *printable_len));
/* Return 0 if overflow printable_len else 1 */
S_(add_char_stream_t add_char_stream_euc)
static int add_char_stream_euc(ret,len,alloced,set, output_state,iso2022_word,
ctrlset,printable_len)
unsigned char **ret;
int *len;
int *alloced;
struct iso2022_setid *set; /* NULL, if control characters */
screen_info_p output_state;
unsigned iso2022_word;
struct iso2022_setid *ctrlset; /* 'set' used when outputing control
characters */
struct cs_printable_len *printable_len;
{
int width = -1;
enum iso2022_bank bank = bank_unspecified;
struct iso2022_setid ID;
if (set) {
int i;
ID = *set;
i = iso2022_give_setpos(&ID,output_state);
bank = ID.bank;
if (i < 0 || bank_unspecified == bank) {
/* BAD */
DPRINT(Debug,9,(&Debug,
"add_char_stream_euc: Bad bank or set? (printing space instead)\n"));
iso2022_word = 32;
set = NULL;
goto restart;
}
width = output_state->width[i];
} else {
/* iso2022_word is character itself */
restart:
if (32 == iso2022_word) { /* SPACE */
width = 1;
} else { /* Control characters have no width */
width = 0;
}
}
if (printable_len && width < 0) {
DPRINT(Debug,9,(&Debug,
"add_char_stream_euc: Can't print character because width is not available (printing space instead) [width=%d]\n",
width));
iso2022_word = 32;
set = NULL;
goto restart;
}
if (printable_len &&
printable_len->max_len < printable_len->ret_len + width) {
DPRINT(Debug,9,(&Debug,
"add_char_stream_euc: No space for character ret_len=%d width=%d max_len=%d\n",
printable_len->ret_len,width,printable_len->max_len));
return 0;
}
if (set) {
int l = 0;
unsigned char temp[5];
int is_upper = -1;
if (bank == bank_unspecified) {
DPRINT(Debug,9,(&Debug,
"add_char_stream_euc: No bank (printing space instead)\n"));
iso2022_word = 32;
set = NULL;
goto restart;
}
if (bank == output_state->current_L)
is_upper = 0;
else if (bank == output_state->current_R)
is_upper = 1;
else {
is_upper = 1;
if ((l = do_single_shift(temp,sizeof temp,bank,is_upper)) < 1) {
DPRINT(Debug,9,(&Debug,
"add_char_stream_euc: Can't single shift to bank %d (printing space instead), ret=%d\n",
bank,l));
iso2022_word = 32;
set = NULL;
goto restart;
}
}
add_char_stream_helper(ret,len,alloced, temp,l,sizeof temp,ID.type,
iso2022_word,is_upper);
} else {
unsigned char temp[1];
/* We are printing control characters or space
iso2022_word is character itself
-- BAD characters are also stored as control
characters therefore all codes between 0 - 255
are possible.
*/
if (iso2022_word > 255)
panic("STRING PANIC",__FILE__,__LINE__,"add_char_stream_euc",
"Bad control character",0);
temp[0] = iso2022_word;
DPRINT(Debug,63,(&Debug,
"add_char_stream_euc: Adding ctrl: %02x [iso2022_word %04x]\n",
temp[0],iso2022_word));
add_bytes_stream(ret,len,alloced,temp,1);
}
if (printable_len)
printable_len->ret_len += width;
return 1;
}
/* Return 0 if overflow printable_len else 1 */
S_(add_char_stream_t add_char_stream)
static int add_char_stream(ret,len,alloced,set, output_state,iso2022_word,
ctrlset,printable_len)
unsigned char **ret;
int *len;
int *alloced;
struct iso2022_setid *set; /* NULL, if control characters */
screen_info_p output_state;
unsigned iso2022_word;
struct iso2022_setid *ctrlset; /* 'set' used when outputing control
characters */
struct cs_printable_len *printable_len;
{
int is_upper;
struct iso2022_setid ID;
int have_id;
int width;
restart:
have_id = 0;
is_upper = 0;
ID.bank = bank_unspecified;
ID.type = iso2022_other;
if (!set) {
/* If set is NULL, then we have ouputting control characters
(or space). Most ISO-2022-x mime sets require that we switch
ascii before outputting control characters (or space) -- in that
case iso2022_word is control character itself. */
/* ASCII must be first set declared so that works correctly */
if (ctrlset) {
ID = *ctrlset; /* ASCII? */
have_id++;
}
} else {
ID = *set;
have_id++;
}
width = 1;
if (have_id)
is_upper = select_upper_lower(ret,len,alloced,&ID,output_state,&width);
if (!set) {
/* iso2022_word is character itself */
if (32 == iso2022_word) { /* SPACE */
if (width < 1) width = 1;
} else { /* COntrol characters have no width */
width = 0;
}
}
if (printable_len && width < 0) {
DPRINT(Debug,9,(&Debug,
"add_char_stream: Can't print character because width is not available (printing space instead) [width=%d]\n",
width));
iso2022_word = 32;
set = NULL;
goto restart;
}
if (printable_len &&
printable_len->max_len < printable_len->ret_len + width) {
DPRINT(Debug,9,(&Debug,
"add_char_stream: No space for character ret_len=%d width=%d max_len=%d\n",
printable_len->ret_len,width,printable_len->max_len));
return 0;
}
if (!set) {
unsigned char temp[1];
/* We are printing control characters or space
iso2022_word is character itself
-- BAD characters are also stored as control
characters therefore all codes between 0 - 255
are possible.
*/
if (iso2022_word > 255)
panic("STRING PANIC",__FILE__,__LINE__,"add_char_stream",
"Bad control character",0);
temp[0] = iso2022_word;
DPRINT(Debug,63,(&Debug,
"add_char_stream: Adding ctrl: %02x [iso2022_word %04x]\n",
temp[0],iso2022_word));
add_bytes_stream(ret,len,alloced,temp,1);
} else if (!have_id)
panic("STRING PANIC",__FILE__,__LINE__,"add_char_stream",
"have_id is not set",0);
else {
unsigned char temp[2];
add_char_stream_helper(ret,len,alloced, temp,0,sizeof temp,ID.type,
iso2022_word,is_upper);
}
if (printable_len)
printable_len->ret_len += width;
return 1;
}
/* Find ASCII bank (or other similar) */
static struct iso2022_setid *find_ctrlset P_((struct setlist * iso2022_info));
static struct iso2022_setid *find_ctrlset(iso2022_info)
struct setlist * iso2022_info;
{
int i;
struct iso2022_setid *ctrlset = NULL;
for (i = 0;
i < sizeof (iso2022_info->sets) / sizeof (iso2022_info->sets[0]);
i++) {
if (iso2022_info->sets[i]) {
/* Find ASCII bank (or other similar) */
if (iso2022_94 == iso2022_info->sets[i]->type &&
bank_G0 == iso2022_info->sets[i]->bank) {
ctrlset = iso2022_info->sets[i];
break;
}
}
}
return ctrlset;
}
typedef void charset_reset_routine P_((unsigned char **ret,
int *len,
int *alloced,
screen_info_p output_state,
struct setlist * iso2022_info));
S_(charset_reset_routine reset_iso2022)
static void reset_iso2022(ret,len,alloced,output_state,iso2022_info)
unsigned char **ret;
int *len;
int *alloced;
screen_info_p output_state;
struct setlist * iso2022_info;
{
int i;
output_state->current_L = bank_unspecified;
output_state->current_R = bank_unspecified;
for (i = 0;
i < sizeof (output_state->bank) /
sizeof (output_state->bank[0]);
i++)
output_state->bank[i] = -1;
SIGDPRINT(Debug,8,(&Debug,
"reset_iso2022: Doing initial ISO 2022 assignments\n"));
if (bank_unspecified != iso2022_info->initial_L) {
char *c;
output_state->current_L = iso2022_info->initial_L;
c = lock_shift(0,output_state->current_L,NULL,0);
if (c) {
int l = strlen(c);
add_bytes_stream(ret,len,alloced,s2us(c),l);
#ifdef DEBUG
{
int x;
DPRINT(Debug,58,(&Debug,
"reset_iso2022: setting left to bank %d: ",
output_state->current_L));
for (x = 0; x < l; x++) {
DPRINT(Debug,58,(&Debug," %02x",c[x]));
}
DPRINT(Debug,58,(&Debug,"\n"));
}
#endif
free(c);
}
}
if (bank_unspecified != iso2022_info->initial_R) {
char *c;
output_state->current_R = iso2022_info->initial_R;
c = lock_shift(1,output_state->current_R,NULL,0);
if (c) {
int l = strlen(c);
add_bytes_stream(ret,len,alloced,s2us(c),l);
#ifdef DEBUG
{
int x;
DPRINT(Debug,58,(&Debug,
"reset_iso2022: setting rigth to bank %d: ",
output_state->current_R));
for (x = 0; x < l; x++) {
DPRINT(Debug,58,(&Debug," %02x",c[x]));
}
DPRINT(Debug,58,(&Debug,"\n"));
}
#endif
free(c);
}
}
for (i = 0;
i < sizeof (iso2022_info->initial_bank) /
sizeof (iso2022_info->initial_bank[0]);
i++) {
int x = iso2022_info->initial_bank[i];
if (-1 != x) {
struct iso2022_setid ID;
char *c = NULL;
if (x < 0 ||
x >= sizeof (iso2022_info->sets) /
sizeof (iso2022_info->sets[0]) ||
! iso2022_info->sets[x])
panic("STRING PANIC",__FILE__,__LINE__,
"reset_iso2022",
"Bad initial_bank (set)",
0);
ID = * (iso2022_info->sets[x]);
if (ID.bank != i)
panic("STRING PANIC",__FILE__,__LINE__,
"reset_iso2022",
"Bad initial_bank (bank number)",
0);
set_initial_bank(&c,ID,output_state,NULL,0,0);
if (c) {
int l = strlen(c);
add_bytes_stream(ret,len,alloced,s2us(c),l);
#ifdef DEBUG
{
int x;
DPRINT(Debug,58,(&Debug,
"reset_iso2022: setting initial bank %d: ",
i));
for (x = 0; x < l; x++) {
DPRINT(Debug,58,(&Debug," %02x",c[x]));
}
DPRINT(Debug,58,(&Debug,"\n"));
}
#endif
free(c);
}
}
}
}
S_(charset_reset_routine reset_euc)
static void reset_euc(ret,len,alloced,output_state,iso2022_info)
unsigned char **ret;
int *len;
int *alloced;
screen_info_p output_state;
struct setlist * iso2022_info;
{
/* NO reset on EUC ! */
return;
}
/* Return -1 when must quit */
static int add_char1_stream_GEN P_((add_char_stream_t *ADD_CHAR_STREAM,
unsigned char **ret,
int *len,
int *alloced,
screen_info_p output_state,
struct setlist * iso2022_info,
struct map_info * map_info,
struct iso2022_setid * ctrlset,
int printable,
struct mb_data_part * part,
int j,
int * need_reset,
struct cs_printable_len *printable_len,
charset_reset_routine *RESET_ROUTINE
));
static int add_char1_stream_GEN(ADD_CHAR_STREAM,
ret,len,alloced,output_state,iso2022_info,map_info,
ctrlset,printable,part,j,need_reset,printable_len,
RESET_ROUTINE
)
add_char_stream_t * ADD_CHAR_STREAM;
unsigned char ** ret;
int * len;
int * alloced;
screen_info_p output_state;
struct setlist * iso2022_info;
struct map_info * map_info;
struct iso2022_setid * ctrlset;
int printable;
struct mb_data_part * part;
int j;
int * need_reset;
struct cs_printable_len * printable_len;
charset_reset_routine *RESET_ROUTINE;
{
int char_added = 0;
if (*need_reset) {
RESET_ROUTINE(ret,len,alloced,output_state,iso2022_info);
*need_reset = 0;
}
switch (part->set_index) {
case -1: /* control characters , (also space with 94, 94x94 sets)
*/
if (printable && 32 != part->words[j])
goto bad_char;
if (ADD_CHAR_STREAM(ret,len,alloced,NULL,output_state,
part->words[j],ctrlset,printable_len) < 1) {
return -1;
}
char_added++;
if (part->words[j] < 32) {
/*
Reapply lock shifts and bank assigments after controls
so that these appear on every line (at least)
*/
*need_reset = 1;
}
break;
case -2: /* bad iso2022 bank */
bad_char:
if (iso2022_info && map_info) {
int index;
enum iso2022_settype type;
uint16 iso2022_word;
if (map_unicode_to_ISO2022_word(0x003F /* '?' */,
iso2022_info,
&index,&type,&iso2022_word,
map_info)
&& index >= 0) {
if (index > sizeof (iso2022_info->sets) /
sizeof (iso2022_info->sets[0]) ||
! iso2022_info->sets[index])
panic("ISO2022 PANIC",__FILE__,__LINE__,"add_char1_stream_GEN",
"Bad index",0);
if (ADD_CHAR_STREAM(ret,len,alloced,
iso2022_info->sets[index],
output_state,
iso2022_word,
ctrlset,printable_len) < 1) {
return -1;
}
char_added++;
break;
}
}
if (ctrlset) { /* We can add space instead */
if (ADD_CHAR_STREAM(ret,len,alloced,NULL,output_state,32,ctrlset,printable_len) < 1) {
return -1;
}
char_added++;
}
break;
default:
if (printable) {
/* Require printable character */
int iso2022_map_index = part->iso2022_map_index;
if (-1 != iso2022_map_index) {
uint16 code;
int found = map_ISO2022_word_to_unicode(part->words[j],
part->type,
iso2022_map_index,
&code);
if (!found)
goto bad_char; /* No mapping available */
if (!unicode_ch(code,UOP_printable))
goto bad_char; /* Not printable */
} else
goto bad_char; /* No mapping available */
}
if (ADD_CHAR_STREAM(ret,len,alloced,
iso2022_info->sets[part->set_index],
output_state,
part->words[j],ctrlset,printable_len) < 1) {
return -1;
}
char_added++;
break;
}
return char_added;
}
/* Return -1 when must quit */
static int add_char1_stream P_((unsigned char **ret,
int *len,
int *alloced,
screen_info_p output_state,
struct setlist * iso2022_info,
struct map_info * map_info,
struct iso2022_setid * ctrlset,
int printable,
struct mb_data_part * part,
int j,
int * need_reset,
struct cs_printable_len *printable_len));
static int add_char1_stream(ret,len,alloced,output_state,iso2022_info,map_info,
ctrlset,printable,part,j,need_reset,printable_len)
unsigned char **ret;
int *len;
int *alloced;
screen_info_p output_state;
struct setlist * iso2022_info;
struct map_info * map_info;
struct iso2022_setid * ctrlset;
int printable;
struct mb_data_part * part;
int j;
int * need_reset;
struct cs_printable_len *printable_len;
{
return add_char1_stream_GEN(add_char_stream,
ret,len,alloced,output_state,iso2022_info,map_info,
ctrlset,printable,part,j,need_reset,printable_len,
reset_iso2022
);
}
static void fill_euc_state P_((screen_info_p output_state,
struct setlist *iso2022_info));
static void fill_euc_state(output_state,iso2022_info)
screen_info_p output_state;
struct setlist *iso2022_info;
{
int i;
if (bank_unspecified != iso2022_info->initial_L)
output_state->current_L = iso2022_info->initial_L;
else
output_state->current_L = bank_G0;
if (bank_unspecified != iso2022_info->initial_R)
output_state->current_R = iso2022_info->initial_R;
else
output_state->current_R = bank_G1;
output_state->set_count = 0;
for (i =0;
i < sizeof (iso2022_info->sets) / sizeof (iso2022_info->sets[0]) &&
iso2022_info->sets[i];
i++) {
enum iso2022_bank bank = iso2022_info->sets[i]->bank;
int num = -1;
int j;
if (bank_unspecified == bank) {
if (iso2022_94 == iso2022_info->sets[i]->type &&
-1 == output_state->bank[0])
bank = bank_G0;
}
for (j = 0;
j < output_state->set_count;
j++) {
if (output_state->sets[j].type == iso2022_info->sets[i]->type &&
0 == strncmp(us2s(output_state->sets[j].bytes),
us2s(iso2022_info->sets[i]->bytes),
sizeof (output_state->sets[j].bytes))) {
DPRINT(Debug,6,(&Debug,
"fill_euc_state: same set given several times\n"));
num = j;
break;
}
}
if (-1 == num) {
if (output_state->set_count +1 >=
sizeof(output_state->sets) / sizeof(output_state->sets[0]))
panic("ISO2022 PANIC",__FILE__,__LINE__,"fill_euc_state",
"Too many sets",0);
num = output_state->set_count;
output_state->sets[num].bank = bank; /* Not needed */
output_state->sets[num].type = iso2022_info->sets[i]->type;
memcpy(output_state->sets[num].bytes,
iso2022_info->sets[i]->bytes,
sizeof (output_state->sets[num].bytes));
output_state->set_count++;
}
if (bank >= 0 && bank < ISO2022_BANK_NUM) {
if (-1 != output_state->bank[bank])
panic("ISO2022 PANIC",__FILE__,__LINE__,"fill_euc_state",
"Multiple sets on bank",0);
output_state->bank[bank] = num;
}
}
DPRINT(Debug,9,(&Debug,
"fill_euc_state: %d sets\n",output_state->set_count));
}
S_(cs_stream_from_string cs_stream_from_euc)
static unsigned char * cs_stream_from_euc(str,printable,terminal,reslen)
CONST struct string *str;
int printable;
screen_info_p terminal;
int *reslen;
{
screen_info_p output_state = terminal;
int alloced = str->p->len+1;
unsigned char * ret = safe_malloc(alloced);
int RESLEN = 0;
int i;
int need_reset = 0;
struct mb_data * X1 = str->p->a.data;
struct iso2022_setid *ctrlset = NULL;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_stream_from_euc",
"Bad magic number (string)",0);
if (!output_state) {
output_state = create_terminal_info();
if (str->string_type->iso2022_info)
fill_euc_state(output_state,str->string_type->iso2022_info);
}
if (DISPLAY_STATE_magic != output_state->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_stream_from_euc",
"Bad magic number (output state)",0);
/* Fill indexes if current not filled */
if (printable &&
str->string_type->map_info && str->string_type->iso2022_info)
fill_iso2022_map_index(str->string_type->iso2022_info,
X1,
str->string_type->map_info);
/* Find ASCII bank (or other similar) */
if (str->string_type->iso2022_info)
ctrlset = find_ctrlset(str->string_type->iso2022_info);
for (i = 0; i < X1->part_count; i++) {
int j;
#ifdef DEBUG
DPRINT(Debug,59,(&Debug,
"cs_stream_from_euc: %d: type=%d set_index=%d <",
i,X1->parts[i].type, X1->parts[i].set_index));
if (Debug.active > 58 && str->string_type->iso2022_info)
debug_iso2022_info_index(59,X1->parts[i].set_index,
str->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,">\n"));
#endif
switch (X1->parts[i].set_index) {
case -1:
DPRINT(Debug,58,(&Debug,
"cs_stream_from_euc: %d control characters\n",
X1->parts[i].word_count));
if (iso2022_other != X1->parts[i].type)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_stream_from_euc",
"Bad type for control characters",0);
break;
case -2:
DPRINT(Debug,58,(&Debug,
"cs_stream_from_iso2022: %d bad characters\n",
X1->parts[i].word_count));
break;
default:
DPRINT(Debug,58,(&Debug,
"cs_stream_from_euc: %d characters from set %d\n",
X1->parts[i].word_count,
X1->parts[i].set_index));
if (X1->parts[i].set_index < 0 ||
!str->string_type->iso2022_info ||
X1->parts[i].set_index > sizeof (str->string_type->iso2022_info->sets) /
sizeof (str->string_type->iso2022_info->sets[0]) ||
! str->string_type->iso2022_info->sets[X1->parts[i].set_index])
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_stream_from_euc",
"Bad set_index",0);
break;
}
for (j = 0; j < X1->parts[i].word_count; j++) {
int r = add_char1_stream_GEN(add_char_stream_euc,
&ret,&RESLEN,&alloced,output_state,
str->string_type->iso2022_info,
str->string_type->map_info,
ctrlset,printable,& (X1->parts[i]),j,
&need_reset,NULL,
reset_euc
);
if (r < 0) {
goto out;
}
}
}
out:
#if 0 /* NOT needed on EUC? */
/* Reset to 94 bank */
if (ctrlset) {
struct iso2022_setid ID = *ctrlset; /* ASCII? */
int width;
DPRINT(Debug,63,(&Debug,
"cs_stream_from_iso2022: Returning to 94 bank\n"));
select_upper_lower(&ret,&RESLEN,&alloced,&ID,output_state,&width);
}
#endif
if (output_state != terminal)
free_terminal_info(&output_state);
*reslen = RESLEN; /* Do not count final \0 to reslen */
{
unsigned char temp[1];
temp[0] = '\0';
add_bytes_stream(&ret,&RESLEN,&alloced,temp,1);
}
return ret;
}
S_(cs_stream_from_string cs_stream_from_iso2022)
static unsigned char * cs_stream_from_iso2022(str,printable,terminal,reslen)
CONST struct string *str;
int printable;
screen_info_p terminal;
int *reslen;
{
screen_info_p output_state = terminal;
int alloced = str->p->len+1;
unsigned char * ret = safe_malloc(alloced);
int RESLEN = 0;
int i;
int need_reset = 0;
struct mb_data * X1 = str->p->a.data;
struct iso2022_setid *ctrlset = NULL;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_stream_from_iso2022",
"Bad magic number (string)",0);
if (!output_state) {
output_state = create_terminal_info();
}
if (DISPLAY_STATE_magic != output_state->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_stream_from_iso2022",
"Bad magic number (output state)",0);
/* Fill indexes if current not filled */
if (printable &&
str->string_type->map_info && str->string_type->iso2022_info)
fill_iso2022_map_index(str->string_type->iso2022_info,
X1,
str->string_type->map_info);
/* Find ASCII bank (or other similar) */
if (str->string_type->iso2022_info)
ctrlset = find_ctrlset(str->string_type->iso2022_info);
for (i = 0; i < X1->part_count; i++) {
int j;
#ifdef DEBUG
DPRINT(Debug,59,(&Debug,
"cs_stream_from_iso2022: %d: type=%d set_index=%d <",
i,X1->parts[i].type, X1->parts[i].set_index));
if (Debug.active > 58 && str->string_type->iso2022_info)
debug_iso2022_info_index(59,X1->parts[i].set_index,
str->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,">\n"));
#endif
switch (X1->parts[i].set_index) {
case -1:
DPRINT(Debug,58,(&Debug,
"cs_stream_from_iso2022: %d control characters\n",
X1->parts[i].word_count));
if (iso2022_other != X1->parts[i].type)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_stream_from_iso2022",
"Bad type for control characters",0);
break;
case -2:
DPRINT(Debug,58,(&Debug,
"cs_stream_from_iso2022: %d bad characters\n",
X1->parts[i].word_count));
break;
default:
DPRINT(Debug,58,(&Debug,
"cs_stream_from_iso2022: %d characters from set %d\n",
X1->parts[i].word_count,
X1->parts[i].set_index));
if (X1->parts[i].set_index < 0 ||
!str->string_type->iso2022_info ||
X1->parts[i].set_index > sizeof (str->string_type->iso2022_info->sets) /
sizeof (str->string_type->iso2022_info->sets[0]) ||
! str->string_type->iso2022_info->sets[X1->parts[i].set_index])
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_stream_from_iso2022",
"Bad set_index",0);
break;
}
for (j = 0; j < X1->parts[i].word_count; j++) {
int r = add_char1_stream(&ret,&RESLEN,&alloced,output_state,
str->string_type->iso2022_info,
str->string_type->map_info,
ctrlset,printable,& (X1->parts[i]),j,
&need_reset,NULL);
if (r < 0) {
goto out;
}
}
}
out:
/* Reset to 94 bank */
if (ctrlset) {
struct iso2022_setid ID = *ctrlset; /* ASCII? */
int width;
DPRINT(Debug,63,(&Debug,
"cs_stream_from_iso2022: Returning to 94 bank\n"));
select_upper_lower(&ret,&RESLEN,&alloced,&ID,output_state,&width);
}
if (output_state != terminal)
free_terminal_info(&output_state);
*reslen = RESLEN; /* Do not count final \0 to reslen */
{
unsigned char temp[1];
temp[0] = '\0';
add_bytes_stream(&ret,&RESLEN,&alloced,temp,1);
}
return ret;
}
S_(cs_can_ascii_string cs_can_ascii_iso2022_gen)
static int cs_can_ascii_iso2022_gen(str)
CONST struct string *str;
{
struct mb_data * X1 = str->p->a.data;
int i;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_can_ascii_iso2022_gen",
"Bad magic number (string)",0);
/* Fill indexes if current not filled */
if (str->string_type->map_info && str->string_type->iso2022_info)
fill_iso2022_map_index(str->string_type->iso2022_info,
X1,
str->string_type->map_info);
for (i = 0; i < X1->part_count; i++) {
int j;
#ifdef DEBUG
DPRINT(Debug,59,(&Debug,
"cs_can_ascii_iso2022_gen: %d: type=%d set_index=%d <",
i,X1->parts[i].type, X1->parts[i].set_index));
if (Debug.active > 58 && str->string_type->iso2022_info)
debug_iso2022_info_index(59,X1->parts[i].set_index,
str->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,">\n"));
#endif
switch (X1->parts[i].set_index) {
case -1:
if (iso2022_other != X1->parts[i].type)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_can_ascii_iso2022_gen",
"Bad type for control characters",0);
break;
case -2:
return 0; /* Unknown bank -- can not convert to ascii
(well, we can not output this either ... so is this correct?
we anyway output '?' on here...)
*/
default:
if (X1->parts[i].set_index < 0 ||
!str->string_type->iso2022_info ||
X1->parts[i].set_index > sizeof (str->string_type->iso2022_info->sets) /
sizeof (str->string_type->iso2022_info->sets[0]) ||
! str->string_type->iso2022_info->sets[X1->parts[i].set_index])
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_can_ascii_iso2022_gen",
"Bad set_index",0);
break;
}
for (j = 0; j < X1->parts[i].word_count; j++) {
switch (X1->parts[i].set_index) {
int iso2022_map_index; /* index to iso2022_map_list[] */
case -1: /* control characters , (also space with 94, 94x94 sets)
*/
if (X1->parts[i].words[j] > 127)
return 0; /* If C1 control area */
break;
default:
iso2022_map_index = X1->parts[i].iso2022_map_index;
if (-1 != iso2022_map_index) {
uint16 code;
int found = map_ISO2022_word_to_unicode(X1->parts[i].words[j],
X1->parts[i].type,
iso2022_map_index,
&code);
if (!found || code > 127)
return 0; /* Not ASCII */
} else
return 0; /* No mapping available */
break;
}
}
}
return 1; /* No NON-ASCII character found */
}
static int may_add P_((int width, struct cs_printable_len *printable_len));
static int may_add(width,printable_len)
int width;
struct cs_printable_len *printable_len;
{
if (printable_len->max_len < printable_len->ret_len + width)
return 0;
printable_len->ret_len += width;
return 1;
}
static int may_add_from_set P_((struct iso2022_setid *set,
screen_info_p output_state,
struct cs_printable_len *printable_len));
static int may_add_from_set(set,output_state,printable_len)
struct iso2022_setid *set;
screen_info_p output_state;
struct cs_printable_len *printable_len;
{
struct iso2022_setid ID = *set;
int setpos = iso2022_give_setpos(&ID,output_state);
int r;
if (setpos < 0) {
DPRINT(Debug,49,(&Debug,
"may_add_from_set: setpos = %d no information for estimating of width\n",
setpos));
return -1;
}
if (output_state->width[setpos] < 0) {
DPRINT(Debug,49,(&Debug,
"may_add_from_set: setpos = %d, width = %d no information for estimating of width\n",
setpos,output_state->width[setpos]));
return -1;
}
r = may_add(output_state->width[setpos],printable_len);
return r;
}
/* Return number of characters consumed */
S_(cs_estimate_clip_string cs_estimate_clip_iso2022)
static int cs_estimate_clip_iso2022(str,pos,len,terminal,printable_len)
CONST struct string *str;
int pos;
int len; /* UPPER LIMIT */
screen_info_p terminal;
struct cs_printable_len *printable_len;
{
struct mb_data * X1 = str->p->a.data;
int block_number = 0;
int block_index = pos;
int counter = 0;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_estimate_clip_iso2022",
"Bad magic number (string)",0);
printable_len->ret_len = 0;
/* Fill indexes if current not filled */
if (str->string_type->map_info && str->string_type->iso2022_info)
fill_iso2022_map_index(str->string_type->iso2022_info,
X1,
str->string_type->map_info);
if (!pos_to_block(X1,pos,&block_number,&block_index))
return 0; /* No characters consumed */
while (block_number < X1->part_count && counter < len) {
#ifdef DEBUG
DPRINT(Debug,59,(&Debug,
"cs_estimate_clip_iso2022: %d: type=%d set_index=%d <",
block_number,X1->parts[block_number].type,
X1->parts[block_number].set_index));
if (Debug.active > 58 && str->string_type->iso2022_info)
debug_iso2022_info_index(59,X1->parts[block_number].set_index,
str->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,">\n"));
#endif
switch (X1->parts[block_number].set_index) {
case -1:
DPRINT(Debug,58,(&Debug,
"cs_estimate_clip_iso2022: %d control characters\n",
X1->parts[block_number].word_count - block_index));
if (iso2022_other != X1->parts[block_number].type)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_estimate_clip_iso2022",
"Bad type for control characters",0);
break;
case -2:
DPRINT(Debug,58,(&Debug,
"cs_estimate_clip_iso2022: %d bad characters\n",
X1->parts[block_number].word_count - block_index));
goto bail_out;
default:
DPRINT(Debug,58,(&Debug,
"cs_estimate_clip_iso2022: %d characters from set %d\n",
X1->parts[block_number].word_count - block_index,
X1->parts[block_number].set_index));
if (X1->parts[block_number].set_index < 0 ||
!str->string_type->iso2022_info ||
X1->parts[block_number].set_index > sizeof (str->string_type->iso2022_info->sets) /
sizeof (str->string_type->iso2022_info->sets[0]) ||
! str->string_type->iso2022_info->sets[X1->parts[block_number].set_index])
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_estimate_clip_iso2022",
"Bad set_index",0);
break;
}
while (block_index < X1->parts[block_number].word_count
&& counter < len) {
switch (X1->parts[block_number].set_index) {
case -1: /* control characters , (also space with 94, 94x94 sets)
*/
/* However do not handle controls */
if (32 != X1->parts[block_number].words[block_index])
goto bail_out;
/* Asumed that space have width 1 always */
if (!may_add(1,printable_len)) {
DPRINT(Debug,49,(&Debug,
"cs_estimate_clip_iso2022: %d: ended at at %d, counter=%d (ctrl)\n",
block_number,block_index,counter));
goto out;
}
counter++;
break;
case -2:
/* Not occur */
break;
default:
if (-1 == X1->parts[block_number].iso2022_map_index ||
!str->string_type->iso2022_info) {
DPRINT(Debug,49,(&Debug,
"cs_estimate_clip_iso2022: iso2022_map_index=%d or no iso2022_info\n",
X1->parts[block_number].iso2022_map_index));
goto bail_out;
} else {
uint16 code;
int r;
int found = map_ISO2022_word_to_unicode(X1->parts[block_number].words[block_index],
X1->parts[block_number].type,
X1->parts[block_number].iso2022_map_index,
&code);
if (!found) {
DPRINT(Debug,49,(&Debug,
"cs_estimate_clip_iso2022: %d: at %d, counter=%d -- iso2022 character %04x type %d with map index %d not found\n",
block_number,block_index,counter,
X1->parts[block_number].words[block_index],
X1->parts[block_number].type,
X1->parts[block_number].iso2022_map_index));
goto bail_out; /* No mapping available */
}
if (!unicode_ch(code,UOP_printable)) {
DPRINT(Debug,49,(&Debug,
"cs_estimate_clip_iso2022: %d: at %d, counter=%d -- unicode character %04x not printable\n",
block_number,block_index,counter,code));
goto bail_out; /* Not printable */
}
r = may_add_from_set(str->string_type->iso2022_info->
sets[X1->parts[block_number].set_index],
terminal,
printable_len);
if (r < 0)
goto bail_out;
if (!r) {
DPRINT(Debug,49,(&Debug,
"cs_estimate_clip_iso2022: %d: ended at at %d, counter=%d (no space)\n",
block_number,block_index,counter));
goto out;
}
counter++;
}
break;
}
block_index++;
}
block_number++;
block_index = 0;
}
out:
return counter;
bail_out:
DPRINT(Debug,49,(&Debug,
"cs_estimate_clip_iso2022: %d: bailing out at %d, counter=%d\n",
block_number,block_index,counter));
if (counter > 0)
return counter;
return -1;
}
S_(cs_streamclip_from_string cs_streamclip_from_euc)
static unsigned char * cs_streamclip_from_euc(str,pos,len,terminal,printable_len)
CONST struct string *str;
int *pos;
int len;
screen_info_p terminal;
struct cs_printable_len *printable_len;
{
screen_info_p output_state = terminal;
struct mb_data * X1 = str->p->a.data;
int block_number = 0;
int block_index = *pos;
int start_pos = *pos;
int alloced = 0;
unsigned char * ret = NULL;
int RESLEN = 0;
struct iso2022_setid *ctrlset = NULL;
int need_reset = 0;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_streamclip_from_euc",
"Bad magic number (string)",0);
if (*pos < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_streamclip_from_euc",
"Index out of array",0);
if (len < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_streamclip_from_euc",
"Negative size",0);
if (printable_len)
printable_len->ret_len = 0;
if (!pos_to_block(X1,*pos,&block_number,&block_index)) {
unsigned char * S = safe_malloc(1);
*S = '\0';
return S;
}
alloced = len+1;
ret = safe_malloc(alloced);
if (!output_state) {
output_state = create_terminal_info();
if (str->string_type->iso2022_info)
fill_euc_state(output_state,str->string_type->iso2022_info);
}
/* Fill indexes if current not filled */
if (str->string_type->map_info && str->string_type->iso2022_info)
fill_iso2022_map_index(str->string_type->iso2022_info,
X1,
str->string_type->map_info);
/* Find ASCII bank (or other similar) */
if (str->string_type->iso2022_info)
ctrlset = find_ctrlset(str->string_type->iso2022_info);
while (block_number < X1->part_count && *pos - start_pos < len) {
#ifdef DEBUG
DPRINT(Debug,59,(&Debug,
"cs_streamclip_from_euc: %d: type=%d set_index=%d <",
block_number,X1->parts[block_number].type,
X1->parts[block_number].set_index));
if (Debug.active > 58 && str->string_type->iso2022_info)
debug_iso2022_info_index(59,X1->parts[block_number].set_index,
str->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,">\n"));
#endif
switch (X1->parts[block_number].set_index) {
case -1:
DPRINT(Debug,58,(&Debug,
"cs_streamclip_from_euc: %d control characters\n",
X1->parts[block_number].word_count - block_index,
X1->parts[block_number].set_index));
if (iso2022_other != X1->parts[block_number].type)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_streamclip_from_euc",
"Bad type for control characters",0);
break;
case -2:
DPRINT(Debug,58,(&Debug,
"cs_streamclip_from_euc: %d bad characters\n",
X1->parts[block_number].word_count - block_index,
X1->parts[block_number].set_index));
break;
default:
DPRINT(Debug,58,(&Debug,
"cs_streamclip_from_euc: %d characters from set %d\n",
X1->parts[block_number].word_count - block_index,
X1->parts[block_number].set_index));
if (X1->parts[block_number].set_index < 0 ||
!str->string_type->iso2022_info ||
X1->parts[block_number].set_index > sizeof (str->string_type->iso2022_info->sets) /
sizeof (str->string_type->iso2022_info->sets[0]) ||
! str->string_type->iso2022_info->sets[X1->parts[block_number].set_index])
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_streamclip_from_euc",
"Bad set_index",0);
break;
}
while (block_index < X1->parts[block_number].word_count
&& *pos - start_pos < len) {
int r = add_char1_stream_GEN(add_char_stream_euc,
&ret,&RESLEN,&alloced,output_state,
str->string_type->iso2022_info,
str->string_type->map_info,
ctrlset,1,& (X1->parts[block_number]),
block_index,&need_reset,printable_len,
reset_euc
);
if (r < 0)
goto out;
if (r > 0) {
/* nothing to count */
} else {
DPRINT(Debug,1,(&Debug,
"cs_streamclip_from_euc: FAILED to add char to steam\n"));
}
block_index++;
(*pos)++;
}
block_index = 0;
block_number++;
}
out:
#if 0 /* NOT needed on EUC? */
/* Reset to 94 bank
*/
if (ctrlset) {
struct iso2022_setid ID = *ctrlset; /* ASCII? */
int width;
DPRINT(Debug,63,(&Debug,
"cs_streamclip_from_euc: Returning to 94 bank\n"));
select_upper_lower(&ret,&RESLEN,&alloced,&ID,output_state,&width);
}
#endif
if (output_state != terminal)
free_terminal_info(&output_state);
{
unsigned char temp[1];
temp[0] = '\0';
add_bytes_stream(&ret,&RESLEN,&alloced,temp,1);
}
return ret;
}
S_(cs_streamclip_from_string cs_streamclip_from_iso2022)
static unsigned char * cs_streamclip_from_iso2022(str,pos,len,terminal,printable_len)
CONST struct string *str;
int *pos;
int len;
screen_info_p terminal;
struct cs_printable_len *printable_len;
{
screen_info_p output_state = terminal;
struct mb_data * X1 = str->p->a.data;
int block_number = 0;
int block_index = *pos;
int start_pos = *pos;
int alloced = 0;
unsigned char * ret = NULL;
int RESLEN = 0;
struct iso2022_setid *ctrlset = NULL;
int need_reset = 0;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_streamclip_from_iso2022",
"Bad magic number (string)",0);
if (*pos < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_streamclip_from_iso2022",
"Index out of array",0);
if (len < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_streamclip_from_iso2022",
"Negative size",0);
if (printable_len)
printable_len->ret_len = 0;
if (!pos_to_block(X1,*pos,&block_number,&block_index)) {
unsigned char * S = safe_malloc(1);
*S = '\0';
return S;
}
alloced = len+1;
ret = safe_malloc(alloced);
if (!output_state) {
output_state = create_terminal_info();
}
/* Fill indexes if current not filled */
if (str->string_type->map_info && str->string_type->iso2022_info)
fill_iso2022_map_index(str->string_type->iso2022_info,
X1,
str->string_type->map_info);
/* Find ASCII bank (or other similar) */
if (str->string_type->iso2022_info)
ctrlset = find_ctrlset(str->string_type->iso2022_info);
while (block_number < X1->part_count && *pos - start_pos < len) {
#ifdef DEBUG
DPRINT(Debug,59,(&Debug,
"cs_streamclip_from_iso2022: %d: type=%d set_index=%d <",
block_number,X1->parts[block_number].type,
X1->parts[block_number].set_index));
if (Debug.active > 58 && str->string_type->iso2022_info)
debug_iso2022_info_index(59,X1->parts[block_number].set_index,
str->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,">\n"));
#endif
switch (X1->parts[block_number].set_index) {
case -1:
DPRINT(Debug,58,(&Debug,
"cs_streamclip_from_iso2022: %d control characters\n",
X1->parts[block_number].word_count - block_index,
X1->parts[block_number].set_index));
if (iso2022_other != X1->parts[block_number].type)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_streamclip_from_iso2022",
"Bad type for control characters",0);
break;
case -2:
DPRINT(Debug,58,(&Debug,
"cs_streamclip_from_iso2022: %d bad characters\n",
X1->parts[block_number].word_count - block_index,
X1->parts[block_number].set_index));
break;
default:
DPRINT(Debug,58,(&Debug,
"cs_streamclip_from_iso2022: %d characters from set %d\n",
X1->parts[block_number].word_count - block_index,
X1->parts[block_number].set_index));
if (X1->parts[block_number].set_index < 0 ||
!str->string_type->iso2022_info ||
X1->parts[block_number].set_index > sizeof (str->string_type->iso2022_info->sets) /
sizeof (str->string_type->iso2022_info->sets[0]) ||
! str->string_type->iso2022_info->sets[X1->parts[block_number].set_index])
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_streamclip_from_iso2022",
"Bad set_index",0);
break;
}
while (block_index < X1->parts[block_number].word_count
&& *pos - start_pos < len) {
int r = add_char1_stream(&ret,&RESLEN,&alloced,output_state,
str->string_type->iso2022_info,
str->string_type->map_info,
ctrlset,1,& (X1->parts[block_number]),
block_index,&need_reset,printable_len);
if (r < 0)
goto out;
if (r > 0) {
/* nothing to count */
} else {
DPRINT(Debug,1,(&Debug,
"cs_streamclip_from_iso2022: FAILED to add char to steam\n"));
}
block_index++;
(*pos)++;
}
block_index = 0;
block_number++;
}
out:
/* Reset to 94 bank
*/
if (ctrlset) {
struct iso2022_setid ID = *ctrlset; /* ASCII? */
int width;
DPRINT(Debug,63,(&Debug,
"cs_streamclip_from_iso2022: Returning to 94 bank\n"));
select_upper_lower(&ret,&RESLEN,&alloced,&ID,output_state,&width);
}
if (output_state != terminal)
free_terminal_info(&output_state);
{
unsigned char temp[1];
temp[0] = '\0';
add_bytes_stream(&ret,&RESLEN,&alloced,temp,1);
}
return ret;
}
S_(cs_clip_from_string cs_clip_from_iso2022_gen)
static void cs_clip_from_iso2022_gen(ret,str,pos,len)
struct string *ret;
CONST struct string *str;
int *pos;
int len;
{
struct mb_data * X1 = str->p->a.data;
struct mb_data * X2 = ret->p->a.data;
int block_number = 0;
int block_index = *pos;
int start_pos = *pos;
if (ret->string_type->charset_type !=
str->string_type->charset_type)
panic("STRING PANIC",__FILE__,__LINE__,"cs_clip_from_iso2022_gen",
"String type mismatch",0);
if (*pos < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_clip_from_iso2022_gen",
"Index out of array",0);
if (len < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_clip_from_iso2022_gen",
"Negative size",0);
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_clip_from_iso2022_gen",
"Bad magic number (string)",0);
if (CS_ISO2022_magic != X2->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_clip_from_iso2022_gen",
"Bad magic number (ret)",0);
free_parts(X2); /* Quarantee */
ret->p->len = 0;
if (!pos_to_block(X1,*pos,&block_number,&block_index)) {
return ;
}
/* FIXME: Optimeze this */
while (block_number < X1->part_count && *pos - start_pos < len) {
int l1 = X1->parts[block_number].word_count - block_index;
int new_len;
struct mb_data_part * X3;
if (l1 < 1)
continue; /* Avoid job */
#ifdef DEBUG
DPRINT(Debug,59,(&Debug,
"cs_clip_from_iso2022_gen: %d: type=%d set_index=%d <",
block_number,X1->parts[block_number].type,
X1->parts[block_number].set_index));
if (Debug.active > 58 && str->string_type->iso2022_info)
debug_iso2022_info_index(59,X1->parts[block_number].set_index,
str->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,">\n"));
#endif
X3 = get_part(X2,
X1->parts[block_number].set_index,
X1->parts[block_number].type);
new_len = X3->word_count + l1;
X3->words = safe_realloc(X3->words,
(new_len) *
sizeof (X3->words[0]));
while (block_index < X1->parts[block_number].word_count &&
X3->word_count < new_len &&
*pos - start_pos < len) {
X3->words[X3->word_count++] =
X1->parts[block_number].words[block_index];
ret->p->len++;
block_index++;
(*pos)++;
}
block_index = 0;
block_number++;
}
}
S_(cs_find_pattern_from_string cs_find_pattern_from_iso2022_gen)
static int cs_find_pattern_from_iso2022_gen(str,pattern,ignore_case)
CONST struct string *str;
CONST struct string *pattern;
int ignore_case;
{
/* FIXME: pattern match should be done on here */
DPRINT(Debug,63,(&Debug,
"cs_find_pattern_from_iconv_gen=-1\n"));
return -1; /* Use UNICODE comparision on upper level instead */
}
/* Returns number of bytes added */
S_(cs_add_streambytes_to_string cs_add_streambytes_to_iso2022_gen)
static int cs_add_streambytes_to_iso2022_gen(str,count,data,errors)
struct string *str;
int count;
CONST unsigned char *data;
int *errors;
{
int i = 0;
struct state_iso2022 * X ;
*errors = 0;
if (!str->p->state)
str->p->state = new_state_1(str->string_type);
if (str->p->state->charset->charset_type != &cs_iso2022 &&
str->p->state->charset->charset_type != &cs_euc
)
panic("STRING PANIC",__FILE__,__LINE__,"cs_add_streambytes_to_iso2022_gen",
"Bad state",0);
X = str->p->state->p->a.iso2022;
if (STATE_ISO2022_magic != X->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_add_streambytes_to_iso2022_gen",
"Bad magic number (state)",0);
while (1) {
if (str->p->state->p->ready) {
iso2022_add_char(str,str->p->state);
cs_soft_reset_s_iso2022_gen(str->p->state);
} else {
int c = -1;
if (X->raw_bytes_count > 0) {
DPRINT(Debug,8,(&Debug,
"cs_add_streambytes_to_iso2022_gen: %d bytes collected\n",
X->raw_bytes_count));
c = streambyte_make_code_2(str->p->state,X);
}
if (c < 0) {
/* need more characters */
if (i < count) {
if (!state_add_raw(X,data[i])) {
DPRINT(Debug,8,(&Debug,
"cs_add_streambytes_to_iso2022_gen: failed to add code\n"));
/* Failed to add character */
(*errors)++;
cs_soft_reset_s_iso2022_gen(str->p->state);
X->raw_bytes_count = 0;
}
i++;
} else {
break; /* All characters entered */
}
}
if (0 == c) {
DPRINT(Debug,8,(&Debug,
"cs_add_streambytes_to_iso2022_gen: bad code\n"));
(*errors)++;
cs_soft_reset_s_iso2022_gen(str->p->state);
}
}
}
return i;
}
S_(cs_find_map_type cs_find_euc)
static struct map_info *cs_find_euc(map_name)
CONST char * map_name;
{
int i;
struct map_info *ret;
static struct map_info ** dyn_maps = NULL;
static int dyn_map_count = 0;
static struct map_info * maps[] = { &map_EUC_ascii,
&map_EUC_ascii_latin1,
NULL };
for (i = 0; maps[i]; i++)
if (0 == strcmp(map_name,maps[i]->map_name))
return maps[i];
for (i =0; i < dyn_map_count; i++)
if (0 == strcmp(dyn_maps[i]->map_name,map_name))
return dyn_maps[i];
ret = open_euc_mapset(map_name);
if (ret) {
dyn_maps = safe_realloc(dyn_maps,
(dyn_map_count + 1) *
sizeof (struct map_info *));
dyn_maps[dyn_map_count++] = ret;
}
return ret;
}
S_(cs_find_map_type cs_find_iso2022)
static struct map_info *cs_find_iso2022(map_name)
CONST char * map_name;
{
int i;
struct map_info *ret;
static struct map_info ** dyn_maps = NULL;
static int dyn_map_count = 0;
static struct map_info * maps[] = { &map_ISO2022_ascii,
&map_ISO2022_ascii_latin1,
NULL };
for (i = 0; maps[i]; i++)
if (0 == strcmp(map_name,maps[i]->map_name))
return maps[i];
for (i =0; i < dyn_map_count; i++)
if (0 == strcmp(dyn_maps[i]->map_name,map_name))
return dyn_maps[i];
ret = open_iso2022_mapset(map_name);
if (ret) {
dyn_maps = safe_realloc(dyn_maps,
(dyn_map_count + 1) *
sizeof (struct map_info *));
dyn_maps[dyn_map_count++] = ret;
}
return ret;
}
S_(cs_remove_control cs_remove_control_iso2022_gen)
static void cs_remove_control_iso2022_gen(str)
CONST struct string *str;
{
struct mb_data * X1 = str->p->a.data;
struct mb_data * new_X1 = alloc_mb_data();
int i;
if (CS_ISO2022_magic != X1->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_remove_control_iso2022_gen",
"Bad magic number (string)",0);
/* Fill indexes if current not filled */
if (str->string_type->map_info && str->string_type->iso2022_info)
fill_iso2022_map_index(str->string_type->iso2022_info,
X1,
str->string_type->map_info);
/* FIXME: This is very inefficient -- we rebuild string internally */
for (i = 0; i < X1->part_count; i++) {
int j;
#ifdef DEBUG
DPRINT(Debug,59,(&Debug,
"cs_remove_control_iso2022_gen: %d: type=%d set_index=%d <",
i,X1->parts[i].type, X1->parts[i].set_index));
if (Debug.active > 58 && str->string_type->iso2022_info)
debug_iso2022_info_index(59,X1->parts[i].set_index,
str->string_type->iso2022_info);
DPRINT(Debug,59,(&Debug,">\n"));
#endif
switch (X1->parts[i].set_index) {
case -1:
if (iso2022_other != X1->parts[i].type)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_remove_control_iso2022_gen",
"Bad type for control characters",0);
break;
case -2:
break;
default:
if (X1->parts[i].set_index < 0 ||
!str->string_type->iso2022_info ||
X1->parts[i].set_index >
sizeof (str->string_type->iso2022_info->sets) /
sizeof (str->string_type->iso2022_info->sets[0]) ||
! str->string_type->iso2022_info->sets[X1->parts[i].set_index])
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_remove_control_iso2022_gen",
"Bad set_index",0);
break;
}
for (j = 0; j < X1->parts[i].word_count; j++) {
switch (X1->parts[i].set_index) {
struct mb_data_part * X3;
int iso2022_map_index;
case -1: /* control characters ,
(also space with 94, 94x94 sets)
*/
if (32 != X1->parts[i].words[j])
goto bad_char;
X3 = get_part(new_X1,
X1->parts[i].set_index,
X1->parts[i].type);
add_iso2022_word(X3, X1->parts[i].words[j]);
break;
case -2: bad_char:
if (str->string_type->iso2022_info &&
str->string_type->map_info) {
int index;
enum iso2022_settype type;
uint16 iso2022_word;
if (map_unicode_to_ISO2022_word(0x003F /* '?' */,
str->string_type->
iso2022_info,
&index,&type,&iso2022_word,
str->string_type->
map_info)
&& index >= 0) {
if (index >
sizeof (str->string_type->iso2022_info->sets) /
sizeof (str->string_type->iso2022_info->sets[0]) ||
! str->string_type->iso2022_info->sets[index])
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_remove_control_iso2022_gen",
"Bad index",0);
X3 = get_part(new_X1,index,type);
add_iso2022_word(X3,iso2022_word);
break;
}
}
/* We can add space instead */
X3 = get_part(new_X1,-1,iso2022_other);
add_iso2022_word(X3,32);
break;
default:
iso2022_map_index = X1->parts[i].iso2022_map_index;
if (-1 != iso2022_map_index) {
uint16 code;
int found = map_ISO2022_word_to_unicode(X1->parts[i].words[j],
X1->parts[i].type,
iso2022_map_index,
&code);
if (!found)
goto bad_char; /* No mapping avaiulable */
if (!unicode_ch(code,UOP_printable))
goto bad_char; /* Not printable */
} else
goto bad_char; /* No mapping available */
X3 = get_part(new_X1,
X1->parts[i].set_index,
X1->parts[i].type);
add_iso2022_word(X3, X1->parts[i].words[j]);
break;
}
}
}
free_mb_data(&X1);
str->p->a.data = new_X1;
{
int l = str->p->len;
str->p->len = 0;
for (i = 0; i < new_X1->part_count; i++) {
str->p->len += new_X1->parts[i].word_count;
}
if (l != str->p->len) {
DPRINT(Debug,6,(&Debug,
"cs_remove_control_iso2022_gen: length changed %d => %d\n",
l,str->p->len));
}
}
}
S_(cs_add_state_to_string cs_add_state_to_iso2022_gen)
static void cs_add_state_to_iso2022_gen(str,ch)
struct string *str;
struct charset_state *ch;
{
if (str->string_type->charset_type !=
ch->charset->charset_type)
panic("STRING PANIC",__FILE__,__LINE__,"cs_add_state_to_iso2022_gen",
"String/state type mismatch",0);
iso2022_add_char(str,ch);
}
static void set_initial_state P_((struct charset_state *st));
static void set_initial_state(st)
struct charset_state *st;
{
if (STATE_ISO2022_magic != st->p->a.iso2022->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"set_initial_state",
"Bad magic number",0);
if (st->charset->iso2022_info) {
int i;
if (sizeof (st->charset->iso2022_info->initial_bank) /
sizeof (st->charset->iso2022_info->initial_bank[0]) !=
sizeof (st->p->a.iso2022->banks) /
sizeof (st->p->a.iso2022->banks[0]))
panic("ISO2022 PANIC",__FILE__,__LINE__,
"set_initial_state",
"Array sizes should be same",0);
for (i = 0;
i < sizeof (st->charset->iso2022_info->initial_bank) /
sizeof (st->charset->iso2022_info->initial_bank[0]);
i++) {
int x = st->charset->iso2022_info->initial_bank[i];
if (-1 != x) {
if (x < 0 ||
x >= sizeof (st->charset->iso2022_info->sets) /
sizeof (st->charset->iso2022_info->sets[0]) ||
! st->charset->iso2022_info->sets[x])
panic("STRING PANIC",__FILE__,__LINE__,
"set_initial_state",
"Bad initial_bank (set)",
0);
if (sizeof (st->p->a.iso2022->banks[i].bytes) !=
sizeof (st->charset->iso2022_info->sets[x]->bytes))
panic("STRING PANIC",__FILE__,__LINE__,
"set_initial_state",
"Bad size",
0);
st->p->a.iso2022->banks[i].iso2022_info_index = x;
st->p->a.iso2022->banks[i].type =
st->charset->iso2022_info->sets[x]->type;
memcpy(st->p->a.iso2022->banks[i].bytes,
st->charset->iso2022_info->sets[x]->bytes,
sizeof st->p->a.iso2022->banks[i].bytes);
}
}
}
}
S_(cs_init_state cs_init_s_iso2022)
static void cs_init_s_iso2022(st)
struct charset_state *st;
{
int i;
st->p->a.iso2022 = safe_malloc(sizeof (*st->p->a.iso2022));
/* defined in hdrs/defs.h */
bzero((void *)st->p->a.iso2022, sizeof (*st->p->a.iso2022));
st->p->a.iso2022->magic = STATE_ISO2022_magic;
st->p->a.iso2022->bank = bank_unspecified;
for (i = 0;
i < sizeof (st->p->a.iso2022->banks) /
sizeof (st->p->a.iso2022->banks[0]);
i++) {
st->p->a.iso2022->banks[i].type = iso2022_other;
st->p->a.iso2022->banks[i].iso2022_info_index = -1;
bzero(st->p->a.iso2022->banks[i].bytes,
sizeof (st->p->a.iso2022->banks[i].bytes));
}
st->p->a.iso2022->CL_bank = bank_G0; /* G0 assumed initially */
st->p->a.iso2022->CR_bank = bank_unspecified; /* no assumption for
8-bit characters */
st->p->a.iso2022->raw_bytes_count = 0;
st->p->a.iso2022->word = 0;
set_initial_state(st);
}
S_(cs_init_state cs_init_s_euc)
static void cs_init_s_euc(st)
struct charset_state *st;
{
int i;
st->p->a.iso2022 = safe_malloc(sizeof (*st->p->a.iso2022));
/* defined in hdrs/defs.h */
bzero((void *)st->p->a.iso2022, sizeof (*st->p->a.iso2022));
st->p->a.iso2022->magic = STATE_ISO2022_magic;
st->p->a.iso2022->bank = bank_unspecified;
for (i = 0;
i < sizeof (st->p->a.iso2022->banks) /
sizeof (st->p->a.iso2022->banks[0]);
i++) {
st->p->a.iso2022->banks[i].type = iso2022_other;
st->p->a.iso2022->banks[i].iso2022_info_index = -1;
bzero(st->p->a.iso2022->banks[i].bytes,
sizeof (st->p->a.iso2022->banks[i].bytes));
}
st->p->a.iso2022->CL_bank = bank_G0; /* G0 is left on EUC */
st->p->a.iso2022->CR_bank = bank_G1; /* G1 is for 8-bit characters on
EUC */
st->p->a.iso2022->raw_bytes_count = 0;
st->p->a.iso2022->word = 0;
set_initial_state(st);
if (st->charset->iso2022_info) {
for (i = 0;
i < sizeof (st->charset->iso2022_info->sets) /
sizeof (st->charset->iso2022_info->sets[0]) &&
st->charset->iso2022_info->sets[i];
i++) {
enum iso2022_bank bank = st->charset->iso2022_info->sets[i]->bank;
if (bank == bank_unspecified &&
iso2022_94 == st->charset->iso2022_info->sets[i]->type &&
iso2022_other == st->p->a.iso2022->banks[bank_G0].type)
bank = bank_G0;
if (bank >= 0 && bank < ISO2022_BANK_NUM) {
st->p->a.iso2022->banks[bank].iso2022_info_index = i;
st->p->a.iso2022->banks[bank].type =
st->charset->iso2022_info->sets[i]->type;
memcpy(st->p->a.iso2022->banks[bank].bytes,
st->charset->iso2022_info->sets[i]->bytes,
sizeof st->p->a.iso2022->banks[bank].bytes);
}
}
}
}
S_(cs_free_state cs_free_s_iso2022_gen)
static void cs_free_s_iso2022_gen(st)
struct charset_state *st;
{
if (st->p->a.iso2022) {
if (STATE_ISO2022_magic != st->p->a.iso2022->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"cs_free_s_iso2022",
"Bad magic number",0);
st->p->a.iso2022->magic = 0; /* Invalidate magic */
free(st->p->a.iso2022);
st->p->a.iso2022 = NULL;
}
}
S_(cs_add_streambyte_to_state cs_add_streambyte_to_s_iso2022_gen)
static int cs_add_streambyte_to_s_iso2022_gen(st,ch)
struct charset_state *st;
int ch;
{
struct state_iso2022 * X = st->p->a.iso2022;
if (STATE_ISO2022_magic != X->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_add_streambyte_to_s_iso2022_gen",
"Bad magic number (state)",0);
if (!state_add_raw(X,ch))
return 0;
while (X->raw_bytes_count > 0) {
int code;
if (st->p->ready) {
DPRINT(Debug,4,(&Debug,
"cs_add_streambyte_to_s_iso2022_gen: characters lost!\n"
));
}
code = streambyte_make_code_2(st,X);
if (code < 0) {
DPRINT(Debug,8,(&Debug,
"cs_add_streambyte_to_s_iso2022_gen: too few characters (len = %d)\n",
X->raw_bytes_count));
return 1;
}
if (0 == code) {
DPRINT(Debug,8,(&Debug,
"cs_add_streambyte_to_s_iso2022_gen: bad code\n"));
return 0;
}
}
return 1;
}
S_(cs_soft_reset_state cs_soft_reset_s_iso2022_gen)
static void cs_soft_reset_s_iso2022_gen(st)
struct charset_state *st;
{
struct state_iso2022 * X = st->p->a.iso2022;
if (STATE_ISO2022_magic != X->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_soft_reset_s_iso2022_gen",
"Bad magic number (state)",0);
X->raw_bytes_count = 0;
st->p->ready = 0;
}
S_(cs_give_unicode_from_state cs_give_unicode_from_s_iso2022)
static uint16 cs_give_unicode_from_s_iso2022(st,found)
struct charset_state *st;
int *found;
{
uint16 ret = 0x003F; /* '?' */
struct state_iso2022 * X = st->p->a.iso2022;
if (STATE_ISO2022_magic != X->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_give_unicode_from_s_iso2022",
"Bad magic number (state)",0);
*found = 0;
if (bank_unspecified == X-> bank) {
/* Control characters map directrly to unicode */
ret = X->word;
*found = 1;
} else if (X->bank >= 0 && X->bank < ISO2022_BANK_NUM) {
if (0 <= X->banks[X->bank].iso2022_info_index &&
st->charset->iso2022_info &&
st->charset->map_info) {
int iso2022_map_index;
if (X->banks[X->bank].iso2022_info_index >=
sizeof (st->charset->iso2022_info->sets) /
sizeof (st->charset->iso2022_info->sets[0]) ||
! st->charset->iso2022_info->sets
[X->banks[X->bank].iso2022_info_index])
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_give_unicode_from_s_iso2022",
"Bad iso2022_info_index",0);
if (!st->charset->map_info->map_initialized)
st->charset->map_info->map_init_it(st->charset->map_info);
iso2022_map_index =
give_iso2022_index(st->charset->map_info->b.setlist->setlist,
sizeof (st->charset->map_info->b.setlist->
setlist) /
sizeof (st->charset->map_info->
b.setlist->setlist[0]),
st->charset->iso2022_info->
sets[X->banks[X->bank].iso2022_info_index]);
if (-1 != iso2022_map_index)
*found = map_ISO2022_word_to_unicode(X->word,
X->banks[X->bank].type,
iso2022_map_index,
&ret);
}
} else
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_give_unicode_from_s_iso2022",
"Bad bank number",0);
return ret;
}
S_(cs_state_same_char cs_s_iso2022_same_char_gen)
static int cs_s_iso2022_same_char_gen(A,B,ignore_case)
struct charset_state *A;
struct charset_state *B;
int ignore_case;
{
int r = -1;
struct state_iso2022 * XA = A->p->a.iso2022;
struct state_iso2022 * XB = B->p->a.iso2022;
if (STATE_ISO2022_magic != XA->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_soft_reset_s_iso2022",
"Bad magic number (state A)",0);
if (STATE_ISO2022_magic != XB->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_soft_reset_s_iso2022",
"Bad magic number (state B)",0);
/* If control character */
if (bank_unspecified == XA->bank && bank_unspecified == XB->bank)
r = XA->word == XB->word;
else if (bank_unspecified == XA->bank || bank_unspecified == XB->bank)
r = -1; /* Use UNICODE values for comparision */
else if (XA->bank >= 0 && XB->bank >= 0 &&
XA->bank <= ISO2022_BANK_NUM &&
XB->bank <= ISO2022_BANK_NUM) {
if (-1 == XA->banks[XA->bank].iso2022_info_index &&
-1 == XB->banks[XB->bank].iso2022_info_index &&
0 == memcmp(XA->banks[XA->bank].bytes,
XB->banks[XB->bank].bytes,
sizeof (XA->banks[XA->bank].bytes)))
r = XA->word == XB->word;
else if (0 <= XA->banks[XA->bank].iso2022_info_index &&
XA->banks[XA->bank].iso2022_info_index ==
XB->banks[XB->bank].iso2022_info_index)
r = XA->word == XB->word;
else
r = -1; /* Use UNICODE values for comparision */
} else
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_s_iso2022_same_char_gen",
"Bad bank number",0);
if (0 == r && ignore_case)
r = -1; /* Use UNICODE values for comparision */
return r;
}
S_(cs_state_printable cs_s_iso2022_printable_gen)
static int cs_s_iso2022_printable_gen(st)
struct charset_state *st;
{
int r = -1;
struct state_iso2022 * X = st->p->a.iso2022;
if (STATE_ISO2022_magic != X->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_s_iso2022_printable_gen",
"Bad magic number (state)",0);
if (bank_unspecified == X->bank)
r = 32 == X->word; /* Assume that space is only printable
control character */
else
r = -1; /* Use UNICODE to look printable characters */
return r;
}
/* If character corresponds one byte on stream, returns it.
* Otherwise returns 0. This is used implement ReadCh().
* It is assumed that returned character corresponds to
* code character set (and perhaps also US-ASCII)
*/
S_(cs_state_is_onebyte cs_s_iso2022_is_onebyte_gen)
static int cs_s_iso2022_is_onebyte_gen(st)
struct charset_state *st;
{
int r = 0;
struct state_iso2022 * X = st->p->a.iso2022;
if (STATE_ISO2022_magic != X->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_s_iso2022_is_onebyte_gen",
"Bad magic number (state)",0);
if (bank_unspecified == X-> bank) {
if (X->word < 128)
r = X->word;
} else if (X->bank >= 0 && X->bank < ISO2022_BANK_NUM) {
/* NOTE:
I think that it is better not to test
iso2022_96 == X->banks[X->bank].type
although it is one byte set. One byte sets (without
escape switching use range 160-255) for that normally
*/
if (iso2022_94 == X->banks[X->bank].type) {
if (X->word >= 96)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_s_iso2022_is_onebyte_gen",
"Bad word on iso2022_94 or iso2022_96",0);
r = X->word + 32;
}
} else
panic("ISO2022 PANIC",__FILE__,__LINE__,
"cs_s_iso2022_is_onebyte_gen",
"Bad bank number",0);
return r;
}
S_(cs_set_properties cs_iso2022_properties_gen)
static int cs_iso2022_properties_gen(st)
charset_t st;
{
int prop = 0;
if (st->map_info && st->iso2022_info)
prop |= CS_mapping | CS_printable | CS_printable_len;
return prop;
}
S_(cs_iso2022_info_set cs_iso2022_info_set_iso2022)
static int cs_iso2022_info_set_iso2022(new_vals, new_setlist,setcount)
struct charcode_info *new_vals;
struct setlist *new_setlist;
int setcount;
{
int i;
/* No requirements? */
for (i = setcount;
i < sizeof (new_setlist->sets) / sizeof (new_setlist->sets[0]);
i++)
new_setlist->sets[i] = NULL;
new_vals->iso2022_info = loc_setlist(*new_setlist);
new_vals->flags &= ~SET_nodata;
return 1;
}
S_(cs_iso2022_info_set cs_iso2022_info_set_euc)
static int cs_iso2022_info_set_euc(new_vals, new_setlist,setcount)
struct charcode_info *new_vals;
struct setlist *new_setlist;
int setcount;
{
int banks[ISO2022_BANK_NUM];
int i;
for (i = 0; i < ISO2022_BANK_NUM; i++)
banks[i] = -1;
for (i = 0; i < setcount; i++) {
if (new_setlist->sets[i]->bank >= 0 &&
new_setlist->sets[i]->bank <= ISO2022_BANK_NUM) {
if (-1 == banks[new_setlist->sets[i]->bank])
banks[new_setlist->sets[i]->bank] = i;
else {
lib_error(CATGETS(elm_msg_cat, MeSet, MeNoSeveralBank,
"Charset type %s does not allow several bank-G%d specifications"),
new_vals->charset_type->type_name,
new_setlist->sets[i]->bank);
return 0; /* Discard bank defination */
}
}
}
for (i = setcount;
i < sizeof (new_setlist->sets) / sizeof (new_setlist->sets[0]);
i++)
new_setlist->sets[i] = NULL;
new_vals->iso2022_info = loc_setlist(*new_setlist);
new_vals->flags &= ~SET_nodata;
return 1;
}
struct charset_type cs_iso2022 = { "iso2022",
cs_init_iso2022_gen,
cs_free_iso2022_gen,
cs_add_streambyte_to_iso2022_gen,
cs_add_intdata_to_iso2022_gen,
cs_check_length_iso2022_gen,
cs_give_unicode_from_iso2022_gen,
cs_add_unicodedata_to_iso2022_gen,
cs_cmp_iso2022_gen,
cs_stream_from_iso2022,
cs_can_ascii_iso2022_gen,
cs_streamclip_from_iso2022,
cs_clip_from_iso2022_gen,
cs_find_pattern_from_iso2022_gen,
cs_add_streambytes_to_iso2022_gen,
cs_find_iso2022,
cs_remove_control_iso2022_gen,
cs_add_state_to_iso2022_gen,
cs_init_s_iso2022,
cs_free_s_iso2022_gen,
cs_add_streambyte_to_s_iso2022_gen,
cs_soft_reset_s_iso2022_gen,
cs_give_unicode_from_s_iso2022,
cs_s_iso2022_same_char_gen,
cs_s_iso2022_printable_gen,
cs_s_iso2022_is_onebyte_gen,
cs_iso2022_properties_gen,
cs_estimate_clip_iso2022,
cs_iso2022_info_set_iso2022,
&cs_euc,
};
struct charset_type cs_euc = { "euc",
cs_init_iso2022_gen,
cs_free_iso2022_gen,
cs_add_streambyte_to_iso2022_gen,
cs_add_intdata_to_iso2022_gen,
cs_check_length_iso2022_gen,
cs_give_unicode_from_iso2022_gen,
cs_add_unicodedata_to_iso2022_gen,
cs_cmp_iso2022_gen,
cs_stream_from_euc,
cs_can_ascii_iso2022_gen,
cs_streamclip_from_euc,
cs_clip_from_iso2022_gen,
cs_find_pattern_from_iso2022_gen,
cs_add_streambytes_to_iso2022_gen,
cs_find_euc,
cs_remove_control_iso2022_gen,
cs_add_state_to_iso2022_gen,
cs_init_s_euc,
cs_free_s_iso2022_gen,
cs_add_streambyte_to_s_iso2022_gen,
cs_soft_reset_s_iso2022_gen,
cs_give_unicode_from_s_iso2022,
cs_s_iso2022_same_char_gen,
cs_s_iso2022_printable_gen,
cs_s_iso2022_is_onebyte_gen,
cs_iso2022_properties_gen,
cs_estimate_clip_iso2022,
cs_iso2022_info_set_euc,
NULL
};
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1