/* utf2.c (emx+gcc) */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <emx/locale.h>

static void usage (void)
{
  fputs ("Usage:\n"
         " utf2 -c      Test wctomb() and mbtowc() with all wchar_t values\n"
         " utf2 -s      Test wcstombs() and mbstowcs() with random strings\n",
         stdout);
  exit (1);
}


static void test_c (void)
{
  wchar_t w0, w1;
  int n0, n1;
  char mb[MB_LEN_MAX];

  w0 = 0;
  do
    {
      memset (mb, 0, sizeof (mb));
      n0 = wctomb (mb, w0);
      if (n0 == -1)
        printf ("wctomb() fails for %lu\n", (unsigned long)w0);
      else
        {
          n1 = mblen (mb, n0);
          if (n1 == -1)
            printf ("mblen() fails for %lu\n", (unsigned long)w0);
          else if (n1 != n0 && !(n1 == 0 && n0 == 1 && w0 == 0))
            printf ("mblen() returns wrong length for %lu\n",
                    (unsigned long)w0);
          else
            {
              n1 = mbtowc (&w1, mb, n0);
              if (n1 == -1)
                printf ("mbtowc() fails for %lu\n", (unsigned long)w0);
              else if (n1 != n0 && !(n1 == 0 && n0 == 1 && w0 == 0))
                printf ("mbtowc() returns wrong length for %lu\n",
                        (unsigned long)w0);
              else if (w0 != w1 && w0 != 0)
                printf ("mbtowc() computes wrong value for %lu\n",
                        (unsigned long)w0);
            }
        }
      ++w0;
    } while (w0 != 0);
}


#define MAX_WCS 20

static void test_s (void)
{
  char mbs[MAX_WCS * MB_LEN_MAX];
  wchar_t wcs0[MAX_WCS];
  wchar_t wcs1[MAX_WCS];
  int repeat, nwcs, i, n0, n1;

  srandom (1);
  for (repeat = 0; repeat < 20000; ++repeat)
    {
      nwcs = (int)(random () % (MAX_WCS - 1));
      for (i = 0; i < nwcs; ++i)
        do
          {
            wcs0[i] = (wchar_t)random ();
          } while (wcs0[i] == 0);
      wcs0[nwcs] = 0;
      n0 = wcstombs (mbs, wcs0, sizeof (mbs));
      if (n0 == -1)
        printf ("wcstombs() fails in loop %d\n", repeat);
      else
        {
          n1 = mbstowcs (wcs1, mbs, sizeof (mbs));
          if (n1 == -1)
            printf ("mbstowcs() fails in loop %d\n", repeat);
          else if (n1 != nwcs)
            printf ("mbstowcs() returns an incorrect value in loop %d\n",
                    repeat);
          else if (memcmp (wcs0, wcs1, nwcs * sizeof (wcs0[0])) != 0)
            printf ("mbstowcs() computes wrong value in loop %d\n", repeat);
        }
    }
}


int main (int argc, char *argv[])
{
  char mode;

  if (argc != 2)
    usage ();
  if (strcmp (argv[1], "-c") == 0)
    mode = 'c';
  else if (strcmp (argv[1], "-s") == 0)
    mode = 's';
  else
    usage ();

  /* There's no locale using UTF-2.  Select UTF-2 `manually'.  You
     should not do this in application programs. */

  _cur_mbyte.mode = _MB_UTF_2;

  switch (mode)
    {
    case 'c':
      test_c ();
      break;

    case 's':
      test_s ();
      break;
    }
  return 0;
}
