diff --git a/src/modules/_Charset/charsetmod.c b/src/modules/_Charset/charsetmod.c index da2fc46a8d48619b89785ee0b8d5b5e024ce633a..f8e25d1ff6522aaf6a78512a1c5eb362c2930ad7 100644 --- a/src/modules/_Charset/charsetmod.c +++ b/src/modules/_Charset/charsetmod.c @@ -3,7 +3,7 @@ #endif /* HAVE_CONFIG_H */ #include "global.h" -RCSID("$Id: charsetmod.c,v 1.15 1999/06/19 20:25:51 hubbe Exp $"); +RCSID("$Id: charsetmod.c,v 1.16 1999/07/26 22:11:28 marcus Exp $"); #include "program.h" #include "interpret.h" #include "stralloc.h" @@ -100,6 +100,27 @@ static void f_set_repcb(INT32 args) pop_n_elems(args); } +static int call_repcb(struct svalue *repcb, p_wchar2 ch) +{ + push_string(make_shared_binary_string2(&ch, 1)); + apply_svalue(repcb, 1); + if(sp[-1].type == T_STRING) + return 1; + pop_stack(); + return 0; +} + +#define REPLACE_CHAR(ch, func, ctx) \ + if(repcb != NULL && call_repcb(repcb, ch)) { \ + func(ctx, sb, sp[-1].u.string, rep, NULL); \ + pop_stack(); \ + } else if(rep != NULL) \ + func(ctx, sb, rep, NULL, NULL); \ + else \ + error("Character unsupported by encoding.\n"); + +#define MKREPCB(c) ((c).type == T_FUNCTION? &(c):NULL) + static void f_drain(INT32 args) { struct std_cs_stor *s = (struct std_cs_stor *)fp->current_storage; @@ -621,8 +642,9 @@ static void f_feed_8bit(INT32 args) } -static void feed_utf8e(struct string_builder *sb, - struct pike_string *str, struct pike_string *rep) +static void feed_utf8e(struct std_cs_stor *cs, struct string_builder *sb, + struct pike_string *str, struct pike_string *rep, + struct svalue *repcb) { INT32 l = str->len; @@ -686,10 +708,8 @@ static void feed_utf8e(struct string_builder *sb, string_builder_putchar(sb, 0x80|((c>>12)&0x3f)); string_builder_putchar(sb, 0x80|((c>>6)&0x3f)); string_builder_putchar(sb, 0x80|(c&0x3f)); - } else if(rep != NULL) - feed_utf8e(sb, rep, NULL); - else - error("Character unsupported by encoding.\n"); + } else + REPLACE_CHAR(c, feed_utf8e, cs); } break; default: @@ -704,14 +724,15 @@ static void f_feed_utf8e(INT32 args) get_all_args("feed()", args, "%W", &str); - feed_utf8e(&cs->strbuild, str, cs->replace); + feed_utf8e(cs, &cs->strbuild, str, cs->replace, MKREPCB(cs->repcb)); pop_n_elems(args); push_object(this_object()); } static void feed_utf7e(struct utf7_stor *u7, struct string_builder *sb, - struct pike_string *str, struct pike_string *rep) + struct pike_string *str, struct pike_string *rep, + struct svalue *repcb) { INT32 l = str->len, dat = u7->dat; int shift = u7->shift, datbit = u7->datbit; @@ -807,16 +828,13 @@ static void feed_utf7e(struct utf7_stor *u7, struct string_builder *sb, string_builder_putchar(sb, '+'); string_builder_putchar(sb, '-'); } else if(c>0x10ffff) { - if(rep != NULL) { - u7->dat = dat; - u7->shift = shift; - u7->datbit = datbit; - feed_utf7e(u7, sb, rep, NULL); - dat = u7->dat; - shift = u7->shift; - datbit = u7->datbit; - } else - error("Character unsupported by encoding.\n"); + u7->dat = dat; + u7->shift = shift; + u7->datbit = datbit; + REPLACE_CHAR(c, feed_utf7e, u7); + dat = u7->dat; + shift = u7->shift; + datbit = u7->datbit; } else { if(!shift) { string_builder_putchar(sb, '+'); @@ -861,7 +879,7 @@ static void f_feed_utf7e(INT32 args) get_all_args("feed()", args, "%W", &str); feed_utf7e((struct utf7_stor *)(((char*)fp->current_storage)+utf7_stor_offs), - &cs->strbuild, str, cs->replace); + &cs->strbuild, str, cs->replace, MKREPCB(cs->repcb)); pop_n_elems(args); push_object(this_object()); @@ -906,7 +924,8 @@ static void std_8bite_exit_stor(struct object *o) } static void feed_std8e(struct std8e_stor *s8, struct string_builder *sb, - struct pike_string *str, struct pike_string *rep) + struct pike_string *str, struct pike_string *rep, + struct svalue *repcb) { INT32 l = str->len; p_wchar0 *tab = s8->revtab; @@ -922,10 +941,8 @@ static void feed_std8e(struct std8e_stor *s8, struct string_builder *sb, string_builder_putchar(sb, c); else if(c>=lo && c<hi && (ch=tab[c-lo])!=0) string_builder_putchar(sb, ch); - else if(rep != NULL) - feed_std8e(s8, sb, rep, NULL); else - error("Character unsupported by encoding.\n"); + REPLACE_CHAR(c, feed_std8e, s8) } break; case 1: @@ -936,10 +953,8 @@ static void feed_std8e(struct std8e_stor *s8, struct string_builder *sb, string_builder_putchar(sb, c); else if(c>=lo && c<hi && (ch=tab[c-lo])!=0) string_builder_putchar(sb, ch); - else if(rep != NULL) - feed_std8e(s8, sb, rep, NULL); else - error("Character unsupported by encoding.\n"); + REPLACE_CHAR(c, feed_std8e, s8); } break; case 2: @@ -950,10 +965,8 @@ static void feed_std8e(struct std8e_stor *s8, struct string_builder *sb, string_builder_putchar(sb, c); else if(c>=lo && c<hi && (ch=tab[c-lo])!=0) string_builder_putchar(sb, ch); - else if(rep != NULL) - feed_std8e(s8, sb, rep, NULL); else - error("Character unsupported by encoding.\n"); + REPLACE_CHAR(c, feed_std8e, s8); } break; default: @@ -970,7 +983,7 @@ static void f_feed_std8e(INT32 args) feed_std8e((struct std8e_stor *)(((char*)fp->current_storage)+ std8e_stor_offs), - &cs->strbuild, str, cs->replace); + &cs->strbuild, str, cs->replace, MKREPCB(cs->repcb)); pop_n_elems(args); push_object(this_object()); @@ -997,7 +1010,8 @@ static void std_16bite_exit_stor(struct object *o) } static void feed_std16e(struct std16e_stor *s16, struct string_builder *sb, - struct pike_string *str, struct pike_string *rep) + struct pike_string *str, struct pike_string *rep, + struct svalue *repcb) { INT32 l = str->len; p_wchar1 *tab = s16->revtab; @@ -1014,10 +1028,8 @@ static void feed_std16e(struct std16e_stor *s16, struct string_builder *sb, else if(c>=lo && c<hi && (ch=tab[c-lo])!=0) { string_builder_putchar(sb, (ch>>8)&0xff); string_builder_putchar(sb, ch&0xff); - } else if(rep != NULL) - feed_std16e(s16, sb, rep, NULL); - else - error("Character unsupported by encoding.\n"); + } else + REPLACE_CHAR(c, feed_std16e, s16); } break; case 1: @@ -1029,10 +1041,8 @@ static void feed_std16e(struct std16e_stor *s16, struct string_builder *sb, else if(c>=lo && c<hi && (ch=tab[c-lo])!=0) { string_builder_putchar(sb, (ch>>8)&0xff); string_builder_putchar(sb, ch&0xff); - } else if(rep != NULL) - feed_std16e(s16, sb, rep, NULL); - else - error("Character unsupported by encoding.\n"); + } else + REPLACE_CHAR(c, feed_std16e, s16); } break; case 2: @@ -1044,10 +1054,8 @@ static void feed_std16e(struct std16e_stor *s16, struct string_builder *sb, else if(c>=lo && c<hi && (ch=tab[c-lo])!=0) { string_builder_putchar(sb, (ch>>8)&0xff); string_builder_putchar(sb, ch&0xff); - } else if(rep != NULL) - feed_std16e(s16, sb, rep, NULL); - else - error("Character unsupported by encoding.\n"); + } else + REPLACE_CHAR(c, feed_std16e, s16); } break; default: @@ -1064,7 +1072,7 @@ static void f_feed_std16e(INT32 args) feed_std16e((struct std16e_stor *)(((char*)fp->current_storage)+ std16e_stor_offs), - &cs->strbuild, str, cs->replace); + &cs->strbuild, str, cs->replace, MKREPCB(cs->repcb)); pop_n_elems(args); push_object(this_object());