[Jon Willeke] I'm attaching a few tweaks to build psqlodbc with Unicode support on...
authorDave Page <dpage@pgadmin.org>
Wed, 4 Feb 2004 08:55:28 +0000 (08:55 +0000)
committerDave Page <dpage@pgadmin.org>
Wed, 4 Feb 2004 08:55:28 +0000 (08:55 +0000)
I tested this with unixODBC 2.2.7 on SuSE Linux 8.2.  I built unixODBC --with-iconv-ucode-enc=UCS-4LE and with SQL_WCHART_CONVERT defined, so that SQLWCHAR is wchar_t.  I have not tested it with UCS-2 / unsigned short.

I also tested this with iODBC 3.51.1, which always uses wchar_t on Unix.

One caveat, if anyone actually plays with this: sqlext.h should include sqlucode.h, so I haven't patched psqlodbc to do so.  The next release of unixODBC will contain this fix, and I've mentioned it to the iODBC maintainer.

Makefile.am
configure.ac
convert.c
execute.c
info.c
info30.c
psqlodbc.h
win_unicode.c

index 28fc87bf41b95689e0b58821ac7f3296aa2fb815..0728ab07f334603e71eecaae7b306119b6d23e39 100644 (file)
@@ -2,7 +2,7 @@
 #
 # Makefile.am for psqlodbc (PostgreSQL ODBC driver)
 #
-# $Header: /home/heikki/psqlodbc-cvs-copy/psqlodbc/Makefile.am,v 1.9 2003/12/09 10:01:37 hinoue Exp $
+# $Header: /home/heikki/psqlodbc-cvs-copy/psqlodbc/Makefile.am,v 1.10 2004/02/04 08:55:28 dpage Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -27,6 +27,11 @@ psqlodbc_la_SOURCES += \
    psqlodbc.h qresult.h resource.h socket.h statement.h tuple.h \
    tuplelist.h version.h
 
+if enable_unicode
+psqlodbc_la_SOURCES += \
+   odbcapi30w.c odbcapiw.c win_unicode.c
+endif
+
 EXTRA_psqlodbc_la_SOURCES = md5.c
 
 if with_unixodbc
@@ -45,7 +50,7 @@ BUILT_SOURCES = odbc-drop.sql
 EXTRA_DIST = README.unix license.txt notice.txt readme.txt odbcinst.ini \
    libtool.m4 psqlodbc_win32.def psqlodbc_apiw.def psqlodbc_api30w.def \
    psqlodbc_api25.def win32.mak win32_30w.mak win32_25.mak \
-   dlg_wingui.c win_unicode.c win_setup.h win_md5.c setup.c \
+   dlg_wingui.c win_setup.h win_md5.c setup.c \
    psqlodbc.reg psqlodbc25.reg psqlodbc30w.reg
 MAINTAINERCLEANFILES = odbc-drop.sql \
    Makefile.in config.guess config.h.in config.sub configure \
index 4ef425323899b524a0c3f792d58041ca252155af..e273020ba719ab917a3d0a5e31904c8eec8e1485 100644 (file)
@@ -13,7 +13,8 @@ AC_DEFINE(DRIVER_CURSOR_IMPLEMENT, 1,
 PGAC_ARG_BOOL(with, unixodbc, no,
               [  --with-unixodbc         build ODBC driver for unixODBC],
               [AC_DEFINE(WITH_UNIXODBC, 1,
-                         [Define to 1 to build with unixODBC support (--with-unixodbc)])])
+                         [Define to 1 to build with unixODBC support (--with-unixodbc)])
+               AC_DEFINE(SQL_WCHART_CONVERT, [], [Define to use wchar_t as SQLWCHAR in unixODBC])])
 
 PGAC_ARG_BOOL(with, iodbc, no,
               [  --with-iodbc            build ODBC driver for iODBC],
@@ -34,8 +35,20 @@ PGAC_ARG_REQ(with, odbcver, [  --with-odbcver=VERSION  change default ODBC versi
            [Define to ODBC version (--with-odbcver)])])
 AC_MSG_RESULT([$with_odbcver])
 
+# to implement the Unicode driver
+AC_ARG_ENABLE(unicode,
+              [  --enable-unicode            build ODBC driver for Unicode],
+              [AC_DEFINE(UNICODE_SUPPORT, 1,
+                         [Define to 1 to build with Unicode support (--enable-unicode)])
+               AC_DEFINE(UNICODE, [],
+                         [Define to use wide APIs])
+               AC_DEFINE(SQL_NOUNICODEMAP, [],
+                         [Define to disable mapping SQL* to SQL*W])
+               AC_CHECK_FUNCS(iswascii)])
+
 AM_CONDITIONAL(with_unixodbc, [test $with_unixodbc = yes])
 AM_CONDITIONAL(with_iodbc, [test $with_iodbc = yes])
+AM_CONDITIONAL(enable_unicode, [test x"$enable_unicode" = xyes])
 
 AC_CHECK_FUNCS(strtoul strtoll)
 AC_CHECK_LIB(socket, socket)
index 5332be1daca099204f0f3d9e0a52987849cd5494..106b0af11b914a1b2680ffe3d54ffab85325c85c 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -763,7 +763,7 @@ inolog("2stime fr=%d\n", std_time.fr);
                    if (fCType == SQL_C_WCHAR)
                    {
                        len = utf8_to_ucs2_lf(neut_str, -1, lf_conv, NULL, 0);
-                       len *= 2;
+                       len *= WCLEN;
                        wchanged = changed = TRUE;
                    }
                    else
@@ -810,7 +810,7 @@ inolog("2stime fr=%d\n", std_time.fr);
 #ifdef UNICODE_SUPPORT
                        if (fCType == SQL_C_WCHAR)
                        {
-                           utf8_to_ucs2_lf(neut_str, -1, lf_conv, (SQLWCHAR *) pgdc->ttlbuf, len / 2);
+                           utf8_to_ucs2_lf(neut_str, -1, lf_conv, (SQLWCHAR *) pgdc->ttlbuf, len / WCLEN);
                        }
                        else
 #endif /* UNICODE_SUPPORT */
@@ -942,18 +942,18 @@ inolog("2stime fr=%d\n", std_time.fr);
 #ifdef UNICODE_SUPPORT
        if (SQL_C_WCHAR == fCType && ! wchanged)
        {
-           if (cbValueMax > 2 * len)
+           if (cbValueMax > WCLEN * len)
            {
                char *str = strdup(rgbValueBindRow);
-               UInt4   ucount = utf8_to_ucs2(str, len, (SQLWCHAR *) rgbValueBindRow, cbValueMax / 2);
-               if (cbValueMax < 2 * (SDWORD) ucount)
+               UInt4   ucount = utf8_to_ucs2(str, len, (SQLWCHAR *) rgbValueBindRow, cbValueMax / WCLEN);
+               if (cbValueMax < WCLEN * (SDWORD) ucount)
                    result = COPY_RESULT_TRUNCATED;
-               len = ucount * 2;
+               len = ucount * WCLEN;
                free(str); 
            }
            else
            {
-               len *= 2;
+               len *= WCLEN;
                result = COPY_RESULT_TRUNCATED;
            }
        }
@@ -2647,8 +2647,8 @@ ResolveOneParam(QueryBuild *qb)
 
 #ifdef UNICODE_SUPPORT
        case SQL_C_WCHAR:
-           buf = allocbuf = ucs2_to_utf8((SQLWCHAR *) buffer, used / 2, &used, FALSE);
-           used *= 2;
+           buf = allocbuf = ucs2_to_utf8((SQLWCHAR *) buffer, used / WCLEN, &used, FALSE);
+           used *= WCLEN;
            break;
 #endif /* UNICODE_SUPPORT */
 
index 2e1933de6591eb0ac204c3489a4ce031c313d3e8..7b3c87971a90bd1f5533c5184d44bcf443f042a1 100644 (file)
--- a/execute.c
+++ b/execute.c
@@ -990,7 +990,7 @@ PGAPI_PutData(
 #ifdef UNICODE_SUPPORT
        if (SQL_C_WCHAR == ctype)
        {
-           putlen = 2 * ucs2strlen((SQLWCHAR *) rgbValue);
+           putlen = WCLEN * ucs2strlen((SQLWCHAR *) rgbValue);
            lenset = TRUE;
        }
        else
diff --git a/info.c b/info.c
index e0676d55680701182add79056b5f2e55b2c62b7e..3917ce1029668b4fb530268eaec64f6a1ccfcb3c 100644 (file)
--- a/info.c
+++ b/info.c
@@ -751,7 +751,7 @@ PGAPI_GetInfo(
            if (conn->unicode)
            {
                len = utf8_to_ucs2(p, len, (SQLWCHAR *) rgbInfoValue, cbInfoValueMax / 2);
-               len *= 2;
+               len *= WCLEN;
            }
            else
 #endif /* UNICODE_SUPPORT */
index 026fddea0cc459320c4779455af5256e08a598bf..bb784f0a10e532106e5d4838a218a63b03f34381 100644 (file)
--- a/info30.c
+++ b/info30.c
@@ -369,7 +369,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
            if (conn->unicode)
            {
                len = utf8_to_ucs2(p, len, (SQLWCHAR *) rgbInfoValue, cbInfoValueMax / 2);
-               len *= 2;
+               len *= WCLEN;
            }
            else
 #endif /* UNICODE_SUPPORT */
index 2448ef860fbde17e17c6505277ed5b1245884185..05d3011d24f11b87f1cf7119c88eadf94d544c30 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Comments:       See "notice.txt" for copyright and license information.
  *
- * $Id: psqlodbc.h,v 1.81 2003/12/09 10:01:38 hinoue Exp $
+ * $Id: psqlodbc.h,v 1.82 2004/02/04 08:55:28 dpage Exp $
  *
  */
 
@@ -321,6 +321,7 @@ int initialize_global_cs(void);
 const pthread_mutexattr_t *getMutexAttr(void);
 #endif /* POSIX_THREADMUTEX_SUPPORT */
 #ifdef UNICODE_SUPPORT
+#define WCLEN sizeof(SQLWCHAR)
 UInt4  ucs2strlen(const SQLWCHAR *ucs2str);
 char   *ucs2_to_utf8(const SQLWCHAR *ucs2str, Int4 ilen, UInt4 *olen, BOOL tolower);
 UInt4  utf8_to_ucs2_lf(const char * utf8str, Int4 ilen, BOOL lfconv, SQLWCHAR *ucs2str, UInt4 buflen);
index e3ab7f8ec899289cf7dc477e045d0ca66e1d872c..68ac8644190761b0e0aa9e0d30c15fa269ce96c8 100644 (file)
@@ -11,7 +11,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#define    byte3check  0xf800
+#define    byte3check  0xfffff800
 #define    byte2_base  0x80c0
 #define    byte2_mask1 0x07c0
 #define    byte2_mask2 0x003f
 #define    byte3_mask2 0x0fc0
 #define    byte3_mask3 0x003f
 
+#ifndef WIN32
+#ifdef HAVE_ISWASCII
+#include <wctype.h>
+#else
+#include <wchar.h>
+#include <ctype.h>
+int    iswascii(wchar_t c)
+{
+   return isascii(wctob(c));
+}
+#endif  /* HAVE_ISWASCII */
+#endif  /* WIN32 */
+
 UInt4  ucs2strlen(const SQLWCHAR *ucs2str)
 {
    UInt4   len;
@@ -49,7 +62,7 @@ char *ucs2_to_utf8(const SQLWCHAR *ucs2str, Int4 ilen, UInt4 *olen, BOOL lower_i
        {
            if (!*wstr)
                break;
-           else if (0 == (*wstr & 0xff80)) /* ASCII */
+           else if (0 == (*wstr & 0xffffff80)) /* ASCII */
            {
                if (lower_identifier)
                    utf8str[len++] = (char) tolower(*wstr);