Blame gnulib-tests/test-wcrtomb-w32.c

Packit 709fb3
/* Test of conversion of wide character to multibyte character.
Packit 709fb3
   Copyright (C) 2008-2017 Free Software Foundation, Inc.
Packit 709fb3
Packit 709fb3
   This program is free software: you can redistribute it and/or modify
Packit 709fb3
   it under the terms of the GNU General Public License as published by
Packit 709fb3
   the Free Software Foundation; either version 3 of the License, or
Packit 709fb3
   (at your option) any later version.
Packit 709fb3
Packit 709fb3
   This program is distributed in the hope that it will be useful,
Packit 709fb3
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 709fb3
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 709fb3
   GNU General Public License for more details.
Packit 709fb3
Packit 709fb3
   You should have received a copy of the GNU General Public License
Packit 709fb3
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 709fb3
Packit 709fb3
#include <config.h>
Packit 709fb3
Packit 709fb3
#include <wchar.h>
Packit 709fb3
Packit 709fb3
#include <locale.h>
Packit 709fb3
#include <stdio.h>
Packit 709fb3
#include <stdlib.h>
Packit 709fb3
#include <string.h>
Packit 709fb3
Packit 709fb3
#include "macros.h"
Packit 709fb3
Packit 709fb3
#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
Packit 709fb3
Packit 709fb3
static int
Packit 709fb3
test_one_locale (const char *name, int codepage)
Packit 709fb3
{
Packit 709fb3
  char buf[64];
Packit 709fb3
  size_t ret;
Packit 709fb3
Packit 709fb3
# if 1
Packit 709fb3
  /* Portable code to set the locale.  */
Packit 709fb3
  {
Packit 709fb3
    char name_with_codepage[1024];
Packit 709fb3
Packit 709fb3
    sprintf (name_with_codepage, "%s.%d", name, codepage);
Packit 709fb3
Packit 709fb3
    /* Set the locale.  */
Packit 709fb3
    if (setlocale (LC_ALL, name_with_codepage) == NULL)
Packit 709fb3
      return 77;
Packit 709fb3
  }
Packit 709fb3
# else
Packit 709fb3
  /* Hacky way to set a locale.codepage combination that setlocale() refuses
Packit 709fb3
     to set.  */
Packit 709fb3
  {
Packit 709fb3
    /* Codepage of the current locale, set with setlocale().
Packit 709fb3
       Not necessarily the same as GetACP().  */
Packit 709fb3
    extern __declspec(dllimport) unsigned int __lc_codepage;
Packit 709fb3
Packit 709fb3
    /* Set the locale.  */
Packit 709fb3
    if (setlocale (LC_ALL, name) == NULL)
Packit 709fb3
      return 77;
Packit 709fb3
Packit 709fb3
    /* Clobber the codepage and MB_CUR_MAX, both set by setlocale().  */
Packit 709fb3
    __lc_codepage = codepage;
Packit 709fb3
    switch (codepage)
Packit 709fb3
      {
Packit 709fb3
      case 1252:
Packit 709fb3
      case 1256:
Packit 709fb3
        MB_CUR_MAX = 1;
Packit 709fb3
        break;
Packit 709fb3
      case 932:
Packit 709fb3
      case 950:
Packit 709fb3
      case 936:
Packit 709fb3
        MB_CUR_MAX = 2;
Packit 709fb3
        break;
Packit 709fb3
      case 54936:
Packit 709fb3
      case 65001:
Packit 709fb3
        MB_CUR_MAX = 4;
Packit 709fb3
        break;
Packit 709fb3
      }
Packit 709fb3
Packit 709fb3
    /* Test whether the codepage is really available.  */
Packit 709fb3
    {
Packit 709fb3
      mbstate_t state;
Packit 709fb3
      wchar_t wc;
Packit 709fb3
Packit 709fb3
      memset (&state, '\0', sizeof (mbstate_t));
Packit 709fb3
      if (mbrtowc (&wc, " ", 1, &state) == (size_t)(-1))
Packit 709fb3
        return 77;
Packit 709fb3
    }
Packit 709fb3
  }
Packit 709fb3
# endif
Packit 709fb3
Packit 709fb3
  /* Test NUL character.  */
Packit 709fb3
  {
Packit 709fb3
    buf[0] = 'x';
Packit 709fb3
    ret = wcrtomb (buf, 0, NULL);
Packit 709fb3
    ASSERT (ret == 1);
Packit 709fb3
    ASSERT (buf[0] == '\0');
Packit 709fb3
  }
Packit 709fb3
Packit 709fb3
  /* Test single bytes.  */
Packit 709fb3
  {
Packit 709fb3
    int c;
Packit 709fb3
Packit 709fb3
    for (c = 0; c < 0x100; c++)
Packit 709fb3
      switch (c)
Packit 709fb3
        {
Packit 709fb3
        case '\t': case '\v': case '\f':
Packit 709fb3
        case ' ': case '!': case '"': case '#': case '%':
Packit 709fb3
        case '&': case '\'': case '(': case ')': case '*':
Packit 709fb3
        case '+': case ',': case '-': case '.': case '/':
Packit 709fb3
        case '0': case '1': case '2': case '3': case '4':
Packit 709fb3
        case '5': case '6': case '7': case '8': case '9':
Packit 709fb3
        case ':': case ';': case '<': case '=': case '>':
Packit 709fb3
        case '?':
Packit 709fb3
        case 'A': case 'B': case 'C': case 'D': case 'E':
Packit 709fb3
        case 'F': case 'G': case 'H': case 'I': case 'J':
Packit 709fb3
        case 'K': case 'L': case 'M': case 'N': case 'O':
Packit 709fb3
        case 'P': case 'Q': case 'R': case 'S': case 'T':
Packit 709fb3
        case 'U': case 'V': case 'W': case 'X': case 'Y':
Packit 709fb3
        case 'Z':
Packit 709fb3
        case '[': case '\\': case ']': case '^': case '_':
Packit 709fb3
        case 'a': case 'b': case 'c': case 'd': case 'e':
Packit 709fb3
        case 'f': case 'g': case 'h': case 'i': case 'j':
Packit 709fb3
        case 'k': case 'l': case 'm': case 'n': case 'o':
Packit 709fb3
        case 'p': case 'q': case 'r': case 's': case 't':
Packit 709fb3
        case 'u': case 'v': case 'w': case 'x': case 'y':
Packit 709fb3
        case 'z': case '{': case '|': case '}': case '~':
Packit 709fb3
          /* c is in the ISO C "basic character set".  */
Packit 709fb3
          ret = wcrtomb (buf, btowc (c), NULL);
Packit 709fb3
          ASSERT (ret == 1);
Packit 709fb3
          ASSERT (buf[0] == (char) c);
Packit 709fb3
          break;
Packit 709fb3
        }
Packit 709fb3
  }
Packit 709fb3
Packit 709fb3
  /* Test special calling convention, passing a NULL pointer.  */
Packit 709fb3
  {
Packit 709fb3
    ret = wcrtomb (NULL, '\0', NULL);
Packit 709fb3
    ASSERT (ret == 1);
Packit 709fb3
    ret = wcrtomb (NULL, btowc ('x'), NULL);
Packit 709fb3
    ASSERT (ret == 1);
Packit 709fb3
  }
Packit 709fb3
Packit 709fb3
  switch (codepage)
Packit 709fb3
    {
Packit 709fb3
    case 1252:
Packit 709fb3
      /* Locale encoding is CP1252, an extension of ISO-8859-1.  */
Packit 709fb3
      {
Packit 709fb3
        /* Convert "B\374\337er": "Büßer" */
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x00FC, NULL);
Packit 709fb3
        ASSERT (ret == 1);
Packit 709fb3
        ASSERT (memcmp (buf, "\374", 1) == 0);
Packit 709fb3
        ASSERT (buf[1] == 'x');
Packit 709fb3
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x00DF, NULL);
Packit 709fb3
        ASSERT (ret == 1);
Packit 709fb3
        ASSERT (memcmp (buf, "\337", 1) == 0);
Packit 709fb3
        ASSERT (buf[1] == 'x');
Packit 709fb3
      }
Packit 709fb3
      return 0;
Packit 709fb3
Packit 709fb3
    case 1256:
Packit 709fb3
      /* Locale encoding is CP1256, not the same as ISO-8859-6.  */
Packit 709fb3
      {
Packit 709fb3
        /* Convert "x\302\341\346y": "xآلوy" */
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x0622, NULL);
Packit 709fb3
        ASSERT (ret == 1);
Packit 709fb3
        ASSERT (memcmp (buf, "\302", 1) == 0);
Packit 709fb3
        ASSERT (buf[1] == 'x');
Packit 709fb3
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x0644, NULL);
Packit 709fb3
        ASSERT (ret == 1);
Packit 709fb3
        ASSERT (memcmp (buf, "\341", 1) == 0);
Packit 709fb3
        ASSERT (buf[1] == 'x');
Packit 709fb3
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x0648, NULL);
Packit 709fb3
        ASSERT (ret == 1);
Packit 709fb3
        ASSERT (memcmp (buf, "\346", 1) == 0);
Packit 709fb3
        ASSERT (buf[1] == 'x');
Packit 709fb3
      }
Packit 709fb3
      return 0;
Packit 709fb3
Packit 709fb3
    case 932:
Packit 709fb3
      /* Locale encoding is CP932, similar to Shift_JIS.  */
Packit 709fb3
      {
Packit 709fb3
        /* Convert "<\223\372\226\173\214\352>": "<日本語>" */
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x65E5, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\223\372", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x672C, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\226\173", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x8A9E, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\214\352", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
      }
Packit 709fb3
      return 0;
Packit 709fb3
Packit 709fb3
    case 950:
Packit 709fb3
      /* Locale encoding is CP950, similar to Big5.  */
Packit 709fb3
      {
Packit 709fb3
        /* Convert "<\244\351\245\273\273\171>": "<日本語>" */
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x65E5, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\244\351", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x672C, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\245\273", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x8A9E, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\273\171", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
      }
Packit 709fb3
      return 0;
Packit 709fb3
Packit 709fb3
    case 936:
Packit 709fb3
      /* Locale encoding is CP936 = GBK, an extension of GB2312.  */
Packit 709fb3
      {
Packit 709fb3
        /* Convert "<\310\325\261\276\325\132>": "<日本語>" */
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x65E5, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\310\325", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x672C, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\261\276", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x8A9E, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\325\132", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
      }
Packit 709fb3
      return 0;
Packit 709fb3
Packit 709fb3
    case 54936:
Packit 709fb3
      /* Locale encoding is CP54936 = GB18030.  */
Packit 709fb3
      {
Packit 709fb3
        /* Convert "B\250\271\201\060\211\070er": "Büßer" */
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x00FC, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\250\271", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x00DF, NULL);
Packit 709fb3
        ASSERT (ret == 4);
Packit 709fb3
        ASSERT (memcmp (buf, "\201\060\211\070", 4) == 0);
Packit 709fb3
        ASSERT (buf[4] == 'x');
Packit 709fb3
      }
Packit 709fb3
      return 0;
Packit 709fb3
Packit 709fb3
    case 65001:
Packit 709fb3
      /* Locale encoding is CP65001 = UTF-8.  */
Packit 709fb3
      {
Packit 709fb3
        /* Convert "B\303\274\303\237er": "Büßer" */
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x00FC, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\303\274", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
Packit 709fb3
        memset (buf, 'x', 8);
Packit 709fb3
        ret = wcrtomb (buf, 0x00DF, NULL);
Packit 709fb3
        ASSERT (ret == 2);
Packit 709fb3
        ASSERT (memcmp (buf, "\303\237", 2) == 0);
Packit 709fb3
        ASSERT (buf[2] == 'x');
Packit 709fb3
      }
Packit 709fb3
      return 0;
Packit 709fb3
Packit 709fb3
    default:
Packit 709fb3
      return 1;
Packit 709fb3
    }
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
int
Packit 709fb3
main (int argc, char *argv[])
Packit 709fb3
{
Packit 709fb3
  int codepage = atoi (argv[argc - 1]);
Packit 709fb3
  int result;
Packit 709fb3
  int i;
Packit 709fb3
Packit 709fb3
  result = 77;
Packit 709fb3
  for (i = 1; i < argc - 1; i++)
Packit 709fb3
    {
Packit 709fb3
      int ret = test_one_locale (argv[i], codepage);
Packit 709fb3
Packit 709fb3
      if (ret != 77)
Packit 709fb3
        result = ret;
Packit 709fb3
    }
Packit 709fb3
Packit 709fb3
  if (result == 77)
Packit 709fb3
    {
Packit 709fb3
      fprintf (stderr, "Skipping test: found no locale with codepage %d\n",
Packit 709fb3
               codepage);
Packit 709fb3
    }
Packit 709fb3
  return result;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
#else
Packit 709fb3
Packit 709fb3
int
Packit 709fb3
main (int argc, char *argv[])
Packit 709fb3
{
Packit 709fb3
  fputs ("Skipping test: not a native Windows system\n", stderr);
Packit 709fb3
  return 77;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
#endif