私の愛用しているxipmsgには「れ」や「レ」の文字が化ける (ほかにもいろいろ化ける) というバグがあったのだが、やっと解決した。
最初に、kanji.cのSJIS - EUC 変換の部分の関数をチェックしてみたのだが、(といっても「れ」をいれるとどうなるか確認しただけ) 特に問題はなかった。なぜ、SJIS - EUC 変換の部分かというと、IPmessengerは通信経路においてSJISで日本語をやりとりすることを前提としているし、表示のほうはEUCだからだ。だいたい、「るれろ」や「ルレロ」の文字列はどの日本語コードでも連続しているので、この辺で問題がでるとは考えにくい。
WinのIPmessengerといろいろ試していると、実は封書チェックがはいったときだけ文字化けするようだ。そういえばそういうこともあったかもしれない。すっかりわすれていた。
ちなみに私のxipmsgはbrocas.c の bro_send 関数を
686c686
< unsigned long cmd = IPMSG_SENDMSG | IPMSG_SENDCHECKOPT;
---
> unsigned long cmd = IPMSG_SENDMSG | IPMSG_SENDCHECKOPT | IPMSG_SECRETOPT;
と変更してあり、いつも封書で送信するようにしている。
xipmsg で封書を実現するのには xipmsg.c 中の cryption 関数を使っている。cryption(文字列, 0)で読めない文字列を作りだしそれを表示しているのだ。開封ボタンを押すことにより読めない文字列は cryption(文字列, 1) により再変換され、もとの文字列となり再び表示される。
調べてみると、この関数に問題があった。もともとcryption 関数は
static char *
cryption(char *str, int decode_flag)
{
unsigned char *p = (unsigned char *)str;
int xx = decode_flag ? 0x100 - '\n' : '\n';
while (*p != '\0') {
if (*p != '\n' && *p != 0x100 - '\n')
*p = (*p + xx) & 0xff;
p++;
}/* while */
return str;
}/* cryption */
であった (つまり 0x100-'\n'-'\n' がまずいわけだ) のを
static char *
cryption(char *str, int decode_flag)
{
unsigned char *p = (unsigned char *)str;
int xx = decode_flag ? 0x100 - '\n' : '\n';
while (*p != '\0') {
if (*p != '\n'){
if(decode_flag && *p == '\n'+ '\n')
*p = '\0';
*p = (*p + xx) & 0xff;
if(*p == '\0')
*p = '\n'+ '\n';
}
p++;
}/* while */
return str;
}/* cryption */
というふうに修正すれは文字化けは解消する。条件判断が多くなっているが、扱う文章の量がたいしたことないので、まあいいだろう。これはもとの操作を尊重したためこうなったのであって、
static char *
cryption(char *str, int decode_flag)
{
unsigned char *p = (unsigned char *)str;
decode_flag;
while (*p != '\0') {
if (*p != '\n' && *p != 0xff - '\n')
*p = *p ^ 0xff;
p++;
}/* while */
return str;
}/* cryption */
ぐらいでもいい気がする。decode_flagの意味はなくなるが。
ついでに
1191c1197
< #define TITLE "XIP Messenger V0.8086"
---
> #define TITLE "XIP Messenger V0.8087"
も修正しておくといい。