Blame win_iconv_test.c

Packit 2bcd41

Packit 2bcd41
#ifdef USE_ICONV_H
Packit 2bcd41
#include <iconv.h>
Packit 2bcd41
#include <windows.h>
Packit 2bcd41
#include <errno.h>
Packit 2bcd41
#include <string.h>
Packit 2bcd41
#include <stdlib.h>
Packit 2bcd41
#else
Packit 2bcd41
#include "win_iconv.c"
Packit 2bcd41
#endif
Packit 2bcd41

Packit 2bcd41
#include <stdio.h>
Packit 2bcd41

Packit 2bcd41
const char *
Packit 2bcd41
tohex(const char *str, int size)
Packit 2bcd41
{
Packit 2bcd41
    static char buf[BUFSIZ];
Packit 2bcd41
    char *pbuf = buf;
Packit 2bcd41
    int i;
Packit 2bcd41
    buf[0] = 0;
Packit 2bcd41
    for (i = 0; i < size; ++i)
Packit 2bcd41
        pbuf += sprintf(pbuf, "%02X", str[i] & 0xFF);
Packit 2bcd41
    return buf;
Packit 2bcd41
}
Packit 2bcd41

Packit 2bcd41
const char *
Packit 2bcd41
errstr(int errcode)
Packit 2bcd41
{
Packit 2bcd41
    static char buf[BUFSIZ];
Packit 2bcd41
    switch (errcode)
Packit 2bcd41
    {
Packit 2bcd41
    case 0: return "NOERROR";
Packit 2bcd41
    case EINVAL: return "EINVAL";
Packit 2bcd41
    case EILSEQ: return "EILSEQ";
Packit 2bcd41
    case E2BIG: return "E2BIG";
Packit 2bcd41
    }
Packit 2bcd41
    sprintf(buf, "%d\n", errcode);
Packit 2bcd41
    return buf;
Packit 2bcd41
}
Packit 2bcd41

Packit 2bcd41
#ifdef USE_LIBICONV_DLL
Packit 2bcd41
int use_dll;
Packit 2bcd41

Packit 2bcd41
int
Packit 2bcd41
setdll(const char *dllpath)
Packit 2bcd41
{
Packit 2bcd41
    char buf[BUFSIZ];
Packit 2bcd41
    rec_iconv_t cd;
Packit 2bcd41

Packit 2bcd41
    sprintf(buf, "WINICONV_LIBICONV_DLL=%s", dllpath);
Packit 2bcd41
    putenv(buf);
Packit 2bcd41
    if (libiconv_iconv_open(&cd, "ascii", "ascii"))
Packit 2bcd41
    {
Packit 2bcd41
        FreeLibrary(cd.hlibiconv);
Packit 2bcd41
        use_dll = TRUE;
Packit 2bcd41
        return TRUE;
Packit 2bcd41
    }
Packit 2bcd41
    use_dll = FALSE;
Packit 2bcd41
    return FALSE;
Packit 2bcd41
}
Packit 2bcd41
#endif
Packit 2bcd41

Packit 2bcd41
/*
Packit 2bcd41
 * We can test the codepage that is installed in the system.
Packit 2bcd41
 */
Packit 2bcd41
int
Packit 2bcd41
check_enc(const char *encname, int codepage)
Packit 2bcd41
{
Packit 2bcd41
    iconv_t cd;
Packit 2bcd41
    int cp;
Packit 2bcd41
    cd = iconv_open("utf-8", encname);
Packit 2bcd41
    if (cd == (iconv_t)(-1))
Packit 2bcd41
    {
Packit 2bcd41
        printf("%s(%d) IS NOT SUPPORTED: SKIP THE TEST\n", encname, codepage);
Packit 2bcd41
        return FALSE;
Packit 2bcd41
    }
Packit 2bcd41
#ifndef USE_ICONV_H
Packit 2bcd41
    cp = ((rec_iconv_t *)cd)->from.codepage;
Packit 2bcd41
    if (cp != codepage)
Packit 2bcd41
    {
Packit 2bcd41
        printf("%s(%d) ALIAS IS MAPPED TO DIFFERENT CODEPAGE (%d)\n", encname, codepage, cp);
Packit 2bcd41
        exit(1);
Packit 2bcd41
    }
Packit 2bcd41
#endif
Packit 2bcd41
    iconv_close(cd);
Packit 2bcd41
    return TRUE;
Packit 2bcd41
}
Packit 2bcd41

Packit 2bcd41
void
Packit 2bcd41
test(const char *from, const char *fromstr, int fromsize, const char *to, const char *tostr, int tosize, int errcode, int bufsize, int line)
Packit 2bcd41
{
Packit 2bcd41
    char outbuf[BUFSIZ];
Packit 2bcd41
    char *pin;
Packit 2bcd41
    char *pout;
Packit 2bcd41
    size_t inbytesleft;
Packit 2bcd41
    size_t outbytesleft;
Packit 2bcd41
    iconv_t cd;
Packit 2bcd41
    size_t r;
Packit 2bcd41
#ifdef USE_LIBICONV_DLL
Packit 2bcd41
    char dllpath[_MAX_PATH];
Packit 2bcd41
#endif
Packit 2bcd41

Packit 2bcd41
    cd = iconv_open(to, from);
Packit 2bcd41
    if (cd == (iconv_t)(-1))
Packit 2bcd41
    {
Packit 2bcd41
        printf("%s -> %s: NG: INVALID ENCODING NAME: line=%d\n", from, to, line);
Packit 2bcd41
        exit(1);
Packit 2bcd41
    }
Packit 2bcd41

Packit 2bcd41
#ifdef USE_LIBICONV_DLL
Packit 2bcd41
    if (((rec_iconv_t *)cd)->hlibiconv != NULL)
Packit 2bcd41
        GetModuleFileNameA(((rec_iconv_t *)cd)->hlibiconv, dllpath, sizeof(dllpath));
Packit 2bcd41

Packit 2bcd41
    if (use_dll && ((rec_iconv_t *)cd)->hlibiconv == NULL)
Packit 2bcd41
    {
Packit 2bcd41
        printf("%s: %s -> %s: NG: FAILED TO USE DLL: line=%d\n", dllpath, from, to, line);
Packit 2bcd41
        exit(1);
Packit 2bcd41
    }
Packit 2bcd41
    else if (!use_dll && ((rec_iconv_t *)cd)->hlibiconv != NULL)
Packit 2bcd41
    {
Packit 2bcd41
        printf("%s: %s -> %s: NG: DLL IS LOADED UNEXPECTEDLY: line=%d\n", dllpath, from, to, line);
Packit 2bcd41
        exit(1);
Packit 2bcd41
    }
Packit 2bcd41
#endif
Packit 2bcd41

Packit 2bcd41
    errno = 0;
Packit 2bcd41

Packit 2bcd41
    pin = (char *)fromstr;
Packit 2bcd41
    pout = outbuf;
Packit 2bcd41
    inbytesleft = fromsize;
Packit 2bcd41
    outbytesleft = bufsize;
Packit 2bcd41
    r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft);
Packit 2bcd41
    if (r != (size_t)(-1))
Packit 2bcd41
        r = iconv(cd, NULL, NULL, &pout, &outbytesleft);
Packit 2bcd41
    *pout = 0;
Packit 2bcd41

Packit 2bcd41
#ifdef USE_LIBICONV_DLL
Packit 2bcd41
    if (use_dll)
Packit 2bcd41
        printf("%s: ", dllpath);
Packit 2bcd41
#endif
Packit 2bcd41
    printf("%s(%s) -> ", from, tohex(fromstr, fromsize));
Packit 2bcd41
    printf("%s(%s%s%s): ", to, tohex(tostr, tosize),
Packit 2bcd41
            errcode == 0 ? "" : ":",
Packit 2bcd41
            errcode == 0 ? "" : errstr(errcode));
Packit 2bcd41
    if (strcmp(outbuf, tostr) == 0 && errno == errcode)
Packit 2bcd41
        printf("OK\n");
Packit 2bcd41
    else
Packit 2bcd41
    {
Packit 2bcd41
        printf("RESULT(%s:%s): ", tohex(outbuf, sizeof(outbuf) - outbytesleft),
Packit 2bcd41
                errstr(errno));
Packit 2bcd41
        printf("NG: line=%d\n", line);
Packit 2bcd41
        exit(1);
Packit 2bcd41
    }
Packit 2bcd41
}
Packit 2bcd41

Packit 2bcd41
#define STATIC_STRLEN(arr) (sizeof(arr) - 1)
Packit 2bcd41

Packit 2bcd41
#define success(from, fromstr, to, tostr) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), 0, BUFSIZ, __LINE__)
Packit 2bcd41
#define einval(from, fromstr, to, tostr) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), EINVAL, BUFSIZ, __LINE__)
Packit 2bcd41
#define eilseq(from, fromstr, to, tostr) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), EILSEQ, BUFSIZ, __LINE__)
Packit 2bcd41
#define e2big(from, fromstr, to, tostr, bufsize) test(from, fromstr, STATIC_STRLEN(fromstr), to, tostr, STATIC_STRLEN(tostr), E2BIG, bufsize, __LINE__)
Packit 2bcd41

Packit 2bcd41
int
Packit 2bcd41
main(int argc, char **argv)
Packit 2bcd41
{
Packit 2bcd41
#ifdef USE_LIBICONV_DLL
Packit 2bcd41
    /* test use of dll if $DEFAULT_LIBICONV_DLL was defined. */
Packit 2bcd41
    if (setdll(""))
Packit 2bcd41
    {
Packit 2bcd41
        success("ascii", "ABC", "ascii", "ABC");
Packit 2bcd41
        success("ascii", "ABC", "utf-16be", "\x00\x41\x00\x42\x00\x43");
Packit 2bcd41
    }
Packit 2bcd41
    else
Packit 2bcd41
    {
Packit 2bcd41
        printf("\nDLL TEST IS SKIPPED\n\n");
Packit 2bcd41
    }
Packit 2bcd41

Packit 2bcd41
    setdll("none");
Packit 2bcd41
#endif
Packit 2bcd41

Packit 2bcd41
    if (check_enc("ascii", 20127))
Packit 2bcd41
    {
Packit 2bcd41
        success("ascii", "ABC", "ascii", "ABC");
Packit 2bcd41
        /* MSB is dropped.  Hmm... */
Packit 2bcd41
        success("ascii", "\x80\xFF", "ascii", "\x00\x7F");
Packit 2bcd41
    }
Packit 2bcd41

Packit 2bcd41
    /* unicode (CP1200 CP1201 CP12000 CP12001 CP65001) */
Packit 2bcd41
    if (check_enc("utf-8", 65001)
Packit 2bcd41
            && check_enc("utf-16be", 1201) && check_enc("utf-16le", 1200)
Packit 2bcd41
            && check_enc("utf-32be", 12001) && check_enc("utf-32le", 12000)
Packit 2bcd41
            )
Packit 2bcd41
    {
Packit 2bcd41
        /* Test the BOM behavior
Packit 2bcd41
         * 1. Remove the BOM when "fromcode" is utf-16 or utf-32.
Packit 2bcd41
         * 2. Add the BOM when "tocode" is utf-16 or utf-32.  */
Packit 2bcd41
        success("utf-16", "\xFE\xFF\x01\x02", "utf-16be", "\x01\x02");
Packit 2bcd41
        success("utf-16", "\xFF\xFE\x02\x01", "utf-16be", "\x01\x02");
Packit 2bcd41
        success("utf-32", "\x00\x00\xFE\xFF\x00\x00\x01\x02", "utf-32be", "\x00\x00\x01\x02");
Packit 2bcd41
        success("utf-32", "\xFF\xFE\x00\x00\x02\x01\x00\x00", "utf-32be", "\x00\x00\x01\x02");
Packit 2bcd41
        success("utf-16", "\xFE\xFF\x00\x01", "utf-8", "\x01");
Packit 2bcd41
#ifndef GLIB_COMPILATION
Packit 2bcd41
        success("utf-8", "\x01", "utf-16", "\xFE\xFF\x00\x01");
Packit 2bcd41
        success("utf-8", "\x01", "utf-32", "\x00\x00\xFE\xFF\x00\x00\x00\x01");
Packit 2bcd41
#else
Packit 2bcd41
        success("utf-8", "\x01", "utf-16", "\xFF\xFE\x01\x00");
Packit 2bcd41
        success("utf-8", "\x01", "utf-32", "\xFF\xFE\x00\x00\x01\x00\x00\x00");
Packit 2bcd41
#endif
Packit 2bcd41

Packit 2bcd41
        success("utf-16be", "\xFE\xFF\x01\x02", "utf-16be", "\xFE\xFF\x01\x02");
Packit 2bcd41
        success("utf-16le", "\xFF\xFE\x02\x01", "utf-16be", "\xFE\xFF\x01\x02");
Packit 2bcd41
        success("utf-32be", "\x00\x00\xFE\xFF\x00\x00\x01\x02", "utf-32be", "\x00\x00\xFE\xFF\x00\x00\x01\x02");
Packit 2bcd41
        success("utf-32le", "\xFF\xFE\x00\x00\x02\x01\x00\x00", "utf-32be", "\x00\x00\xFE\xFF\x00\x00\x01\x02");
Packit 2bcd41
        success("utf-16be", "\xFE\xFF\x00\x01", "utf-8", "\xEF\xBB\xBF\x01");
Packit 2bcd41
        success("utf-8", "\xEF\xBB\xBF\x01", "utf-8", "\xEF\xBB\xBF\x01");
Packit 2bcd41

Packit 2bcd41
        success("utf-16be", "\x01\x02", "utf-16le", "\x02\x01");
Packit 2bcd41
        success("utf-16le", "\x02\x01", "utf-16be", "\x01\x02");
Packit 2bcd41
        success("utf-16be", "\xFE\xFF", "utf-16le", "\xFF\xFE");
Packit 2bcd41
        success("utf-16le", "\xFF\xFE", "utf-16be", "\xFE\xFF");
Packit 2bcd41
        success("utf-32be", "\x00\x00\x03\x04", "utf-32le", "\x04\x03\x00\x00");
Packit 2bcd41
        success("utf-32le", "\x04\x03\x00\x00", "utf-32be", "\x00\x00\x03\x04");
Packit 2bcd41
        success("utf-32be", "\x00\x00\xFF\xFF", "utf-16be", "\xFF\xFF");
Packit 2bcd41
        success("utf-16be", "\xFF\xFF", "utf-32be", "\x00\x00\xFF\xFF");
Packit 2bcd41
        success("utf-32be", "\x00\x01\x00\x00", "utf-16be", "\xD8\x00\xDC\x00");
Packit 2bcd41
        success("utf-16be", "\xD8\x00\xDC\x00", "utf-32be", "\x00\x01\x00\x00");
Packit 2bcd41
        success("utf-32be", "\x00\x10\xFF\xFF", "utf-16be", "\xDB\xFF\xDF\xFF");
Packit 2bcd41
        success("utf-16be", "\xDB\xFF\xDF\xFF", "utf-32be", "\x00\x10\xFF\xFF");
Packit 2bcd41
        eilseq("utf-32be", "\x00\x11\x00\x00", "utf-16be", "");
Packit 2bcd41
        eilseq("utf-16be", "\xDB\xFF\xE0\x00", "utf-32be", "");
Packit 2bcd41
        success("utf-8", "\xE3\x81\x82", "utf-16be", "\x30\x42");
Packit 2bcd41
        einval("utf-8", "\xE3", "utf-16be", "");
Packit 2bcd41
    }
Packit 2bcd41

Packit 2bcd41
    /* Japanese (CP932 CP20932 CP50220 CP50221 CP50222 CP51932) */
Packit 2bcd41
    if (check_enc("cp932", 932)
Packit 2bcd41
            && check_enc("cp20932", 20932) && check_enc("euc-jp", 51932)
Packit 2bcd41
            && check_enc("cp50220", 50220) && check_enc("cp50221", 50221)
Packit 2bcd41
            && check_enc("cp50222", 50222) && check_enc("iso-2022-jp", 50221))
Packit 2bcd41
    {
Packit 2bcd41
        /* Test the compatibility for each other Japanese codepage.
Packit 2bcd41
         * And validate the escape sequence handling for iso-2022-jp. */
Packit 2bcd41
        success("utf-16be", "\xFF\x5E", "cp932", "\x81\x60");
Packit 2bcd41
        success("utf-16be", "\x30\x1C", "cp932", "\x81\x60");
Packit 2bcd41
        success("utf-16be", "\xFF\x5E", "cp932//nocompat", "\x81\x60");
Packit 2bcd41
        eilseq("utf-16be", "\x30\x1C", "cp932//nocompat", "");
Packit 2bcd41
        success("euc-jp", "\xA4\xA2", "utf-16be", "\x30\x42");
Packit 2bcd41
        einval("euc-jp", "\xA4\xA2\xA4", "utf-16be", "\x30\x42");
Packit 2bcd41
        eilseq("euc-jp", "\xA4\xA2\xFF\xFF", "utf-16be", "\x30\x42");
Packit 2bcd41
        success("cp932", "\x81\x60", "iso-2022-jp", "\x1B\x24\x42\x21\x41\x1B\x28\x42");
Packit 2bcd41
        success("UTF-16BE", "\xFF\x5E", "iso-2022-jp", "\x1B\x24\x42\x21\x41\x1B\x28\x42");
Packit 2bcd41
        eilseq("UTF-16BE", "\x30\x1C", "iso-2022-jp//nocompat", "");
Packit 2bcd41
        success("UTF-16BE", "\x30\x42\x30\x44", "iso-2022-jp", "\x1B\x24\x42\x24\x22\x24\x24\x1B\x28\x42");
Packit 2bcd41
        success("iso-2022-jp", "\x1B\x24\x42\x21\x41\x1B\x28\x42", "UTF-16BE", "\xFF\x5E");
Packit 2bcd41
    }
Packit 2bcd41

Packit 2bcd41
    /*
Packit 2bcd41
     * test for //translit
Packit 2bcd41
     * U+FF41 (FULLWIDTH LATIN SMALL LETTER A) <-> U+0062 (LATIN SMALL LETTER A)
Packit 2bcd41
     */
Packit 2bcd41
    eilseq("UTF-16BE", "\xFF\x41", "iso-8859-1", "");
Packit 2bcd41
    success("UTF-16BE", "\xFF\x41", "iso-8859-1//translit", "a");
Packit 2bcd41

Packit 2bcd41
    /*
Packit 2bcd41
     * test for //translit
Packit 2bcd41
     * Some character, not in "to" encoding -> DEFAULT CHARACTER (maybe "?")
Packit 2bcd41
     */
Packit 2bcd41
    eilseq("UTF-16BE", "\x30\x42", "ascii", "");
Packit 2bcd41
    success("UTF-16BE", "\x30\x42", "ascii//translit", "?");
Packit 2bcd41

Packit 2bcd41
    /*
Packit 2bcd41
     * test for //ignore
Packit 2bcd41
     */
Packit 2bcd41
    eilseq("UTF-8", "\xFF A \xFF B", "ascii//ignore", " A  B");
Packit 2bcd41
    eilseq("UTF-8", "\xEF\xBC\xA1 A \xEF\xBC\xA2 B", "ascii//ignore", " A  B");
Packit 2bcd41
    eilseq("UTF-8", "\xEF\x01 A \xEF\x02 B", "ascii//ignore", "\x01 A \x02 B");
Packit 2bcd41

Packit 2bcd41
    /*
Packit 2bcd41
     * TODO:
Packit 2bcd41
     * Test for state after iconv() failed.
Packit 2bcd41
     * Ensure iconv() error is safe and continuable.
Packit 2bcd41
     */
Packit 2bcd41

Packit 2bcd41
    return 0;
Packit 2bcd41
}
Packit 2bcd41