test-wcrtomb.c 4.51 KB
Newer Older
1
/* Test of conversion of wide character to multibyte character.
Eric Blake's avatar
Eric Blake committed
2
   Copyright (C) 2008-2014 Free Software Foundation, Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* Written by Bruno Haible <bruno@clisp.org>, 2008.  */

#include <config.h>

#include <wchar.h>

Eric Blake's avatar
Eric Blake committed
23 24 25
#include "signature.h"
SIGNATURE_CHECK (wcrtomb, size_t, (char *, wchar_t, mbstate_t *));

26 27 28 29
#include <locale.h>
#include <stdlib.h>
#include <string.h>

30
#include "macros.h"
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

/* Check the multibyte character s[0..n-1].  */
static void
check_character (const char *s, size_t n)
{
  wchar_t wc;
  char buf[64];
  int iret;
  size_t ret;

  wc = (wchar_t) 0xBADFACE;
  iret = mbtowc (&wc, s, n);
  ASSERT (iret == n);

  ret = wcrtomb (buf, wc, NULL);
  ASSERT (ret == n);
  ASSERT (memcmp (buf, s, n) == 0);

  /* Test special calling convention, passing a NULL pointer.  */
  ret = wcrtomb (NULL, wc, NULL);
  ASSERT (ret == 1);
}

int
main (int argc, char *argv[])
{
  char buf[64];
  size_t ret;

  /* configure should already have checked that the locale is supported.  */
  if (setlocale (LC_ALL, "") == NULL)
    return 1;

  /* Test NUL character.  */
  {
    buf[0] = 'x';
    ret = wcrtomb (buf, 0, NULL);
    ASSERT (ret == 1);
    ASSERT (buf[0] == '\0');
  }

  /* Test single bytes.  */
  {
    int c;

    for (c = 0; c < 0x100; c++)
      switch (c)
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
        {
        case '\t': case '\v': case '\f':
        case ' ': case '!': case '"': case '#': case '%':
        case '&': case '\'': case '(': case ')': case '*':
        case '+': case ',': case '-': case '.': case '/':
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
        case ':': case ';': case '<': case '=': case '>':
        case '?':
        case 'A': case 'B': case 'C': case 'D': case 'E':
        case 'F': case 'G': case 'H': case 'I': case 'J':
        case 'K': case 'L': case 'M': case 'N': case 'O':
        case 'P': case 'Q': case 'R': case 'S': case 'T':
        case 'U': case 'V': case 'W': case 'X': case 'Y':
        case 'Z':
        case '[': case '\\': case ']': case '^': case '_':
        case 'a': case 'b': case 'c': case 'd': case 'e':
        case 'f': case 'g': case 'h': case 'i': case 'j':
        case 'k': case 'l': case 'm': case 'n': case 'o':
        case 'p': case 'q': case 'r': case 's': case 't':
        case 'u': case 'v': case 'w': case 'x': case 'y':
        case 'z': case '{': case '|': case '}': case '~':
          /* c is in the ISO C "basic character set".  */
          ret = wcrtomb (buf, btowc (c), NULL);
          ASSERT (ret == 1);
          ASSERT (buf[0] == (char) c);
          break;
        }
106 107
  }

Bruno Haible's avatar
Bruno Haible committed
108 109 110 111 112 113 114 115
  /* Test special calling convention, passing a NULL pointer.  */
  {
    ret = wcrtomb (NULL, '\0', NULL);
    ASSERT (ret == 1);
    ret = wcrtomb (NULL, btowc ('x'), NULL);
    ASSERT (ret == 1);
  }

116 117 118 119
  if (argc > 1)
    switch (argv[1][0])
      {
      case '1':
120 121 122
        /* Locale encoding is ISO-8859-1 or ISO-8859-15.  */
        {
          const char input[] = "B\374\337er"; /* "Büßer" */
123

124 125 126 127
          check_character (input + 1, 1);
          check_character (input + 2, 1);
        }
        return 0;
128 129

      case '2':
130 131 132
        /* Locale encoding is UTF-8.  */
        {
          const char input[] = "B\303\274\303\237er"; /* "Büßer" */
133

134 135 136 137
          check_character (input + 1, 2);
          check_character (input + 3, 2);
        }
        return 0;
138 139

      case '3':
140 141 142
        /* Locale encoding is EUC-JP.  */
        {
          const char input[] = "<\306\374\313\334\270\354>"; /* "<日本語>" */
143

144 145 146 147 148
          check_character (input + 1, 2);
          check_character (input + 3, 2);
          check_character (input + 5, 2);
        }
        return 0;
149 150

      case '4':
151 152 153 154 155 156 157 158
        /* Locale encoding is GB18030.  */
        {
          const char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */

          check_character (input + 1, 2);
          check_character (input + 3, 4);
        }
        return 0;
159 160 161 162
      }

  return 1;
}