/* _wctomb.c (emx+gcc) -- Copyright (c) 1994-1996 by Eberhard Mattes */

#include <stdlib.h>
#include <sys/nls.h>
#include <emx/locale.h>

int _wctomb (char *s, wchar_t wchar, size_t n, int *pshift)
{
  wchar_t lead;

  if (n == 0)
    return -1;

  if (wchar == 0)
    {
      *s = 0;
      return 1;
    }

  switch (_cur_mbyte.mode)
    {
    case _MB_8BITS:
      if (wchar <= 255)         /* wchar_t is unsigned */
        {
          *s = (char)wchar;
          return 1;
        }
      break;

    case _MB_DBCS:
      if (wchar <= 255 && !_nls_is_dbcs_lead (wchar)) /* wchar_t is unsigned */
        {
          *s = (char)wchar;
          return 1;
        }
      lead = wchar >> 8; wchar &= 0xff;
      if (_nls_is_dbcs_lead (lead) && wchar != 0 && n >= 2)
        {
          *s++ = lead;
          *s++ = (char)wchar;
          return 2;
        }
      break;

    case _MB_UTF_2:             /* UTF-2 */
      if (wchar <= 0x7f)
        {
          *s = (char)wchar;
          return 1;
        }
      else
        {
          /* wchar_t has (only) 16 bits, therefore there are only two
             cases. */

          if (wchar <= 0x7ff && n >= 2)
            {
              *s++ = (char)((wchar >> 6) | 0xc0);
              *s = (char)(((wchar >> 0) & 0x3f) | 0x80);
              return 2;
            }
          else if (n >= 3)
            {
              *s++ = (char)((wchar >> 12) | 0xe0);
              *s++ = (char)(((wchar >> 6) & 0x3f) | 0x80);
              *s = (char)(((wchar >> 0) & 0x3f) | 0x80);
              return 3;
            }
        }

    case _MB_SHIFT:

      /* ANSI X3.159-1989, 4.10.7.3: "If the value of wchar is zero,
         the wctomb function is left in the initial shift state." */

      if (wchar == 0)
        *pshift = 0;

      /* Not yet implemented */

      break;
    }
  return -1;
}
