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 (was hurtta+elm@ozone.FMI.FI) * * Table koi82unicode is from RFC 1489, * author Andrew A. Chernov * * Table cp12512unicode is contributed by * Andrey A. Chernov * * 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 * *****************************************************************************/ #include "headers.h" #include "s_me.h" #include "cs_imp.h" #include "bindata.h" DEBUG_VAR(Debug,__FILE__,"charset"); #include #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: */