1/* Test of character set conversion. 2 Copyright (C) 2007 Free Software Foundation, Inc. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17/* Written by Bruno Haible <bruno@clisp.org>, 2007. */ 18 19#include <config.h> 20 21#if HAVE_ICONV 22# include <iconv.h> 23#endif 24 25#include <errno.h> 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29 30#define ASSERT(expr) \ 31 do \ 32 { \ 33 if (!(expr)) \ 34 { \ 35 fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ 36 abort (); \ 37 } \ 38 } \ 39 while (0) 40 41int 42main () 43{ 44#if HAVE_ICONV 45 /* Assume that iconv() supports at least the encodings ASCII, ISO-8859-1, 46 and UTF-8. */ 47 iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); 48 iconv_t cd_utf8_to_88591 = iconv_open ("ISO-8859-1", "UTF-8"); 49 50 ASSERT (cd_88591_to_utf8 != (iconv_t)(-1)); 51 ASSERT (cd_utf8_to_88591 != (iconv_t)(-1)); 52 53 /* Test conversion from ISO-8859-1 to UTF-8 with no errors. */ 54 { 55 static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; 56 static const char expected[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237"; 57 char buf[50]; 58 const char *inptr = input; 59 size_t inbytesleft = strlen (input); 60 char *outptr = buf; 61 size_t outbytesleft = sizeof (buf); 62 size_t res = iconv (cd_88591_to_utf8, 63 (ICONV_CONST char **) &inptr, &inbytesleft, 64 &outptr, &outbytesleft); 65 ASSERT (res == 0 && inbytesleft == 0); 66 ASSERT (outptr == buf + strlen (expected)); 67 ASSERT (memcmp (buf, expected, strlen (expected)) == 0); 68 } 69 70 /* Test conversion from ISO-8859-1 to UTF-8 with E2BIG. */ 71 { 72 static const char input[] = "\304"; 73 static char buf[2] = { (char)0xDE, (char)0xAD }; 74 const char *inptr = input; 75 size_t inbytesleft = 1; 76 char *outptr = buf; 77 size_t outbytesleft = 1; 78 size_t res = iconv (cd_88591_to_utf8, 79 (ICONV_CONST char **) &inptr, &inbytesleft, 80 &outptr, &outbytesleft); 81 ASSERT (res == (size_t)(-1) && errno == E2BIG); 82 ASSERT (inbytesleft == 1); 83 ASSERT (outbytesleft == 1); 84 ASSERT ((unsigned char) buf[1] == 0xAD); 85 ASSERT ((unsigned char) buf[0] == 0xDE); 86 } 87 88 /* Test conversion from UTF-8 to ISO-8859-1 with no errors. */ 89 { 90 static const char input[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237"; 91 static const char expected[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; 92 char buf[50]; 93 const char *inptr = input; 94 size_t inbytesleft = strlen (input); 95 char *outptr = buf; 96 size_t outbytesleft = sizeof (buf); 97 size_t res = iconv (cd_utf8_to_88591, 98 (ICONV_CONST char **) &inptr, &inbytesleft, 99 &outptr, &outbytesleft); 100 ASSERT (res == 0 && inbytesleft == 0); 101 ASSERT (outptr == buf + strlen (expected)); 102 ASSERT (memcmp (buf, expected, strlen (expected)) == 0); 103 } 104 105 /* Test conversion from UTF-8 to ISO-8859-1 with EILSEQ. */ 106 { 107 static const char input[] = "\342\202\254"; /* EURO SIGN */ 108 char buf[10]; 109 const char *inptr = input; 110 size_t inbytesleft = strlen (input); 111 char *outptr = buf; 112 size_t outbytesleft = sizeof (buf); 113 size_t res = iconv (cd_utf8_to_88591, 114 (ICONV_CONST char **) &inptr, &inbytesleft, 115 &outptr, &outbytesleft); 116 if (res == (size_t)(-1)) 117 { 118 ASSERT (errno == EILSEQ); 119 ASSERT (inbytesleft == strlen (input) && outptr == buf); 120 } 121 else 122 { 123 ASSERT (res == 1); 124 ASSERT (inbytesleft == 0); 125 } 126 } 127 128 /* Test conversion from UTF-8 to ISO-8859-1 with EINVAL. */ 129 { 130 static const char input[] = "\342"; 131 char buf[10]; 132 const char *inptr = input; 133 size_t inbytesleft = 1; 134 char *outptr = buf; 135 size_t outbytesleft = sizeof (buf); 136 size_t res = iconv (cd_utf8_to_88591, 137 (ICONV_CONST char **) &inptr, &inbytesleft, 138 &outptr, &outbytesleft); 139 ASSERT (res == (size_t)(-1) && errno == EINVAL); 140 ASSERT (inbytesleft == 1 && outptr == buf); 141 } 142 143 iconv_close (cd_88591_to_utf8); 144 iconv_close (cd_utf8_to_88591); 145#endif 146 147 return 0; 148} 149