Preparation for UNICODE support on UNIX
authorVictor Kirhenshtein <victor@netxms.org>
Mon, 28 Jan 2008 18:09:39 +0000 (18:09 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Mon, 28 Jan 2008 18:09:39 +0000 (18:09 +0000)
23 files changed:
.gitattributes
configure.ac
doc/internal/Makefile.am
doc/internal/unicode.txt [new file with mode: 0644]
include/config-netware.h
include/nms_agent.h
include/nms_common.h
include/nms_util.h
include/unicode.h
src/libnetxms/Makefile.am
src/libnetxms/dload.cpp
src/libnetxms/inline.cpp
src/libnetxms/main.cpp
src/libnetxms/message.cpp
src/libnetxms/nxcp.cpp
src/libnetxms/serial.cpp
src/libnetxms/strtoll.c
src/libnetxms/strtoull.c
src/libnetxms/table.cpp
src/libnetxms/tools.cpp
src/libnetxms/unicode.cpp
src/libnxcl/Makefile.am
src/libnxmap/Makefile.am

index 76b6a47..e5d57cf 100644 (file)
@@ -158,6 +158,7 @@ doc/internal/ipso.txt -text
 doc/internal/layer2-topology.txt -text
 doc/internal/netxms_architecture.vsd -text
 doc/internal/snmp.txt -text
+doc/internal/unicode.txt -text
 doc/manuals/Makefile.am -text
 doc/manuals/client_library.doc -text
 doc/manuals/netxms_install_guide.odt -text svneol=unset#unset
index a7865dc..1b64b6b 100644 (file)
@@ -1,10 +1,10 @@
-# $Id: configure.ac,v 1.283 2008-01-21 17:05:30 victor Exp $
+# $Id: configure.ac,v 1.284 2008-01-28 18:09:37 victor Exp $
 #
 # NetXMS - Network Management System
 # Configure script
 #
 
-AC_INIT([NetXMS], [0.2.20-dev4], [NetXMS Team <bugs@netxms.org>])
+AC_INIT([NetXMS], [0.2.20-rc1], [NetXMS Team <bugs@netxms.org>])
 AC_CONFIG_AUX_DIR(config)
 AM_CONFIG_HEADER(config.h)
 AM_INIT_AUTOMAKE
@@ -55,6 +55,7 @@ SERVER_TOOLS=""
 TOP_LEVEL_MODULES=""
 CONTRIB_MODULES=""
 CLIENT_COMPONENTS=""
+BUILD_UNICODE="no"
 
 
 #--------------------------------------------------------------------
@@ -740,7 +741,7 @@ AC_TYPE_SIGNAL
 AC_TYPE_SIZE_T
 AC_STRUCT_TIMEZONE
 
-AC_CHECK_TYPES([int64_t, uint64_t, u_int64_t])
+AC_CHECK_TYPES([int64_t, uint64_t, u_int64_t, mode_t])
 AC_CHECK_TYPES([off_t, socklen_t],,,[
 #if HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -834,11 +835,36 @@ fi
 
 
 #--------------------------------------------------------------------
+# Check for wxWidgets
+#--------------------------------------------------------------------
+
+if test "x$NEED_WXWIDGETS" = "xyes"; then
+       AC_PATH_PROGS([WXCONF], [wx-config wxgtk2-2.8-config], [no], [$PATH:/usr/local/bin])
+       if test "x$WXCONF" = "xno"; then
+               AC_MSG_ERROR([*** wxWidgets not installed - unable to build GUI components ***])
+       else
+               AC_PATH_PROGS([WXRC], [wxrc wxrc-gtk2-2.8], [no], [$PATH:/usr/local/bin])
+               if test "x$WXRC" = "xno"; then
+                       AC_MSG_ERROR([*** wxWidgets resource compiler not found - unable to build GUI components ***])
+               else
+                       NEED_UNICODE=`$WXCONF --selected-config | grep unicode | wc -l`
+                       if test $NEED_UNICODE -eq 1; then
+                               BUILD_UNICODE="yes"
+                       fi
+                       CXXFLAGS="$CXXFLAGS `$WXCONF --cxxflags --debug=$ENABLE_DEBUG`"
+                       LDFLAGS="$LDFLAGS `$WXCONF --libs --debug=$ENABLE_DEBUG`"
+               fi
+       fi
+fi
+
+
+#--------------------------------------------------------------------
 # Check for UNICODE stuff
 #--------------------------------------------------------------------
 
-AC_CHECK_HEADERS([wchar.h iconv.h])
+AC_CHECK_HEADERS([wchar.h wctype.h iconv.h])
 AC_CHECK_SIZEOF(wchar_t)
+AC_CHECK_FUNCS([wcstoll wcstoull wfopen wopen wstat])
 
 if test "x$DISABLE_ICONV" != "xyes"; then
        AC_CHECK_LIB(iconv, libiconv_open,
@@ -891,9 +917,7 @@ AC_RUN_IFELSE(
     valid_ucs2_code="UCS-2"
   ],
   [ AC_MSG_RESULT(no) ],
-  [ AC_MSG_RESULT(yes)
-    AC_DEFINE(HAVE_ICONV_UCS_2, 1, Define to 1 if iconv supports UCS-2)
-  ]
+  [ AC_MSG_RESULT(no) ]
 )
 
 AC_MSG_CHECKING(whether iconv supports UCS2)
@@ -932,6 +956,78 @@ AC_RUN_IFELSE(
   [ AC_MSG_RESULT(no) ]
 )
 
+AC_MSG_CHECKING(whether iconv supports UCS-4-INTERNAL)
+AC_RUN_IFELSE(
+  [AC_LANG_PROGRAM([
+#if HAVE_ICONV_H
+#include <iconv.h>
+#endif
+     ], [
+     return iconv_open("UTF-8","UCS-4-INTERNAL")==(iconv_t)(-1);
+     ])
+  ],
+  [ AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_ICONV_UCS_4_INTERNAL, 1, Define to 1 if iconv supports UCS-4-INTERNAL)
+    valid_ucs4_code="UCS-4-INTERNAL"
+  ],
+  [ AC_MSG_RESULT(no) ],
+  [ AC_MSG_RESULT(no) ]
+)
+
+AC_MSG_CHECKING(whether iconv supports UCS-4)
+AC_RUN_IFELSE(
+  [AC_LANG_PROGRAM([
+#if HAVE_ICONV_H
+#include <iconv.h>
+#endif
+     ], [
+     return iconv_open("UTF-8","UCS-4")==(iconv_t)(-1);
+     ])
+  ],
+  [ AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_ICONV_UCS_4, 1, Define to 1 if iconv supports UCS-4)
+    valid_ucs4_code="UCS-4"
+  ],
+  [ AC_MSG_RESULT(no) ],
+  [ AC_MSG_RESULT(no) ]
+)
+
+AC_MSG_CHECKING(whether iconv supports UCS4)
+AC_RUN_IFELSE(
+  [AC_LANG_PROGRAM([
+#if HAVE_ICONV_H
+#include <iconv.h>
+#endif
+     ], [
+     return iconv_open("UTF-8","UCS4")==(iconv_t)(-1);
+     ])
+  ],
+  [ AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_ICONV_UCS4, 1, Define to 1 if iconv supports UCS4)
+    valid_ucs4_code="UCS4"
+  ],
+  [ AC_MSG_RESULT(no) ],
+  [ AC_MSG_RESULT(no) ]
+)
+
+AC_MSG_CHECKING(whether iconv supports UCS-4BE)
+AC_RUN_IFELSE(
+  [AC_LANG_PROGRAM([
+#if HAVE_ICONV_H
+#include <iconv.h>
+#endif
+     ], [
+     return iconv_open("UTF-8","UCS-4BE")==(iconv_t)(-1);
+     ])
+  ],
+  [ AC_MSG_RESULT(yes)
+    AC_DEFINE(HAVE_ICONV_UCS_4BE, 1, Define to 1 if iconv supports UCS-4BE)
+    valid_ucs4_code="UCS-4BE"
+  ],
+  [ AC_MSG_RESULT(no) ],
+  [ AC_MSG_RESULT(no) ]
+)
+
 AC_MSG_CHECKING(whether iconv supports ISO8859-1)
 AC_RUN_IFELSE(
   [AC_LANG_PROGRAM([
@@ -1021,7 +1117,17 @@ if test "x$ac_found_iconv" = "xyes"; then
 fi
 
 if test $ac_cv_sizeof_wchar_t -eq 2; then
-       AC_DEFINE(HAVE_USEABLE_WCHAR_T, 1, Define to 1 if you have useable wchar_t)
+       AC_DEFINE(UNICODE_UCS2, 1, Define to 1 if you have 2-byte wchar_t)
+fi
+
+if test $ac_cv_sizeof_wchar_t -eq 4; then
+       AC_DEFINE(UNICODE_UCS4, 1, Define to 1 if you have 4-byte wchar_t)
+fi
+
+if test "x$BUILD_UNICODE" = "xyes"; then
+       UNICODE_LIBNETXMS="libnetxmsw.la"
+       UNICODE_LIBNXMAP="libnxmapw.la"
+       UNICODE_LIBNXCL="libnxclw.la"
 fi
 
 
@@ -1129,31 +1235,13 @@ fi
 
 
 #--------------------------------------------------------------------
-# Check for wxWidgets
-#--------------------------------------------------------------------
-
-if test "x$NEED_WXWIDGETS" = "xyes"; then
-       AC_PATH_PROGS([WXCONF], [wx-config wxgtk2-2.8-config], [no], [$PATH:/usr/local/bin])
-       if test "x$WXCONF" = "xno"; then
-               AC_MSG_ERROR([*** wxWidgets not installed - unable to build GUI components ***])
-       else
-               AC_PATH_PROGS([WXRC], [wxrc wxrc-gtk2-2.8], [no], [$PATH:/usr/local/bin])
-               if test "x$WXRC" = "xno"; then
-                       AC_MSG_ERROR([*** wxWidgets resource compiler not found - unable to build GUI components ***])
-               else
-                       CXXFLAGS="$CXXFLAGS `$WXCONF --cxxflags --debug=$ENABLE_DEBUG`"
-                       LDFLAGS="$LDFLAGS `$WXCONF --libs --debug=$ENABLE_DEBUG`"
-               fi
-       fi
-fi
-
-
-#--------------------------------------------------------------------
 # Other settings
 #--------------------------------------------------------------------
 
 CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DPREFIX=\\\"\${prefix}\\\" -DDATADIR=\\\"\${pkgdatadir}\\\" -DLIBDIR=\\\"\${libdir}\\\""
 
+AM_CONDITIONAL([BUILD_UNICODE_LIBS], [test "x$BUILD_UNICODE" = "xyes"])
+
 
 #--------------------------------------------------------------------
 # Substitute variables
@@ -1356,46 +1444,53 @@ echo '---------------------------------------------------------------------'
 echo '                         Configure results'
 echo '---------------------------------------------------------------------'
 echo
-       echo "Prefix              : ${prefix}"
+       echo "Prefix                  : ${prefix}"
 if test "x${BUILD_SERVER}" = "xyes"; then
-       echo "Build Server        : YES"
+       echo "Build Server            : YES"
 else
-       echo "Build Server        : NO"
+       echo "Build Server            : NO"
 fi
 if test "x${ac_cv_lib_crypto_RSA_new}" = "xyes"; then
-       echo "Encryption enabled  : YES"
+       echo "Encryption enabled      : YES"
 else
-       echo "Encryption enabled  : NO"
+       echo "Encryption enabled      : NO"
 fi
 if test "x${DB_DRIVERS}" != "x"; then
-       echo "Build DB-Drivers    :${DB_DRIVERS}"
+       echo "Build DB-Drivers        :${DB_DRIVERS}"
 else
-       echo "Build DB-Drivers    : NO"
+       echo "Build DB-Drivers        : NO"
 fi
 if test "x${BUILD_CLIENT}" = "xyes"; then
-       echo "Build Clients       : YES"
+       echo "Build Clients           : YES"
 else
-       echo "Build Clients       : NO"
+       echo "Build Clients           : NO"
 fi
 if test "x${BUILD_CONSOLE}" = "xyes"; then
-       echo "Build Console       : YES"
+       echo "Build Console           : YES"
+       echo "wxWidgets config        :" `$WXCONF --selected-config`
 else
-       echo "Build Console       : NO"
+       echo "Build Console           : NO"
 fi
 if test "x${BUILD_NXHTTPD}" = "xyes"; then
-       echo "Build Web Interface : YES"
+       echo "Build Web Interface     : YES"
 else
-       echo "Build Web Interface : NO"
+       echo "Build Web Interface     : NO"
 fi
 if test "x${BUILD_AGENT}" = "xyes"; then
-       echo "Build Agent         : YES"
-       echo "Subagents list      : ${SUBAGENT_DIRS}"
+       echo "Build Agent             : YES"
+       echo "Subagents list          : ${SUBAGENT_DIRS}"
 else
-       echo "Build Agent         : NO"
+       echo "Build Agent             : NO"
 fi
 if test "x${BUILD_STATIC_AGENT}" = "xyes"; then
-       echo "Build Static Agent  : YES"
-       echo "Subagents list      : ${STATIC_SUBAGENT_LIST}"
+       echo "Build Static Agent      : YES"
+       echo "Subagents list          : ${STATIC_SUBAGENT_LIST}"
 else
-       echo "Build Static Agent  : NO"
+       echo "Build Static Agent      : NO"
 fi
+if test "x${BUILD_UNICODE}" = "xyes"; then
+       echo "Build UNICODE libraries : YES"
+else
+       echo "Build UNICODE libraries : NO"
+fi
+
index 6dcef24..41ff12c 100644 (file)
@@ -13,4 +13,5 @@ EXTRA_DIST = \
        db_format_change.txt \
        event_code_ranges.txt \
        ipso.txt \
-       netxms_architecture.vsd
+       netxms_architecture.vsd \
+       unicode.txt
diff --git a/doc/internal/unicode.txt b/doc/internal/unicode.txt
new file mode 100644 (file)
index 0000000..624a28d
--- /dev/null
@@ -0,0 +1,8 @@
+Data types:
+
+WCHAR          platform-dependent wide char (can be UCS-2 or UCS-4)
+UCS2CHAR       2-byte wide char (UCS-2)
+TCHAR          char for ANSI build or WCHAR for UNICODE build
+
+* All wcs... functions works with WCHAR
+* For working with UCS-2 strings use appropriate ucs2_str... functions.
index a3fab09..7fd16b8 100644 (file)
@@ -7,7 +7,7 @@
 #define HAVE_STRTOULL 1
 
 /* Define to 1 if you have sizeof(wchar_t) == 2. */
-#define HAVE_USEABLE_WCHAR 1
+#define UNICODE_UCS2 1
 
 /* Define to 1 if you have the `iconv' function. */
 //#define HAVE_ICONV 1
index d61dc4a..d8e1964 100644 (file)
@@ -299,34 +299,34 @@ inline void ret_string(TCHAR *rbuf, const TCHAR *value)
 
 inline void ret_int(TCHAR *rbuf, LONG value)
 {
-   _stprintf(rbuf, _T("%d"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%d"), value);
 }
 
 inline void ret_uint(TCHAR *rbuf, DWORD value)
 {
-   _stprintf(rbuf, _T("%u"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%u"), value);
 }
 
 inline void ret_double(TCHAR *rbuf, double value)
 {
-   _stprintf(rbuf, _T("%f"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%f"), value);
 }
 
 inline void ret_int64(TCHAR *rbuf, INT64 value)
 {
 #ifdef _WIN32
-   _stprintf(rbuf, _T("%I64d"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%I64d"), value);
 #else    /* _WIN32 */
-   _stprintf(rbuf, _T("%lld"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%lld"), value);
 #endif   /* _WIN32 */
 }
 
 inline void ret_uint64(TCHAR *rbuf, QWORD value)
 {
 #ifdef _WIN32
-   _stprintf(rbuf, _T("%I64u"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%I64u"), value);
 #else    /* _WIN32 */
-   _stprintf(rbuf, _T("%llu"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%llu"), value);
 #endif   /* _WIN32 */
 }
 
index 24716a7..2e84fce 100644 (file)
@@ -248,6 +248,10 @@ typedef int SOCKET;
 #include <wchar.h>
 #endif
 
+#if HAVE_WCTYPE_H
+#include <wctype.h>
+#endif
+
 #include <errno.h>
 
 #define FS_PATH_SEPARATOR       _T("/")
@@ -324,6 +328,10 @@ typedef unsigned char BYTE;
 typedef void * HANDLE;
 typedef void * HMODULE;
 
+#if !HAVE_MODE_T
+typedef int mode_t;
+#endif
+
 #if HAVE_INT64_T
 typedef int64_t INT64;
 #else
@@ -663,6 +671,8 @@ typedef struct tagICMPHDR
 #ifndef _WIN32
 #define stricmp   strcasecmp
 #define strnicmp  strncasecmp
+#define wcsicmp   wcscasecmp
+#define wcsnicmp  wcsncasecmp
 #endif
 
 
index c78de20..d63f4ea 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: nms_util.h,v 1.114 2008-01-18 17:00:34 victor Exp $ */
+/* $Id: nms_util.h,v 1.115 2008-01-28 18:09:38 victor Exp $ */
 /* 
 ** NetXMS - Network Management System
 ** Copyright (C) 2003, 2004, 2005, 2006, 2007 Victor Kirhenshtein
@@ -415,7 +415,10 @@ extern "C"
    void LIBNETXMS_EXPORTABLE __bswap_wstr(WCHAR *pStr);
 
 #if !defined(_WIN32) && !defined(_NETWARE)
-   void LIBNETXMS_EXPORTABLE strupr(TCHAR *in);
+#if defined(UNICODE_UCS2) || defined(UNICODE_UCS4)
+   void LIBNETXMS_EXPORTABLE wcsupr(WCHAR *in);
+#endif   
+   void LIBNETXMS_EXPORTABLE strupr(char *in);
 #endif
    
        void LIBNETXMS_EXPORTABLE QSortEx(void *base, size_t nmemb, size_t size, void *arg,
@@ -489,31 +492,57 @@ extern "C"
    int LIBNETXMS_EXPORTABLE MultiByteToWideChar(int iCodePage, DWORD dwFlags, const char *pByteStr, 
                                                 int cchByteChar, WCHAR *pWideCharStr, 
                                                 int cchWideChar);
-#if !HAVE_USEABLE_WCHAR
-       int LIBNETXMS_EXPORTABLE nx_wcslen(const WCHAR *pStr);
-       WCHAR LIBNETXMS_EXPORTABLE *nx_wcsncpy(WCHAR *pDst, const WCHAR *pSrc, int nDstLen);
-       WCHAR LIBNETXMS_EXPORTABLE *nx_wcsdup(const WCHAR *pStr);
+#ifndef UNICODE_UCS2
+       int LIBNETXMS_EXPORTABLE ucs2_strlen(const UCS2CHAR *pStr);
+       UCS2CHAR LIBNETXMS_EXPORTABLE *ucs2_strncpy(UCS2CHAR *pDst, const UCS2CHAR *pSrc, int nDstLen);
+       UCS2CHAR LIBNETXMS_EXPORTABLE *ucs2_strdup(const UCS2CHAR *pStr);
 #endif
+
+#ifndef UNICODE
+       size_t LIBNETXMS_EXPORTABLE ucs2_to_mb(const UCS2CHAR *src, size_t srcLen, char *dst, size_t dstLen);
+       size_t LIBNETXMS_EXPORTABLE mb_to_ucs2(const char *src, size_t srcLen, UCS2CHAR *dst, size_t dstLen);
+#endif
+
 #endif /* _WIN32 */
+
    WCHAR LIBNETXMS_EXPORTABLE *WideStringFromMBString(const char *pszString);
    char LIBNETXMS_EXPORTABLE *MBStringFromWideString(const WCHAR *pwszString);
    char LIBNETXMS_EXPORTABLE *UTF8StringFromWideString(const WCHAR *pwszString);
-
+   
 #ifdef _WITH_ENCRYPTION
        WCHAR LIBNETXMS_EXPORTABLE *ERR_error_string_W(int nError, WCHAR *pwszBuffer);
 #endif
 
 #ifdef UNICODE
-INT64 LIBNETXMS_EXPORTABLE wcstoll(const WCHAR *nptr, WCHAR **endptr, int base);
-QWORD LIBNETXMS_EXPORTABLE wcstoull(const WCHAR *nptr, WCHAR **endptr, int base);
-#else
-#if !(HAVE_STRTOLL)
-   INT64 LIBNETXMS_EXPORTABLE strtoll(const char *nptr, char **endptr, int base);
+
+#ifdef UNICODE_UCS4
+       size_t LIBNETXMS_EXPORTABLE ucs2_to_ucs4(const UCS2CHAR *src, size_t srcLen, WCHAR *dst, size_t dstLen);
+       size_t LIBNETXMS_EXPORTABLE ucs4_to_ucs2(const WCHAR *src, size_t srcLen, UCS2CHAR *dst, size_t dstLen);
 #endif
-#if !(HAVE_STRTOULL)
-   QWORD LIBNETXMS_EXPORTABLE strtoull(const char *nptr, char **endptr, int base);
+
+#if !HAVE_WCSTOLL
+       INT64 LIBNETXMS_EXPORTABLE wcstoll(const WCHAR *nptr, WCHAR **endptr, int base);
+#endif
+#if !HAVE_WCSTOULL
+       QWORD LIBNETXMS_EXPORTABLE wcstoull(const WCHAR *nptr, WCHAR **endptr, int base);
+#endif
+#if !HAVE_WFOPEN
+       FILE LIBNETXMS_EXPORTABLE *wfopen(const WCHAR *_name, const WCHAR *_type);
+#endif
+#if !HAVE_WOPEN
+       int LIBNETXMS_EXPORTABLE wopen(const WCHAR *, int, ...);
 #endif
+#if !HAVE_WSTAT
+       int wstat(const WCHAR *_path, struct stat *_sbuf);
 #endif
+#else          /* UNICODE */
+#if !HAVE_STRTOLL
+       INT64 LIBNETXMS_EXPORTABLE strtoll(const char *nptr, char **endptr, int base);
+#endif
+#if !HAVE_STRTOULL
+       QWORD LIBNETXMS_EXPORTABLE strtoull(const char *nptr, char **endptr, int base);
+#endif
+#endif /* UNICODE */
 
 #ifdef _WIN32
 #ifndef SWIGPERL
@@ -551,6 +580,9 @@ void LIBNETXMS_EXPORTABLE StartMainLoop(THREAD_RESULT (THREAD_CALL * pfSignalHan
 /*
 
 $Log: not supported by cvs2svn $
+Revision 1.114  2008/01/18 17:00:34  victor
+Correct checking for getopt_long()
+
 Revision 1.113  2007/12/05 14:17:23  victor
 
 SetDefaultCodePage now will check if codepage supported by iconv
index b0b9f07..338cd29 100644 (file)
 #ifndef _unicode_h_
 #define _unicode_h_
 
+// Undef UNICODE_UCS2 and UNICODE_UCS4 if they are defined to 0
+#if !UNICODE_UCS2
+#undef UNICODE_UCS2
+#endif
+#if !UNICODE_UCS4
+#undef UNICODE_UCS4
+#endif
+
 #ifdef _WIN32
 
 // Ensure that both UNICODE and _UNICODE are defined
@@ -42,6 +50,9 @@
 
 #ifdef UNICODE
 
+// Windows always use UCS-2
+#define UNICODE_UCS2                           1
+
 #define _tcstoll  wcstoll
 #define _tcstoull wcstoull
 
 
 #define ICONV_DEFAULT_CODEPAGE "ACP"
 
+#define ucs2_strlen    wcslen
+#define ucs2_strdup    wcsdup
+#define ucs2_strncpy   wcsncpy
+
+#define ucs2_to_mb(wstr, wlen, mstr, mlen)     WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, wstr, wlen, mstr, mlen, NULL, NULL)
+#define mb_to_ucs2(mstr, mlen, wstr, wlen)     MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, mstr, mlen, wstr, wlen)
+
+#define HAVE_WFOPEN    1
+#define HAVE_WOPEN     1
+
 #else    /* not _WIN32 */
 
 #if HAVE_WCHAR_H
 #include <string.h>
 #endif
 
-#ifdef _NETWARE
+/*#ifdef _NETWARE
 #define WCHAR     wchar_t
 #else
 #define WCHAR     unsigned short
+#endif*/
+
+#define WCHAR     wchar_t
+#if UNICODE_UCS2
+#define UCS2CHAR  wchar_t
+#else
+#define UCS2CHAR  unsigned short
 #endif
 
-// Redefine wide character functions if system's wchar_t is not 2 bytes long
-#if !HAVE_USEABLE_WCHAR
+// Use system wide character functions if system's wchar_t is 2 bytes long
+#if UNICODE_UCS2
 
-#define wcslen         nx_wcslen
-#define wcsdup         nx_wcsdup
-#define wcsncpy        nx_wcsncpy
+#define ucs2_strlen    wcslen
+#define ucs2_strdup    wcsdup
+#define ucs2_strncpy   wcsncpy
 
 #endif
 
+// On some old systems, ctype.h defines _T macro, so we include it
+// before our definition and do an undef
+#include <ctype.h>
+#undef _T
+
 #ifdef UNICODE
 
-#error UNICODE is not supported on non-Windows platforms
+#define _T(x)     L##x
+#define TCHAR wchar_t
+#define _TINT     int
 
-#else
+#define _tcscpy   wcscpy
+#define _tcsncpy  wcsncpy
+#define _tcslen   wcslen
+#define _tcschr   wcschr
+#define _tcsrchr  wcsrchr
+#define _tcscmp   wcscmp
+#define _tcsicmp  wcsicmp
+#define _tcsncmp  wcsncmp
+#define _tcsnicmp wcsnicmp
+#define _tprintf  wprintf
+//#define _stprintf swprintf
+#define _ftprintf fwprintf
+#define _sntprintf swprintf
+#define _vtprintf vwprintf
+//#define _vstprintf vswprintf
+#define _vsntprintf vswprintf
+#define _tfopen   wfopen
+#define _fgetts   fgetws
+#define _fputts   fputws
+#define _tcstol   wcstol
+#define _tcstoul  wcstoul
+#define _tcstoll  wcstoll
+#define _tcstoull wcstoull
+#define _tcstod   wcstod
+#define _tcsdup   wcsdup
+#define _tcsupr   wcsupr
+#define _tcsspn   wcsspn
+#define _tcscspn  wcscspn
+#define _tcsstr   wcsstr
+#define _tcscat   wcscat
+#define _topen    wopen
+#define _taccess  waccess
+#define _tstat    wstat
+#define _tunlink  wunlink
+#define _tcsftime wcsftime
+#define _tctime   wctime
+#define _istspace iswspace
+#define _istdigit iswdigit
+#define _istalpha iswalpha
+#define _istupper iswupper
+#define _tgetenv  wgetenv
 
-// On some old systems, ctype.h defines _T macro, so we include it
-// before our definition and do an undef
-#include <ctype.h>
+#else
 
-#undef _T
 #define _T(x)     x
 #define TCHAR     char
 #define _TINT     int
 #define _tcscat   strcat
 #define _topen    open
 #define _taccess  access
+#define _tstat    stat
 #define _tunlink  unlink
 #define _tcsftime strftime
 #define _tctime   ctime
 #endif
 
 
+// Check that either UNICODE_UCS2 or UNICODE_UCS4 are defined
+#ifdef UNICODE
+#if !defined(UNICODE_UCS2) && !defined(UNICODE_UCS4)
+#error Neither UNICODE_UCS2 nor UNICODE_UCS4 are defined
+#endif
+#endif
+
 #endif   /* _unicode_h_ */
+
index 5253de0..0e32d8d 100644 (file)
@@ -1,9 +1,19 @@
 INCLUDES=-I@top_srcdir@/include
+SOURCES = config.cpp crypto.cpp gen_uuid.c dload.cpp hash.cpp icmp.cpp inline.cpp main.cpp md5.cpp message.cpp msgwq.cpp nxcp.cpp qsort.c queue.cpp rwlock.cpp scandir.c serial.cpp sha1.cpp string.cpp strmap.cpp strtoll.c strtoull.c table.cpp threads.cpp tools.cpp unicode.cpp uuid.c
 
+if BUILD_UNICODE_LIBS
+lib_LTLIBRARIES = libnetxms.la libnetxmsw.la
+else
 lib_LTLIBRARIES = libnetxms.la
-libnetxms_la_SOURCES = config.cpp crypto.cpp gen_uuid.c dload.cpp hash.cpp icmp.cpp inline.cpp main.cpp md5.cpp message.cpp msgwq.cpp nxcp.cpp qsort.c queue.cpp rwlock.cpp scandir.c serial.cpp sha1.cpp string.cpp strmap.cpp strtoll.c strtoull.c table.cpp threads.cpp tools.cpp unicode.cpp uuid.c
+endif
+
+libnetxms_la_SOURCES = $(SOURCES)
 libnetxms_la_LDFLAGS = -version-info $(NETXMS_LIBRARY_VERSION)
 
+libnetxmsw_la_SOURCES = $(SOURCES)
+libnetxmsw_la_CPPFLAGS = -DUNICODE
+libnetxmsw_la_LDFLAGS = -version-info $(NETXMS_LIBRARY_VERSION)
+
 EXTRA_DIST = \
        libnetxms.dsp libnetxms.dsw \
        libnetxms.vcp libnetxms.vcw \
index 440a80e..adc479e 100644 (file)
@@ -1,7 +1,7 @@
 /* 
 ** NetXMS - Network Management System
 ** Utility Library
-** Copyright (C) 2003, 2004, 2005, 2006 Victor Kirhenshtein
+** Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Victor Kirhenshtein
 **
 ** 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
@@ -17,7 +17,7 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
-** $module: dload.cpp
+** File: dload.cpp
 **
 **/
 
@@ -97,11 +97,23 @@ HMODULE LIBNETXMS_EXPORTABLE DLOpen(const TCHAR *pszLibName, TCHAR *pszErrorText
                if (pszErrorText != NULL)
        nx_strncpy(pszErrorText, (nError <= 19) ? m_pszErrorText[nError] : "Unknown error code", 255);
    }
-#else    /* _WIN32 */
+#else    /* not _WIN32 and not _NETWARE */
+#ifdef UNICODE
+       char *mbbuffer = MBStringFromWideString(pszLibName);
+   hModule = dlopen(mbbuffer, RTLD_NOW | RTLD_GLOBAL);
+   if ((hModule == NULL) && (pszErrorText != NULL))
+   {
+       WCHAR *wbuffer = WideStringFromMBString(dlerror());
+      nx_strncpy(pszErrorText, wbuffer, 255);
+      free(wbuffer);
+   }
+   free(mbbuffer);
+#else
    hModule = dlopen(pszLibName, RTLD_NOW | RTLD_GLOBAL);
    if ((hModule == NULL) && (pszErrorText != NULL))
       nx_strncpy(pszErrorText, dlerror(), 255);
 #endif
+#endif
    return hModule;
 }
 
@@ -156,9 +168,23 @@ void LIBNETXMS_EXPORTABLE *DLGetSymbolAddr(HMODULE hModule,
    if (pszErrorText != NULL)
       *pszErrorText = 0;
 #else    /* _WIN32 */
+#ifdef UNICODE
+   char mbbuffer[256];
+
+   WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,
+                       pszSymbol, -1, mbbuffer, 256, NULL, NULL);
+   pAddr = dlsym(hModule, mbbuffer);
+   if ((pAddr == NULL) && (pszErrorText != NULL))
+   {
+       WCHAR *wbuffer = WideStringFromMBString(dlerror());
+      nx_strncpy(pszErrorText, wbuffer, 255);
+      free(wbuffer);
+   }
+#else
    pAddr = dlsym(hModule, pszSymbol);
    if ((pAddr == NULL) && (pszErrorText != NULL))
       nx_strncpy(pszErrorText, dlerror(), 255);
 #endif
+#endif
    return pAddr;
 }
index 6333c82..41817b1 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** libnetxms - Common NetXMS utility library
-** Copyright (C) 2003, 2004 Victor Kirhenshtein
+** Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Victor Kirhenshtein
 **
 ** 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
@@ -16,7 +16,7 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
-** $module: inline.cpp
+** File: inline.cpp
 **
 **/
 
@@ -37,34 +37,34 @@ extern "C" void LIBNETXMS_EXPORTABLE ret_string(TCHAR *rbuf, const TCHAR *value)
 
 extern "C" void LIBNETXMS_EXPORTABLE ret_int(TCHAR *rbuf, LONG value)
 {
-   _stprintf(rbuf, _T("%d"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%d"), value);
 }
 
 extern "C" void LIBNETXMS_EXPORTABLE ret_uint(TCHAR *rbuf, DWORD value)
 {
-   _stprintf(rbuf, _T("%u"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%u"), value);
 }
 
 extern "C" void LIBNETXMS_EXPORTABLE ret_double(TCHAR *rbuf, double value)
 {
-   _stprintf(rbuf, _T("%f"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%f"), value);
 }
 
 extern "C" void LIBNETXMS_EXPORTABLE ret_int64(TCHAR *rbuf, INT64 value)
 {
 #ifdef _WIN32
-   _stprintf(rbuf, _T("%I64d"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%I64d"), value);
 #else    /* _WIN32 */
-   _stprintf(rbuf, _T("%lld"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%lld"), value);
 #endif   /* _WIN32 */
 }
 
 extern "C" void LIBNETXMS_EXPORTABLE ret_uint64(TCHAR *rbuf, QWORD value)
 {
 #ifdef _WIN32
-   _stprintf(rbuf, _T("%I64u"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%I64u"), value);
 #else    /* _WIN32 */
-   _stprintf(rbuf, _T("%llu"), value);
+   _sntprintf(rbuf, MAX_RESULT_LENGTH, _T("%llu"), value);
 #endif   /* _WIN32 */
 }
 
index 390a84c..691fe10 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: main.cpp,v 1.12 2007-02-09 17:31:57 victor Exp $ */
+/* $Id: main.cpp,v 1.13 2008-01-28 18:09:38 victor Exp $ */
 /* 
 ** NetXMS - Network Management System
 ** Utility Library
@@ -100,6 +100,26 @@ void LIBNETXMS_EXPORTABLE strupr(char *in)
        }
 }
 
+#if defined(UNICODE_UCS2) || defined(UNICODE_UCS4)
+
+void LIBNETXMS_EXPORTABLE wcsupr(WCHAR *in)
+{
+       WCHAR *p = in;
+
+       if (in == NULL) 
+   { 
+               return;
+       }
+       
+       for (; *p != 0; p++) 
+   {
+               // TODO: check/set locale
+               *p = towupper(*p);
+       }
+}
+
+#endif
+
 #endif
 
 
index 6735b13..4bbc078 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: message.cpp,v 1.5 2007-09-19 16:57:40 victor Exp $ */
+/* $Id: message.cpp,v 1.6 2008-01-28 18:09:38 victor Exp $ */
 /* 
 ** NetXMS - Network Management System
 ** NetXMS Foundation Library
@@ -211,8 +211,8 @@ void *CSCPMessage::Set(DWORD dwVarId, BYTE bType, const void *pValue, DWORD dwSi
 {
    DWORD dwIndex, dwLength;
    CSCP_DF *pVar;
-#ifndef UNICODE
-   WCHAR *pBuffer;
+#ifndef UNICODE_UCS2
+   UCS2CHAR *pBuffer;
 #endif
 
    // Create CSCP_DF structure
@@ -238,11 +238,18 @@ void *CSCPMessage::Set(DWORD dwVarId, BYTE bType, const void *pValue, DWORD dwSi
          dwLength = (DWORD)_tcslen((const TCHAR *)pValue);
          pVar = (CSCP_DF *)malloc(12 + dwLength * 2);
          pVar->df_string.dwLen = dwLength * 2;
-#ifdef UNICODE
+#ifdef UNICODE         
+#ifdef UNICODE_UCS2
          memcpy(pVar->df_string.szValue, pValue, pVar->df_string.dwLen);
-#else
-         pBuffer = (WCHAR *)malloc(dwLength * 2 + 2);
-         MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (const char *)pValue, dwLength, pBuffer, dwLength + 1);
+#else          /* assume UNICODE_UCS4 */
+         pBuffer = (UCS2CHAR *)malloc(dwLength * 2 + 2);
+         ucs4_to_ucs2((WCHAR *)pValue, dwLength, pBuffer, dwLength + 1);
+         memcpy(pVar->df_string.szValue, pBuffer, pVar->df_string.dwLen);
+         free(pBuffer);
+#endif         
+#else          /* not UNICODE */
+         pBuffer = (UCS2CHAR *)malloc(dwLength * 2 + 2);
+         mb_to_ucs2((const char *)pValue, dwLength, pBuffer, dwLength + 1);
          memcpy(pVar->df_string.szValue, pBuffer, pVar->df_string.dwLen);
          free(pBuffer);
 #endif
@@ -387,7 +394,9 @@ TCHAR *CSCPMessage::GetVariableStr(DWORD dwVarId, TCHAR *pszBuffer, DWORD dwBufS
    {
       if (pszBuffer == NULL)
       {
-#ifdef UNICODE
+#if defined(UNICODE) && defined(UNICODE_UCS4)
+         pStr = (TCHAR *)malloc(*((DWORD *)pValue) * 2 + 4);
+#elif defined(UNICODE) && defined(UNICODE_UCS2)
          pStr = (TCHAR *)malloc(*((DWORD *)pValue) + 2);
 #else
          pStr = (TCHAR *)malloc(*((DWORD *)pValue) / 2 + 1);
@@ -399,11 +408,12 @@ TCHAR *CSCPMessage::GetVariableStr(DWORD dwVarId, TCHAR *pszBuffer, DWORD dwBufS
       }
 
       dwLen = (pszBuffer == NULL) ? (*((DWORD *)pValue) / 2) : min(*((DWORD *)pValue) / 2, dwBufSize - 1);
-#ifdef UNICODE
+#if defined(UNICODE) && defined(UNICODE_UCS4)
+               ucs2_to_ucs4((UCS2CHAR *)pValue + 4, dwLen, pStr, dwLen + 1);
+#elif defined(UNICODE) && defined(UNICODE_UCS2)
       memcpy(pStr, (BYTE *)pValue + 4, dwLen * 2);
 #else
-      WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, 
-                          (WCHAR *)((BYTE *)pValue + 4), dwLen, pStr, dwLen + 1, NULL, NULL);
+               ucs2_to_mb((UCS2CHAR *)((BYTE *)pValue + 4), dwLen, pStr, dwLen + 1);
 #endif
       pStr[dwLen] = 0;
    }
index 53cf48b..3184d5f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: nxcp.cpp,v 1.20 2008-01-17 09:07:12 victor Exp $ */
+/* $Id: nxcp.cpp,v 1.21 2008-01-28 18:09:38 victor Exp $ */
 /* 
 ** NetXMS - Network Management System
 ** NetXMS Foundation Library
@@ -253,7 +253,7 @@ TCHAR LIBNETXMS_EXPORTABLE *NXCPMessageCodeName(WORD wCode, TCHAR *pszBuffer)
    if ((wCode >= CMD_LOGIN) && (wCode <= CMD_SEND_SMS))
       _tcscpy(pszBuffer, pszMsgNames[wCode - CMD_LOGIN]);
    else
-      _stprintf(pszBuffer, _T("CMD_UNKNOWN(%d)"), wCode);
+      _sntprintf(pszBuffer, 64, _T("CMD_UNKNOWN(%d)"), wCode);
    return pszBuffer;
 }
 
index 8743f44..ca8f17c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: serial.cpp,v 1.19 2007-01-24 21:34:55 victor Exp $ */
+/* $Id: serial.cpp,v 1.20 2008-01-28 18:09:38 victor Exp $ */
 
 /* 
 ** NetXMS - Network Management System
@@ -91,7 +91,7 @@ bool Serial::Open(TCHAR *pszPort)
        if (m_hPort != INVALID_HANDLE_VALUE)
        {
 #else // UNIX
-               m_hPort = open(pszPort, O_RDWR | O_NOCTTY | O_NDELAY); 
+               m_hPort = _topen(pszPort, O_RDWR | O_NOCTTY | O_NDELAY); 
                if (m_hPort != -1)
                {
                        tcgetattr(m_hPort, &m_originalSettings);
@@ -505,6 +505,10 @@ void Serial::Flush(void)
 /*
 
 $Log: not supported by cvs2svn $
+Revision 1.19  2007/01/24 21:34:55  victor
+- Fixed Serial::ReadAll() under Windows
+- Added isSystem object's attribute
+
 Revision 1.18  2007/01/24 00:54:17  alk
 Serial::ReadAll() implementation
 
index 768d96a..781a1ec 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "libnetxms.h"
 
-#if !(HAVE_STRTOLL)
+#if (!defined(UNICODE) && !(HAVE_STRTOLL)) || (defined(UNICODE) && !(HAVE_WCSTOLL))
 
 #ifndef UNDER_CE
 #include <sys/types.h>
index 1a7655c..3c74f00 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "libnetxms.h"
 
-#if !(HAVE_STRTOULL)
+#if (!defined(UNICODE) && !(HAVE_STRTOULL)) || (defined(UNICODE) && !(HAVE_WCSTOULL))
 
 #ifndef UNDER_CE
 #include <sys/types.h>
index 43339ef..6b46d7b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: table.cpp,v 1.1 2006-11-03 08:58:58 victor Exp $ */
+/* $Id: table.cpp,v 1.2 2008-01-28 18:09:38 victor Exp $ */
 /* 
 ** NetXMS - Network Management System
 ** Copyright (C) 2003, 2004, 2005, 2006 Victor Kirhenshtein
@@ -118,7 +118,7 @@ void Table::SetAt(int nRow, int nCol, LONG nData)
 {
    TCHAR szBuffer[32];
 
-   _stprintf(szBuffer, _T("%d"), nData);
+   _sntprintf(szBuffer, 32, _T("%d"), nData);
    SetAt(nRow, nCol, szBuffer);
 }
 
@@ -126,7 +126,7 @@ void Table::SetAt(int nRow, int nCol, DWORD dwData)
 {
    TCHAR szBuffer[32];
 
-   _stprintf(szBuffer, _T("%u"), dwData);
+   _sntprintf(szBuffer, 32, _T("%u"), dwData);
    SetAt(nRow, nCol, szBuffer);
 }
 
@@ -134,7 +134,7 @@ void Table::SetAt(int nRow, int nCol, INT64 nData)
 {
    TCHAR szBuffer[32];
 
-   _stprintf(szBuffer, INT64_FMT, nData);
+   _sntprintf(szBuffer, 32, INT64_FMT, nData);
    SetAt(nRow, nCol, szBuffer);
 }
 
@@ -142,7 +142,7 @@ void Table::SetAt(int nRow, int nCol, QWORD qwData)
 {
    TCHAR szBuffer[32];
 
-   _stprintf(szBuffer, UINT64_FMT, qwData);
+   _sntprintf(szBuffer, 32, UINT64_FMT, qwData);
    SetAt(nRow, nCol, szBuffer);
 }
 
@@ -150,7 +150,7 @@ void Table::SetAt(int nRow, int nCol, double dData)
 {
    TCHAR szBuffer[32];
 
-   _stprintf(szBuffer, _T("%f"), dData);
+   _sntprintf(szBuffer, 32, _T("%f"), dData);
    SetAt(nRow, nCol, szBuffer);
 }
 
index 1a40be1..363d1e2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tools.cpp,v 1.68 2007-09-25 16:53:01 victor Exp $ */
+/* $Id: tools.cpp,v 1.69 2008-01-28 18:09:38 victor Exp $ */
 /* 
 ** NetXMS - Network Management System
 ** Copyright (C) 2003, 2004, 2005 Victor Kirhenshtein
@@ -86,7 +86,7 @@ TCHAR LIBNETXMS_EXPORTABLE *IpToStr(DWORD dwAddr, TCHAR *szBuffer)
    TCHAR *szBufPtr;
 
    szBufPtr = szBuffer == NULL ? szInternalBuffer : szBuffer;
-   _stprintf(szBufPtr, _T("%d.%d.%d.%d"), dwAddr >> 24, (dwAddr >> 16) & 255,
+   _sntprintf(szBufPtr, 32, _T("%d.%d.%d.%d"), dwAddr >> 24, (dwAddr >> 16) & 255,
              (dwAddr >> 8) & 255, dwAddr & 255);
    return szBufPtr;
 }
@@ -710,7 +710,7 @@ QWORD LIBNETXMS_EXPORTABLE FileSize(const TCHAR *pszFileName)
 
    return (unsigned __int64)fd.nFileSizeLow + ((unsigned __int64)fd.nFileSizeHigh << 32);
 #else
-   if (stat(pszFileName, &fileInfo) == -1)
+   if (_tstat(pszFileName, &fileInfo) == -1)
       return 0;
 
    return (QWORD)fileInfo.st_size;
index 1ae22c6..928fcba 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: unicode.cpp,v 1.26 2007-12-05 15:29:58 victor Exp $ */
+/* $Id: unicode.cpp,v 1.27 2008-01-28 18:09:38 victor Exp $ */
 /*
 ** NetXMS - Network Management System
 ** Copyright (C) 2003, 2004, 2005, 2006, 2007 Victor Kirhenshtein
@@ -60,9 +60,36 @@ static char m_cpDefault[MAX_CODEPAGE_LEN] = ICONV_DEFAULT_CODEPAGE;
 #elif HAVE_ICONV_UCS_2BE && WORDS_BIGENDIAN
 #define UCS2_CODEPAGE_NAME     "UCS-2BE"
 #else
+#ifdef UNICODE
+#error Cannot determine valid UCS-2 codepage name
+#else
 #warning Cannot determine valid UCS-2 codepage name
 #undef HAVE_ICONV
 #endif
+#endif
+
+#if HAVE_ICONV_UCS_4_INTERNAL
+#define UCS4_CODEPAGE_NAME     "UCS-4-INTERNAL"
+#elif HAVE_ICONV_UCS_4
+#define UCS4_CODEPAGE_NAME     "UCS-4"
+#elif HAVE_ICONV_UCS4
+#define UCS4_CODEPAGE_NAME     "UCS4"
+#elif HAVE_ICONV_UCS_4BE && WORDS_BIGENDIAN
+#define UCS4_CODEPAGE_NAME     "UCS-4BE"
+#else
+#if defined(UNICODE) && defined(UNICODE_UCS4)
+#error Cannot determine valid UCS-4 codepage name
+#else
+#warning Cannot determine valid UCS-4 codepage name
+#undef HAVE_ICONV
+#endif
+#endif
+
+#ifdef UNICODE_UCS4
+#define UNICODE_CODEPAGE_NAME  UCS4_CODEPAGE_NAME
+#else  /* assume UCS-2 */
+#define UNICODE_CODEPAGE_NAME  UCS2_CODEPAGE_NAME
+#endif
 
 #endif   /* __DISABLE_ICONV */
 
@@ -100,12 +127,12 @@ BOOL LIBNETXMS_EXPORTABLE SetDefaultCodepage(const char *cp)
 // Calculate length of wide character string
 //
 
-#if !HAVE_USEABLE_WCHAR
+#if !UNICODE_UCS2
 
-int LIBNETXMS_EXPORTABLE nx_wcslen(const WCHAR *pStr)
+int LIBNETXMS_EXPORTABLE ucs2_strlen(const UCS2CHAR *pStr)
 {
    int iLen = 0;
-   const WCHAR *pCurr = pStr;
+   const UCS2CHAR *pCurr = pStr;
 
    while(*pCurr++)
       iLen++;
@@ -119,11 +146,11 @@ int LIBNETXMS_EXPORTABLE nx_wcslen(const WCHAR *pStr)
 // Duplicate wide character string
 //
 
-#if !HAVE_USEABLE_WCHAR
+#if !UNICODE_UCS2
 
-WCHAR LIBNETXMS_EXPORTABLE *nx_wcsdup(const WCHAR *pStr)
+UCS2CHAR LIBNETXMS_EXPORTABLE *ucs2_strdup(const UCS2CHAR *pStr)
 {
-       return (WCHAR *)nx_memdup(pStr, (wcslen(pStr) + 1) * sizeof(WCHAR));
+       return (UCS2CHAR *)nx_memdup(pStr, (ucs2_strlen(pStr) + 1) * sizeof(UCS2CHAR));
 }
 
 #endif
@@ -133,16 +160,16 @@ WCHAR LIBNETXMS_EXPORTABLE *nx_wcsdup(const WCHAR *pStr)
 // Copy wide character string with length limitation
 //
 
-#if !HAVE_USEABLE_WCHAR
+#if !UNICODE_UCS2
 
-WCHAR LIBNETXMS_EXPORTABLE *nx_wcsncpy(WCHAR *pDst, const WCHAR *pSrc, int nDstLen)
+UCS2CHAR LIBNETXMS_EXPORTABLE *ucs2_strncpy(UCS2CHAR *pDst, const UCS2CHAR *pSrc, int nDstLen)
 {
        int nLen;
 
-       nLen = wcslen(pSrc) + 1;
+       nLen = ucs2_strlen(pSrc) + 1;
        if (nLen > nDstLen)
                nLen = nDstLen;
-       memcpy(pDst, pSrc, nLen * sizeof(WCHAR));
+       memcpy(pDst, pSrc, nLen * sizeof(UCS2CHAR));
        return pDst;
 }
 
@@ -178,7 +205,7 @@ int LIBNETXMS_EXPORTABLE WideCharToMultiByte(int iCodePage, DWORD dwFlags,
 #if HAVE_ICONV_IGNORE
        strcat(cp, "//IGNORE");
 #endif
-       cd = iconv_open(iCodePage == CP_UTF8 ? "UTF-8" : cp, UCS2_CODEPAGE_NAME);
+       cd = iconv_open(iCodePage == CP_UTF8 ? "UTF-8" : cp, UNICODE_CODEPAGE_NAME);
        if (cd != (iconv_t)(-1))
        {
                inbuf = (const char *)pWideCharStr;
@@ -241,7 +268,6 @@ int LIBNETXMS_EXPORTABLE MultiByteToWideChar(int iCodePage, DWORD dwFlags, const
                                              int cchByteChar, WCHAR *pWideCharStr, int cchWideChar)
 {
 #if HAVE_ICONV && !defined(__DISABLE_ICONV)
-
        iconv_t cd;
        int nRet;
        const char *inbuf;
@@ -253,7 +279,7 @@ int LIBNETXMS_EXPORTABLE MultiByteToWideChar(int iCodePage, DWORD dwFlags, const
                return strlen(pByteStr) + 1;
        }
 
-       cd = iconv_open(UCS2_CODEPAGE_NAME, iCodePage == CP_UTF8 ? "UTF-8" : m_cpDefault);
+       cd = iconv_open(UNICODE_CODEPAGE_NAME, iCodePage == CP_UTF8 ? "UTF-8" : m_cpDefault);
        if (cd != (iconv_t)(-1))
        {
                inbuf = pByteStr;
@@ -399,3 +425,302 @@ WCHAR LIBNETXMS_EXPORTABLE *ERR_error_string_W(int nError, WCHAR *pwszBuffer)
 }
 
 #endif
+
+
+#if defined(UNICODE) && defined(UNICODE_UCS4)
+
+//
+// Convert UCS-2 to UCS-4
+//
+
+size_t LIBNETXMS_EXPORTABLE ucs2_to_ucs4(const UCS2CHAR *src, size_t srcLen, WCHAR *dst, size_t dstLen)
+{
+       iconv_t cd;
+       const char *inbuf;
+       char *outbuf;
+       size_t count, inbytes, outbytes;
+       
+       cd = iconv_open(UCS4_CODEPAGE_NAME, UCS2_CODEPAGE_NAME);
+       if (cd != (iconv_t)(-1))
+       {
+               inbuf = (const char *)src;
+               inbytes = (srcLen == -1) ? ucs2_strlen(src) + 1 : srcLen;
+               outbuf = (char *)dst;
+               outbytes = dstLen * sizeof(WCHAR);
+               count = iconv(cd, (ICONV_CONST char **)&inbuf, &inbytes, &outbuf, &outbytes);
+               iconv_close(cd);
+               if (count == -1)
+               {
+                       if (errno == EILSEQ)
+                       {
+                               count = (dstLen * sizeof(WCHAR) - outbytes) / sizeof(WCHAR);
+                       }
+                       else
+                       {
+                               count = 0;
+                       }
+               }
+               if ((srcLen == -1) && (outbytes >= sizeof(WCHAR)))
+               {
+                       *((WCHAR *)outbuf) = 0;
+               }
+       }
+       else
+       {
+               *dst = 0;
+               count = 0;
+       }
+       return count;
+}
+
+
+//
+// Convert UCS-4 to UCS-2
+//
+
+size_t LIBNETXMS_EXPORTABLE ucs4_to_ucs2(const WCHAR *src, size_t srcLen, UCS2CHAR *dst, size_t dstLen)
+{
+       iconv_t cd;
+       const char *inbuf;
+       char *outbuf;
+       size_t count, inbytes, outbytes;
+       
+       cd = iconv_open(UCS2_CODEPAGE_NAME, UCS4_CODEPAGE_NAME);
+       if (cd != (iconv_t)(-1))
+       {
+               inbuf = (const char *)src;
+               inbytes = (srcLen == -1) ? wcslen(src) + 1 : srcLen;
+               outbuf = (char *)dst;
+               outbytes = dstLen * sizeof(UCS2CHAR);
+               count = iconv(cd, (ICONV_CONST char **)&inbuf, &inbytes, &outbuf, &outbytes);
+               iconv_close(cd);
+               if (count == -1)
+               {
+                       if (errno == EILSEQ)
+                       {
+                               count = (dstLen * sizeof(UCS2CHAR) - outbytes) / sizeof(UCS2CHAR);
+                       }
+                       else
+                       {
+                               count = 0;
+                       }
+               }
+               if (((char *)outbuf - (char *)dst > sizeof(UCS2CHAR)) && (*dst == 0xFEFF))
+               {
+                       // Remove UNICODE byte order indicator if presented
+                       memmove(dst, &dst[1], (char *)outbuf - (char *)dst - sizeof(UCS2CHAR));
+                       outbuf -= sizeof(UCS2CHAR);
+               }
+               if ((srcLen == -1) && (outbytes >= sizeof(UCS2CHAR)))
+               {
+                       *((UCS2CHAR *)outbuf) = 0;
+               }
+       }
+       else
+       {
+               *dst = 0;
+               count = 0;
+       }
+       return count;
+}
+
+#endif /* UNICODE && UNICODE_UCS4 */
+
+
+#if !defined(_WIN32) && !defined(UNICODE)
+
+//
+// Convert UCS-2 to multibyte
+//
+
+size_t LIBNETXMS_EXPORTABLE ucs2_to_mb(const UCS2CHAR *src, size_t srcLen, char *dst, size_t dstLen)
+{
+#if HAVE_ICONV && !defined(__DISABLE_ICONV)
+       iconv_t cd;
+       const char *inbuf;
+       char *outbuf;
+       size_t count, inbytes, outbytes;
+       
+       cd = iconv_open(m_cpDefault, UCS2_CODEPAGE_NAME);
+       if (cd != (iconv_t)(-1))
+       {
+               inbuf = (const char *)src;
+               inbytes = ((srcLen == -1) ? ucs2_strlen(src) + 1 : srcLen) * sizeof(UCS2CHAR);
+               outbuf = (char *)dst;
+               outbytes = dstLen;
+               count = iconv(cd, (ICONV_CONST char **)&inbuf, &inbytes, &outbuf, &outbytes);
+               iconv_close(cd);
+               if (count == -1)
+               {
+                       if (errno == EILSEQ)
+                       {
+                               count = (dstLen * sizeof(char) - outbytes) / sizeof(char);
+                       }
+                       else
+                       {
+                               count = 0;
+                       }
+               }
+               if ((srcLen == -1) && (outbytes >= sizeof(char)))
+               {
+                       *((char *)outbuf) = 0;
+               }
+       }
+       else
+       {
+               *dst = 0;
+               count = 0;
+       }
+       return count;
+       
+#else
+
+   const UCS2CHAR *psrc;
+   char *pdst;
+   int pos, size;
+
+   size = (srcLen == -1) ? ucs2_strlen(src) : srcLen;
+   if (size >= dstLen)
+      size = dstLen - 1;
+   for(psrc = src, pos = 0, pdst = dst; pos < size; pos++, psrc++, pdst++)
+      *pdst = (*psrc < 256) ? (char)(*psrc) : '?';
+   *pdst = 0;
+   return size;
+#endif
+}
+
+
+//
+// Convert multibyte to UCS-2
+//
+
+size_t LIBNETXMS_EXPORTABLE mb_to_ucs2(const char *src, size_t srcLen, UCS2CHAR *dst, size_t dstLen)
+{
+#if HAVE_ICONV && !defined(__DISABLE_ICONV)
+       iconv_t cd;
+       const char *inbuf;
+       char *outbuf;
+       size_t count, inbytes, outbytes;
+       
+       cd = iconv_open(UCS2_CODEPAGE_NAME, m_cpDefault);
+       if (cd != (iconv_t)(-1))
+       {
+               inbuf = (const char *)src;
+               inbytes = (srcLen == -1) ? strlen(src) + 1 : srcLen;
+               outbuf = (char *)dst;
+               outbytes = dstLen * sizeof(UCS2CHAR);
+               count = iconv(cd, (ICONV_CONST char **)&inbuf, &inbytes, &outbuf, &outbytes);
+               iconv_close(cd);
+               if (count == -1)
+               {
+                       if (errno == EILSEQ)
+                       {
+                               count = (dstLen * sizeof(UCS2CHAR) - outbytes) / sizeof(UCS2CHAR);
+                       }
+                       else
+                       {
+                               count = 0;
+                       }
+               }
+               if (((char *)outbuf - (char *)dst > sizeof(UCS2CHAR)) && (*dst == 0xFEFF))
+               {
+                       // Remove UNICODE byte order indicator if presented
+                       memmove(dst, &dst[1], (char *)outbuf - (char *)dst - sizeof(UCS2CHAR));
+                       outbuf -= sizeof(UCS2CHAR);
+               }
+               if ((srcLen == -1) && (outbytes >= sizeof(UCS2CHAR)))
+               {
+                       *((UCS2CHAR *)outbuf) = 0;
+               }
+       }
+       else
+       {
+               *dst = 0;
+               count = 0;
+       }
+       return count;
+       
+#else
+
+       const char *psrc;
+       UCS2CHAR *pdst;
+       int pos, size;
+
+       size = (srcLen == -1) ? strlen(src) : srcLen;
+       if (size >= dstLen)
+               size = dstLen - 1;
+       for(psrc = src, pos = 0, pdst = dst; pos < size; pos++, psrc++, pdst++)
+               *pdst = (UCS2CHAR)(*psrc);
+       *pdst = 0;
+
+       return size;
+#endif
+}
+
+#endif /* !defined(_WIN32) && !defined(UNICODE) */
+
+
+//
+// Wide character version of some functions
+//
+
+#if !defined(_WIN32) && defined(UNICODE)
+
+#if !HAVE_WFOPEN
+
+FILE LIBNETXMS_EXPORTABLE *wfopen(const WCHAR *_name, const WCHAR *_type)
+{
+       char *name, *type;
+       FILE *f;
+       
+       name = MBStringFromWideString(_name);
+       type = MBStringFromWideString(_type);
+       f = fopen(name, type);
+       free(name);
+       free(type);
+       return f;
+}
+
+#endif
+
+#if !HAVE_WOPEN
+
+int LIBNETXMS_EXPORTABLE wopen(const WCHAR *_name, int flags, ...)
+{
+       char *name;
+       int rc;
+       
+       name = MBStringFromWideString(_name);
+       if (flags & O_CREAT)
+       {
+               va_list args;
+               
+               va_start(args, flags);
+               rc = open(name, flags, va_arg(args, mode_t));
+               va_end(args); 
+       }
+       else
+       {
+               rc = open(name, flags);
+       }
+       free(name);
+       return rc;
+}
+
+#endif
+
+#if !HAVE_WSTAT
+
+int wstat(const WCHAR *_path, struct stat *_sbuf)
+{
+       char path[MAX_PATH];
+       
+       WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,
+                       _path, -1, path, MAX_PATH, NULL, NULL);
+       return stat(path, _sbuf);
+}
+
+#endif
+
+#endif
+
index 627d598..8e982bf 100644 (file)
@@ -1,14 +1,26 @@
 INCLUDES=-I@top_srcdir@/include
 
+SOURCES = actions.cpp agentcfg.cpp alarms.cpp cert.cpp comm.cpp \
+          datacoll.cpp epp.cpp eventdb.cpp events.cpp graph.cpp \
+          image.cpp layer2.cpp lpp.cpp main.cpp map.cpp mib.cpp \
+          mp.cpp objects.cpp objtools.cpp package.cpp script.cpp \
+          server.cpp session.cpp snmptrap.cpp snmp.cpp users.cpp
+
+if BUILD_UNICODE_LIBS
+lib_LTLIBRARIES = libnxcl.la libnxclw.la
+else
 lib_LTLIBRARIES = libnxcl.la
-libnxcl_la_SOURCES = actions.cpp agentcfg.cpp alarms.cpp cert.cpp comm.cpp \
-                    datacoll.cpp epp.cpp eventdb.cpp events.cpp graph.cpp \
-                    image.cpp layer2.cpp lpp.cpp main.cpp map.cpp mib.cpp \
-                    mp.cpp objects.cpp objtools.cpp package.cpp script.cpp \
-                    server.cpp session.cpp snmptrap.cpp snmp.cpp users.cpp
+endif
+
+libnxcl_la_SOURCES = $(SOURCES)
 libnxcl_la_LDFLAGS = -version-info $(NETXMS_LIBRARY_VERSION)
 libnxcl_la_LIBADD = ../libnetxms/libnetxms.la ../libnxmap/libnxmap.la
 
+libnxclw_la_SOURCES = $(SOURCES)
+libnxclw_la_CPPFLAGS = -DUNICODE
+libnxclw_la_LDFLAGS = -version-info $(NETXMS_LIBRARY_VERSION)
+libnxclw_la_LIBADD = ../libnetxms/libnetxmsw.la ../libnxmap/libnxmapw.la
+
 EXTRA_DIST = \
        libnxcl.dsp libnxcl.dsw \
        libnxcl.vcp libnxcl.vcw \
index 952ffa0..2d5c091 100644 (file)
@@ -1,11 +1,22 @@
 INCLUDES=-I@top_srcdir@/include
 
+SOURCES = graph.cpp main.cpp map.cpp objlist.cpp radial.cpp rt.cpp submap.cpp vertex.cpp
+
+if BUILD_UNICODE_LIBS
+lib_LTLIBRARIES = libnxmap.la libnxmapw.la
+else
 lib_LTLIBRARIES = libnxmap.la
-libnxmap_la_SOURCES = graph.cpp main.cpp map.cpp objlist.cpp radial.cpp rt.cpp \
-                     submap.cpp vertex.cpp
+endif
+
+libnxmap_la_SOURCES = $(SOURCES)
 libnxmap_la_LDFLAGS = -version-info $(NETXMS_LIBRARY_VERSION)
 libnxmap_la_LIBADD = ../libnetxms/libnetxms.la
 
+libnxmapw_la_SOURCES = $(SOURCES)
+libnxmapw_la_CPPFLAGS = -DUNICODE
+libnxmapw_la_LDFLAGS = -version-info $(NETXMS_LIBRARY_VERSION)
+libnxmapw_la_LIBADD = ../libnetxms/libnetxmsw.la
+
 EXTRA_DIST = \
        libnxmap.dsp libnxmap.dsw \
        libnxmap.h