static char rcsid[] = "@(#)$Id: cs_binary.c,v 1.48 2006/04/16 21:01:35 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.48 $ $State: Exp $
*
* Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
*
* Table koi82unicode is from RFC 1489,
* author Andrew A. Chernov <ache@astral.msk.su>
*
* Table cp12512unicode is contributed by
* Andrey A. Chernov <ache@nagual.pp.ru>
*
* Table cp12522unicode is from
* http://www.microsoft.com/globaldev/reference/sbcs/1252.htm
* reference given on windows-1252 charset registeration.
*
* Table iso8859152unicode is from
# http://www.unicode.org/Public/MAPPINGS/ISO8859/
# file 8859-15.TXT
# (from same place that files on charset/MAPPINGS/ISO8859 directory)
*
* Table koi8u_additions is contributed by
* Mikhail Teterin <mi@aldan.algebra.com>
*
*****************************************************************************/
#include "headers.h"
#include "s_me.h"
#include "cs_imp.h"
#include "bindata.h"
DEBUG_VAR(Debug,__FILE__,"charset");
#include <errno.h>
#ifndef ANSI_C
extern int errno;
#endif
/* bindata ---------------------------------------------------------------- */
static uint16 lookup_binmap_0 P_((unsigned int ch,
struct map_info *map,
int *found));
static uint16 lookup_binmap_0(ch,map,found)
unsigned int ch;
struct map_info *map;
int *found;
{
*found = 0;
if (&cs_ascii != map->map_type &&
&cs_onebyte != map->map_type)
panic("STRING PANIC",__FILE__,__LINE__,"lookup_binmap_0",
"Bad maptype",0);
return lookup_binmap(ch,map->c.bindata,found);
}
static unsigned char lookup_binmap_rev_0 P_((struct map_info *map,
unsigned int val,
int *found));
static unsigned char lookup_binmap_rev_0(map,val,found)
struct map_info *map;
unsigned int val;
int *found;
{
*found = 0;
if (&cs_ascii != map->map_type &&
&cs_onebyte != map->map_type)
panic("STRING PANIC",__FILE__,__LINE__,"lookup_binmap_rev_0",
"Bad maptype",0);
return lookup_binmap_rev(map->c.bindata,val,found);
}
static struct bindata_ops bindata_ops = {
lookup_binmap_0,
lookup_binmap_rev_0
};
/* ascii ------------------------------------------------------------------ */
static void map_ascii_init_rev P_((struct map_info *map));
static void map_ascii_init_rev(map)
struct map_info *map;
{
int i;
int col = 0;
for (i = 0; i < MAP_REV_MAP_DIV; i++)
map->b.ascii->map_ascii_rev[i] = 0;
for (i = 0; i < 128; i++)
map->b.ascii->map_ascii_rev[i] = i;
for (i = 0; i < 128; i++) {
unsigned char c = i + 128;
uint16 val = map->b.ascii->map_ascii_upper[i];
if (val != MAPPING_NONE) {
if (map->b.ascii->map_ascii_rev[val % MAP_REV_MAP_DIV])
col++;
map->b.ascii->map_ascii_rev[val % MAP_REV_MAP_DIV] = c;
}
}
if (col) {
DPRINT(Debug,4,(&Debug,
"Ascii/upper map %s -- %d collisions\n",
map->map_name,col));
}
}
static unsigned char cs_map_ascii_rev_0 P_((struct map_info *map,
unsigned int val,
int *found));
static unsigned char cs_map_ascii_rev_0(map,val,found)
struct map_info *map;
unsigned int val;
int *found;
{
unsigned char c;
int i;
*found = 0;
if (&cs_ascii != map->map_type)
panic("STRING PANIC",__FILE__,__LINE__,"cs_map_ascii_rev_0",
"Bad maptype",0);
c = map->b.ascii->map_ascii_rev[val % MAP_REV_MAP_DIV];
if (!c)
return 0x3F; /* '?' */
/* Can't be < 128, because val >= 128 here */
if (c < 128)
return 0x3F; /* '?' */
/* Check case no collision */
if (map->b.ascii->map_ascii_upper[c - 128] == val) {
*found = 1;
return c;
}
/* Do scan on case of collision */
for (i = 0; i < 128; i++) {
unsigned char c = i + 128;
if (val == map->b.ascii->map_ascii_upper[i]) {
*found = 1;
return c;
}
}
return 0x3F; /* '?' */ /* Not found */
}
static uint16 cs_unicode_ascii_helper_0 P_((unsigned int ch,
struct map_info *map,
int *found));
static uint16 cs_unicode_ascii_helper_0(ch,map,found)
unsigned int ch;
struct map_info *map;
int *found;
{
uint16 val;
if (&cs_ascii != map->map_type || ch > 255)
panic("STRING PANIC",__FILE__,__LINE__,"cs_unicode_ascii_helper_0",
"Bad maptype or value",0);
val = map->b.ascii->map_ascii_upper[ch-128];
if (val != MAPPING_NONE) {
*found = 1;
return val;
}
return 0x003F; /* '?' */
}
static struct bindata_ops ascii_ops = {
cs_unicode_ascii_helper_0,
cs_map_ascii_rev_0
};
uint16 cs_unicode_ascii_helper_1(ch,map,found)
unsigned int ch;
struct map_info *map;
int *found;
{
if (ch <= 127) {
*found = 1;
return ch;
}
if (!map->map_initialized)
map->map_init_it(map);
if (&cs_ascii != map->map_type || ch > 255)
panic("STRING PANIC",__FILE__,__LINE__,"cs_unicode_ascii_helper_1",
"Bad maptype or value",0);
return map->d.binary_ops->map_it(ch,map,found);
}
unsigned char cs_map_ascii_rev(map,val,found)
struct map_info *map;
unsigned int val;
int *found;
{
unsigned char c;
int i;
*found = 0;
if (val < 128) {
*found = 1;
return val;
}
if (&cs_ascii != map->map_type)
panic("STRING PANIC",__FILE__,__LINE__,"cs_map_ascii_rev",
"Bad maptype",0);
return map->d.binary_ops->map_rev_it(map,val,found);
}
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);
}
#if ANSI_C
static set_map_callmap set_asciimap_value;
#endif
static int set_asciimap_value(name,map_info,l1,l2,fn)
CONST char *name;
struct map_info *map_info;
long l1;
long l2;
CONST char *fn;
{
if (map_info -> map_type != &cs_ascii)
panic("STRING PANIC",__FILE__,__LINE__,"set_asciimap_value",
"map_info bad",0);
if (l1 < 0 || l1 > 0xFF) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapBadValueL,
"Map %s: %s: Bad value: %ld"),
name,fn,l1);
return 0;
}
if (l2 < 0 || l2 > 0xFFFF) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapBadValueL,
"Map %s: %s: Bad value: %ld"),
name,fn,l2);
return 0;
}
if (l1 < 128) {
if (l1 != l2) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapBadValueL,
"Map %s: %s: Bad value: %ld"),
name,fn,l1);
return 0;
}
return 1;
}
map_info -> b.ascii->map_ascii_upper[l1-128] = l2;
return 1;
}
static void add_text_to_asciimap P_((CONST char *name,
struct map_info *map,
FILE *F, char *fn));
static void add_text_to_asciimap(name,map,F,fn)
CONST char *name;
struct map_info *map;
FILE *F;
char *fn;
{
static enum field_type vector[3] = {
val_byte, val_unicode, val_comment
};
int l;
if (map -> map_type != &cs_ascii)
panic("STRING PANIC",__FILE__,__LINE__,"add_text_to_asciimap",
"map bad",0);
if (!map -> b.ascii)
map -> b.ascii = safe_malloc(sizeof (* (map -> b.ascii)));
for (l = 0; l < 128; l++)
map -> b.ascii->map_ascii_upper[l] = MAPPING_NONE;
read_map_format_a(name,map,NULL,
F,
set_asciimap_value,
3,vector,fn);
map_ascii_init_rev(map);
}
static struct map_info * open_asciimap P_((const char *name));
static struct map_info * open_asciimap(name)
CONST char *name;
{
struct map_info *ret = NULL;
char *fn = NULL;
FILE *F = NULL;
struct bindata_mapped_data * F1 = default_bindata();
if (F1) {
struct bindata_map * X = give_mapping(F1,name);
if (X) {
ret = safe_malloc(sizeof (*ret));
ret -> map_type = &cs_ascii;
ret -> map_name = safe_strdup(name);
ret -> b.ascii = NULL;
ret -> c.bindata = X;
ret -> d.binary_ops = &bindata_ops;
ret -> map_initialized = 1;
ret -> map_init_it = map_init_bad;
DPRINT(Debug,5,(&Debug,
"Map %s -- using bindata\n",ret->map_name));
return ret;
}
}
F = open_mapname(name,&fn);
if (F) {
ret = safe_malloc(sizeof (*ret));
ret -> map_type = &cs_ascii;
ret -> map_name = safe_strdup(name);
ret -> b.ascii = safe_malloc(sizeof (* (ret -> b.ascii)));
ret -> c.dummy = NULL;
ret -> d.binary_ops = &ascii_ops;
ret -> map_initialized = 1;
ret -> map_init_it = map_init_bad;
add_text_to_asciimap(name,ret,F,fn);
fclose(F);
DPRINT(Debug,5,(&Debug,
"Map %s -- using text data\n",ret->map_name));
}
if (fn)
free(fn);
return ret;
}
/* US-ASCII ------------------------------------------------------------- */
static void map_init_us_ascii P_((struct map_info *map));
static void map_init_us_ascii(map)
struct map_info *map;
{
int i;
map -> b.ascii = safe_malloc(sizeof (* (map -> b.ascii)));
for (i = 0; i < 128; i++) {
map->b.ascii->map_ascii_upper[i] = MAPPING_NONE;
}
map_ascii_init_rev(map);
map->map_initialized = 1;
DPRINT(Debug,5,(&Debug,
"Map %s initialized\n",map->map_name));
}
struct map_info map_ascii = {
&cs_ascii, "US-ASCII", 0, map_init_us_ascii, NULL, NULL, &ascii_ops };
/* ISO-8859-1 ------------------------------------------------------------ */
static void map_init_latin1 P_((struct map_info *map));
static void map_init_latin1(map)
struct map_info *map;
{
int i;
map -> b.ascii = safe_malloc(sizeof (* (map -> b.ascii)));
for (i = 0; i < 128; i++) {
map->b.ascii->map_ascii_upper[i] = i + 128;
}
map_ascii_init_rev(map);
map->map_initialized = 1;
DPRINT(Debug,5,(&Debug,
"Map %s initialized\n",map->map_name));
}
struct map_info map_latin1 = {
&cs_ascii, "ISO-8859-1", 0, map_init_latin1, NULL, NULL, &ascii_ops };
/* KOI8-R ------------------------------------------------------------ */
/* Table compied from RFC 1489 */
static uint16 koi82unicode[128] = {
0x2500,0x2502,0x250c,0x2510,0x2514,0x2518,0x251c,0x2524,
0x252c,0x2534,0x253c,0x2580,0x2584,0x2588,0x258c,0x2590,
0x2591,0x2592,0x2593,0x2320,0x25a0,0x2219,0x221a,0x2248,
0x2264,0x2265,0x00a0,0x2321,0x00b0,0x00b2,0x00b7,0x00f7,
0x2550,0x2551,0x2552,0x0451,0x2553,0x2554,0x2555,0x2556,
0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,
0x255f,0x2560,0x2561,0x0401,0x2562,0x2563,0x2564,0x2565,
0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x00a9,
0x044e,0x0430,0x0431,0x0446,0x0434,0x0435,0x0444,0x0433,
0x0445,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,
0x043f,0x044f,0x0440,0x0441,0x0442,0x0443,0x0436,0x0432,
0x044c,0x044b,0x0437,0x0448,0x044d,0x0449,0x0447,0x044a,
0x042e,0x0410,0x0411,0x0426,0x0414,0x0415,0x0424,0x0413,
0x0425,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,
0x041f,0x042f,0x0420,0x0421,0x0422,0x0423,0x0416,0x0412,
0x042c,0x042b,0x0417,0x0428,0x042d,0x0429,0x0427,0x042a
};
static void map_init_koi8r P_((struct map_info *map));
static void map_init_koi8r(map)
struct map_info *map;
{
int i;
map -> b.ascii = safe_malloc(sizeof (* (map -> b.ascii)));
for (i = 0; i < 128; i++) {
map->b.ascii->map_ascii_upper[i] = koi82unicode[i];
}
map_ascii_init_rev(map);
map->map_initialized = 1;
DPRINT(Debug,5,(&Debug,
"Map %s initialized\n",map->map_name));
}
struct map_info map_koi8r = {
&cs_ascii, "KOI8-R", 0, map_init_koi8r, NULL, NULL, &ascii_ops };
/* KOI8-U ------------------------------------------------------------ */
/* Table compied from RFC 2319 */
/*
* The koi8-u is a "superset" of koi8-r -- adding the Ukrainian
* and Byelorussian specific characters at the expense of several
* of the pseudo-graphics characters. The KOI8-U RFC is 2319. See,
* for example: http://www.park.kiev.ua/multiling/koi8-u/rfc2319.txt
*/
struct charshort {
unsigned char byte;
unsigned short unicode;
} koi8u_additions[] = {
{ 164, 0x454 }, /* SMALL UKRAINIAN IE */
{ 166, 0x456 }, /* SMALL BYELORUSSIAN-UKRAINIAN I */
{ 167, 0x457 }, /* SMALL YI (UKRAINIAN) */
{ 173, 0x491 }, /* SMALL GHE WITH UPTURN */
{ 180, 0x403 }, /* CAPITAL UKRAINIAN IE */
{ 182, 0x406 }, /* CAPITAL BYELORUSSIAN-UKRAINIAN I */
{ 183, 0x407 }, /* CAPITAL YI (UKRAINIAN) */
{ 189, 0x490 }, /* CAPITAL GHE WITH UPTURN */
{ 0, 0 }
};
static void map_init_koi8u P_((struct map_info *map));
static void map_init_koi8u(map)
struct map_info *map;
{
struct charshort *replace;
int i;
map -> b.ascii = safe_malloc(sizeof (* (map -> b.ascii)));
/* Initialize with koi8r */
for (i = 0; i < 128; i++) {
map->b.ascii->map_ascii_upper[i] = koi82unicode[i];
}
/* replace the few koi8-u specific additions: */
for (replace = koi8u_additions; replace->byte; replace++)
map->b.ascii->map_ascii_upper[replace->byte-128] =
replace->unicode;
map_ascii_init_rev(map);
map->map_initialized = 1;
DPRINT(Debug,5,(&Debug,
"Map %s initialized\n",map->map_name));
}
struct map_info map_koi8u = {
&cs_ascii, "KOI8-U", 0, map_init_koi8u, NULL, NULL, &ascii_ops };
/* CP1251 ------------------------------------------------------------ */
/* Table compied from official Unicode mapping 2.01 */
static uint16 cp12512unicode[128] = {
0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021,
0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F,
0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
0x003F,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F,
0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7,
0x0401,0x00A9,0x0404,0x00AB,0x00AC,0x00AD,0x00AE,0x0407,
0x00B0,0x00B1,0x0406,0x0456,0x0491,0x00B5,0x00B6,0x00B7,
0x0451,0x2116,0x0454,0x00BB,0x0458,0x0405,0x0455,0x0457,
0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,
0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E,0x041F,
0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,
0x0428,0x0429,0x042A,0x042B,0x042C,0x042D,0x042E,0x042F,
0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,
0x0438,0x0439,0x043A,0x043B,0x043C,0x043D,0x043E,0x043F,
0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,
0x0448,0x0449,0x044A,0x044B,0x044C,0x044D,0x044E,0x044F
};
static void map_init_cp1251 P_((struct map_info *map));
static void map_init_cp1251(map)
struct map_info *map;
{
int i;
map -> b.ascii = safe_malloc(sizeof (* (map -> b.ascii)));
for (i = 0; i < 128; i++) {
map->b.ascii->map_ascii_upper[i] = cp12512unicode[i];
}
map_ascii_init_rev(map);
map->map_initialized = 1;
DPRINT(Debug,5,(&Debug,
"Map %s initialized\n",map->map_name));
}
struct map_info map_cp1251 = {
&cs_ascii, "CP1251", 0, map_init_cp1251, NULL, NULL, &ascii_ops };
/* CP1252 ------------------------------------------------------------ */
/* windows-1252 registeration gives:
Charset name: windows-1252
The name is suitable for use as the value of a MIME content-type
parameter.
Published specification(s):
http://www.microsoft.com/globaldev/reference/sbcs/1252.htm
*/
static uint16 cp12522unicode[128] = {
0x20AC,MAPPING_NONE,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
0x02C6,0x2030,0x0160,0x2039,0x0152,MAPPING_NONE,0x017D,MAPPING_NONE,
MAPPING_NONE,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
0x02DC,0x2122,0x0161,0x203A,0x0153,MAPPING_NONE,0x017E,0x0178,
/* rest of mapping is identity ... */
0x00A0,0x00A1,0x00A2,0x00A3,0x00A4,0x00A5,0x00A6,0x00A7,
0x00A8,0x00A9,0x00AA,0x00AB,0x00AC,0x00AD,0x00AE,0x00AF,
0x00B0,0x00B1,0x00B2,0x00B3,0x00B4,0x00B5,0x00B6,0x00B7,
0x00B8,0x00B9,0x00BA,0x00BB,0x00BC,0x00BD,0x00BE,0x00BF,
0x00C0,0x00C1,0x00C2,0x00C3,0x00C4,0x00C5,0x00C6,0x00C7,
0x00C8,0x00C9,0x00CA,0x00CB,0x00CC,0x00CD,0x00CE,0x00CF,
0x00D0,0x00D1,0x00D2,0x00D3,0x00D4,0x00D5,0x00D6,0x00D7,
0x00D8,0x00D9,0x00DA,0x00DB,0x00DC,0x00DD,0x00DE,0x00DF,
0x00E0,0x00E1,0x00E2,0x00E3,0x00E4,0x00E5,0x00E6,0x00E7,
0x00E8,0x00E9,0x00EA,0x00EB,0x00EC,0x00ED,0x00EE,0x00EF,
0x00F0,0x00F1,0x00F2,0x00F3,0x00F4,0x00F5,0x00F6,0x00F7,
0x00F8,0x00F9,0x00FA,0x00FB,0x00FC,0x00FD,0x00FE,0x00FF };
static void map_init_cp1252 P_((struct map_info *map));
static void map_init_cp1252(map)
struct map_info *map;
{
int i;
map -> b.ascii = safe_malloc(sizeof (* (map -> b.ascii)));
for (i = 0; i < 128; i++) {
map->b.ascii->map_ascii_upper[i] = cp12522unicode[i];
}
map_ascii_init_rev(map);
map->map_initialized = 1;
DPRINT(Debug,5,(&Debug,
"Map %s initialized\n",map->map_name));
}
struct map_info map_cp1252 = { &cs_ascii, "CP1252", 0,
map_init_cp1252, NULL, NULL, &ascii_ops };
/* ISO-8859-15 ---------------------------------------------------------- */
static uint16 iso8859152unicode[128] = {
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7,
0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7,
0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
};
static void map_init_885915 P_((struct map_info *map));
static void map_init_885915(map)
struct map_info *map;
{
int i;
map -> b.ascii = safe_malloc(sizeof (* (map -> b.ascii)));
for (i = 0; i < 128; i++) {
map->b.ascii->map_ascii_upper[i] = iso8859152unicode[i];
}
map_ascii_init_rev(map);
map->map_initialized = 1;
DPRINT(Debug,5,(&Debug,
"Map %s initialized\n",map->map_name));
}
struct map_info map_885915 = { &cs_ascii, "ISO-8859-15", 0, map_init_885915,
NULL, NULL, &ascii_ops };
/* bytemap --------------------------------------------------------------- */
static void map_bytemap_init_rev P_((struct map_info *map));
static void map_bytemap_init_rev(map)
struct map_info *map;
{
int i;
int col = 0;
for (i = 0; i < MAP_REV_MAP_DIV; i++)
map->b.bytemap->map_bytemap_rev[i] = 0;
for (i = 0; i < 256; i++) {
uint16 val = map->b.bytemap->map[i];
if (val != MAPPING_NONE) {
if (map->b.bytemap->map_bytemap_rev[val % MAP_REV_MAP_DIV])
col++;
map->b.bytemap->map_bytemap_rev[val % MAP_REV_MAP_DIV] = i;
}
}
if (col) {
DPRINT(Debug,5,(&Debug,
"Single byte map %s -- %d collisions\n",
map->map_name,col));
}
}
static unsigned char cs_map_bytemap_rev_0 P_((struct map_info *map,
unsigned int val,
int * found));
static unsigned char cs_map_bytemap_rev_0(map,val,found)
struct map_info *map;
unsigned int val;
int * found;
{
unsigned char c;
int i;
if (&cs_onebyte != map->map_type)
panic("STRING PANIC",__FILE__,__LINE__," cs_map_bytemap_rev_0",
"Bad maptype",0);
*found = 0;
c = map->b.bytemap->map_bytemap_rev[val % MAP_REV_MAP_DIV];
/* Check case no collision */
if (map->b.bytemap->map[c] == val) {
*found = 1;
return c;
}
if (!c)
return 0;
/* Do scan on case of collision */
for (i = 0; i < 256; i++) {
if (val == map->b.bytemap->map[i]) {
*found = 1;
return i;
}
}
return 0; /* Not found */
}
static uint16 cs_unicode_bytemap_helper_0 P_((unsigned int ch,
struct map_info *map,
int *found));
static uint16 cs_unicode_bytemap_helper_0(ch,map,found)
unsigned int ch;
struct map_info *map;
int *found;
{
uint16 val;
if (&cs_onebyte != map->map_type || ch > 255)
panic("STRING PANIC",__FILE__,__LINE__,"cs_unicode_bytemap_helper_0",
"Bad maptype or value",0);
val = map->b.bytemap->map[ch];
if (val != MAPPING_NONE) {
*found = 1;
return val;
}
return 0x003F; /* '?' */
}
static struct bindata_ops bytemap_ops = {
cs_unicode_bytemap_helper_0,
cs_map_bytemap_rev_0
};
uint16 cs_unicode_bytemap_helper_1(ch,map,found)
unsigned int ch;
struct map_info *map;
int *found;
{
if (&cs_onebyte != map->map_type || ch > 255)
panic("STRING PANIC",__FILE__,__LINE__,"cs_unicode_bytemap_helper_1",
"Bad maptype or value",0);
return map->d.binary_ops->map_it(ch,map,found);
}
unsigned char cs_map_bytemap_rev(map,val,found)
struct map_info *map;
unsigned int val;
int * found;
{
unsigned char c;
int i;
if (&cs_onebyte != map->map_type)
panic("STRING PANIC",__FILE__,__LINE__," cs_map_bytemap_rev",
"Bad maptype",0);
return map->d.binary_ops->map_rev_it(map,val,found);
}
#if ANSI_C
static set_map_callmap set_bytemap_value;
#endif
static int set_bytemap_value(name,map_info,l1,l2,fn)
CONST char *name;
struct map_info *map_info;
long l1;
long l2;
CONST char *fn;
{
if (map_info -> map_type != &cs_onebyte)
panic("STRING PANIC",__FILE__,__LINE__,"set_bytemap_value",
"map_info bad",0);
if (l1 < 0 || l1 > 0xFF) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapBadValueL,
"Map %s: %s: Bad value: %ld"),
name,fn,l1);
return 0;
}
if (l2 < 0 || l2 > 0xFFFF) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeMapBadValueL,
"Map %s: %s: Bad value: %ld"),
name,fn,l2);
return 0;
}
map_info -> b.bytemap->map[l1] = l2;
return 1;
}
static void add_text_to_bytemap P_((CONST char *name,
struct map_info *map,
FILE *F, char *fn));
static void add_text_to_bytemap(name,map,F,fn)
CONST char *name;
struct map_info *map;
FILE *F;
char *fn;
{
static enum field_type vector[3] = {
val_byte, val_unicode, val_comment
};
int l;
if (map -> map_type != &cs_onebyte)
panic("STRING PANIC",__FILE__,__LINE__,"add_text_to_bytemap",
"map bad",0);
if (!map -> b.bytemap)
map -> b.bytemap = safe_malloc(sizeof (* (map -> b.bytemap)));
/* We assume that values < 32 are same control characters
* on all sets -- after all MIME requires that on all
* character sets characters CR and LF are on same position
*/
for (l = 0; l < 32; l++)
map -> b.bytemap->map[l] = l;
for (l = 32; l < 256; l++)
map -> b.bytemap->map[l] = MAPPING_NONE;
read_map_format_a(name,map,NULL,
F,
set_bytemap_value,
3,vector,fn);
map_bytemap_init_rev(map);
}
static struct map_info * open_bytemap P_((const char *name));
static struct map_info * open_bytemap(name)
CONST char *name;
{
struct map_info *ret = NULL;
char *fn = NULL;
FILE *F = NULL;
struct bindata_mapped_data * F1 = default_bindata();
if (F1) {
struct bindata_map * X = give_mapping(F1,name);
if (X) {
ret = safe_malloc(sizeof (*ret));
ret -> map_type = &cs_onebyte;
ret -> map_name = safe_strdup(name);
ret -> b.bytemap = NULL;
ret -> c.bindata = X;
ret -> d.binary_ops = &bindata_ops;
ret -> map_initialized = 1;
ret -> map_init_it = map_init_bad;
DPRINT(Debug,5,(&Debug,
"Map %s -- using bindata\n",ret->map_name));
return ret;
}
}
F = open_mapname(name,&fn);
if (F) {
ret = safe_malloc(sizeof (struct map_info));
ret -> map_type = &cs_onebyte;
ret -> map_name = safe_strdup(name);
ret -> b.bytemap = safe_malloc(sizeof (* (ret -> b.bytemap)));
ret -> c.dummy = NULL;
ret -> d.binary_ops = &bytemap_ops;
ret -> map_initialized = 1;
ret -> map_init_it = map_init_bad;
add_text_to_bytemap(name,ret,F,fn);
fclose(F);
DPRINT(Debug,5,(&Debug,
"Map %s -- using text data\n",ret->map_name));
}
if (fn)
free(fn);
return ret;
}
/* ISO 646 -------------------------------------------------------------- */
static int variant_vector[12] = {
0x23, 0x24, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x60, 0x7B, 0x7C, 0x7D, 0x7E
};
static int variant_index P_((unsigned int ch));
static int variant_index(ch)
unsigned int ch;
{
switch (ch) {
case 0x23: return 0;
case 0x24: return 1;
case 0x40: return 2;
case 0x5B: return 3;
case 0x5C: return 4;
case 0x5D: return 5;
case 0x5E: return 6;
case 0x60: return 7;
case 0x7B: return 8;
case 0x7C: return 9;
case 0x7D: return 10;
case 0x7E: return 11;
}
return -1;
}
static unsigned char map_iso646_rev P_((struct map_info *map,
unsigned int val, int *found));
static unsigned char map_iso646_rev(map,val,found)
struct map_info *map;
unsigned int val;
int * found;
{
int i;
/* Same than on ASCII */
if (val < 128 && -1 == variant_index(val)) {
*found = 1;
return val;
}
if (map) {
if (!map->map_initialized)
map->map_init_it(map);
/* ISO 646 variant part */
for (i = 0; i < 12; i++) {
if (map->b.iso646->iso646[i] == val) {
*found = 1;
return variant_vector[i];
}
}
}
*found = 0;
return 0x3F; /* '?' */
}
static uint16 map_iso646 P_((struct map_info *map,
unsigned int ch));
static uint16 map_iso646(map,ch)
struct map_info *map;
unsigned int ch;
{
int idx;
if (ch > 128)
return MAPPING_NONE; /* iso646 sets are 7-bit */
idx = variant_index(ch);
if (-1 == idx) {
return ch; /* Invariant part */
}
if (map) {
if (!map->map_initialized)
map->map_init_it(map);
/* ISO 646 variant part */
return map->b.iso646->iso646[idx];
}
return MAPPING_NONE;
}
/* INVARIANT ------------------------------------------------------------ */
static void map_init_invariant P_((struct map_info *map));
static void map_init_invariant(map)
struct map_info *map;
{
int i;
map -> b.iso646 = safe_malloc(sizeof (* (map -> b.iso646)));
for (i = 0; i < 12; i++)
map->b.iso646->iso646[i] = MAPPING_NONE;
map->map_initialized = 1;
DPRINT(Debug,5,(&Debug,
"Map %s initialized\n",map->map_name));
}
struct map_info map_invariant = { &cs_iso646, "INVARIANT", 0,
map_init_invariant, NULL, NULL, NULL };
/* ----------------------------------------------------------------------- */
/* Used by generate_bindata and cs_find_ascii */
static struct map_info **asciimaps = NULL;
static int asciimap_count = 0;
/* Used by generate_bindata and cs_find_bytemap */
static struct map_info **bytemaps = NULL;
static int bytemap_count = 0;
struct bindata_mapped_data *generate_bindata()
{
struct bindata_mapped_data *r;
int c = asciimap_count + bytemap_count;
int i;
r = malloc_bindata(c);
for (i = 0; i < asciimap_count; i++) {
if (is_on_mapdir(asciimaps[i]->map_name)) {
/* MAP do not have necessary b.ascii structure
if bindata is on use, because we want regenerate it
we need parse textual map
*/
if (!asciimaps[i]->b.ascii) {
char *fn = NULL;
FILE * F = open_mapname(asciimaps[i]->map_name,&fn);
if (F) {
add_text_to_asciimap(asciimaps[i]->map_name,
asciimaps[i],F,fn);
fclose(F);
}
if (fn)
free(fn);
}
if (asciimaps[i]->b.ascii) {
uint16 vector[256];
int x;
for (x = 0; x < 128; x++)
vector[x] = x;
for (x = 128; x < 256; x++)
vector[x] = asciimaps[i]->b.ascii->map_ascii_upper[x-128];
DPRINT(Debug,4,(&Debug,
"... Adding ascii/upper map %s\n",
asciimaps[i]->map_name));
if (!add_bindata_map(r,vector,
asciimaps[i]->b.ascii->map_ascii_rev,
asciimaps[i]->map_name)) {
DPRINT(Debug,4,(&Debug,
"Ascii/upper map %s can't be added to binary table\n",
asciimaps[i]->map_name));
}
}
}
}
for (i = 0; i < bytemap_count; i++) {
if (is_on_mapdir(bytemaps[i]->map_name)) {
/* MAP do not have necessary b.bytemap structure
if bindata is on use, because we want regenerate it
we need parse textual map
*/
if (!bytemaps[i]->b.bytemap) {
char *fn = NULL;
FILE * F = open_mapname(bytemaps[i]->map_name,&fn);
if (F) {
add_text_to_bytemap(bytemaps[i]->map_name,
bytemaps[i],F,fn);
fclose(F);
}
if (fn)
free(fn);
}
if (bytemaps[i]->b.bytemap) {
DPRINT(Debug,4,(&Debug,
"... Adding single byte map %s\n",
bytemaps[i]->map_name));
if (!add_bindata_map(r,
bytemaps[i]->b.bytemap->map,
bytemaps[i]->b.bytemap->map_bytemap_rev,
bytemaps[i]->map_name)) {
DPRINT(Debug,4,(&Debug,
"Single byte map %s can't be added to binary table\n",
bytemaps[i]->map_name));
}
}
}
}
trim_bindata(r);
return r;
}
/* ======================================================================== */
static void cs_init_binary P_((struct string *str));
static void cs_init_binary(str)
struct string *str;
{
str->p->len = 0;
str->p->a.bytes = 0;
}
static void cs_free_binary P_((struct string *str));
static void cs_free_binary(str)
struct string *str;
{
if (str->p->a.bytes) {
free(str->p->a.bytes);
str->p->a.bytes = NULL;
}
str->p->len = 0;
}
static void cs_init_s_binary P_((struct charset_state *st));
static void cs_init_s_binary(st)
struct charset_state *st;
{
st->p->ready = 0;
st->p->a.byte = 0;
}
static void cs_free_s_binary P_((struct charset_state *st));
static void cs_free_s_binary(st)
struct charset_state *st;
{
st->p->ready = 0;
st->p->a.byte = 0;
}
static void cs_soft_reset_s_binary P_((struct charset_state *st));
static void cs_soft_reset_s_binary(st)
struct charset_state *st;
{
st->p->ready = 0;
st->p->a.byte = 0;
}
static int cs_add_streambyte_to_s_binary P_((struct charset_state *st,
int ch));
static int cs_add_streambyte_to_s_binary(st,ch)
struct charset_state *st;
int ch;
{
st->p->ready = 1;
st->p->a.byte = ch;
return 1;
}
static int cs_add_streambyte_to_binary P_((struct string *str,int ch));
static int cs_add_streambyte_to_binary(str,ch)
struct string *str;
int ch;
{
/* NOTE: str->p->a.bytes is not NUL terminated */
str->p->a.bytes = safe_realloc(str->p->a.bytes,str->p->len+1);
str->p->a.bytes[str->p->len++] = ch;
return 1;
}
static void cs_add_state_to_binary P_((struct string *str,
struct charset_state *ch));
static void cs_add_state_to_binary(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_binary",
"String/state type mismatch",0);
/* NOTE: str->p->a.bytes is not NUL terminated */
str->p->a.bytes = safe_realloc(str->p->a.bytes,str->p->len+1);
str->p->a.bytes[str->p->len++] = ch->p->a.byte;
}
static int cs_s_binary_same_char P_((struct charset_state *A,
struct charset_state *B,
int ignore_case));
static int cs_s_binary_same_char(A,B,ignore_case)
struct charset_state *A;
struct charset_state *B;
int ignore_case;
{
unsigned char c2 = B->p->a.byte;
unsigned char c1 = A->p->a.byte;
if (c1 == c2)
return 1;
if (!ignore_case)
return 0;
return -1; /* Use UNICODE comparision on upper level instead */
}
/* Returns number of bytes added */
static int cs_add_streambytes_to_binary P_((struct string *str,
int count,
const unsigned char *data,
int *errors));
static int cs_add_streambytes_to_binary(str,count,data, errors)
struct string *str;
int count;
CONST unsigned char *data;
int *errors;
{
int i;
if (count < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_add_streambytes_to_binary",
"Negative length",0);
*errors = 0;
if (count > 0) {
/* realloc with size 0 is equivalent of free and may
corrupt memory ...
*/
/* NOTE: str->p->a.bytes is not NUL terminated */
str->p->a.bytes = safe_realloc(str->p->a.bytes,str->p->len+count);
for (i = 0; i < count; i++)
str->p->a.bytes[str->p->len++] = data[i];
return count;
}
return 0;
}
static void cs_add_intdata_to_binary P_((struct string *str,
const struct string *data));
static void cs_add_intdata_to_binary(str,data)
struct string *str;
CONST struct string *data;
{
int i;
if (str->string_type->charset_type !=
data->string_type->charset_type)
panic("STRING PANIC",__FILE__,__LINE__,"cs_add_intdata_to_binary",
"String type mismatch",0);
if (data->p->len > 0) {
/* realloc with size 0 is equivalent of free and may
corrupt memory ...
*/
/* NOTE: str->p->a.bytes is not NUL terminated */
str->p->a.bytes = safe_realloc(str->p->a.bytes,
data->p->len+str->p->len);
for (i = 0; i < data->p->len; i++)
str->p->a.bytes[str->p->len++] = data->p->a.bytes[i];
}
}
static uint16 cs_unicode_bytemap_helper P_((unsigned int ch,
charset_t set, int *found));
static uint16 cs_unicode_bytemap_helper(ch,set, found)
unsigned int ch;
charset_t set;
int *found;
{
*found = 0;
if (set->map_info) {
return cs_unicode_bytemap_helper_1(ch,set->map_info,found);
}
/* We assume that values < 32 are same control characters
* on all sets -- after all MIME requires that on all
* character sets characters CR and LF are on same position
*/
if (ch < 32) {
*found = 1;
return ch;
}
return 0x005F; /* '_' */
}
/* Does compression, recalculation and so on ...
so 'const' is not very const
*/
static void cs_check_length_binary P_((const struct string *str));
static void cs_check_length_binary(str)
CONST struct string *str;
{
/* No compression */
}
static uint16 cs_give_unicode_from_bytemap P_((const struct string *str,
int pos, int *found));
static uint16 cs_give_unicode_from_bytemap(str,pos, found)
CONST struct string *str;
int pos;
int *found;
{
unsigned char ch;
if (pos < 0 || pos >= str->p->len)
panic("STRING PANIC",__FILE__,__LINE__,"cs_give_unicode_from_bytemap",
"Index out of array",0);
ch = str->p->a.bytes[pos];
return cs_unicode_bytemap_helper(ch,str->string_type,found);
}
static uint16 cs_give_unicode_from_s_bytemap P_((struct charset_state *st,
int *found));
static uint16 cs_give_unicode_from_s_bytemap(st,found)
struct charset_state *st;
int *found;
{
unsigned char ch;
ch = st->p->a.byte;
return cs_unicode_bytemap_helper(ch,st->charset,found);
}
static uint16 cs_unicode_ascii_helper P_((unsigned int ch,
charset_t set, int *found));
static uint16 cs_unicode_ascii_helper(ch,set, found)
unsigned int ch;
charset_t set;
int *found;
{
*found = 0;
/* Characters <= 127 are also UNICODE values on
US-ASCII and it's supersets
*/
if (ch <= 127) {
*found = 1;
return ch;
}
if (set->map_info) {
return cs_unicode_ascii_helper_1(ch,set->map_info,found);
}
return 0x005F; /* '_' */
}
static uint16 cs_give_unicode_from_ascii P_((const struct string *str,
int pos, int *found));
static uint16 cs_give_unicode_from_ascii(str,pos, found)
CONST struct string *str;
int pos;
int *found;
{
unsigned char ch;
if (pos < 0 || pos >= str->p->len)
panic("STRING PANIC",__FILE__,__LINE__,"cs_give_unicode_from_ascii",
"Index out of array",0);
ch = str->p->a.bytes[pos];
return cs_unicode_ascii_helper(ch,str->string_type,found);
}
static uint16 cs_give_unicode_from_s_ascii P_((struct charset_state *st,
int *found));
static uint16 cs_give_unicode_from_s_ascii(st,found)
struct charset_state *st;
int *found;
{
unsigned char ch;
ch = st->p->a.byte;
return cs_unicode_ascii_helper(ch,st->charset,found);
}
static uint16 cs_give_unicode_from_iso646 P_((const struct string *str,
int pos, int *found));
static uint16 cs_give_unicode_from_iso646(str,pos, found)
CONST struct string *str;
int pos;
int *found;
{
unsigned char ch;
uint16 res;
if (pos < 0 || pos >= str->p->len)
panic("STRING PANIC",__FILE__,__LINE__,"cs_give_unicode_from_iso646",
"Index out of array",0);
*found = 0;
ch = str->p->a.bytes[pos];
res = map_iso646(str->string_type->map_info,ch);
if (res != MAPPING_NONE)
*found = 1;
else
res = 0x003F; /* '?' */
return res;
}
static uint16 cs_give_unicode_from_s_iso646 P_((struct charset_state *st,
int *found));
static uint16 cs_give_unicode_from_s_iso646(st,found)
struct charset_state *st;
int *found;
{
unsigned char ch;
uint16 res;
*found = 0;
ch = st->p->a.byte;
res = map_iso646(st->charset->map_info,ch);
if (res == MAPPING_NONE)
res = 0x003F; /* '?' */
else
*found = 1;
return res;
}
static void cs_add_unicodedata_to_bytemap P_((struct string *str,
int len, const uint16 *data));
static void cs_add_unicodedata_to_bytemap(str,len,data)
struct string *str;
int len;
CONST uint16 *data;
{
int i;
if (len < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_add_unicodedata_to_bytemap",
"Negative length",0);
if (len > 0) {
/* realloc with size 0 is equivalent of free and may
corrupt memory ...
*/
/* NOTE: str->p->a.bytes is not NUL terminated */
str->p->a.bytes = safe_realloc(str->p->a.bytes,len+str->p->len);
for (i = 0; i < len; i++) {
int found = 0;
unsigned char ch = '\0';
if (str->string_type->map_info) {
ch = cs_map_bytemap_rev(str->string_type->map_info,data[i],
&found);
if (!found) {
/* Try replacement character ... */
ch = cs_map_bytemap_rev(str->string_type->map_info,
0x005F /* '_' */,
&found);
}
}
/* We assume that values < 32 are same control characters
* on all sets -- after all MIME requires that on all
* character sets characters CR and LF are on same position
*/
if (found)
str->p->a.bytes[str->p->len++] = ch;
else if (data[i] < 32)
str->p->a.bytes[str->p->len++] = data[i];
/* Because character set is unknow we do not know any
* replacement character what we can use, therefore
* we add nothing
*/
}
}
}
static void cs_add_unicodedata_to_ascii P_((struct string *str,
int len, const uint16 *data));
static void cs_add_unicodedata_to_ascii(str,len,data)
struct string *str;
int len;
CONST uint16 *data;
{
int i;
if (len < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_add_unicodedata_to_ascii",
"Negative length",0);
if (len > 0) {
/* realloc with size 0 is equivalent of free and may
corrupt memory ...
*/
/* NOTE: str->p->a.bytes is not NUL terminated */
str->p->a.bytes = safe_realloc(str->p->a.bytes,len+str->p->len);
for (i = 0; i < len; i++) {
int found; /* Not used */
/* Characters <= 127 are also UNICODE values on
US-ASCII and it's supersets
*/
if (data[i] <= 127)
str->p->a.bytes[str->p->len++] = data[i];
else if (str->string_type->map_info) {
if (!str->string_type->map_info->map_initialized)
str->string_type->map_info->map_init_it(str->string_type->map_info);
str->p->a.bytes[str->p->len++] =
cs_map_ascii_rev(str->string_type->map_info,data[i],&found);
} else
str->p->a.bytes[str->p->len++] = 0x5F; /* '_' */
}
}
}
static void cs_add_unicodedata_to_iso646 P_((struct string *str,
int len, const uint16 *data));
static void cs_add_unicodedata_to_iso646(str,len,data)
struct string *str;
int len;
CONST uint16 *data;
{
int i;
if (len > 0) {
/* realloc with size 0 is equivalent of free and may
corrupt memory ...
*/
/* NOTE: str->p->a.bytes is not NUL terminated */
str->p->a.bytes = safe_realloc(str->p->a.bytes,len+str->p->len);
for (i = 0; i < len; i++) {
int found = 0;
unsigned char ch = map_iso646_rev(str->string_type->map_info,
data[i],
&found);
if (found)
str->p->a.bytes[str->p->len++] = ch;
else
str->p->a.bytes[str->p->len++] = 0x5F; /* '_' */
}
}
}
static int cs_cmp_binary P_((const struct string *str1,const struct string *str2));
static int cs_cmp_binary(str1,str2)
CONST struct string *str1;
CONST struct string *str2;
{
int i;
if (str1->string_type->charset_type !=
str2->string_type->charset_type)
panic("STRING PANIC",__FILE__,__LINE__,"cs_cmp_binary",
"String type mismatch",0);
for (i = 0; i < str1->p->len && i < str2->p->len; i++) {
if (str1->p->a.bytes[i] < str2->p->a.bytes[i])
return -1;
if (str1->p->a.bytes[i] > str2->p->a.bytes[i])
return 1;
}
if (i < str1->p->len)
return 1;
if (i < str2->p->len)
return -1;
return 0;
}
#ifndef ASCII_CTYPE
unsigned char *cs_stream_from_locale P_((const struct string *str,
int *reslen));
unsigned char *cs_stream_from_locale(str,reslen)
CONST struct string *str;
int *reslen;
{
unsigned char * ret;
int l = 0,i;
ret = safe_malloc(str->p->len+1);
for (i = 0; i < str->p->len; i++) {
if (!isprint(str->p->a.bytes[i]))
ret[l++] = '?';
else
ret[l++] = str->p->a.bytes[i];
}
ret[l] = '\0';
*reslen = l;
return ret;
}
int cs_s_locale_printable P_((struct charset_state *st));
int cs_s_locale_printable(st)
struct charset_state *st;
{
unsigned char c1 = st->p->a.byte;
return isprint(c1);
}
#endif
static int cs_s_generic_printable P_((struct charset_state *st));
static int cs_s_generic_printable(st)
struct charset_state *st;
{
#ifndef ASCII_CTYPE
if (st->charset == system_charset)
return cs_s_locale_printable(st);
#endif
return -1; /* Use unicode values */
}
static int cs_s_binary_is_onebyte P_((struct charset_state *st));
static int cs_s_binary_is_onebyte(st)
struct charset_state *st;
{
unsigned char c1 = st->p->a.byte;
return c1;
}
static unsigned char *cs_stream_from_bytemap P_((const struct string *str,
int printable,
screen_info_p terminal,
int *reslen));
static unsigned char *cs_stream_from_bytemap(str,printable,terminal,reslen)
CONST struct string *str;
int printable;
screen_info_p terminal; /* NOT USED */
int *reslen;
{
unsigned char * ret;
int l = 0,i;
#ifndef ASCII_CTYPE
if (printable &&
str->string_type == system_charset)
return cs_stream_from_locale(str,reslen);
#endif
ret = safe_malloc(str->p->len+1);
if (printable) {
for (i = 0; i < str->p->len; i++) {
int found;
uint16 X = cs_unicode_bytemap_helper(str->p->a.bytes[i],
str->string_type,&found);
/* Check if correspond UNICODE character is printable
*/
if (found && unicode_ch(X,UOP_printable))
ret[l++] = str->p->a.bytes[i];
else {
/* Try replacement character ... */
unsigned char ch;
int found;
ch = cs_map_bytemap_rev(str->string_type->map_info,
0x003F /* '?' */,
&found);
if (found)
ret[l++] = ch;
/* Because charset is unknown we do not have able to print
* printable characters -- also we do not know replacement
* character....
*/
}
}
} else {
for (i = 0; i < str->p->len; i++) {
ret[l++] = str->p->a.bytes[i];
}
}
ret[l] = '\0';
*reslen = l;
return ret;
}
static unsigned char *cs_stream_from_ascii P_((const struct string *str,
int printable,
screen_info_p terminal,
int *reslen));
static unsigned char *cs_stream_from_ascii(str,printable,terminal,reslen)
CONST struct string *str;
int printable;
screen_info_p terminal; /* NOT USED */
int *reslen;
{
unsigned char * ret;
int l = 0,i;
#ifndef ASCII_CTYPE
if (printable &&
str->string_type == system_charset)
return cs_stream_from_locale(str,reslen);
#endif
ret = safe_malloc(str->p->len+1);
for (i = 0; i < str->p->len; i++) {
if (str->p->a.bytes[i] < 32 && printable)
ret[l++] = 0x3F; /* '?' */
else if (str->p->a.bytes[i] > 126 && printable) {
int found;
uint16 X = cs_unicode_ascii_helper(str->p->a.bytes[i],
str->string_type,&found);
if (found && unicode_ch(X,UOP_printable))
ret[l++] = str->p->a.bytes[i];
else
ret[l++] = 0x3F; /* '?' */
} else
ret[l++] = str->p->a.bytes[i];
}
ret[l] = '\0';
*reslen = l;
return ret;
}
static unsigned char *cs_stream_from_iso646 P_((const struct string *str,
int printable,
screen_info_p terminal,
int *reslen));
static unsigned char *cs_stream_from_iso646(str,printable,terminal,reslen)
CONST struct string *str;
int printable;
screen_info_p terminal; /* NOT USED */
int *reslen;
{
unsigned char * ret;
int l = 0,i;
#ifndef ASCII_CTYPE
if (printable &&
str->string_type == system_charset)
return cs_stream_from_locale(str,reslen);
#endif
ret = safe_malloc(str->p->len+1);
for (i = 0; i < str->p->len; i++) {
if ((str->p->a.bytes[i] < 32 && printable) ||
(str->p->a.bytes[i] > 126 && printable))
ret[l++] = 0x3F; /* '?' */
/* ISO 646 variant part */
else if (printable) {
if (map_iso646(str->string_type->map_info,str->p->a.bytes[i])
!= MAPPING_NONE)
ret[l++] = str->p->a.bytes[i]; /* Assume printable */
else
ret[l++] = 0x3F; /* '?' */
} else
ret[l++] = str->p->a.bytes[i];
}
ret[l] = '\0';
*reslen = l;
return ret;
}
#ifndef ASCII_CTYPE
unsigned char *cs_streamclip_from_locale(str,pos,len)
CONST struct string *str;
int *pos;
int len;
{
unsigned char * ret;
int l = 0,i;
ret = safe_malloc(len+1);
for (i = 0; i < len && *pos < str->p->len; i++, (*pos)++) {
if (!isprint(str->p->a.bytes[*pos]))
ret[l++] = '?';
else
ret[l++] = str->p->a.bytes[*pos];
}
ret[l] = '\0';
return ret;
}
#endif
static unsigned char *cs_streamclip_from_bytemap P_((const struct string *str,
int *pos, int len,
screen_info_p terminal,
struct cs_printable_len *printable_len));
static unsigned char *cs_streamclip_from_bytemap(str,pos,len,terminal,printable_len)
CONST struct string *str;
int *pos;
int len;
screen_info_p terminal; /* NOT USED */
struct cs_printable_len *printable_len; /* NOT USED */
{
unsigned char * ret;
int l = 0,i;
if (*pos < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_streamclip_from_bytemap",
"Index out of array",0);
if (len < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_streamclip_from_bytemap",
"Negative size",0);
#ifndef ASCII_CTYPE
if (str->string_type == system_charset)
return cs_streamclip_from_locale(str,pos,len);
#endif
ret = safe_malloc(len+1);
for (i = 0; i < len && *pos < str->p->len; i++, (*pos)++) {
int found;
uint16 X = cs_unicode_bytemap_helper(str->p->a.bytes[*pos],
str->string_type,&found);
if (found && unicode_ch(X,UOP_printable))
ret[l++] = str->p->a.bytes[*pos];
else {
/* Try replacement character ... */
unsigned char ch;
int found;
ch = cs_map_bytemap_rev(str->string_type->map_info,
0x003F /* '?' */,
&found);
if (found)
ret[l++] = ch;
/* Because charset is unknown we do not have able to print
* printable characters -- also we do not know replacement
* character....
*/
}
}
ret[l] = '\0';
return ret;
}
static unsigned char *cs_streamclip_from_ascii P_((const struct string *str,
int *pos, int len,
screen_info_p terminal,
struct cs_printable_len *printable_len));
static unsigned char *cs_streamclip_from_ascii(str,pos,len,terminal,printable_len)
CONST struct string *str;
int *pos;
int len;
screen_info_p terminal; /* NOT USED */
struct cs_printable_len *printable_len; /* NOT USED */
{
unsigned char * ret;
int l = 0,i;
if (*pos < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_streamclip_from_ascii",
"Index out of array",0);
if (len < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_streamclip_from_ascii",
"Negative size",0);
#ifndef ASCII_CTYPE
if (str->string_type == system_charset)
return cs_streamclip_from_locale(str,pos,len);
#endif
ret = safe_malloc(len+1);
for (i = 0; i < len && *pos < str->p->len; i++, (*pos)++) {
if (str->p->a.bytes[*pos] < 32)
ret[l++] = 0x3F; /* '?' */
else if (str->p->a.bytes[*pos] > 126) {
int found;
uint16 X = cs_unicode_ascii_helper(str->p->a.bytes[*pos],
str->string_type,&found);
if (found && unicode_ch(X,UOP_printable))
ret[l++] = str->p->a.bytes[*pos];
else
ret[l++] = 0x3F; /* '?' */
} else
ret[l++] = str->p->a.bytes[*pos];
}
ret[l] = '\0';
return ret;
}
static unsigned char *cs_streamclip_from_iso646 P_((const struct string *str,
int *pos, int len,
screen_info_p terminal,
struct cs_printable_len *printable_len));
static unsigned char *cs_streamclip_from_iso646(str,pos,len,terminal,printable_len)
CONST struct string *str;
int *pos;
int len;
screen_info_p terminal; /* NOT USED */
struct cs_printable_len *printable_len; /* NOT USED */
{
unsigned char * ret;
int i, l=0;
if (*pos < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_streamclip_from_iso646",
"Index out of array",0);
if (len < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_streamclip_from_iso646",
"Negative size",0);
#ifndef ASCII_CTYPE
if (str->string_type == system_charset)
return cs_streamclip_from_locale(str,pos,len);
#endif
ret = safe_malloc(len+1);
for (i = 0; i < len && *pos < str->p->len; i++, (*pos)++) {
if (str->p->a.bytes[*pos] < 32 ||
str->p->a.bytes[*pos] > 126)
ret[l++] = 0x3F; /* '?' */
/* ISO 646 variant part */
else if (MAPPING_NONE != map_iso646(str->string_type->map_info,
str->p->a.bytes[*pos]))
ret[l++] = str->p->a.bytes[*pos]; /* Assume printable */
else
ret[l++] = 0x3F; /* '?' */
}
ret[l] = '\0';
return ret;
}
static void cs_clip_from_binary P_((struct string *ret,
const struct string *str,
int *pos, int len));
static void cs_clip_from_binary(ret,str,pos,len)
struct string *ret;
CONST struct string *str;
int *pos;
int len;
{
int i;
if (ret->string_type->charset_type !=
str->string_type->charset_type)
panic("STRING PANIC",__FILE__,__LINE__,"cs_clip_from_binary",
"String type mismatch",0);
if (*pos < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_clip_from_binary",
"Index out of array",0);
if (len < 0)
panic("STRING PANIC",__FILE__,__LINE__,"cs_clip_from_binary",
"Negative size",0);
if (len > 0) {
int POS = *pos;
int source_len = str->p->len;
unsigned char * target_bytes;
unsigned char * source_bytes = str->p->a.bytes;
/* realloc with len == 0 is equivalent of freeing and
may result corruption of memory ...
*/
/* NOTE: str->p->a.bytes is not NUL terminated */
ret->p->a.bytes = safe_realloc(ret->p->a.bytes,len);
ret->p->len = 0;
target_bytes = ret->p->a.bytes;
for (i = 0; i < len && POS < source_len; i++, POS++) {
target_bytes[i] = source_bytes[POS];
}
ret->p->len = i;
*pos = POS;
} else {
/* NULL (empty) string */
if (ret->p->a.bytes)
free(ret->p->a.bytes);
ret->p->a.bytes = NULL;
ret->p->len = 0;
}
}
static int cs_can_ascii_bytemap P_((const struct string *str));
static int cs_can_ascii_bytemap(str)
CONST struct string *str;
{
if (str->string_type->map_info) {
int i;
for (i = 0; i < str->p->len; i++) {
unsigned char ch = str->p->a.bytes[i];
int found;
uint16 val = val =
cs_unicode_bytemap_helper_1(ch,str->string_type->map_info,
&found);
if (!found || val > 127)
return 0;
}
return 1;
} else
return 0;
}
static int cs_can_ascii_ascii P_((const struct string *str));
static int cs_can_ascii_ascii(str)
CONST struct string *str;
{
int i;
for (i = 0; i < str->p->len; i++) {
/* NOTE: str->p->a.bytes is unsigned */
if (str->p->a.bytes[i] > 127)
return 0;
}
return 1;
}
static int cs_can_ascii_iso646 P_((const struct string *str));
static int cs_can_ascii_iso646(str)
CONST struct string *str;
{
int i;
for (i = 0; i < str->p->len; i++) {
/* NOTE: str->p->a.bytes is unsigned */
if (str->p->a.bytes[i] > 127)
return 0;
/* MAPPING_NONE > 127 */
if (map_iso646(str->string_type->map_info,
str->p->a.bytes[i]) > 127)
return 0;
}
return 1;
}
#ifndef ASCII_CTYPE
int cs_find_pattern_from_locale(str,pattern)
CONST struct string *str;
CONST struct string *pattern;
{
int ret = 0;
int i, j;
for (i = 0; i < str->p->len; ) {
CONST int s = i + 1;
for (j = 0; j < pattern->p->len && i < str->p->len; j++,i++) {
unsigned char c2 = pattern->p->a.bytes[j];
unsigned char c1 = str->p->a.bytes[i];
c1 = tolower(c1);
c2 = tolower(c2);
if (c1 != c2)
break;
}
if (j >= pattern->p->len) {
DPRINT(Debug,63,(&Debug,
"cs_find_pattern_from_locale=1 MATCH -- str='%.*s' pattern='%.*s'\n",
str->p->len,str->p->a.bytes,
pattern->p->len,pattern->p->a.bytes));
ret = 1;
break;
}
i = s;
}
if (!ret) {
DPRINT(Debug,63,(&Debug,
"cs_find_pattern_from_locale=0 NO MATCH -- str='%.*s' pattern='%.*s'\n",
str->p->len,str->p->a.bytes,
pattern->p->len,pattern->p->a.bytes));
}
return ret;
}
#endif
static int cs_find_pattern_from_bytemap P_((const struct string *str,
const struct string *pattern,
int ignore_case));
static int cs_find_pattern_from_bytemap(str,pattern,ignore_case)
CONST struct string *str;
CONST struct string *pattern;
int ignore_case;
{
if (pattern->string_type != str->string_type)
panic("STRING PANIC",__FILE__,__LINE__,"cs_find_pattern_from_bytemap",
"Charset mismatch",0);
#ifndef ASCII_CTYPE
if (ignore_case && str->string_type == system_charset)
return cs_find_pattern_from_locale(str,pattern);
#endif
return -1; /* Use UNICODE comparision on upper level instead */
}
static int cs_find_pattern_from_ascii P_((const struct string *str,
const struct string *pattern,
int ignore_case));
static int cs_find_pattern_from_ascii(str,pattern,ignore_case)
CONST struct string *str;
CONST struct string *pattern;
int ignore_case;
{
int ret = 0;
int i, j;
if (pattern->string_type->charset_type !=
str->string_type->charset_type)
panic("STRING PANIC",__FILE__,__LINE__,"cs_find_pattern_from_ascii",
"String type mismatch",0);
#ifndef ASCII_CTYPE
if (ignore_case && str->string_type == system_charset)
return cs_find_pattern_from_locale(str,pattern);
#endif
for (i = 0; i < str->p->len; ) {
CONST int s = i + 1;
for (j = 0; j < pattern->p->len && i < str->p->len; j++,i++) {
unsigned char c2 = pattern->p->a.bytes[j];
unsigned char c1 = str->p->a.bytes[i];
if (ignore_case && (c1 >= 0x80 || c2 >= 0x80)) {
/* Use UNICODE comparision on upper level instead */
DPRINT(Debug,63,(&Debug,
"cs_find_pattern_from_ascii=-1\n"));
return -1;
}
if (ignore_case && c1 >= 0x41 && c1 <= 0x5A) {
c1 = ( c1 - 0x41) + 0x61;
}
if (ignore_case && c2 >= 0x41 && c2 <= 0x5A) {
c2 = ( c2 - 0x41) + 0x61;
}
if (c1 != c2)
break;
}
if (j >= pattern->p->len) {
DPRINT(Debug,63,(&Debug,
"cs_find_pattern_from_ascii=1 MATCH\n"));
ret = 1;
break;
}
i = s;
}
if (!ret) {
DPRINT(Debug,63,(&Debug,
"cs_find_pattern_from_ascii=0 NO MATCH\n"));
}
return ret;
}
static int cs_find_pattern_from_iso646 P_((const struct string *str,
const struct string *pattern,
int ignore_case));
static int cs_find_pattern_from_iso646(str,pattern,ignore_case)
CONST struct string *str;
CONST struct string *pattern;
int ignore_case;
{
int ret = 0;
int i, j;
if (pattern->string_type->charset_type !=
str->string_type->charset_type)
panic("STRING PANIC",__FILE__,__LINE__,"cs_find_pattern_from_iso646",
"String type mismatch",0);
#ifndef ASCII_CTYPE
if (ignore_case && str->string_type == system_charset)
return cs_find_pattern_from_locale(str,pattern);
#endif
for (i = 0; i < str->p->len; ) {
CONST int s = i + 1;
for (j = 0; j < pattern->p->len && i < str->p->len; j++,i++) {
/* TODO: We should check also mapping to unicode and use
unicode information to see what is lowecase equivalent
of character...
*/
unsigned char c2 = pattern->p->a.bytes[j];
unsigned char c1 = str->p->a.bytes[i];
if (ignore_case && c1 >= 0x41 && c1 <= 0x5A) {
c1 = ( c1 - 0x41) + 0x61;
}
if (ignore_case && c2 >= 0x41 && c2 <= 0x5A) {
c2 = ( c2 - 0x41) + 0x61;
}
if (c1 != c2)
break;
}
if (j >= pattern->p->len) {
DPRINT(Debug,63,(&Debug,
"cs_find_pattern_from_iso646=1 MATCH\n"));
ret = 1;
break;
}
i = s;
}
if (!ret) {
DPRINT(Debug,63,(&Debug,
"cs_find_pattern_from_iso646=0 NO MATCH\n"));
}
return ret;
}
#ifndef ASCII_CTYPE
void cs_remove_control_locale(str,repl)
CONST struct string *str;
unsigned int repl;
{
int i;
for (i = 0; i < str->p->len; i++) {
if (iscntrl(str->p->a.bytes[i]))
str->p->a.bytes[i] = repl;
}
}
#endif
static void cs_remove_control_ascii P_((const struct string *str));
static void cs_remove_control_ascii(str)
CONST struct string *str;
{
int i;
#ifndef ASCII_CTYPE
/* 32 is space on ascii... */
if (str->string_type == system_charset) {
cs_remove_control_locale(str,32);
return;
}
#endif
for (i = 0; i < str->p->len; i++) {
if (str->p->a.bytes[i] < 32 ||
str->p->a.bytes[i] == 127)
str->p->a.bytes[i] = 32;
else if (str->p->a.bytes[i] > 127 &&
str->string_type->map_info) {
unsigned char ch = str->p->a.bytes[i];
int found;
uint16 val = cs_unicode_ascii_helper_1(ch,str->string_type->map_info,&found);
if (!found ||
unicode_ch(val,UOP_noctrl) == 0)
str->p->a.bytes[i] = 32;
}
}
}
static void cs_remove_control_bytemap P_((const struct string *str));
static void cs_remove_control_bytemap(str)
CONST struct string *str;
{
int i;
int found;
unsigned char rep = 32;
if (str->string_type->map_info)
rep = cs_map_bytemap_rev(str->string_type->map_info,
0x0020 /* '?' */,
&found);
#ifndef ASCII_CTYPE
if (str->string_type == system_charset) {
cs_remove_control_locale(str,rep);
return;
}
#endif
for (i = 0; i < str->p->len; i++) {
if (str->string_type->map_info) {
unsigned char ch = str->p->a.bytes[i];
int found;
uint16 val = cs_unicode_bytemap_helper_1(ch,str->string_type->map_info,&found);
if (!found ||
unicode_ch(val,UOP_noctrl) == 0)
str->p->a.bytes[i] = rep;
}
/* We assume that values < 32 are same control characters
* on all sets -- after all MIME requires that on all
* character sets characters CR and LF are on same position
*/
else if (str->p->a.bytes[i] < 32)
str->p->a.bytes[i] = rep;
}
}
static void cs_remove_control_iso646 P_((const struct string *str));
static void cs_remove_control_iso646(str)
CONST struct string *str;
{
int i;
for (i = 0; i < str->p->len; i++) {
if (str->p->a.bytes[i] < 32 ||
str->p->a.bytes[i] >= 127)
str->p->a.bytes[i] = 32;
else {
if (map_iso646(str->string_type->map_info,str->p->a.bytes[i])
== MAPPING_NONE)
str->p->a.bytes[i] = 0x3F; /* '?' */
}
}
}
static struct map_info * cs_find_bytemap P_((const char * map_name));
static struct map_info * cs_find_bytemap(map_name)
CONST char * map_name;
{
int i;
struct map_info *ret;
for (i =0; i < bytemap_count; i++)
if (0 == strcmp(bytemaps[i]->map_name,map_name))
return bytemaps[i];
ret = open_bytemap(map_name);
if (ret) {
bytemaps = safe_realloc(bytemaps,
(bytemap_count + 1) *
sizeof (struct map_info *));
bytemaps[bytemap_count++] = ret;
}
return ret;
}
static struct map_info * cs_find_ascii P_((const char * map_name));
static struct map_info * cs_find_ascii(map_name)
CONST char * map_name;
{
struct map_info *ret;
int i;
static struct map_info * maps[] = { &map_ascii, &map_latin1,
&map_koi8r, &map_cp1251,
&map_cp1252, &map_koi8u,
&map_885915, NULL };
for (i = 0; maps[i]; i++)
if (0 == strcmp(map_name,maps[i]->map_name))
return maps[i];
for (i =0; i < asciimap_count; i++)
if (0 == strcmp(asciimaps[i]->map_name,map_name))
return asciimaps[i];
ret = open_asciimap(map_name);
if (ret) {
asciimaps = safe_realloc(asciimaps,
(asciimap_count + 1) *
sizeof (struct map_info *));
asciimaps[asciimap_count++] = ret;
}
return ret;
}
static struct map_info * cs_find_iso646 P_((const char * map_name));
static struct map_info * cs_find_iso646(map_name)
CONST char * map_name;
{
int vector[12];
char * str, *p;
struct map_info * ret = NULL;
int i;
int err = 0;
static struct map_info ** dyn_maps = NULL;
static int dyn_map_count = 0;
if (0 == istrcmp(map_name,map_invariant.map_name))
return &map_invariant;
for (i =0; i < dyn_map_count; i++)
if (0 == strcmp(dyn_maps[i]->map_name,map_name))
return dyn_maps[i];
str = safe_strdup(map_name);
i = 0;
for (p = strtok(str," \t,"); p; p = strtok(NULL," \t,")) {
char *c = '\0';
long l;
if (i >= 12) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeTooManyPositions,
"Map %s: Too many positions given on defination"),
map_name);
err++;
break;
}
if (0 == strcmp(p,"-"))
vector[i] = l = MAPPING_NONE;
else if ('#' == p[0])
vector[i] = l = strtol(p+1,&c,10);
else
vector[i] = l = strtol(p,&c,16);
if (*c || l < 0 || l > 0xFFFF) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeTooManyPositions,
"Map %s: Bad value on position: %s"),
map_name,p);
err++;
}
i++;
}
if (i < 12) {
lib_error(CATGETS(elm_msg_cat, MeSet,MeTooFewPositions,
"Map %s: Too few positions given on defination"),
map_name);
err++;
}
if (!err) {
for (i = 0; i < dyn_map_count; i++) {
int j;
for (j = 0; j < 12; j++)
if (vector[j] != dyn_maps[i]->b.iso646->iso646[j])
break;
if (12 == j)
ret = dyn_maps[i];
}
}
if (!err && !ret) {
ret = safe_malloc(sizeof (struct map_info));
ret -> map_type = &cs_iso646;
ret -> map_name = safe_strdup(map_name);
ret -> b.iso646 = safe_malloc(sizeof (* (ret -> b.iso646)));
ret -> map_initialized = 1;
ret -> map_init_it = map_init_bad;
for (i = 0; i < 12; i++)
ret->b.iso646->iso646[i] = vector[i];
dyn_maps = safe_realloc(dyn_maps,
(dyn_map_count + 1) *
sizeof (struct map_info *));
dyn_maps[dyn_map_count++] = ret;
}
free(str);
return ret;
}
static int cs_iso646_properties P_((charset_t st));
static int cs_iso646_properties(st)
charset_t st;
{
int prop = 0;
/* We know at least invariant part of charset */
prop |= CS_mapping | CS_printable;
return prop;
}
static int cs_onebyte_properties P_((charset_t st));
static int cs_onebyte_properties(st)
charset_t st;
{
int prop = 0;
if (st->map_info)
prop |= CS_mapping | CS_printable;
#ifndef ASCII_CTYPE
/* We know printable characters from locale */
if (system_charset == st)
prop |= CS_printable;
#endif
return prop;
}
static int cs_ascii_properties P_((charset_t st));
static int cs_ascii_properties(st)
charset_t st;
{
int prop = 0;
/* We know at least ascii part of charset */
prop |= CS_printable | CS_mapping;
return prop;
}
#if ANSI_C
#define S_(x) static x;
#else
#define S_(x)
#endif
S_(cs_estimate_clip_string cs_estimate_clip_unsupported)
static int cs_estimate_clip_unsupported(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;
{
panic("STRING PANIC",__FILE__,__LINE__,"cs_estimate_clip_unsupported",
"cs_estimate_clip_unsupported() called",0);
return -1;
}
int cs_info_set_scan(new_vals,new_setlist,setcount,ptr_94,ptr_96,
banks)
struct charcode_info *new_vals;
struct setlist *new_setlist;
int setcount;
int *ptr_94;
int *ptr_96;
int banks[ISO2022_BANK_NUM];
{
int i;
for (i = 0; i < ISO2022_BANK_NUM; i++)
banks[i] = -1;
/* Non ISO2022 charsets there may be only on 94 and one 96 set */
for (i = 0; i < setcount; i++) {
switch (new_setlist->sets[i]->type) {
case iso2022_94x94:
case iso2022_94:
if (-1 == *ptr_94)
*ptr_94 = i;
else {
lib_error(CATGETS(elm_msg_cat, MeSet, MeNoSeveral94,
"Charset type %s does not allow several 94 or 94x94 bank specifications"),
new_vals->charset_type->type_name);
return 0; /* Discard bank defination */
}
break;
case iso2022_96x96:
case iso2022_96:
if (-1 == *ptr_96)
*ptr_96 = i;
else {
lib_error(CATGETS(elm_msg_cat, MeSet, MeNoSeveral96,
"Charset type %s does not allow several 96 or 96x96 bank specifications"),
new_vals->charset_type->type_name);
return 0; /* Discard bank defination */
}
break;
}
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;
return 1;
}
static int cs_iso2022_info_set_ascii P_((struct charcode_info *new_vals,
struct setlist *new_setlist,
int setcount));
static int cs_iso2022_info_set_ascii(new_vals, new_setlist,setcount)
struct charcode_info *new_vals;
struct setlist *new_setlist;
int setcount;
{
int ptr_94 = -1;
int ptr_96 = -1;
int banks[ISO2022_BANK_NUM];
int i;
if (!cs_info_set_scan(new_vals,new_setlist,setcount,&ptr_94,&ptr_96,
banks)) {
return 0;
}
for (i = 0; i < setcount; i++) {
switch (new_setlist->sets[i]->type) {
case iso2022_94x94:
lib_error(CATGETS(elm_msg_cat, MeSet, MeNoMultibyte,
"Charset type %s does not allow multibyte bank specifications."),
new_vals->charset_type->type_name);
return 0;
case iso2022_96x96:
lib_error(CATGETS(elm_msg_cat, MeSet, MeNoMultibyte,
"Charset type %s does not allow multibyte bank specifications."),
new_vals->charset_type->type_name);
return 0;
}
}
/* Auto add ASCII bank */
if (banks[0] == -1 && -1 == ptr_94 &&
setcount < sizeof (new_setlist->sets) /
sizeof (new_setlist->sets[0])) {
new_setlist->sets[setcount++] = ASCII_BANK;
}
new_vals->iso2022_info = loc_setlist(*new_setlist);
new_vals->flags &= ~SET_nodata;
return 1;
}
static int cs_iso2022_info_set_binary P_((struct charcode_info *new_vals,
struct setlist *new_setlist,
int setcount));
static int cs_iso2022_info_set_binary(new_vals, new_setlist,setcount)
struct charcode_info *new_vals;
struct setlist *new_setlist;
int setcount;
{
int ptr_94 = -1;
int ptr_96 = -1;
int banks[ISO2022_BANK_NUM];
int i;
if (!cs_info_set_scan(new_vals,new_setlist,setcount,&ptr_94,&ptr_96,
banks)) {
return 0;
}
for (i = 0; i < setcount; i++) {
switch (new_setlist->sets[i]->type) {
case iso2022_94x94:
lib_error(CATGETS(elm_msg_cat, MeSet, MeNoMultibyte,
"Charset type %s does not allow multibyte bank specifications."),
new_vals->charset_type->type_name);
return 0;
case iso2022_96x96:
lib_error(CATGETS(elm_msg_cat, MeSet, MeNoMultibyte,
"Charset type %s does not allow multibyte bank specifications."),
new_vals->charset_type->type_name);
return 0;
}
}
new_vals->iso2022_info = loc_setlist(*new_setlist);
new_vals->flags &= ~SET_nodata;
return 0;
}
/* --------------------------------------------------------------------- */
struct charset_type cs_iso646 = { "iso646-set",
cs_init_binary,
cs_free_binary,
cs_add_streambyte_to_binary,
cs_add_intdata_to_binary,
cs_check_length_binary,
cs_give_unicode_from_iso646,
cs_add_unicodedata_to_iso646,
cs_cmp_binary,
cs_stream_from_iso646,
cs_can_ascii_iso646,
cs_streamclip_from_iso646,
cs_clip_from_binary,
cs_find_pattern_from_iso646,
cs_add_streambytes_to_binary,
cs_find_iso646,
cs_remove_control_iso646,
cs_add_state_to_binary,
cs_init_s_binary,
cs_free_s_binary,
cs_add_streambyte_to_s_binary,
cs_soft_reset_s_binary,
cs_give_unicode_from_s_iso646,
cs_s_binary_same_char,
cs_s_generic_printable,
cs_s_binary_is_onebyte,
cs_iso646_properties,
cs_estimate_clip_unsupported,
cs_iso2022_info_set_binary,
&cs_utf8
};
struct charset_type cs_onebyte = { "one-byte-map",
cs_init_binary,
cs_free_binary,
cs_add_streambyte_to_binary,
cs_add_intdata_to_binary,
cs_check_length_binary,
cs_give_unicode_from_bytemap,
cs_add_unicodedata_to_bytemap,
cs_cmp_binary,
cs_stream_from_bytemap,
cs_can_ascii_bytemap,
cs_streamclip_from_bytemap,
cs_clip_from_binary,
cs_find_pattern_from_bytemap,
cs_add_streambytes_to_binary,
cs_find_bytemap,
cs_remove_control_bytemap,
cs_add_state_to_binary,
cs_init_s_binary,
cs_free_s_binary,
cs_add_streambyte_to_s_binary,
cs_soft_reset_s_binary,
cs_give_unicode_from_s_bytemap,
cs_s_binary_same_char,
cs_s_generic_printable,
cs_s_binary_is_onebyte,
cs_onebyte_properties,
cs_estimate_clip_unsupported,
cs_iso2022_info_set_binary,
&cs_iso646
};
struct charset_type cs_ascii = { "ascii-set",
cs_init_binary,
cs_free_binary,
cs_add_streambyte_to_binary,
cs_add_intdata_to_binary,
cs_check_length_binary,
cs_give_unicode_from_ascii,
cs_add_unicodedata_to_ascii,
cs_cmp_binary,
cs_stream_from_ascii,
cs_can_ascii_ascii,
cs_streamclip_from_ascii,
cs_clip_from_binary,
cs_find_pattern_from_ascii,
cs_add_streambytes_to_binary,
cs_find_ascii,
cs_remove_control_ascii,
cs_add_state_to_binary,
cs_init_s_binary,
cs_free_s_binary,
cs_add_streambyte_to_s_binary,
cs_soft_reset_s_binary,
cs_give_unicode_from_s_ascii,
cs_s_binary_same_char,
cs_s_generic_printable,
cs_s_binary_is_onebyte,
cs_ascii_properties,
cs_estimate_clip_unsupported,
cs_iso2022_info_set_ascii,
&cs_onebyte
};
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1