diff --git a/src/modules/_Charset/iso2022.c b/src/modules/_Charset/iso2022.c index f8879a90ecb926753dc9ccd0725588e81bdad9ae..c69e4095ca25f284b174c3a65f0ef056d9fb8a10 100644 --- a/src/modules/_Charset/iso2022.c +++ b/src/modules/_Charset/iso2022.c @@ -3,7 +3,7 @@ #endif /* HAVE_CONFIG_H */ #include "global.h" -RCSID("$Id: iso2022.c,v 1.11 1999/07/27 22:19:12 marcus Exp $"); +RCSID("$Id: iso2022.c,v 1.12 1999/07/28 21:16:37 marcus Exp $"); #include "program.h" #include "interpret.h" #include "stralloc.h" @@ -35,6 +35,10 @@ struct iso2022_stor { struct iso2022enc_stor { struct gdesc g[2]; + struct { + p_wchar1 *map; + unsigned lo, hi; + } r[2]; struct pike_string *replace; struct string_builder strbuild; struct svalue repcb; @@ -382,15 +386,27 @@ static void eat_enc_string(struct pike_string *str, struct iso2022enc_stor *s, if(s->g[0].mode != MODE_94 || s->g[0].index != 0x12) { s->g[0].transl = NULL; s->g[0].index = 0; + if(s->r[0].map != NULL) { + free(s->r[0].map); + s->r[0].map = NULL; + } } s->g[1].transl = NULL; s->g[1].index = 0; + if(s->r[1].map != NULL) { + free(s->r[1].map); + s->r[1].map = NULL; + } lat = 0; } else if(!asc && c>' ' && c<0x7f) { string_builder_strcat(&s->strbuild, "\033(B"); s->g[0].transl = map_ANSI_X3_4_1968; s->g[0].mode = MODE_94; s->g[0].index = 0x12; + if(s->r[0].map != NULL) { + free(s->r[0].map); + s->r[0].map = NULL; + } asc = 1; } } else if(!lat) { @@ -398,6 +414,10 @@ static void eat_enc_string(struct pike_string *str, struct iso2022enc_stor *s, s->g[1].transl = map_ISO_8859_1_1987; s->g[1].mode = MODE_96; s->g[1].index = 0x11; + if(s->r[1].map != NULL) { + free(s->r[1].map); + s->r[1].map = NULL; + } lat = 1; } string_builder_putchar(&s->strbuild,c); @@ -423,9 +443,17 @@ static void eat_enc_string(struct pike_string *str, struct iso2022enc_stor *s, if(s->g[0].mode != MODE_94 || s->g[0].index != 0x12) { s->g[0].transl = NULL; s->g[0].index = 0; + if(s->r[0].map != NULL) { + free(s->r[0].map); + s->r[0].map = NULL; + } } s->g[1].transl = NULL; s->g[1].index = 0; + if(s->r[1].map != NULL) { + free(s->r[1].map); + s->r[1].map = NULL; + } } string_builder_putchar(&s->strbuild,c); } else if(c<0x7f) { @@ -434,6 +462,10 @@ static void eat_enc_string(struct pike_string *str, struct iso2022enc_stor *s, s->g[0].transl = map_ANSI_X3_4_1968; s->g[0].mode = MODE_94; s->g[0].index = 0x12; + if(s->r[0].map != NULL) { + free(s->r[0].map); + s->r[0].map = NULL; + } } string_builder_putchar(&s->strbuild,c); } else if(c<0x100) { @@ -442,18 +474,38 @@ static void eat_enc_string(struct pike_string *str, struct iso2022enc_stor *s, s->g[1].transl = map_ISO_8859_1_1987; s->g[1].mode = MODE_96; s->g[1].index = 0x11; + if(s->r[1].map != NULL) { + free(s->r[1].map); + s->r[1].map = NULL; + } } string_builder_putchar(&s->strbuild,c); } else if(c==0xfffd) { /* Substitution character... */ REPLACE_CHAR(0xfffd); - } else if(c>=0x3000) { - /* CJK */ - error("Not implemented.\n"); + } else if(s->r[0].map != NULL && c >= s->r[0].lo && c < s->r[0].hi && + s->r[0].map[c-s->r[0].lo]) { + /* Char contained in current G0 set */ + if((c = s->r[0].map[c-s->r[0].lo])>=0x100) + string_builder_putchar(&s->strbuild,(c&0x7f00)>>8); + string_builder_putchar(&s->strbuild,c&0x7f); + } else if(s->r[1].map != NULL && c >= s->r[1].lo && c < s->r[1].hi && + s->r[1].map[c-s->r[1].lo]) { + /* Char contained in current G1 set */ + if((c = s->r[1].map[c-s->r[1].lo])>=0x100) + string_builder_putchar(&s->strbuild,((c&0x7f00)>>8)|0x80); + string_builder_putchar(&s->strbuild,(c&0x7f)|0x80); } else { - int mode, index, ch; + /* Need to switch to another map */ + + int mode, index=0, ch; UNICHAR *ttab = NULL; - if(c<0x180) { + p_wchar1 *rmap = NULL; + + if(c>=0x3000) { + /* CJK */ + error("Not implemented.\n"); + } else if(c<0x180) { unsigned char map1[] = { 0x02, 0x00, 0x15, 0x00, 0xa0, 0xa0, 0x02, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0x80, 0xc0, @@ -465,30 +517,37 @@ static void eat_enc_string(struct pike_string *str, struct iso2022enc_stor *s, } else { error("Not implemented.\n"); } + if(index!=0 && (ttab = transltab[mode][index-0x10])!=NULL) { switch(mode) { case MODE_96: + rmap = (p_wchar1 *)xalloc((0x10000-0x100)*sizeof(p_wchar1)); + memset(rmap, 0, (0x10000-0x100)*sizeof(p_wchar1)); for(ch=0; ch<96; ch++) - if(ttab[ch]==c) - break; - if(ch<96) { - if(s->g[1].mode != MODE_96 || s->g[1].index != index) { - string_builder_strcat(&s->strbuild, "\033-"); - string_builder_putchar(&s->strbuild,index+0x30); - s->g[1].transl = ttab; - s->g[1].mode = MODE_96; - s->g[1].index = index; - } - string_builder_putchar(&s->strbuild,ch+160); + if(ttab[ch]>=0x100) + rmap[ttab[ch]-0x100]=ch+32; + if(rmap[c-0x100]) { + string_builder_strcat(&s->strbuild, "\033-"); + string_builder_putchar(&s->strbuild, 48+index); + string_builder_putchar(&s->strbuild, rmap[c-0x100]|0x80); + s->g[1].transl = ttab; + s->g[1].mode = MODE_96; + s->g[1].index = index; + if(s->r[1].map != NULL) + free(s->r[1].map); + s->r[1].map = rmap; + s->r[1].lo = 0x100; + s->r[1].hi = 0x10000; } else ttab = NULL; break; - default: - ttab = NULL; } } - if(ttab == NULL) + if(ttab == NULL) { + if(rmap != NULL) + free(rmap); REPLACE_CHAR(c); + } } } } @@ -592,6 +651,9 @@ static void f_enc_clear(INT32 args) s->g[i].transl = NULL; s->g[i].mode = MODE_96; s->g[i].index = 0; + s->r[i].map = NULL; + s->r[i].lo = 0; + s->r[i].hi = 0; } s->g[0].transl = map_ANSI_X3_4_1968; s->g[0].mode = MODE_94;