Logo Search packages:      
Sourcecode: canna version File versions  Download package

RKkana.c

/* Copyright 1992 NEC Corporation, Tokyo, Japan.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without
 * fee, provided that the above copyright notice appear in all copies
 * and that both that copyright notice and this permission notice
 * appear in supporting documentation, and that the name of NEC
 * Corporation not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior
 * permission.  NEC Corporation makes no representations about the
 * suitability of this software for any purpose.  It is provided "as
 * is" without express or implied warranty.
 *
 * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN 
 * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 
 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 
 * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
 * PERFORMANCE OF THIS SOFTWARE. 
 */

#if !defined(lint) && !defined(__CODECENTER__)
static char rcsid[]="@(#) 102.1 $Id: RKkana.c,v 1.3 2003/09/17 08:50:53 aida_s Exp $";
#endif

/* LINTLIBRARY */
#include "canna.h"

/*********************************************************************
 *                      wchar_t replace begin                        *
 *********************************************************************/
#ifdef wchar_t
# error "wchar_t is already defined"
#endif
#define wchar_t cannawc

/* RkCvtZen
 *    hankaku moji wo zenkaku moji ni suru 
 */
static
unsigned short
hiragana[] = 
{
/* 0x00 */
      0x0000,     0x0000, 0x0000, 0x0000,       0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/* 0x10 */
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/* 0x20 */
      0xa1a1, 0xa1aa, 0xa1ed, 0xa1f4,           0xa1f0, 0xa1f3, 0xa1f5, 0xa1c7,
      0xa1ca, 0xa1cb, 0xa1f6, 0xa1dc,           0xa1a4, 0xa1dd, 0xa1a5, 0xa1bf,
/* 0x30 */
      0xa3b0, 0xa3b1, 0xa3b2, 0xa3b3,           0xa3b4, 0xa3b5, 0xa3b6, 0xa3b7,
      0xa3b8, 0xa3b9, 0xa1a7, 0xa1a8,           0xa1e3, 0xa1e1, 0xa1e4, 0xa1a9,
/* 0x40 */
      0xa1f7, 0xa3c1, 0xa3c2, 0xa3c3,           0xa3c4, 0xa3c5, 0xa3c6, 0xa3c7,
      0xa3c8, 0xa3c9, 0xa3ca, 0xa3cb,           0xa3cc, 0xa3cd, 0xa3ce, 0xa3cf,
/* 0x50 */
      0xa3d0, 0xa3d1, 0xa3d2, 0xa3d3,           0xa3d4, 0xa3d5, 0xa3d6, 0xa3d7,
      0xa3d8, 0xa3d9, 0xa3da, 0xa1ce,           0xa1ef, 0xa1cf, 0xa1b0, 0xa1b2,
/* 0x60 */
      0xa1c6, 0xa3e1, 0xa3e2, 0xa3e3,           0xa3e4, 0xa3e5, 0xa3e6, 0xa3e7,
      0xa3e8, 0xa3e9, 0xa3ea, 0xa3eb,           0xa3ec, 0xa3ed, 0xa3ee, 0xa3ef,
/* 0x70 */
      0xa3f0, 0xa3f1, 0xa3f2, 0xa3f3,           0xa3f4, 0xa3f5, 0xa3f6, 0xa3f7,
      0xa3f8, 0xa3f9, 0xa3fa, 0xa1d0,           0xa1c3, 0xa1d1, 0xa1c1, 0xa2a2,
/*0x80 */
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0x90 */
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0xa0 */
      0xa1a1, 0xa1a3, 0xa1d6, 0xa1d7,           0xa1a2, 0xa1a6, 0xa4f2, 0xa4a1,
      0xa4a3, 0xa4a5, 0xa4a7, 0xa4a9,           0xa4e3, 0xa4e5, 0xa4e7, 0xa4c3,
/*0xb0 */
      0xa1bc, 0xa4a2, 0xa4a4, 0xa4a6,           0xa4a8, 0xa4aa, 0xa4ab, 0xa4ad,
      0xa4af, 0xa4b1, 0xa4b3, 0xa4b5,           0xa4b7, 0xa4b9, 0xa4bb, 0xa4bd,
/*0xc0 */
      0xa4bf, 0xa4c1, 0xa4c4, 0xa4c6,           0xa4c8, 0xa4ca, 0xa4cb, 0xa4cc,
      0xa4cd, 0xa4ce, 0xa4cf, 0xa4d2,           0xa4d5, 0xa4d8, 0xa4db, 0xa4de,
/*0xd0 */
      0xa4df, 0xa4e0, 0xa4e1, 0xa4e2,           0xa4e4, 0xa4e6, 0xa4e8, 0xa4e9,
      0xa4ea, 0xa4eb, 0xa4ec, 0xa4ed,           0xa4ef, 0xa4f3, 0xa1ab, 0xa1ac,
/* 0xe0 */
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/* 0xf0 */
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
};
static
unsigned short    
hankaku[] = {
/*0x00*/
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0x10*/
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0x20*/
      0x0000,    ' ', 0x8ea4, 0x8ea1,              ',',    '.', 0x8ea5,    ':',
         ';',    '?',    '!', 0x8ede,           0x8edf, 0x0000, 0x0000, 0x0000,
/*0x30*/
         '^', 0x0000,    '_', 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x8eb0, 0x0000, 0x0000,    '/',
/*0x40*/
      0x0000,    '~', 0x0000,    '|',           0x0000, 0x0000,   '\'',   '\'',
         '"',    '"',    '(',    ')',              '[',    ']',    '[',    ']',
/*0x50*/
      '{',    '}', 0x0000, 0x0000,        0x0000, 0x0000, 0x8ea2, 0x8ea3,
      0x0000, 0x0000, 0x0000, 0x0000,              '+',    '-', 0x0000, 0x0000,
/*0x60*/
      0x0000,    '=', 0x0000,    '<',              '>', 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000,   '\\',
/*0x70*/
          '$',0x0000, 0x0000,    '%',              '#',    '&',    '*',    '@',
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0x80*/
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0x90*/
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0xa0*/
      0x0020, 0x00a7, 0x00b1, 0x00a8,     0x00b2, 0x00a9, 0x00b3, 0x00aa,
      0x00b4, 0x00ab, 0x00b5, 0x00b6,     0xb6de, 0x00b7, 0xb7de, 0x00b8,
/*0xb0*/
      0xb8de, 0x00b9, 0xb9de, 0x00ba,     0xbade, 0x00bb, 0xbbde, 0x00bc,
      0xbcde, 0x00bd, 0xbdde, 0x00be,     0xbede, 0x00bf, 0xbfde, 0x00c0,
/*0xc0*/
      0xc0de, 0x00c1, 0xc1de, 0x00af,     0x00c2, 0xc2de, 0x00c3, 0xc3de,
      0x00c4, 0xc4de, 0x00c5, 0x00c6,     0x00c7, 0x00c8, 0x00c9, 0x00ca,
/*0xd0*/
      0xcade, 0xcadf, 0x00cb, 0xcbde,     0xcbdf, 0x00cc, 0xccde, 0xccdf,
      0x00cd, 0xcdde, 0xcddf, 0x00ce,     0xcede, 0xcedf, 0x00cf, 0x00d0,
/*0xe0*/
      0x00d1, 0x00d2, 0x00d3, 0x00ac,     0x00d4, 0x00ad, 0x00d5, 0x00ae,
      0x00d6, 0x00d7, 0x00d8, 0x00d9,     0x00da, 0x00db, 0x00dc, 0x00dc,
/*0xf0*/
      0x00b2, 0x00b4, 0x00a6, 0x00dd,           0xb3de, 0x00b6, 0x00b9, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
};

#ifdef OBSOLETE_RKKANA

#define     ADDCODE(dst, maxdst, count, code, length) {\
    if ( (unsigned long)(length) <= (unsigned long)(maxdst) ) {\
      (maxdst) -= (length); (count) += (length);\
      if ( (dst) ) {\
          (dst) += (length);\
          switch((length)) {\
          case 4: *--(dst) = (code)&255; (code) >>= 8;\
          case 3: *--(dst) = (code)&255; (code) >>= 8;\
          case 2: *--(dst) = (code)&255; (code) >>= 8;\
          case 1: *--(dst) = (code)&255; (code) >>= 8;\
          };\
          (dst) += (length);\
      };\
    };\
}

#else /* !OBSOLETE_RKKANA */

static int
_ADDCODE(dst, maxdst, count, code, length)
unsigned char *dst;
int maxdst, count, length;
unsigned long code;
{
  if ((unsigned long)length <= (unsigned long)maxdst) {
    maxdst -= length;
    count += length;
    if (dst) {
      dst += length;
      switch (length) {
      case 4:     *--dst = (unsigned char)code; code >>= 8;
      case 3:     *--dst = (unsigned char)code; code >>= 8;
      case 2:     *--dst = (unsigned char)code; code >>= 8;
      case 1:     *--dst = (unsigned char)code; code >>= 8;
      }
    }
    return length;
  }
  return 0;
}

#define ADDCODE(dst, maxdst, count, code, length) \
{ int llen = _ADDCODE(dst, maxdst, count, (unsigned long)code, length); \
  if (llen > 0 && (dst)) { (dst) += llen; (maxdst) -= llen; (count) += llen; }}

#endif /* !OBSOLETE_RKKANA */

/* RkCvtZen
 *    hankaku moji(ASCII+katakana) wo taiou suru zenkaku moji ni suru
 *    dakuten,handakuten shori mo okonau.
 */
int   
RkCvtZen(zen, maxzen, han, maxhan)
unsigned char     *zen;
int         maxzen;
unsigned char     *han;
int         maxhan;
{
    unsigned char *z = zen;
    unsigned char *h = han;
    unsigned char *H = han + maxhan;
    unsigned short      hi, lo;
    unsigned            byte;
    int           count = 0;
    unsigned long code;

    if ( --maxzen <= 0 )
      return count;
    while ( h < H ) {
      hi = *h++;
      byte = 2;
      if ( hi == 0x8e ) {     /* hankaku katakana */
          if ( !(code = hiragana[lo = *h++]) )
            code = (hi<<8)|lo;
          byte = (code>>8) ? 2 : 1;
          if ( (code>>8) == 0xa4 ) {
            code |= 0x100;
          /* dakuten/handakuten ga tuku baai */
            if ( h + 1 < H && h[0] == 0x8e ) {
                lo = h[1];
                switch(code&255) {
          /* u */ case 0xa6:
                  if ( lo == 0xde ) code = 0xa5f4, h += 2;
                  break;
          /* ha */case 0xcf: case 0xd2: case 0xd5: case 0xd8: case 0xdb:
                  if ( lo == 0xdf ) {
                      code += 2, h += 2;
                      break;
                  };
          /* ka */case 0xab: case 0xad: case 0xaf: case 0xb1: case 0xb3:
          /* sa */case 0xb5: case 0xb7: case 0xb9: case 0xbb: case 0xbd:
          /* ta */case 0xbf: case 0xc1: case 0xc4: case 0xc6: case 0xc8:
                  if ( lo == 0xde ) {
                      code += 1, h += 2;
                      break;
                  };
                };
            };
          };
      }
      else if (hi == 0x8f) {
        ADDCODE(z, maxzen, count, hi, 1);
        code = (((unsigned long)h[0]) << 8)
                   | ((unsigned long)h[1]); h += 2;
        byte = 2;
      }
      else if ( hi & 0x80 )
        code = (hi<<8)|*h++;
      else  {
        if ( !(code = hiragana[hi]) ) 
          code = hi;
        byte = (code>>8) ? 2 : 1;
      }
      ADDCODE(z, maxzen, count, code, byte);
    };
    if ( z )
      *z = 0;
    return count;
}
/* RkCvtHan
 *    zenkaku kana moji wo hankaku moji ni suru 
 */
int   
RkCvtHan(han, maxhan, zen, maxzen)
unsigned char     *han;
int         maxhan;
unsigned char     *zen;
int         maxzen;
{
    unsigned char *h = han;
    unsigned char *z = zen;
    unsigned char *Z = zen + maxzen;
    unsigned short      hi, lo;
    unsigned short      byte;
    int           count = 0;
    unsigned long code;

    if ( --maxhan <= 0 )
      return 0;
    while ( z < Z ) {
      hi = *z++;
      byte = 1;
      switch(hi) {
      case  0xa1: /* kigou */
          lo = *z++;
          if ( !(code = hankaku[lo&0x7f]) )
            code = (hi<<8)|lo;
          byte = (code>>8) ? 2 : 1;
          break;
      case  0xa3: /* eisuuji */
          lo = *z++;
          if ( 0xb0 <= lo && lo <= 0xb9 ) code = (lo - 0xb0) + '0';
          else
          if ( 0xc1 <= lo && lo <= 0xda ) code = (lo - 0xc1) + 'A';
          else
          if ( 0xe1 <= lo && lo <= 0xfa ) code = (lo - 0xe1) + 'a';
          else
                                  code = (hi<<8)|lo, byte = 2;
          break;
      case  0xa4: /* hiragana */
      case  0xa5: /* katakana */
          lo = *z++;
          if ( (code = hankaku[lo]) &&
            (lo <= (unsigned short)(hi==0xa4 ? 0xf3: 0xf6)) ) {
            if ( code>>8 ) {
                code = 0x8e000000|((code>>8)<<16)|0x00008e00|(code&255);
                byte = 4;
            }
            else {
                code = 0x00008e00|(code&255);
                byte = 2;
            };
          }
          else
            code = (hi<<8)|lo, byte = 2;
          break;
      default:
          if (hi == 0x8f) {
            ADDCODE(h, maxhan, count, hi, 1);
            code = (((unsigned long)z[0]) << 8)
                       | ((unsigned long)z[1]); z += 2;
            byte = 2;
          }
          else if ( hi & 0x80 ) {   /* kanji */
            code = (hi<<8)|(*z++);
            byte = 2;
          }
          else
            switch(hi) {
            /*
            case  ',':  code = 0x8ea4; byte = 2; break;
            case  '-':  code = 0x8eb0; byte = 2; break;
            case  '.':  code = 0x8ea1; byte = 2; break;
            */
            default:    code = hi; break;
            };
          break;
      };
      ADDCODE(h, maxhan, count, code, byte);
    };
    if ( h )
      *h = 0;
    return count;
}
/* RkCvtKana/RkCvtHira
 *    zenkaku hiragana wo katakana ni suru 
 */
int   
RkCvtKana(kana, maxkana, hira, maxhira)
unsigned char     *kana;
int         maxkana;
unsigned char     *hira;
int         maxhira;
{
    register unsigned char    *k = kana;
    register unsigned char    *h = hira;
    register unsigned char    *H = hira + maxhira;
    unsigned short      hi;
    unsigned short      byte;
    int           count = 0;
    unsigned long code;

    if ( --maxkana <= 0 )
      return 0;
    while ( h < H ) {
      hi = *h++;
      if (hi == 0x8f) {
        ADDCODE(k, maxkana, count, hi, 1);
        code = (((unsigned long)h[0]) << 8) 
                   | ((unsigned long)h[1]); h += 2;
        byte = 2;
      }
      else if ( hi & 0x80 ) {
          int           dakuon;

          code = (hi == 0xa4) ? (0xa500|(*h++)) : ((hi<<8)|(*h++));
          byte = 2;
      /* hiragana U + " */
          dakuon = ( h + 1 < H && 
              ((((unsigned long)h[0])<<8)|((unsigned long)h[1])) == 0xa1ab );
          if ( hi == 0xa4 && code == 0xa5a6 && dakuon ) {
            code = 0xa5f4;
            h += 2;
          };
      }
      else 
          code = hi, byte = 1;
      ADDCODE(k, maxkana, count, code, byte);
    };
    if ( k )
      *k = 0;
    return count;
}
int   
RkCvtHira(hira, maxhira, kana, maxkana)
unsigned char     *hira;
int         maxhira;
unsigned char     *kana;
int         maxkana;
{
    register unsigned char    *h = hira;
    register unsigned char    *k = kana;
    register unsigned char    *K = kana + maxkana;
    unsigned short            hi;
    unsigned short            byte;
    int                 count = 0;
    unsigned long       code;

    if ( --maxhira <= 0 )
      return 0;
    while ( k < K ) {
      hi = *k++;
      if (hi == 0x8f) {
        ADDCODE(h, maxhira, count, hi, 1);
        code = (((unsigned long)k[0]) << 8) 
                   | ((unsigned long)k[1]); k += 2;
        byte = 2;
      }
      else if ( hi & 0x80 ) {
          code = (hi == 0xa5) ? (0xa400|(*k++)) : ((hi<<8)|(*k++));
          byte = 2;
      /* katakana U + " */
          if ( code == 0xa4f4 ) {   /* u no dakuon */
            code = 0xa4a6a1ab;
            byte = 4;
          }
          else
          if ( code == 0xa4f5 ) 
            code = 0xa4ab;
          else
          if ( code == 0xa4f6 ) 
            code = 0xa4b1;
      }
      else 
          code = hi, byte = 1;
      ADDCODE(h, maxhira, count, code, byte);
    };
    if ( h )
      *h = 0;
    return count;
}
int   
RkCvtNone(dst, maxdst, src, maxsrc)
unsigned char     *dst;
int         maxdst;
unsigned char     *src;
int         maxsrc;
{
    register unsigned char    *d = dst;
    register unsigned char    *s = src;
    register unsigned char    *S = src + maxsrc;
    unsigned short            byte;
    int                 count = 0;
    unsigned long       code;

    if ( --maxdst <= 0 )
      return 0;
    while ( s < S ) {
      code = *s++;
      byte = 1;
      if (code == 0x8f) {
        ADDCODE(d, maxdst, count, code, 1);
        code = (((unsigned long)s[0]) << 8) 
                   | ((unsigned long)s[1]); s += 2;
        byte = 2;
      }
      else if ( code & 0x80 ) 
          code = (code<<8)|(*s++), byte = 2;
      ADDCODE(d, maxdst, count, code, byte);
    };
    if ( d )
      *d = 0;
    return count;
}

/* RkEuc
 *    shift jis --> euc 
 */
int
RkCvtEuc(euc, maxeuc, sj, maxsj)
unsigned char     *euc;
int         maxeuc;
unsigned char     *sj;
int         maxsj;
{
    unsigned char *e = euc;
    unsigned char *s = sj;
    unsigned char *S = sj + maxsj;
    unsigned short      hi, lo;
    unsigned short      byte;
    int           count = 0;
    unsigned long code;

    if ( --maxeuc <= 0 )
      return 0;

    while ( s < S ) {
      hi = *s++;
      if ( hi <= 0x7f )                   /* ascii */
          code = hi, byte = 1;
      else 
      if ( 0xa0 <= hi && hi <= 0xdf )     /* hankaku katakana */
          code = 0x8e00|hi, byte = 2;
        else
        if (0xf0 <= hi && hi <= 0xfc) {         /* gaiji */
            hi -= 0xf0;
            hi = 2*hi + 0x21;
            if ((lo = *s++) <= 0x9e) {
                if (lo < 0x80)
                    lo++;
                lo -= 0x20;
            }
            else {
                hi++;
                lo -= 0x7e;
            }
            code = 0x8f8080 | (hi<<8) | lo, byte = 3;
        }
      else {
          hi -= (hi <= 0x9f) ?  0x80 : 0xc0;
          hi = 2*hi + 0x20;
          if ( (lo = *s++) <= 0x9e ) {    /* kisuu ku */
            hi--;
            if ( 0x80 <= lo ) lo--;
            lo -= (0x40 - 0x21);
          }
          else                /* guusuu ku */
            lo -= (0x9f - 0x21);
          code = 0x8080|(hi<<8)|lo, byte = 2;
      };
      ADDCODE(e, maxeuc, count, code, byte);
    };
    if ( e )
      *e = 0;
    return count;
}
/* RkCvtSuuji
 *    arabia suuji wo kansuuji ni kaeru
 */
static unsigned suujinew[] = {
      0xa1bb, 0xb0ec, 0xc6f3, 0xbbb0, 0xbbcd, 
      0xb8de, 0xcfbb, 0xbcb7, 0xc8ac, 0xb6e5,
};
static unsigned suujiold[] = {
      0xa1bb, 0xb0ed, 0xc6f5, 0xbbb2, 0xbbcd, 
      0xb8e0, 0xcfbb, 0xbcb7, 0xc8ac, 0xb6e5,
};
static unsigned kurai4[] = {
      0, 0xcbfc, 0xb2af, 0xc3fb, 0xb5fe, 0,           
};

static unsigned kurai3new[] = { 0, 0xbdbd, 0xc9b4, 0xc0e9, };
static unsigned kurai3old[] = { 0, 0xbdbd, 0xc9b4, 0xc0e9, };

int
RkCvtSuuji(dst, maxdst, src, maxsrc, format)
unsigned char     *dst;
int         maxdst;
unsigned char     *src;
int         maxsrc;
int         format;
{
    int                 count;
    int                 i, j, k;
    int                 digit[4], pend;
    unsigned            code, tmp;
    unsigned char *d = dst;
    unsigned char *s = src + maxsrc - 1;

    if ( --maxdst <= 0 )
      return 0;
/* yuukou keta suu wo kazoeru */
    pend = 0;
    for ( count = k = 0; s >= src; k++ ) {
      int   dec;

      if ( *s & 0x80 ) {
          if ( !(0xb0 <= *s && *s <= 0xb9) )
            break;
          dec = *s - 0xb0;
          if ( --s < src || *s != 0xa3 )
            break;
          s--;
      }
      else {
          if ( !('0' <= *s && *s <= '9') )
            break;
          dec = *s-- - '0';
      };

      switch(format) {
    /* simple */
      case 0:     /* sanyou suuji */
          code = hiragana[dec + '0'];
          ADDCODE(d, maxdst, count, code, 2);
          break;
      case 1:     /* kanji suuji */
          code = suujinew[dec];
          ADDCODE(d, maxdst, count, code, 2);
          break;
    /* kanji kurai dori */
      case 2:
      case 3:
      case 4:     /* 12 O 3456 M 7890 */
          digit[pend++] = dec;
          if ( pend == 4 ) {
            while ( pend > 0 && digit[pend - 1] == 0 )
                pend--;
            if ( pend ) {
            /* kurai wo shuturyoku */
                code = kurai4[k/4];
                if (code)
                  ADDCODE(d, maxdst, count, code, 2)
                else
                  if ( k >= 4 )
                      return 0;

                for ( i = 0; i < pend; i++ ) 
                  switch(format) {
                  case 2:
                      if ( digit[i] ) {
                          code = kurai3new[i];
                        if (code)
                            ADDCODE(d, maxdst, count, code, 2);
                        if ( i == 0 || (digit[i] > 1) ) {
                            code = suujinew[digit[i]];
                            ADDCODE(d, maxdst, count, code, 2);
                        };
                      };
                      break;
                  case 3:
                      if ( digit[i] ) {
                          code = kurai3old[i]; 
                        if (code)
                            ADDCODE(d, maxdst, count, code, 2);
                        code = suujiold[digit[i]];
                        ADDCODE(d, maxdst, count, code, 2);
                      };
                      break;
                  case 4:
                      code = hiragana[digit[i]+'0'];
                      ADDCODE(d, maxdst, count, code, 2);
                      break;
                  };
            };
            pend = 0;
          };
          break;
       case 5: /* 1,234,567,890 */
          if ( k && k%3 == 0 ) {
            code = hiragana[','];
            ADDCODE(d, maxdst, count, code, 2);
          };
          code = hiragana[dec + '0'];
          ADDCODE(d, maxdst, count, code, 2);
          break;
      default:
          return 0;
      };
    };

    if ( format == 2 || format == 3 || format == 4 ) {
      while ( pend > 0 && digit[pend - 1] == 0 )
          pend--;
      if ( pend ) {
          code = kurai4[k/4];
          if (code)
            ADDCODE(d, maxdst, count, code, 2)
          else
            if ( k >= 4 )
                return 0;
          for ( i = 0; i < pend; i++ ) 
            switch(format) {
            case 2:
                if ( digit[i] ) {
                    code = kurai3new[i];
                  if (code)
                      ADDCODE(d, maxdst, count, code, 2);
                  if ( i == 0 || (digit[i] > 1) ) {
                      code = suujinew[digit[i]];
                      ADDCODE(d, maxdst, count, code, 2);
                  };
                };
                break;
            case 3:
                if ( digit[i] ) {
                    code = kurai3old[i];
                  if (code)
                      ADDCODE(d, maxdst, count, code, 2);
                  code = suujiold[digit[i]];
                  ADDCODE(d, maxdst, count, code, 2);
                };
                break;
            case 4:
                code = hiragana[digit[i]+'0'];
                ADDCODE(d, maxdst, count, code, 2);
                break;
            };
      };
    };

    if ( dst ) {
      *d = 0;
      for ( i = 0, j = count - 1; i < j; i++, j-- ) {
          tmp = dst[i]; dst[i] = dst[j]; dst[j] = tmp;
      };
      for ( i = count - 1; i > 0; i-- )
          if ( dst[i] & 0x80 ) {
            tmp = dst[i+0]; dst[i+0] = dst[i-1]; dst[i-1] = tmp;
            i--;
          };
    };
    return count;
}

/* ワイドキャラクタ */

#define CBUFSIZE     512

RkwCvtHan(dst, maxdst, src, srclen)
wchar_t *dst, *src;
int maxdst, srclen;
{
  int len = 0;
#ifndef USE_MALLOC_FOR_BIG_ARRAY
  char cbuf[CBUFSIZE], cbuf2[CBUFSIZE];
#else
  char *cbuf, *cbuf2;

  cbuf = malloc(CBUFSIZE);
  cbuf2 = malloc(CBUFSIZE);
  if (!cbuf || !cbuf2) {
    if (cbuf) {
      (void)free(cbuf);
    }
    if (cbuf2) {
      (void)free(cbuf2);
    }
    return len;
  }
#endif

  len = CNvW2E(src, srclen, cbuf, CBUFSIZE);
  len = RkCvtHan((unsigned char *)cbuf2, CBUFSIZE, (unsigned char *)cbuf, len);
  if (len > 0) {
    cbuf2[len] = '\0';
    len = MBstowcs(dst, cbuf2, maxdst);
  }
#ifdef USE_MALLOC_FOR_BIG_ARRAY
  free(cbuf2);
  free(cbuf);
#endif
  return len;
}

RkwCvtHira(dst, maxdst, src, srclen)
wchar_t *dst, *src;
int maxdst, srclen;
{
  int len = 0;
#ifndef USE_MALLOC_FOR_BIG_ARRAY
  char cbuf[CBUFSIZE], cbuf2[CBUFSIZE];
#else
  char *cbuf, *cbuf2;

  cbuf = malloc(CBUFSIZE);
  cbuf2 = malloc(CBUFSIZE);
  if (!cbuf || !cbuf2) {
    if (cbuf) {
      (void)free(cbuf);
    }
    if (cbuf2) {
      (void)free(cbuf2);
    }
    return len;
  }
#endif

  len = CNvW2E(src, srclen, cbuf, CBUFSIZE);
  len = RkCvtHira((unsigned char *)cbuf2, CBUFSIZE,
              (unsigned char *)cbuf, len);
  if (len > 0) {
    cbuf2[len] = (unsigned char)0;
    len = MBstowcs(dst, cbuf2, maxdst);
  }
#ifdef USE_MALLOC_FOR_BIG_ARRAY
  free(cbuf2);
  free(cbuf);
#endif
  return len;
}
  
RkwCvtKana(dst, maxdst, src, srclen)
wchar_t *dst, *src;
int maxdst, srclen;
{
  int len = 0;
#ifndef USE_MALLOC_FOR_BIG_ARRAY
  char cbuf[CBUFSIZE], cbuf2[CBUFSIZE];
#else
  char *cbuf, *cbuf2;

  cbuf = malloc(CBUFSIZE);
  cbuf2 = malloc(CBUFSIZE);
  if (!cbuf || !cbuf2) {
    if (cbuf) {
      (void)free(cbuf);
    }
    if (cbuf2) {
      (void)free(cbuf2);
    }
    return len;
  }
#endif

  len = CNvW2E(src, srclen, cbuf, CBUFSIZE);
  len = RkCvtKana((unsigned char *)cbuf2, CBUFSIZE,
              (unsigned char *)cbuf, len);
  if (len > 0) {
    cbuf2[len] = '\0';
    len = MBstowcs(dst, cbuf2, maxdst);
  }
#ifdef USE_MALLOC_FOR_BIG_ARRAY
  free(cbuf2);
  free(cbuf);
#endif
  return len;
}
  
RkwCvtZen(dst, maxdst, src, srclen)
wchar_t *dst, *src;
int maxdst, srclen;
{
  int len = 0;
#ifndef USE_MALLOC_FOR_BIG_ARRAY
  char cbuf[CBUFSIZE], cbuf2[CBUFSIZE];
#else
  char *cbuf, *cbuf2;

  cbuf = malloc(CBUFSIZE);
  cbuf2 = malloc(CBUFSIZE);
  if (!cbuf || !cbuf2) {
    if (cbuf) {
      (void)free(cbuf);
    }
    if (cbuf2) {
      (void)free(cbuf2);
    }
    return len;
  }
#endif

  len = CNvW2E(src, srclen, cbuf, CBUFSIZE);
  len = RkCvtZen((unsigned char *)cbuf2, CBUFSIZE,
             (unsigned char *)cbuf, len);
  if (len > 0) {
    cbuf2[len] = '\0';
    len = MBstowcs(dst, cbuf2, maxdst);
  }
#ifdef USE_MALLOC_FOR_BIG_ARRAY
  free(cbuf2);
  free(cbuf);
#endif
  return len;
}

RkwCvtNone(dst, maxdst, src, srclen)
wchar_t *dst, *src;
int maxdst, srclen;
{
  int i;
  int len = (maxdst < srclen) ? maxdst : srclen;

  for (i = 0 ; i < len ; i++) {
    *dst++ = *src++;
  }
/*  *dst = *src; なんでこれが必要なの? */
  return len;
}

RkwMapRoma(romaji, dst, maxdst, src, srclen, flags, status)
struct RkRxDic *romaji;
wchar_t *dst, *src;
int maxdst, srclen, flags, *status;
{
  int len = 0, ret;
#ifndef USE_MALLOC_FOR_BIG_ARRAY
  char cbuf1[CBUFSIZE], cbuf2[CBUFSIZE];
#else
  char *cbuf1, *cbuf2;

  cbuf1 = malloc(CBUFSIZE);
  cbuf2 = malloc(CBUFSIZE);
  if (!cbuf1 || !cbuf2) {
    if (cbuf1) {
      (void)free(cbuf1);
    }
    if (cbuf2) {
      (void)free(cbuf2);
    }
    return len;
  }
#endif

  len = CNvW2E(src, srclen, cbuf1, CBUFSIZE);
  len = RkMapRoma(romaji, (unsigned char *)cbuf2, CBUFSIZE,
              (unsigned char *)cbuf1, len, flags, status);
  cbuf2[(*status > 0) ? *status : -*status] = (unsigned char)0;
  ret = MBstowcs(dst, cbuf2, maxdst);
  if (*status > 0) {
    *status = ret;
  }
  else {
    *status = -ret;
  }
#ifdef USE_MALLOC_FOR_BIG_ARRAY
  free(cbuf2);
  free(cbuf1);
#endif
  return len;
}

#ifdef __STDC__
RkwMapPhonogram(struct RkRxDic *romaji, wchar_t *dst, int maxdst,
            wchar_t *src, int srclen, wchar_t key, int flags,
            int *ulen, int *dlen, int *tlen, int *rule)
#else
RkwMapPhonogram(romaji, dst, maxdst, src, srclen, key, flags,
            ulen, dlen, tlen, rule)
struct RkRxDic *romaji;
wchar_t *dst, *src, key;
int maxdst, srclen, flags, *ulen, *dlen, *tlen, *rule;
#endif
{
  int status = 0;
  char tmpch;
  int len, ret, fdlen, fulen, ftlen;
#ifndef USE_MALLOC_FOR_BIG_ARRAY
  char cbuf1[CBUFSIZE], cbuf2[CBUFSIZE];
  wchar_t wbuf[CBUFSIZE];
#else
  char *cbuf1, *cbuf2;
  wchar_t *wbuf;

  cbuf1 = malloc(CBUFSIZE);
  cbuf2 = malloc(CBUFSIZE);
  wbuf = (wchar_t *)malloc(sizeof(wchar_t) * CBUFSIZE);
  if (!cbuf1 || !cbuf2 || !wbuf) {
    if (cbuf1) {
      (void)free(cbuf1);
    }
    if (cbuf2) {
      (void)free(cbuf2);
    }
    if (wbuf) {
      (void)free((char *)wbuf);
    }
    return status;
  }
#endif

  len = CNvW2E(src, srclen, cbuf1, CBUFSIZE);
  status = RkMapPhonogram(romaji, (unsigned char *)cbuf2, CBUFSIZE,
                    (unsigned char *)cbuf1, len,
                    (unsigned) key, flags,
                    &fulen, &fdlen, &ftlen, rule);
  tmpch = cbuf2[fdlen];
  cbuf2[fdlen] = '\0';
  ret = MBstowcs(dst, cbuf2, maxdst);
  cbuf2[fdlen] = tmpch;
  if (dlen) {
    *dlen = ret;
  }
  cbuf2[fdlen + ftlen] = (unsigned char)0;
  ret = MBstowcs(dst + ret, cbuf2 + fdlen, maxdst - ret);
  if (tlen) {
    *tlen = ret;
  }
  if (ulen) {
    cbuf1[fulen] = '\0';
    *ulen = MBstowcs(wbuf, cbuf1, CBUFSIZE);
  }
#ifdef USE_MALLOC_FOR_BIG_ARRAY
  free(cbuf2);
  free(cbuf1);
#endif
  return status;
}

RkwCvtRoma(romaji, dst, maxdst, src, srclen, flags)
struct RkRxDic *romaji;
wchar_t *dst, *src;
int maxdst, srclen, flags;
{
  int ret = 0, len;
#ifndef USE_MALLOC_FOR_BIG_ARRAY
  char cbuf1[CBUFSIZE], cbuf2[CBUFSIZE];
#else
  char *cbuf1, *cbuf2;

  cbuf1 = malloc(CBUFSIZE);
  cbuf2 = malloc(CBUFSIZE);
  if (!cbuf1 || !cbuf2) {
    if (cbuf1) {
      (void)free(cbuf1);
    }
    if (cbuf2) {
      (void)free(cbuf2);
    }
    return ret;
  }
#endif

  if (srclen) {
    len = CNvW2E(src, srclen, cbuf1, CBUFSIZE);
    len = RkCvtRoma(romaji, (unsigned char *)cbuf2, CBUFSIZE,
                (unsigned char *)cbuf1, len, flags);
    cbuf2[len] = (unsigned char)0;
    ret = MBstowcs(dst, cbuf2, maxdst);
    dst[ret] = (wchar_t)0;
  } else {
    ret = 0;
    *dst = (wchar_t)0;
  }
#ifdef USE_MALLOC_FOR_BIG_ARRAY
  free(cbuf2);
  free(cbuf1);
#endif
  return ret;
}

#ifndef wchar_t
# error "wchar_t is already undefined"
#endif
#undef wchar_t
/*********************************************************************
 *                       wchar_t replace end                         *
 *********************************************************************/

Generated by  Doxygen 1.6.0   Back to index