static char rcsid[] = "@(#)$Id: iso2022_map.c,v 1.14 2006/04/09 07:37:08 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.14 $ $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"
DEBUG_VAR(Debug,__FILE__,"charset");
#include <errno.h>
#ifndef ANSI_C
extern int errno;
#endif
static FILE *null_charmap_copy_callback P_((const char *name,
const char *pathname));
static FILE *null_charmap_copy_callback(name,pathname)
CONST char *name;
CONST char *pathname;
{
return NULL;
}
static charmap_copy_callback * copy_cb = null_charmap_copy_callback;
void set_charmap_copy_callback(cb)
charmap_copy_callback *cb;
{
copy_cb = cb;
}
int is_on_mapdir(name)
CONST char *name;
{
return NULL == strpbrk(name,"/$\\;{}()");
}
FILE * open_mapname(name,fn)
CONST char *name;
char **fn;
{
int err = 0;
int map_dir = 0;
if ('\0' == *name)
return NULL;
if (is_on_mapdir(name)) {
/* give_dt_estr_as_str adds / to end */
char * map_txtdir_val = give_dt_estr_as_str(&map_txtdir_e,
"map-text-dir");
if (!map_txtdir_val)
return NULL;
if (0 != access(map_txtdir_val,ACCESS_EXISTS)) {
int err = errno;
lib_error(CATGETS(elm_msg_cat, MeSet,MeNoTxtMapDir,
"Map %s: no map-text-dir exist: %s: %s"),
name,map_txtdir_val,error_description(err));
return NULL;
}
*fn = elm_message(FRM("%s%s"),map_txtdir_val,name);
map_dir++;
} else {
char buffer[STRING];
if (expand_meta(buffer,name,sizeof buffer) < 0 ||
'/' != buffer[0]) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeBadMapName,
"Map %s: bad map name"),
name);
return NULL;
}
*fn = safe_strdup(buffer);
}
err = can_open(*fn,"r");
if (ENOENT == err && map_dir) {
FILE *F = copy_cb(name,*fn);
if (F) {
return F;
}
}
if (0 != err) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapCantOpen,
"Map %s: can't open %s: %s"),
name,*fn,error_description(err));
} else {
FILE *F = fopen(*fn,"r");
if (!F) {
int err = errno;
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapCantOpen,
"Map %s: can't open %s: %s"),
name,*fn,error_description(err));
return NULL;
}
return F;
}
return NULL;
}
#define ISO2022_MAPINFO_magic 0xF303
struct iso2022_mapinfo {
unsigned short magic; /* ISO2022_MAPINFO_magic */
enum iso2022_settype type;
struct map_info *builtin_map; /* refers builtin ISO8859-X maps */
char * name;
int flag;
int vlen;
uint16 * vector;
};
#define PF_RANGE 4
#define PF_lower 0
#define PF_upper 2
#define PF_upper_lower_mask (PF_lower|PF_upper)
#define PF_3COL2 1
#define PF_ascii_lower (PF_IS_BUILTIN | PF_ascii | PF_lower )
#define PF_ascii_upper (PF_IS_BUILTIN | PF_ascii | PF_upper )
#define PF_bytemap_lower (PF_IS_BUILTIN | PF_bytemap | PF_lower )
#define PF_bytemap_upper (PF_IS_BUILTIN | PF_bytemap | PF_upper )
#define PF_RANGE_lower (PF_RANGE | PF_lower)
#define PF_RANGE_upper (PF_RANGE | PF_upper)
struct iso2022_mapinfo latin_iso2022_map_ascii = {
ISO2022_MAPINFO_magic, iso2022_94, &map_ascii,
NULL, PF_ascii_lower, 0, NULL }; /* ASCII */
struct iso2022_mapinfo latin_iso2022_map_latin1 = {
ISO2022_MAPINFO_magic, iso2022_96, &map_latin1,
NULL, PF_ascii_upper, 0, NULL }; /* ISO-8859-1 */
#if ANSI_C
static set_map_callmap NULL_set_map_callmap;
#endif
static int NULL_set_map_callmap(name,map_info,l1,l2,fn)
CONST char *name;
struct map_info *map_info;
long l1;
long l2;
CONST char *fn;
{
panic("ISO2022 PANIC",__FILE__,__LINE__,"NULL_set_map_callmap",
"NULL_set_map_callmap called",0);
return 1;
}
#define MAX_ERROR 5
void read_map_format_a(name,map_info,iso2022_map_info,
F,pass_caller,
field_count, vector,
fn
)
CONST char *name;
struct map_info *map_info;
struct iso2022_mapinfo *iso2022_map_info;
FILE *F;
set_map_callmap * pass_caller;
int field_count;
enum field_type *vector;
CONST char *fn;
{
int l;
char buffer[STRING];
int ok = 0;
int ok_iso2022 = 0;
int lineno = 0;
int error_count = 0;
struct X {
char * N;
long l;
} * col;
if (field_count < 2)
panic("ISO2022 PANIC",__FILE__,__LINE__,"read_map_format_a",
"too few fields",0);
col = safe_malloc ( field_count * sizeof (col[0]));
while (0 < (l = mail_gets(buffer,sizeof buffer,F))) {
int count = 0;
int i;
long l1 = -1;
long l2 = -1;
long lmb = -1;
for (i = 0; i < field_count; i++) {
col[i].N = NULL;
col[i].l = -1;
}
if (buffer[l-1] != '\n') {
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapTooLongLine,
"Map %s: %s: Too long line: %s"),
name,fn,buffer);
} else {
l--;
buffer[l] = '\0';
lineno++;
}
if (buffer[0] == '#')
continue;
col[0].N = buffer;
for (i = 0; i < l; i++) {
switch (buffer[i]) {
case '\t': {
field_separator:
count++;
buffer[i] = '\0';
if (count < field_count) {
/* Jump column forward --- THIS is not necessary correct */
while (i < l-1 && whitespace(buffer[i+1]))
i++;
col[count].N = &(buffer[i+1]);
}
}
break;
case ' ': { /* KSX1001.TXT is not really TAB separated */
if (count < field_count &&
vector[count] != val_comment)
goto field_separator;
}
break;
}
}
if (count < field_count-1 &&
val_comment != vector[count+1]) {
int i;
if (++error_count > MAX_ERROR)
continue;
DPRINT(Debug,9,(&Debug,
"%s: line %d -- %d fields:\n",
name, lineno,count+1));
for (i = 0; i <= count && i < field_count; i++) {
DPRINT(Debug,9,(&Debug," ... field %d: %s\n",
i,col[i].N));
}
DPRINT(Debug,9,(&Debug,
" ... line %d: %s\n",
lineno,buffer));
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapBadLine,
"Map %s: %s: line %d: Bad line: %s..."),
name,fn,lineno,buffer);
if (error_count == MAX_ERROR)
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapTooManyErr,
"Map %s: %s: Too many errors ... rest ignored"),
name,fn);
continue;
}
for (i = 0; i < field_count; i++) {
char * end;
if (val_comment == vector[i])
continue;
if (count <= i) {
DPRINT(Debug,12,(&Debug,
"%s: line %s... no field %d\n",
name, buffer, i));
}
if (col[i].N == NULL ||
'\0' == col[i].N[0] ||
'#' == col[i].N[0]) {
DPRINT(Debug,9,(&Debug,
"%s: line %s... no mapping\n",
name, buffer));
goto no_mapping;
}
col[i].l = strtol(col[i].N,&end,16);
if (*end != '\0' || col[i].l < 0) {
if (++error_count <= MAX_ERROR)
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapBadValueLineNo,
"Map %s: %s: line %d: Bad value: %s"),
name,fn,lineno,col[i].N);
if (error_count == MAX_ERROR)
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapTooManyErr,
"Map %s: %s: Too many errors ... rest ignored"),
name,fn);
goto no_mapping;
}
switch (vector[i]) {
int a,b;
case val_unicode: /* We do not support values > 0xFFFF */
if (col[i].l > 0xFFFF) {
if (++error_count <= MAX_ERROR)
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapBadValueLineNo,
"Map %s: %s: line %d: Bad value: %s"),
name,fn,lineno,col[i].N);
if (error_count == MAX_ERROR)
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapTooManyErr,
"Map %s: %s: Too many errors ... rest ignored"),
name,fn);
goto no_mapping;
}
break;
case val_byte:
if (col[i].l > 0xFF) {
if (++error_count < MAX_ERROR)
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapBadValueLineNo,
"Map %s: %s: line %d: Bad value: %s"),
name,fn,lineno,col[i].N);
if (error_count == MAX_ERROR)
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapTooManyErr,
"Map %s: %s: Too many errors ... rest ignored"),
name,fn);
goto no_mapping;
}
break;
case val_iso2022_mb: /* Both bytes should be on range
0x20 -- 0x7F
*/
a = col[i].l / 256;
b = col[i].l % 256;
if (a < 0x20 || b < 0x20 || a > 0x7F || b > 0x7F) {
if (++error_count <= MAX_ERROR)
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapBadValueLineNo,
"Map %s: %s: line %d: Bad value: %s"),
name,fn,col[i].N);
if (error_count == MAX_ERROR)
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapTooManyErr,
"Map %s: %s: Too many errors ... rest ignored"),
name,fn);
goto no_mapping;
}
break;
}
if (val_unicode == vector[i]) {
l2 = col[i].l;
} else if (val_byte == vector[i] && -1 == l1) {
l1 = col[i].l;
} else if (val_iso2022_mb == vector[i] && -1 == lmb) {
lmb = col[i].l;
}
}
if (NULL_set_map_callmap != pass_caller) {
if (l1 != -1 && l2 != -1) {
if (!pass_caller(name,map_info,l1,l2,fn))
continue;
ok ++;
} else {
DPRINT(Debug,12,(&Debug,
"%s: line %s... no intresting values l1=%ld l2=%ld\n",
name, buffer,l1,l2));
}
}
if (iso2022_map_info) {
if ( 256 == iso2022_map_info->vlen &&
iso2022_other == iso2022_map_info->type) {
if (l1 >= 0 && l1 < iso2022_map_info->vlen && l2 != -1) {
iso2022_map_info->vector[l1] = l2;
ok_iso2022++;
} else {
DPRINT(Debug,12,(&Debug,
"%s: line %s... no intresting values l1=%ld l2=%ld\n",
name, buffer,l1,l2));
}
} else if (96 == iso2022_map_info->vlen &&
( iso2022_94 == iso2022_map_info->type ||
iso2022_96 == iso2022_map_info->type )) {
uint16 Z;
int A = l1;
if (PF_upper & iso2022_map_info->flag)
A = l1 - 128;
if (A >= 32 && A < 128 && l2 != -1 &&
(Z = ISO2022_1byte_to_word(A)) < iso2022_map_info->vlen) {
iso2022_map_info->vector[Z] = l2;
ok_iso2022++;
} else {
DPRINT(Debug,12,(&Debug,
"%s: line %s... no intresting values l1=%ld l2=%ld\n",
name, buffer,l1,l2));
}
} else if (96*96 == iso2022_map_info->vlen &&
( iso2022_94x94 == iso2022_map_info->type ||
iso2022_96x96 == iso2022_map_info->type )) {
uint16 Z;
if (lmb >= 0 && l2 != -1 &&
(Z = ISO2022_2byte_to_word(lmb / 256, lmb % 256)) <
iso2022_map_info->vlen) {
iso2022_map_info->vector[Z] = l2;
ok_iso2022++;
} else {
DPRINT(Debug,12,(&Debug,
"%s: line %s... no intresting values lmb=%ld l2=%ld\n",
name, buffer,lmb,l2));
}
} else {
panic("ISO2022 PANIC",__FILE__,__LINE__,"read_map_format_a",
"Bad iso2022_map_info ?",0);
}
}
no_mapping:
;
}
free(col);
col = NULL;
DPRINT(Debug,8,(&Debug,
"%s: %d / %d items read\n",
name,
ok,ok_iso2022));
}
int iso2022_parseflag_ok (flag)
CONST char * flag;
{
if (0 == istrcmp("3col=2",flag))
return PF_3COL2;
if (0 == istrcmp("ascii=lower",flag))
return PF_ascii_lower;
if (0 == istrcmp("ascii=upper",flag))
return PF_ascii_upper;
if (0 == istrcmp("one-byte-map=lower",flag))
return PF_bytemap_lower;
if (0 == istrcmp("one-byte-map=upper",flag))
return PF_bytemap_upper;
if (0 == istrcmp("range=lower",flag))
return PF_RANGE_lower;
if (0 == istrcmp("range=upper",flag))
return PF_RANGE_upper;
return 0;
}
/* name on STRDUPed --- caller must malloc/strdup name !!! */
static struct iso2022_mapinfo *alloc_iso2022_mapinfo P_((char *name,
enum iso2022_settype
type,
int code));
static struct iso2022_mapinfo *alloc_iso2022_mapinfo(name,type,code)
char *name;
enum iso2022_settype type;
int code;
{
struct iso2022_mapinfo * ret = NULL;
ret = safe_malloc(sizeof (*ret));
ret->magic = ISO2022_MAPINFO_magic;
ret->type = type;
ret->name = name;
ret->flag = code;
ret->builtin_map = NULL;
ret->vlen = 0;
ret->vector = NULL;
return ret;
}
struct iso2022_mapinfo * make_iso2022_map(builtin_map,type,code,flag)
struct map_info *builtin_map;
enum iso2022_settype type;
int code;
CONST char *flag;
{
int ok = 0;
struct iso2022_mapinfo * ret = NULL;
switch(type) {
case iso2022_94:
if (builtin_map -> map_type == &cs_ascii)
ok = 1;
if (builtin_map -> map_type == &cs_onebyte)
ok = 1;
break;
case iso2022_96:
if (builtin_map -> map_type == &cs_ascii)
ok = 1;
if (builtin_map -> map_type == &cs_onebyte)
ok = 1;
break;
}
if (!ok) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeBuiltinISO2022Unsupported,
"Builtin ISO2022 map %s is unsupported or is different type"),
builtin_map->map_name);
return NULL;
}
ret = alloc_iso2022_mapinfo(NULL,type,code);
ret->builtin_map = builtin_map;
return ret;
}
struct iso2022_mapinfo * read_iso2022_map(filename,type,code,flag)
CONST char *filename;
enum iso2022_settype type;
int code;
CONST char *flag;
{
struct iso2022_mapinfo * ret = NULL;
char *fn = NULL;
FILE * F;
if ( (code & PF_RANGE) &&
type != iso2022_94 && type != iso2022_96) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeUnsupportedFlag,
"Flag %s is not supported with that bank type"),
flag);
return NULL;
}
F = open_mapname(filename,&fn);
if (F) {
int i;
ret = alloc_iso2022_mapinfo(safe_strdup(filename),type,code);
switch(type) {
case iso2022_other: ret->vlen = 256; break;
case iso2022_94: case iso2022_96: ret->vlen = 96; break;
case iso2022_94x94: case iso2022_96x96: ret->vlen = 96*96; break;
default:
panic("ISO2022 PANIC",__FILE__,__LINE__,"read_iso2022_map",
"bad type",0);
}
ret->vector = safe_malloc(ret->vlen * sizeof (ret->vector[0]));
for (i = 0; i < ret->vlen; i++) {
ret->vector[i] = MAPPING_NONE;
}
switch (code) {
case PF_3COL2: {
static enum field_type vector_BYTE3[4] = {
val_ignore, val_byte, val_unicode, val_comment
};
static enum field_type vector_MB3[4] = {
val_ignore, val_iso2022_mb, val_unicode, val_comment
};
if (ret->vlen > 256)
read_map_format_a(filename,NULL,ret,F,
NULL_set_map_callmap,
4,vector_MB3,fn);
else
read_map_format_a(filename,NULL,ret,F,
NULL_set_map_callmap,
4,vector_BYTE3,fn);
}
break;
case PF_RANGE_lower: case PF_RANGE_upper: {
static enum field_type vector_BYTE2[3] = {
val_byte, val_unicode, val_comment
};
read_map_format_a(filename,NULL,ret,F,
NULL_set_map_callmap,
3,vector_BYTE2,fn);
}
break;
case 0: {
static enum field_type vector_BYTE2[3] = {
val_byte, val_unicode, val_comment
};
static enum field_type vector_MB2[3] = {
val_iso2022_mb, val_unicode, val_comment
};
if (ret->vlen > 256)
read_map_format_a(filename,NULL,ret,F,
NULL_set_map_callmap,
3,vector_MB2,fn);
else
read_map_format_a(filename,NULL,ret,F,
NULL_set_map_callmap,
3,vector_BYTE2,fn);
}
break;
}
fclose(F);
}
if (fn)
free(fn);
return ret;
}
CONST char * iso2022_mapname(map)
struct iso2022_mapinfo *map;
{
if (ISO2022_MAPINFO_magic != map->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"iso2022_mapname",
"Bad magic number",0);
if (!map->name) {
if (! (map->flag & PF_IS_BUILTIN))
panic("ISO2022 PANIC",__FILE__,__LINE__,"iso2022_mapname",
"No map_name",0);
if (!map->builtin_map)
panic("ISO2022 PANIC",__FILE__,__LINE__,"iso2022_mapname",
"No builtin_map",0);
return map->builtin_map->map_name;
}
return map->name;
}
CONST char * iso2022_mapflags(map)
struct iso2022_mapinfo *map;
{
if (ISO2022_MAPINFO_magic != map->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"iso2022_mapflags",
"Bad magic number",0);
switch(map->flag) {
case PF_3COL2:
return "3col=2";
case PF_ascii_lower:
return "ascii=lower";
case PF_ascii_upper:
return "ascii=upper";
case PF_bytemap_lower:
return "one-byte-map=lower";
case PF_bytemap_upper:
return "one-byte-map=upper";
case PF_RANGE_lower:
return "range=lower";
case PF_RANGE_upper:
return "range=upper";
}
return NULL;
}
uint16 ISO2022_1byte_to_word(ch1)
int ch1;
{
if (ch1 < 32 || ch1 > 127)
panic("ISO2022 PANIC",__FILE__,__LINE__,"ISO2022_1byte_to_word",
"bad byte",0);
return ch1 -32;
}
uint16 ISO2022_2byte_to_word(ch1,ch2)
int ch1;
int ch2;
{
if (ch1 < 32 || ch1 > 127 ||
ch2 < 32 || ch2 > 127)
panic("ISO2022 PANIC",__FILE__,__LINE__,"ISO2022_2byte_to_word",
"bad bytes",0);
return (ch1 - 32) * 96 + (ch2 - 32);
}
/* 0 == not found, 1 == found */
int map_ISO2022_word_to_unicode(word,type,iso2022_map_index,ret)
unsigned word;
enum iso2022_settype type;
int iso2022_map_index;
uint16 *ret;
{
struct iso2022_mapinfo *Mx;
if (iso2022_map_index < 0 || iso2022_map_index >= iso2022_map_list_count)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_ISO2022_word_to_unicode",
"iso2022_map_index out of range",0);
if (!iso2022_map_list[iso2022_map_index].map) {
DPRINT(Debug,10,(&Debug,
"map_ISO2022_word_to_unicode: No map with iso2022_map_index %d\n",
iso2022_map_index));
return 0;
}
Mx = iso2022_map_list[iso2022_map_index].map;
if (ISO2022_MAPINFO_magic != Mx->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,"map_ISO2022_word_to_unicode",
"Bad magic number",0);
if (Mx->type != type)
panic("ISO2022 PANIC",__FILE__,__LINE__,"map_ISO2022_word_to_unicode",
"Map type mismatch",0);
if (Mx->builtin_map) {
unsigned int ch = '\0';
int found;
switch((Mx->flag) & PF_upper_lower_mask) {
case PF_lower:
if (iso2022_94 == type ||
iso2022_96 == type) {
if (word >= 96) {
DPRINT(Debug,10,(&Debug,
"map_ISO2022_word_to_unicode: word %u out of range (type iso2022_94 or iso2022_96)",
word));
return 0;
}
ch = word + 32;
} else
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_ISO2022_word_to_unicode",
"unsupported type for PF_BUILTIN_lower",0);
break;
case PF_upper:
if (iso2022_94 == type ||
iso2022_96 == type) {
if (word >= 96) {
DPRINT(Debug,10,(&Debug,
"map_ISO2022_word_to_unicode: word %u out of range (type iso2022_94 or iso2022_96)",
word));
return 0;
}
ch = word + 32 + 128;
} else
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_ISO2022_word_to_unicode",
"unsupported type for PF_BUILTIN_upper",0);
break;
default:
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_ISO2022_word_to_unicode",
"Bad or unsupported map->flag",0);
}
if (&cs_onebyte == Mx->builtin_map->map_type)
*ret = cs_unicode_bytemap_helper_1(ch,Mx->builtin_map,&found);
else if (&cs_ascii == Mx->builtin_map->map_type)
*ret = cs_unicode_ascii_helper_1(ch,Mx->builtin_map,&found);
else
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_ISO2022_word_to_unicode",
"Unsupported builtin map type",0);
DPRINT(Debug,61,(&Debug,
"ISO2022 word %04x type %d map index %d => %04x (found=%d) builtin ch=%c\n",
word,type,iso2022_map_index,*ret,found,ch));
return found;
} else {
if (word >= Mx->vlen) {
DPRINT(Debug,10,(&Debug,
"map_ISO2022_word_to_unicode: word %u out of range (vector len=%d)",
word,Mx->vlen));
} else if (MAPPING_NONE != Mx->vector[word]) {
*ret = Mx->vector[word];
DPRINT(Debug,61,(&Debug,
"ISO2022 word %04x type %d map index %d => %04x (found) \n",
word,type,iso2022_map_index,*ret));
return 1;
}
}
DPRINT(Debug,61,(&Debug,
"ISO2022 word %04x type %d map index %d => %04x (NOT FOUND)\n",
word,type,iso2022_map_index,*ret));
return 0;
}
/* 0 == not found, 1 == found */
int map_unicode_to_ISO2022_word_1(unicode,type,iso2022_map_index,iso2022_word)
unsigned unicode;
enum iso2022_settype * type;
int iso2022_map_index;
uint16 * iso2022_word;
{
struct iso2022_mapinfo *Mx;
if (iso2022_map_index < 0 || iso2022_map_index >= iso2022_map_list_count)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_unicode_to_ISO2022_word_1",
"iso2022_map_index out of range",0);
if (!iso2022_map_list[iso2022_map_index].map) {
DPRINT(Debug,10,(&Debug,
"map_unicode_to_ISO2022_word_1: No map with iso2022_map_index %d\n",
iso2022_map_index));
return 0;
}
Mx = iso2022_map_list[iso2022_map_index].map;
if (ISO2022_MAPINFO_magic != Mx->magic)
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_unicode_to_ISO2022_word_1",
"Bad magic number",0);
*type = Mx->type;
if (Mx->builtin_map) {
int ch = '\0';
int found = 0;
if (&cs_onebyte == Mx->builtin_map->map_type)
ch = cs_map_bytemap_rev(Mx->builtin_map,unicode,&found);
else if (&cs_ascii == Mx->builtin_map->map_type)
ch = cs_map_ascii_rev(Mx->builtin_map,unicode,&found);
else
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_unicode_to_ISO2022_word_1",
"Unsupported builtin map type",0);
if (found)
switch((Mx->flag) & PF_upper_lower_mask) {
case PF_lower:
if (iso2022_94 == Mx->type ||
iso2022_96 == Mx->type) {
if (ch < 32 || ch > 127) {
DPRINT(Debug,10,(&Debug,
"map_unicode_to_ISO2022_word_1: char %c (unicode %u) out of range (type iso2022_94 or iso2022_96, PF_BUILTIN_lower)",
ch,unicode));
return 0;
}
*iso2022_word = ch - 32;
DPRINT(Debug,63,(&Debug,
"map_unicode_to_ISO2022_word_1: iso2022_map_index=%d %04x => %04x (ch=%02x lower) [%s]\n",
iso2022_map_index,unicode,
*iso2022_word,ch,
Mx->builtin_map->map_name ?
Mx->builtin_map->map_name :
"???"));
return 1;
} else
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_unicode_to_ISO2022_word_1",
"unsupported type for PF_BUILTIN_lower",0);
break;
case PF_upper:
if (iso2022_94 == Mx->type ||
iso2022_96 == Mx->type) {
if (ch < 32 + 128) {
DPRINT(Debug,10,(&Debug,
"map_unicode_to_ISO2022_word_1: char %c (unicode %u) out of range (type iso2022_94 or iso2022_96, PF_BUILTIN_upper)",
ch,unicode));
return 0;
}
*iso2022_word = ch - (32 + 128);
DPRINT(Debug,63,(&Debug,
"map_unicode_to_ISO2022_word_1: iso2022_map_index=%d %04x => %04x (ch=%02x upper) [%s]\n",
iso2022_map_index,unicode,
*iso2022_word,ch,
Mx->builtin_map->map_name ?
Mx->builtin_map->map_name :
"???"));
return 1;
} else
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_unicode_to_ISO2022_word_1",
"unsupported type for PF_BUILTIN_upper",0);
break;
default:
panic("ISO2022 PANIC",__FILE__,__LINE__,
"map_ISO2022_word_to_unicode",
"Bad or unsupported map->flag",0);
}
DPRINT(Debug,63,(&Debug,
"map_unicode_to_ISO2022_word_1: iso2022_map_index=%d %04x (ch=%02x) not found [%s]\n",
iso2022_map_index,unicode,
ch,
Mx->builtin_map->map_name ?
Mx->builtin_map->map_name :
"???"));
} else {
int i;
/* TODO: Fix this
-- VERY ineffective
*/
for (i = 0; i < Mx->vlen; i++) {
if (unicode == Mx->vector[i]) {
*iso2022_word = i;
DPRINT(Debug,63,(&Debug,
"map_unicode_to_ISO2022_word_1: iso2022_map_index=%d %04x => %04x\n",
iso2022_map_index,unicode,
*iso2022_word));
return 1;
}
}
DPRINT(Debug,63,(&Debug,
"map_unicode_to_ISO2022_word_1: iso2022_map_index=%d %04x not found (len=%d)\n",
iso2022_map_index,unicode,Mx->vlen));
}
return 0;
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1