Browse Source

HPCC-17070 Ensure system can build with USE_ICU=0 and USE_OPENLDAP=0

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 8 years ago
parent
commit
4445b3971c

+ 7 - 1
common/thorhelper/csvsplitter.cpp

@@ -22,7 +22,9 @@
 #include "junicode.hpp"
 #include "eclhelper.hpp"
 
+#ifdef _USE_ICU
 #include "unicode/uchar.h"
+#endif
 
 #include "csvsplitter.hpp"
 #include "eclrtl.hpp"
@@ -420,6 +422,10 @@ void CSVOutputStream::writeUnicode(size32_t len, const UChar * data)
     rtlFree(utf8Data);
 }
 
+#ifndef _USE_ICU
+static inline bool u_isspace(UChar next) { return isspace((byte)next); }
+#endif
+
 void CSVOutputStream::writeUtf8(size32_t len, const char * data)
 {
     append(prefix);
@@ -498,7 +504,7 @@ void CSVOutputStream::writeUtf8(size32_t len, const char * data)
         else 
             append((size32_t)(e-(const byte *)data),data);
     }
-    prefix = separator; 
+    prefix = separator;
 }
 
 void CSVOutputStream::writeString(size32_t len, const char * data)

+ 0 - 1
common/thorhelper/csvsplitter.hpp

@@ -26,7 +26,6 @@
 
 #include "jregexp.hpp"
 #include "eclhelper.hpp"
-#include "unicode/utf.h"
 
 /**
  * CSVSplitter - splits CSV files into fields and rows.

+ 0 - 1
common/thorhelper/thorparse.ipp

@@ -20,7 +20,6 @@
 
 //MORE: Most of this should really be in a thorrparse.ipp instead.  Move later.
 
-#include "unicode/utf.h"
 #include "thorrparse.hpp"
 #include "eclhelper.hpp"
 

+ 4 - 0
common/thorhelper/thorralgo.ipp

@@ -18,7 +18,11 @@
 #ifndef __THORRALGO_IPP_
 #define __THORRALGO_IPP_
 
+#ifdef _USE_ICU
 #include "unicode/utf.h"
+#else
+typedef unsigned short UChar;
+#endif
 #include "thorparse.ipp"
 #include "thorrparse.hpp"
 #include "eclhelper.hpp"

+ 14 - 2
common/thorhelper/thorrparse.cpp

@@ -25,12 +25,13 @@
 #include "eclrtl.hpp"
 #include "thorcommon.ipp"
 
+#ifdef _USE_ICU
 #include "unicode/utf.h"
 #include "unicode/uchar.h"
 #include "unicode/schriter.h"
 #include "unicode/coll.h"
 #include "unicode/ustring.h"
-
+#endif
 
 #ifdef TRACE_REGEX
 #define MATCH   traceMatch
@@ -128,6 +129,7 @@ bool isUnicodeMatch(unsigned code, unsigned next)
 {
     switch (code)
     {
+#ifdef _USE_ICU
     case RCCalnum: return u_isalnum(next) != 0;
     case RCCcntrl: return u_iscntrl(next) != 0;
     case RCClower: return u_islower(next) != 0;
@@ -140,6 +142,7 @@ bool isUnicodeMatch(unsigned code, unsigned next)
     case RCCgraph: return u_isprint(next) && !u_isspace(next);
     case RCCpunct: return u_isprint(next) && !(u_isspace(next) || u_isalnum(next));
     case RCCxdigit: return (next < 128) && isxdigit(next);          // should be good enough.
+#endif
     case RCCany:   return true;
     default:
         UNIMPLEMENTED;
@@ -857,12 +860,16 @@ RegexMatchAction RegexEndRecursivePattern::beginMatch(RegexState & state)
 
 void encodeUnicode(StringBuffer & out, size32_t len, const UChar * text)
 {
+#ifdef _USE_ICU
     UnicodeString unicode(text, len);
     unsigned len8 = unicode.extract(0, unicode.length(), 0, 0, "UTF-8");
     char * text8 = (char *)malloc(len8);
     unicode.extract(0, unicode.length(), text8, len8, "UTF-8");
     encodeXML(text8, out, ENCODE_WHITESPACE, len8, true);
     free(text8);
+#else
+    throw MakeStringException(99, "System was built without Unicode support");
+#endif
 }
 
 
@@ -922,6 +929,7 @@ RegexMatchAction RegexUnicodePattern::beginMatch(RegexState & state)
 
 //---------------------------------------------------------------------------
 
+#ifdef _USE_ICU
 RegexUnicodeIPattern::RegexUnicodeIPattern(unsigned _len, const UChar * _text)
 {
     UChar * curLower = (UChar *)lower.allocate(_len*2);
@@ -1198,6 +1206,7 @@ RegexMatchAction RegexUtf8IPattern::beginMatch(RegexState & state)
         return pushMatched(state);
     return RegexMatchBacktrack;
 }
+#endif
 
 //---------------------------------------------------------------------------
 
@@ -1327,6 +1336,7 @@ void RegexAsciiISetPattern::addRange(unsigned low, unsigned high)
 
 //---------------------------------------------------------------------------
 
+#ifdef _USE_ICU
 RegexUnicodeSetPattern::RegexUnicodeSetPattern(bool _caseSensitive)
 {
     inverted = false;
@@ -1474,7 +1484,7 @@ void RegexUnicodeSetPattern::toXMLattr(StringBuffer & out, RegexXmlState & state
         out.append("\"");
     }
 }
-
+#endif
 
 
 
@@ -3063,12 +3073,14 @@ RegexPattern * deserializeRegex(MemoryBuffer & in)
         case ThorRegexAsciiI:       next = new RegexAsciiIPattern();                    break;
         case ThorRegexAsciiSet:     next = new RegexAsciiSetPattern();                  break;
         case ThorRegexAsciiISet:    next = new RegexAsciiISetPattern();                 break;
+#ifdef _USE_ICU
         case ThorRegexUnicode:      next = new RegexUnicodePattern();                   break;
         case ThorRegexUnicodeI:     next = new RegexUnicodeIPattern();                  break;
         case ThorRegexUnicodeSet:   next = new RegexUnicodeSetPattern();                break;
         case ThorRegexUtf8:         next = new RegexUtf8Pattern();                      break;
         case ThorRegexUtf8I:        next = new RegexUtf8IPattern();                     break;
 //      case ThorRegexUnicodeISet:  next = new RegexUnicodeISetPattern();               break;
+#endif
         case ThorRegexStart:        next = new RegexStartPattern();                     break;
         case ThorRegexFinish:       next = new RegexFinishPattern();                    break;
         case ThorRegexBeginToken:   next = new RegexBeginTokenPattern();                break;

+ 4 - 0
common/thorhelper/thorxmlread.hpp

@@ -188,7 +188,11 @@ extern thorhelper_decl ICsvToRawTransformer * createCsvRawTransformer(ICsvToRowT
 
 
 #ifndef CHEAP_UCHAR_DEF
+#ifdef _USE_ICU
 #include "unicode/utf.h"
+#else
+typedef unsigned short UChar;
+#endif
 #endif
 
 interface IXMLSelect : extends IInterface

+ 0 - 2
ecl/hqlcpp/hqlnlp.cpp

@@ -31,8 +31,6 @@
 #include "hqltcppc.hpp"
 #include "hqlcpputil.hpp"
 
-#include "unicode/uchar.h"
-
 #define DEFAULT_NLP_DETAIL              1
 #define DEFAULT_PATTERN_MAX_LENGTH      4096
 #ifdef __64BIT__

+ 22 - 0
ecl/hqlcpp/hqlregex.cpp

@@ -30,7 +30,9 @@
 #include "thorralgo.ipp"
 #include "hqlthql.hpp"
 
+#ifdef _USE_ICU
 #include "unicode/uchar.h"
+#endif
 
 //#define NEW_DFA_CALC
 //#define DEFAULT_DFA_COMPLEXITY    0
@@ -831,11 +833,15 @@ static bool canConsume(const ParseInformation & options, unsigned nextChar, unsi
     if (caseSensitive || (options.type == type_utf8))
         return false;
 
+#ifdef _USE_ICU
     if (options.type == type_unicode)
     {
         //MORE: This needs improving for full folding.
         return u_foldCase(nextChar, U_FOLD_CASE_DEFAULT) == u_foldCase(matcherChar, U_FOLD_CASE_DEFAULT);
     }
+#else
+    throw MakeStringException(99, "System was built without Unicode support");
+#endif
 
     return (nextChar == tolower(matcherChar)) || (nextChar == toupper(matcherChar));
 }
@@ -878,10 +884,12 @@ bool HqlRegexExpr::canConsume(unsigned nextChar)
                             {
                                 if (options.type == type_unicode)
                                 {
+#ifdef _USE_ICU
                                     //MORE: Improved unicode
                                     if (u_foldCase(nextChar, U_FOLD_CASE_DEFAULT) >= u_foldCase(low, U_FOLD_CASE_DEFAULT) &&
                                         u_foldCase(nextChar, U_FOLD_CASE_DEFAULT) <= u_foldCase(high, U_FOLD_CASE_DEFAULT))
                                         return !invert;
+#endif
                                 }
                                 else
                                 {
@@ -932,6 +940,7 @@ void HqlRegexExpr::gatherConsumeSymbols(SymbolArray & symbols)
             unsigned charValue = (unsigned)expr->queryValue()->getIntValue();
             if (!caseSensitive && (options.type != type_utf8))
             {
+#ifdef _USE_ICU
                 if (options.type == type_unicode)
                 {
                     //MORE: Unicode - can you have several values, what about case conversion?
@@ -940,6 +949,7 @@ void HqlRegexExpr::gatherConsumeSymbols(SymbolArray & symbols)
                     symbols.addUnique(u_toupper(charValue));
                 }
                 else
+#endif
                 {
                     symbols.addUnique(tolower(charValue));
                     symbols.addUnique(toupper(charValue));
@@ -962,6 +972,7 @@ void HqlRegexExpr::gatherConsumeSymbols(SymbolArray & symbols)
         assertex(options.type == type_string);
         if (options.type == type_unicode)
         {
+#ifdef _USE_ICU
             //MORE: Need some kind of implementation for unicode - although invert and ranges may not be possible.
             if (expr->hasAttribute(notAtom))
                 throwError(HQLERR_DfaTooComplex);
@@ -1006,6 +1017,9 @@ void HqlRegexExpr::gatherConsumeSymbols(SymbolArray & symbols)
                     UNIMPLEMENTED;
                 }
             }
+#else
+            UNIMPLEMENTED;
+#endif
         }
         else
         {
@@ -1461,7 +1475,11 @@ void HqlRegexExpr::generateRegex(GenerateRegexCtx & ctx)
         {
             RegexSetBasePattern * pattern;
             if (ctx.info.type != type_string)
+#ifdef _USE_ICU
                 pattern = new RegexUnicodeSetPattern(caseSensitive);
+#else
+                UNIMPLEMENTED;
+#endif
             else if (caseSensitive)
                 pattern = new RegexAsciiSetPattern;
             else
@@ -1497,6 +1515,7 @@ void HqlRegexExpr::generateRegex(GenerateRegexCtx & ctx)
             unsigned len = castValue->queryType()->getStringLen();
             switch (ctx.info.type)
             {
+#ifdef _USE_ICU
             case type_unicode:
                 {
                     const UChar * data = (const UChar *)castValue->queryValue();
@@ -1515,6 +1534,7 @@ void HqlRegexExpr::generateRegex(GenerateRegexCtx & ctx)
                         created.setown(new RegexUtf8IPattern(len, data));
                     break;
                 }
+#endif
             case type_string:
                 {
                     const char * data = (const char *)castValue->queryValue();
@@ -1524,6 +1544,8 @@ void HqlRegexExpr::generateRegex(GenerateRegexCtx & ctx)
                         created.setown(new RegexAsciiIPattern(len, data));
                     break;
                 }
+            default:
+                UNIMPLEMENTED;
             }
             break;
         }

+ 4 - 2
esp/services/ws_account/CMakeLists.txt

@@ -48,8 +48,10 @@ include_directories (
          ./../../smc/SMCLib  
     )
 
-# NOTE - this should not be needed, it's the result of poor encapsulation and using CLdapSecManager directly 
-include_directories ( ${OPENLDAP_INCLUDE_DIR} )
+if (USE_OPENLDAP)
+    # NOTE - this should not be needed, it's the result of poor encapsulation and using CLdapSecManager directly
+    include_directories ( ${OPENLDAP_INCLUDE_DIR} )
+endif ()
 
 ADD_DEFINITIONS( -D_USRDLL )
 

+ 4 - 2
esp/services/ws_smc/CMakeLists.txt

@@ -60,8 +60,10 @@ include_directories (
          ${CMAKE_BINARY_DIR}/oss
     )
 
-# NOTE - this should not be needed, it's the result of poor encapsulation and using CLdapSecManager directly 
-include_directories ( ${OPENLDAP_INCLUDE_DIR} )
+if (USE_OPENLDAP)
+    # NOTE - this should not be needed, it's the result of poor encapsulation and using CLdapSecManager directly
+    include_directories ( ${OPENLDAP_INCLUDE_DIR} )
+endif ()
 
 ADD_DEFINITIONS( -D_USRDLL -DWS_SMC_EXPORTS )
 

+ 3 - 0
esp/services/ws_workunits/ws_workunitsHelpers.cpp

@@ -29,7 +29,10 @@
 #include "dllserver.hpp"
 #include "wujobq.hpp"
 #include "hqlexpr.hpp"
+
+#ifndef _NO_LDAP
 #include "ldapsecurity.ipp"
+#endif
 
 #ifdef _USE_ZLIB
 #include "zcrypt.hpp"

+ 18 - 15
plugins/unicodelib/CMakeLists.txt

@@ -23,24 +23,27 @@
 #    Cmake Input File for unicodelib
 #####################################################
 
-project( unicodelib ) 
+if (USE_ICU)
 
-set (    SRCS 
-         unicodelib.cpp 
-    )
+    project( unicodelib )
 
-include_directories ( 
-         ./../../system/include 
-         ./../../system/jlib 
-    )
+    set (    SRCS
+             unicodelib.cpp
+        )
 
-ADD_DEFINITIONS( -D_USRDLL -DUNICODELIB_EXPORTS )
+    include_directories (
+             ./../../system/include
+             ./../../system/jlib
+        )
 
-HPCC_ADD_LIBRARY( unicodelib SHARED ${SRCS} )
-install ( TARGETS unicodelib DESTINATION plugins )
-target_link_libraries ( unicodelib 
-    jlib 
-    ${ICU_LIBRARIES} 
-    )
+    ADD_DEFINITIONS( -D_USRDLL -DUNICODELIB_EXPORTS )
 
+    HPCC_ADD_LIBRARY( unicodelib SHARED ${SRCS} )
+    install ( TARGETS unicodelib DESTINATION plugins )
+    target_link_libraries ( unicodelib
+        jlib
+        ${ICU_LIBRARIES}
+        )
+
+endif (USE_ICU)
 

+ 11 - 2
rtl/eclrtl/CMakeLists.txt

@@ -63,7 +63,6 @@ include_directories (
          ./../../system/jlib 
          ./../../roxie/roxiemem
          ./../../testing/unittests
-         ${ICU_INCLUDE_DIR}
          ${BOOST_REGEX_INCLUDE_DIR}
     )
 
@@ -83,12 +82,22 @@ endif ()
 HPCC_ADD_LIBRARY( eclrtl SHARED ${SRCS} )
 target_link_libraries ( eclrtl 
       ${BOOST_REGEX_LIBRARIES}
-      ${ICU_LIBRARIES}
       jlib
       nbcd
       roxiemem
     )
 
+if (USE_ICU)
+    include_directories (
+         ${ICU_INCLUDE_DIR}
+        )
+    target_link_libraries ( eclrtl
+          ${ICU_LIBRARIES}
+        )
+endif ()
+
+
+
 if (NOT PLUGIN)
   install ( TARGETS eclrtl RUNTIME DESTINATION ${EXEC_DIR} LIBRARY DESTINATION ${LIB_DIR} ARCHIVE DESTINATION componentfiles/cl/lib )
   FOREACH( iFILES

+ 17 - 0
rtl/eclrtl/eclregex.cpp

@@ -24,7 +24,9 @@
 #include "platform.h"
 #include "eclrtl.hpp"
 #include "eclrtl_imp.hpp"
+#ifdef _USE_ICU
 #include "unicode/regex.h"
+#endif
 
 #define UTF8_CODEPAGE "UTF-8"
 #define UTF8_MAXSIZE     4
@@ -260,6 +262,7 @@ ECLRTL_API void rtlDestroyStrRegExprFindInstance(IStrRegExprFindInstance * findI
 
 // RegEx Compiler for unicode strings
 
+#ifdef _USE_ICU
 class CUStrRegExprFindInstance : implements IUStrRegExprFindInstance
 {
 private:
@@ -440,6 +443,20 @@ ECLRTL_API void rtlDestroyUStrRegExprFindInstance(IUStrRegExprFindInstance * fin
     if (findInst)
         delete (CUStrRegExprFindInstance*)findInst;
 }
+#else
+ECLRTL_API ICompiledUStrRegExpr * rtlCreateCompiledUStrRegExpr(const UChar * regExpr, bool isCaseSensitive)
+{
+    rtlFail(0, "ICU regex disabled");
+}
+
+ECLRTL_API void rtlDestroyCompiledUStrRegExpr(ICompiledUStrRegExpr * compiledExpr)
+{
+}
+
+ECLRTL_API void rtlDestroyUStrRegExprFindInstance(IUStrRegExprFindInstance * findInst)
+{
+}
+#endif
 
 #else // _USE_BOOST_REGEX or _USE_C11_REGEX not set
 ECLRTL_API ICompiledStrRegExpr * rtlCreateCompiledStrRegExpr(const char * regExpr, bool isCaseSensitive)

+ 356 - 112
rtl/eclrtl/eclrtl.cpp

@@ -28,6 +28,7 @@
 #include "eclrtl.hpp"
 #include "rtlbcd.hpp"
 #include "eclrtl_imp.hpp"
+#ifdef _USE_ICU
 #include "unicode/uchar.h"
 #include "unicode/ucol.h"
 #include "unicode/ustring.h"
@@ -36,6 +37,7 @@
 #include "unicode/regex.h"
 #include "unicode/normlzr.h"
 #include "unicode/locid.h"
+#endif
 #include "jlog.hpp"
 #include "jmd5.hpp"
 #include "rtlqstr.ipp"
@@ -59,6 +61,10 @@ MODULE_EXIT()
     random_->Release();
 }
 
+#ifndef _USE_ICU
+static inline bool u_isspace(UChar next) { return isspace((byte)next); }
+#endif
+
 //=============================================================================
 // Miscellaneous string functions...
 ECLRTL_API void * rtlMalloc(size32_t size)
@@ -121,6 +127,30 @@ ECLRTL_API byte * * rtlLinkRowset(byte * * rowset)
 
 // escape
 
+bool rtlGetNormalizedUnicodeLocaleName(unsigned len, char const * in, char * out)
+{
+    bool isPrimary = true;
+    bool ok = true;
+    unsigned i;
+    for(i=0; i<len; i++)
+        if(in[i] == '_')
+        {
+            out[i] = '_';
+            isPrimary = false;
+        }
+        else if(isalpha(in[i]))
+        {
+            out[i] = (isPrimary ? tolower(in[i]) : toupper(in[i]));
+        }
+        else
+        {
+            out[i] = 0;
+            ok = false;
+        }
+    return ok;
+}
+
+#ifdef _USE_ICU
 static bool stripIgnorableCharacters(size32_t & lenResult, UChar * & result, size32_t length, const UChar * in)
 {
     unsigned numStripped = 0;
@@ -239,29 +269,6 @@ MODULE_EXIT()
     delete localeMap;
 }
 
-bool rtlGetNormalizedUnicodeLocaleName(unsigned len, char const * in, char * out)
-{
-    bool isPrimary = true;
-    bool ok = true;
-    unsigned i;
-    for(i=0; i<len; i++)
-        if(in[i] == '_')
-        {
-            out[i] = '_';
-            isPrimary = false;
-        }
-        else if(isalpha(in[i]))
-        {
-            out[i] = (isPrimary ? tolower(in[i]) : toupper(in[i]));
-        }
-        else
-        {
-            out[i] = 0;
-            ok = false;
-        }
-    return ok;
-}
-
 RTLLocale * queryRTLLocale(char const * locale)
 {
     if (!locale) locale = "";
@@ -433,6 +440,7 @@ void normalizeUnicodeString(UnicodeString const & in, UnicodeString & out)
     Normalizer::compose(in, false, 0, out, err);
     assertex(U_SUCCESS(err));
 }
+#endif
 
 // padding
 
@@ -1473,6 +1481,7 @@ void rtlConcatVStr(char * * tgt, ...)
     *tgt = buffer;
 }
 
+#ifdef _USE_ICU
 void rtlConcatUnicode(unsigned & tlen, UChar * * tgt, ...)
 {
     va_list args;
@@ -1542,6 +1551,17 @@ void rtlConcatVUnicode(UChar * * tgt, ...)
     buffer[idx++] = 0x0000;
     *tgt = buffer;
 }
+#else
+void rtlConcatUnicode(unsigned & tlen, UChar * * tgt, ...)
+{
+    UNIMPLEMENTED;
+}
+
+void rtlConcatVUnicode(UChar * * tgt, ...)
+{
+    UNIMPLEMENTED;
+}
+#endif
 
 //List of strings with length of -1 to mark the end...
 void rtlConcatStrF(unsigned tlen, void * _tgt, int fill, ...)
@@ -1591,6 +1611,7 @@ void rtlConcatVStrF(unsigned tlen, char * tgt, ...)
 }
 
 
+#ifdef _USE_ICU
 void rtlConcatUnicodeF(unsigned tlen, UChar * tgt, ...)
 {
     va_list args;
@@ -1634,7 +1655,7 @@ void rtlConcatVUnicodeF(unsigned tlen, UChar * tgt, ...)
         tgt[idx++] = 0;
     tgt[tlen] = 0;
 }
-
+#endif
 
 //------------------------------------------------------------------------------------------------
 // The followinf concat functions are all deprecated in favour of the variable number of argument
@@ -1674,6 +1695,7 @@ void rtlConcatVStrToVStr(unsigned tlen, void * _tgt, const char * src)
     rtlVStrToVStr(tlen-tend, tgt+tend, src);
 }
 
+#ifdef _USE_ICU
 unsigned rtlConcatUnicodeToUnicode(unsigned tlen, UChar * tgt, unsigned idx, unsigned slen, UChar const * src)
 {
     UErrorCode err = U_ZERO_ERROR;
@@ -1684,6 +1706,7 @@ unsigned rtlConcatVUnicodeToUnicode(unsigned tlen, UChar * tgt, unsigned idx, UC
 {
     return rtlConcatUnicodeToUnicode(tlen, tgt, idx, rtlUnicodeStrlen(src), src);
 }
+#endif
 
 void rtlESpaceFill(unsigned tlen, char * tgt, unsigned idx)
 {
@@ -1920,8 +1943,16 @@ unsigned rtlTrimDataLen(size32_t l, const void * _t)
     return l;
 }
 
+inline size32_t rtlQuickTrimUnicode(size32_t len, UChar const * str)
+{
+    while (len && u_isspace(str[len-1]))
+        len--;
+    return len;
+}
+
 unsigned rtlTrimUnicodeStrLen(size32_t l, UChar const * t)
 {
+#ifdef _USE_ICU
     if (!l)
         return 0;
     UCharCharacterIterator iter(t, l);
@@ -1930,13 +1961,9 @@ unsigned rtlTrimUnicodeStrLen(size32_t l, UChar const * t)
             break;
     if(u_isspace(iter.current32())) return iter.getIndex(); // required as the reverse iteration above doesn't hit the first character
     return iter.getIndex() + 1;
-}
-
-inline size32_t rtlQuickTrimUnicode(size32_t len, UChar const * str)
-{
-    while (len && u_isspace(str[len-1]))
-        len--;
-    return len;
+#else
+    return rtlQuickTrimUnicode(l, t);
+#endif
 }
 
 unsigned rtlTrimVStrLen(const char * t)
@@ -1967,11 +1994,15 @@ inline unsigned rtlLeftTrimStrStart(size32_t slen, const char * src)
 
 inline unsigned rtlLeftTrimUnicodeStrStart(size32_t slen, UChar const * src)
 {
+#ifdef _USE_ICU
     UCharCharacterIterator iter(src, slen);
     for(iter.first32(); iter.hasNext(); iter.next32())
         if(!u_isspace(iter.current32()))
             break;
     return iter.getIndex();
+#else
+    return slen;
+#endif
 }
 
 inline unsigned rtlLeftTrimVStrStart(const char * src)
@@ -2020,6 +2051,7 @@ inline void rtlTrimUtf8Start(unsigned & trimLen, size32_t & trimSize, size32_t l
     trimSize = cur-start;
 }
 
+
 inline char * rtlDupSubString(const char * src, unsigned len)
 {
     char * buffer = (char *)rtlMalloc(len + 1);
@@ -2055,8 +2087,8 @@ inline void rtlCopySubString(size32_t tlen, char * tgt, unsigned slen, const cha
 
 unsigned rtlTrimUtf8StrLen(size32_t len, const char * t)
 {
-    const byte * cur = (const byte *)t;
     unsigned trimLength = 0;
+    const byte * cur = (const byte *)t;
     for (unsigned i=0; i < len; i++)
     {
         unsigned next = readUtf8Character(UTF8_MAXSIZE, cur);
@@ -2285,6 +2317,7 @@ void rtlTrimAll(unsigned & tlen, char * & tgt, unsigned slen, const char * src)
 
 void rtlTrimUnicodeAll(unsigned & tlen, UChar * & tgt, unsigned slen, const UChar * src)
 {
+#ifdef _USE_ICU
     UnicodeString rawStr;
     UCharCharacterIterator iter(src, slen);
     for(iter.first32(); iter.hasNext(); iter.next32())
@@ -2296,6 +2329,9 @@ void rtlTrimUnicodeAll(unsigned & tlen, UChar * & tgt, unsigned slen, const UCha
     tgt = (UChar *)rtlMalloc((tlen+1)*2);
     tgtStr.extract(0, tlen, tgt);
     tgt[tlen] = 0x0000;
+#else
+    throw MakeStringException(99, "System was built without Unicode support");
+#endif
 }
 
 void rtlTrimVAll(unsigned & tlen, char * & tgt, const char * src)
@@ -2560,6 +2596,7 @@ int rtlCompareEStrEStr(unsigned l1, const char * p1, unsigned l2, const char * p
 }
 
 const static UChar nullUStr = 0;
+#ifdef _USE_ICU
 int rtlCompareUnicodeUnicode(unsigned l1, UChar const * p1, unsigned l2, UChar const * p2, char const * locale)
 {
     while(l1 && u_isUWhiteSpace(p1[l1-1])) l1--;
@@ -2577,6 +2614,10 @@ int rtlCompareUnicodeUnicodeStrength(unsigned l1, UChar const * p1, unsigned l2,
     if (!p2) p2 = &nullUStr;
     return ucol_strcoll(queryRTLLocale(locale)->queryCollator(strength), p1, l1, p2, l2);
 }
+#else
+int rtlCompareUnicodeUnicode(unsigned l1, UChar const * p1, unsigned l2, UChar const * p2, char const * locale) { throw MakeStringException(99, "System was built without Unicode support"); }
+int rtlCompareUnicodeUnicodeStrength(unsigned l1, UChar const * p1, unsigned l2, UChar const * p2, char const * locale, unsigned strength) { throw MakeStringException(99, "System was built without Unicode support"); }
+#endif
 
 int rtlCompareVUnicodeVUnicode(UChar const * p1, UChar const * p2, char const * locale)
 {
@@ -2588,6 +2629,7 @@ int rtlCompareVUnicodeVUnicodeStrength(UChar const * p1, UChar const * p2, char
     return rtlCompareUnicodeUnicodeStrength(rtlUnicodeStrlen(p1), p1, rtlUnicodeStrlen(p2), p2, locale, strength);
 }
 
+#ifdef _USE_ICU
 void rtlKeyUnicodeX(unsigned & tlen, void * & tgt, unsigned slen, const UChar * src, const char * locale)
 {
     while(slen && u_isUWhiteSpace(src[slen-1])) slen--;
@@ -2605,6 +2647,18 @@ void rtlKeyUnicodeStrengthX(unsigned & tlen, void * & tgt, unsigned slen, const
     tgt = rtlMalloc(tlen);
     ucol_getSortKey(coll, src, slen, (unsigned char *)tgt, tlen);
 }
+#else
+void rtlKeyUnicodeX(unsigned & tlen, void * & tgt, unsigned slen, const UChar * src, const char * locale)
+{
+    throw MakeStringException(99, "System was built without Unicode support");
+}
+
+void rtlKeyUnicodeStrengthX(unsigned & tlen, void * & tgt, unsigned slen, const UChar * src, const char * locale, unsigned strength)
+{
+    throw MakeStringException(99, "System was built without Unicode support");
+}
+
+#endif
 
 ECLRTL_API int rtlPrefixDiffStrEx(unsigned l1, const char * p1, unsigned l2, const char * p2, unsigned origin)
 {
@@ -2636,6 +2690,7 @@ ECLRTL_API int rtlPrefixDiffStr(unsigned l1, const char * p1, unsigned l2, const
 //MORE: I'm not sure this can really be implemented....
 ECLRTL_API int rtlPrefixDiffUnicodeEx(unsigned l1, const UChar * p1, unsigned l2, const UChar * p2, char const * locale, unsigned origin)
 {
+#ifdef _USE_ICU
     while(l1 && u_isUWhiteSpace(p1[l1-1])) l1--;
     while(l2 && u_isUWhiteSpace(p2[l2-1])) l2--;
     unsigned len = l1 < l2 ? l1 : l2;
@@ -2652,6 +2707,9 @@ ECLRTL_API int rtlPrefixDiffUnicodeEx(unsigned l1, const UChar * p1, unsigned l2
     }
     if (l1 != l2)
         return (l1 < l2) ? -(int)(len+origin+1) : (int)(len+origin+1);
+#else
+    throw MakeStringException(99, "System was built without Unicode support");
+#endif
     return 0;
 }
 
@@ -2674,6 +2732,7 @@ void rtlStringToUpper(size32_t l, char * t)
         *t = toupper(*t);
 }
 
+#ifdef _USE_ICU
 void rtlUnicodeToLower(size32_t l, UChar * t, char const * locale)
 {
     UChar * buff = (UChar *)rtlMalloc(l*2);
@@ -2697,6 +2756,11 @@ void rtlUnicodeToUpper(size32_t l, UChar * t, char const * locale)
     u_strToUpper(buff, l, t, l, locale, &err);
     unicodeNormalizedCopy(buff, t, l);
 }
+#else
+void rtlUnicodeToLower(size32_t l, UChar * t, char const * locale) { throw MakeStringException(99, "System was built without Unicode support"); }
+void rtlUnicodeToLowerX(size32_t & lenout, UChar * & out, size32_t l, const UChar * t, char const * locale) { throw MakeStringException(99, "System was built without Unicode support"); }
+void rtlUnicodeToUpper(size32_t l, UChar * t, char const * locale) { throw MakeStringException(99, "System was built without Unicode support"); }
+#endif
 
 //=============================================================================
 // Miscellaneous helper functions...
@@ -2849,6 +2913,8 @@ int rtlNewSearchStringTable(unsigned count, unsigned elemlen, char * * table, un
     return -1;
 }
 
+
+#ifdef _USE_ICU
 int rtlNewSearchUnicodeTable(unsigned count, unsigned elemlen, UChar * * table, unsigned width, const UChar * search, const char * locale)
 {
     UCollator * coll = queryRTLLocale(locale)->queryCollator();
@@ -2894,6 +2960,7 @@ int rtlNewSearchVUnicodeTable(unsigned count, UChar * * table, const UChar * sea
 
     return -1;
 }
+#endif
 
 //-----------------------------------------------------------------------------
 
@@ -3017,6 +3084,7 @@ void rtlStrToEStr(unsigned outlen, char *out, unsigned inlen, const char *in)
 
 //---------------------------------------------------------------------------
 
+#ifdef _USE_ICU
 void rtlCodepageToUnicode(unsigned outlen, UChar * out, unsigned inlen, char const * in, char const * codepage)
 {
     //If the input contains a character which doesn't exist in its claimed codepage, this will
@@ -3040,16 +3108,6 @@ void rtlCodepageToVUnicode(unsigned outlen, UChar * out, unsigned inlen, char co
     vunicodeEnsureIsNormalized(outlen, out);
 }
 
-void rtlVCodepageToUnicode(unsigned outlen, UChar * out, char const * in, char const * codepage)
-{
-    rtlCodepageToUnicode(outlen, out, strlen(in), in, codepage);
-}
-
-void rtlVCodepageToVUnicode(unsigned outlen, UChar * out, char const * in, char const * codepage)
-{
-    rtlCodepageToVUnicode(outlen, out, strlen(in), in, codepage);
-}
-
 void rtlCodepageToUnicodeUnescape(unsigned outlen, UChar * out, unsigned inlen, char const * in, char const * codepage)
 {
     //If the input contains a character which doesn't exist in its claimed codepage, this will
@@ -3103,22 +3161,6 @@ void rtlUnicodeToVCodepage(unsigned outlen, char * out, unsigned inlen, UChar co
     if (len >= outlen) len = outlen-1;
     out[len] = 0;
 }
-
-void rtlVUnicodeToCodepage(unsigned outlen, char * out, UChar const * in, char const * codepage)
-{
-    rtlUnicodeToCodepage(outlen, out, rtlUnicodeStrlen(in), in, codepage);
-}
-
-void rtlVUnicodeToData(unsigned outlen, void * out, UChar const * in)
-{
-    rtlUnicodeToData(outlen, out, rtlUnicodeStrlen(in), in);
-}
-
-void rtlVUnicodeToVCodepage(unsigned outlen, char * out, UChar const * in, char const * codepage)
-{
-    rtlUnicodeToVCodepage(outlen, out, rtlUnicodeStrlen(in), in, codepage);
-}
-
 void rtlCodepageToUnicodeX(unsigned & outlen, UChar * & out, unsigned inlen, char const * in, char const * codepage)
 {
     //If the input contains a character which doesn't exist in its claimed codepage, this will
@@ -3146,6 +3188,88 @@ UChar * rtlCodepageToVUnicodeX(unsigned inlen, char const * in, char const * cod
     return out;
 }
 
+#else
+void rtlCodepageToUnicode(unsigned outlen, UChar * out, unsigned inlen, char const * in, char const * codepage)
+{
+    if (inlen > outlen)
+        inlen = outlen;
+    unsigned i = 0;
+    for (; i < inlen; i++)
+        out[i] = in[i];
+    while (i < outlen)
+        out[i++] = 0x0020;
+}
+
+void rtlCodepageToVUnicode(unsigned outlen, UChar * out, unsigned inlen, char const * in, char const * codepage)
+{
+    throw MakeStringException(99, "System was built without Unicode support");
+}
+
+void rtlCodepageToUnicodeUnescape(unsigned outlen, UChar * out, unsigned inlen, char const * in, char const * codepage)
+{
+    rtlCodepageToUnicode(outlen, out, inlen, in, codepage);
+}
+
+void rtlUnicodeToCodepage(unsigned outlen, char * out, unsigned inlen, UChar const * in, char const * codepage)
+{
+    if (inlen > outlen)
+        inlen = outlen;
+    unsigned i = 0;
+    for (; i < inlen; i++)
+        out[i] = (char)in[i];
+    while (i < outlen)
+        out[i++] = ' ';
+}
+
+void rtlUnicodeToData(unsigned outlen, void * out, unsigned inlen, UChar const * in)
+{
+    rtlUnicodeToCodepage(outlen, (char *)out, inlen, in, nullptr);
+}
+
+void rtlUnicodeToVCodepage(unsigned outlen, char * out, unsigned inlen, UChar const * in, char const * codepage)
+{
+    throw MakeStringException(99, "System was built without Unicode support");
+}
+
+void rtlCodepageToUnicodeX(unsigned & outlen, UChar * & out, unsigned inlen, char const * in, char const * codepage)
+{
+    outlen = inlen;
+    out = (UChar *)rtlMalloc(outlen*2);
+    rtlCodepageToUnicode(outlen, out, inlen, in, codepage);
+}
+
+UChar * rtlCodepageToVUnicodeX(unsigned inlen, char const * in, char const * codepage)
+{
+    throw MakeStringException(99, "System was built without Unicode support");
+}
+
+#endif
+
+void rtlVCodepageToUnicode(unsigned outlen, UChar * out, char const * in, char const * codepage)
+{
+    rtlCodepageToUnicode(outlen, out, strlen(in), in, codepage);
+}
+
+void rtlVCodepageToVUnicode(unsigned outlen, UChar * out, char const * in, char const * codepage)
+{
+    rtlCodepageToVUnicode(outlen, out, strlen(in), in, codepage);
+}
+
+void rtlVUnicodeToCodepage(unsigned outlen, char * out, UChar const * in, char const * codepage)
+{
+    rtlUnicodeToCodepage(outlen, out, rtlUnicodeStrlen(in), in, codepage);
+}
+
+void rtlVUnicodeToData(unsigned outlen, void * out, UChar const * in)
+{
+    rtlUnicodeToData(outlen, out, rtlUnicodeStrlen(in), in);
+}
+
+void rtlVUnicodeToVCodepage(unsigned outlen, char * out, UChar const * in, char const * codepage)
+{
+    rtlUnicodeToVCodepage(outlen, out, rtlUnicodeStrlen(in), in, codepage);
+}
+
 void rtlVCodepageToUnicodeX(unsigned & outlen, UChar * & out, char const * in, char const * codepage)
 {
     rtlCodepageToUnicodeX(outlen, out, strlen(in), in, codepage);
@@ -3156,6 +3280,7 @@ UChar * rtlVCodepageToVUnicodeX(char const * in, char const * codepage)
     return rtlCodepageToVUnicodeX(strlen(in), in, codepage);
 }
 
+#ifdef _USE_ICU
 void rtlCodepageToUnicodeXUnescape(unsigned & outlen, UChar * & out, unsigned inlen, char const * in, char const * codepage)
 {
     //If the input contains a character which doesn't exist in its claimed codepage, this will
@@ -3201,11 +3326,6 @@ void rtlUnicodeToCodepageX(unsigned & outlen, char * & out, unsigned inlen, UCha
     ucnv_fromUChars(conv, out, outlen, in, inlen, &err);
 }
 
-void rtlUnicodeToDataX(unsigned & outlen, void * & out, unsigned inlen, UChar const * in)
-{
-    rtlUnicodeToCodepageX(outlen, (char * &)out, inlen, in, ASCII_LIKE_CODEPAGE);
-}
-
 char * rtlUnicodeToVCodepageX(unsigned inlen, UChar const * in, char const * codepage)
 {
     //If the unicode contains a character which doesn't exist in the destination codepage,
@@ -3221,6 +3341,34 @@ char * rtlUnicodeToVCodepageX(unsigned inlen, UChar const * in, char const * cod
     out[outlen] = 0x00;
     return out;
 }
+#else
+void rtlCodepageToUnicodeXUnescape(unsigned & outlen, UChar * & out, unsigned inlen, char const * in, char const * codepage)
+{
+    rtlCodepageToUnicodeX(outlen, out, inlen, in, codepage);
+}
+
+void rtlCodepageToUtf8XUnescape(unsigned & outlen, char * & out, unsigned inlen, char const * in, char const * codepage)
+{
+    rtlCodepageToUtf8X(outlen, out, inlen, in, codepage);
+}
+
+void rtlUnicodeToCodepageX(unsigned & outlen, char * & out, unsigned inlen, UChar const * in, char const * codepage)
+{
+    outlen = inlen;
+    out = (char *)rtlMalloc(outlen);
+    rtlUnicodeToCodepage(outlen, out, inlen, in, codepage);
+}
+
+char * rtlUnicodeToVCodepageX(unsigned inlen, UChar const * in, char const * codepage)
+{
+    throw MakeStringException(99, "System was built without Unicode support");
+}
+#endif
+
+void rtlUnicodeToDataX(unsigned & outlen, void * & out, unsigned inlen, UChar const * in)
+{
+    rtlUnicodeToCodepageX(outlen, (char * &)out, inlen, in, ASCII_LIKE_CODEPAGE);
+}
 
 void rtlVUnicodeToCodepageX(unsigned & outlen, char * & out, UChar const * in, char const * codepage)
 {
@@ -3252,6 +3400,7 @@ void rtlUnicodeToStrX(unsigned & outlen, char * & out, unsigned inlen, UChar con
     rtlUnicodeToCodepageX(outlen, out, inlen, in, ASCII_LIKE_CODEPAGE);
 }
 
+#ifdef _USE_ICU
 void rtlUnicodeToEscapedStrX(unsigned & outlen, char * & out, unsigned inlen, UChar const * in)
 {
     StringBuffer outbuff;
@@ -3310,6 +3459,38 @@ int rtlSingleUtf8ToCodepage(char * out, unsigned inlen, char const * in, char co
     return static_cast<int>(trailbytes); //cast okay as is certainly 0--3
 }
 
+#else
+void rtlUnicodeToEscapedStrX(unsigned & outlen, char * & out, unsigned inlen, UChar const * in)
+{
+    return rtlUnicodeToStrX(outlen, out, inlen, in);
+}
+
+bool rtlCodepageToCodepage(unsigned outlen, char * out, unsigned inlen, char const * in, char const * outcodepage, char const * incodepage)
+{
+    if (inlen > outlen)
+        inlen = outlen;
+    memcpy(out, in, inlen);
+    if (inlen < outlen)
+        memset(out+inlen, ' ', outlen-inlen);
+    return true;
+}
+
+bool rtlCodepageToCodepageX(unsigned & outlen, char * & out, unsigned maxoutlen, unsigned inlen, char const * in, char const * outcodepage, char const * incodepage)
+{
+    if (inlen > maxoutlen)
+        inlen = maxoutlen;
+    outlen = inlen;
+    out = (char *)rtlMalloc(inlen);
+    return rtlCodepageToCodepage(outlen, out, inlen, in, outcodepage, incodepage);
+}
+
+int rtlSingleUtf8ToCodepage(char * out, unsigned inlen, char const * in, char const * outcodepage)
+{
+    throw MakeStringException(99, "System was built without Unicode support");
+}
+
+#endif
+
 //---------------------------------------------------------------------------
 
 void rtlStrToDataX(unsigned & tlen, void * & tgt, unsigned slen, const void * src)
@@ -3416,8 +3597,10 @@ hash64_t rtlHash64VStr(const char *str, hash64_t hval)
     return hval;
 }
 
+
 hash64_t rtlHash64Unicode(unsigned length, UChar const * k, hash64_t hval)
 {
+#ifdef _USE_ICU
     unsigned trimLength = rtlTrimUnicodeStrLen(length, k);
     for (unsigned i=0; i < trimLength; i++)
     {
@@ -3446,6 +3629,9 @@ hash64_t rtlHash64Unicode(unsigned length, UChar const * k, hash64_t hval)
             }
         }
     }
+#else
+    throw MakeStringException(99, "System was built without Unicode support");
+#endif
     return hval;
 }
 
@@ -3510,6 +3696,7 @@ unsigned rtlHash32VStr(const char *str, unsigned hval)
 
 unsigned rtlHash32Unicode(unsigned length, UChar const * k, unsigned hval)
 {
+#ifdef _USE_ICU
     unsigned trimLength = rtlTrimUnicodeStrLen(length, k);
     for (unsigned i=0; i < trimLength; i++)
     {
@@ -3538,6 +3725,9 @@ unsigned rtlHash32Unicode(unsigned length, UChar const * k, unsigned hval)
             }
         }
     }
+#else
+    throw MakeStringException(99, "System was built without Unicode support");
+#endif
     return hval;
 }
 
@@ -3626,6 +3816,7 @@ unsigned rtlHashString( unsigned length, const char *_k, unsigned initval)
 
 unsigned rtlHashUnicode(unsigned length, UChar const * k, unsigned initval)
 {
+#ifdef _USE_ICU
     unsigned trimLength = rtlTrimUnicodeStrLen(length, k);
     //Because of the implementation of HASH we need to strip ignoreable code points instead of skipping them
     size32_t tempLength;
@@ -3634,6 +3825,9 @@ unsigned rtlHashUnicode(unsigned length, UChar const * k, unsigned initval)
         return rtlHashData(tempLength*2, temp.getustr(), initval);
 
     return rtlHashData(trimLength*sizeof(UChar), k, initval);
+#else
+    throw MakeStringException(99, "System was built without Unicode support");
+#endif
 }
 
 unsigned rtlHashVStr(const char * k, unsigned initval)
@@ -4265,6 +4459,36 @@ double rtlCreateRealNull()
 }
 
 
+
+unsigned rtlUtf8Size(const void * data)
+{
+    return readUtf8Size(data);
+}
+
+unsigned rtlUtf8Size(unsigned len, const void * _data)
+{
+    const byte * data = (const byte *)_data;
+    size32_t offset = 0;
+    for (unsigned i=0; i< len; i++)
+        offset += readUtf8Size(data+offset);
+    return offset;
+}
+
+unsigned rtlUtf8Length(unsigned size, const void * _data)
+{
+    const byte * data = (const byte *)_data;
+    size32_t length = 0;
+    for (unsigned offset=0; offset < size; offset += readUtf8Size(data+offset))
+        length++;
+    return length;
+}
+
+unsigned rtlUtf8Char(const void * data)
+{
+    return readUtf8Char(data);
+}
+
+
 void rtlUnicodeToUnicode(size32_t outlen, UChar * out, size32_t inlen, UChar const *in)
 {
     if(inlen>outlen) inlen = outlen;
@@ -4324,40 +4548,48 @@ void rtlDecPushUnicode(size32_t len, UChar const * data)
     rtlFree(buff);
 }
 
-unsigned rtlUnicodeStrlen(UChar const * str)
+void rtlUtf8ToUtf8(size32_t outlen, char * out, size32_t inlen, const char *in)
 {
-    return u_strlen(str);
+    //Packs as many characaters as it can into the target, but don't include any half characters
+    size32_t offset = 0;
+    size32_t outsize = outlen*UTF8_MAXSIZE;
+    for (unsigned i=0; i< inlen; i++)
+    {
+        unsigned nextSize = readUtf8Size(in+offset);
+        if (offset + nextSize > outsize)
+            break;
+        offset += nextSize;
+    }
+    memcpy(out, in, offset);
+    if (offset != outsize)
+        memset(out+offset, ' ', outsize-offset);
 }
 
-//---------------------------------------------------------------------------
-
-unsigned rtlUtf8Size(const void * data)
+void rtlUtf8ToUtf8X(size32_t & outlen, char * & out, size32_t inlen, const char *in)
 {
-    return readUtf8Size(data);
+    unsigned insize = rtlUtf8Size(inlen, in);
+    char * buffer = (char *)rtlMalloc(insize);
+    memcpy(buffer, in, insize);
+    outlen = inlen;
+    out = buffer;
 }
 
-unsigned rtlUtf8Size(unsigned len, const void * _data)
+#ifdef _USE_ICU
+unsigned rtlUnicodeStrlen(UChar const * str)
 {
-    const byte * data = (const byte *)_data;
-    size32_t offset = 0;
-    for (unsigned i=0; i< len; i++)
-        offset += readUtf8Size(data+offset);
-    return offset;
+    return u_strlen(str);
 }
-
-unsigned rtlUtf8Length(unsigned size, const void * _data)
+#else
+unsigned rtlUnicodeStrlen(UChar const * str)
 {
-    const byte * data = (const byte *)_data;
-    size32_t length = 0;
-    for (unsigned offset=0; offset < size; offset += readUtf8Size(data+offset))
-        length++;
-    return length;
+    unsigned len = 0;
+    while (*str++)
+        len++;
+    return len;
 }
+#endif
 
-unsigned rtlUtf8Char(const void * data)
-{
-    return readUtf8Char(data);
-}
+//---------------------------------------------------------------------------
 
 void rtlUtf8ToData(size32_t outlen, void * out, size32_t inlen, const char *in)
 {
@@ -4418,32 +4650,6 @@ void rtlStrToUtf8X(size32_t & outlen, char * & out, size32_t inlen, const char *
     outlen = rtlUtf8Length(outsize, out);
 }
 
-void rtlUtf8ToUtf8(size32_t outlen, char * out, size32_t inlen, const char *in)
-{
-    //Packs as many characaters as it can into the target, but don't include any half characters
-    size32_t offset = 0;
-    size32_t outsize = outlen*UTF8_MAXSIZE;
-    for (unsigned i=0; i< inlen; i++)
-    {
-        unsigned nextSize = readUtf8Size(in+offset);
-        if (offset + nextSize > outsize)
-            break;
-        offset += nextSize;
-    }
-    memcpy(out, in, offset);
-    if (offset != outsize)
-        memset(out+offset, ' ', outsize-offset);
-}
-
-void rtlUtf8ToUtf8X(size32_t & outlen, char * & out, size32_t inlen, const char *in)
-{
-    unsigned insize = rtlUtf8Size(inlen, in);
-    char * buffer = (char *)rtlMalloc(insize);
-    memcpy(buffer, in, insize);
-    outlen = inlen;
-    out = buffer;
-}
-
 static int rtlCompareUtf8Utf8ViaUnicode(size32_t llen, const char * left, size32_t rlen, const char * right, const char * locale)
 {
     rtlDataAttr uleft(llen*sizeof(UChar));
@@ -4453,6 +4659,7 @@ static int rtlCompareUtf8Utf8ViaUnicode(size32_t llen, const char * left, size32
     return rtlCompareUnicodeUnicode(llen, uleft.getustr(), rlen, uright.getustr(), locale);
 }
 
+#ifdef _USE_ICU
 int rtlCompareUtf8Utf8(size32_t llen, const char * left, size32_t rlen, const char * right, const char * locale)
 {
     //MORE: Do a simple comparison as long as there are no non->0x80 characters around
@@ -4494,6 +4701,16 @@ int rtlCompareUtf8Utf8Strength(size32_t llen, const char * left, size32_t rlen,
     rtlUtf8ToUnicode(rlen, uright.getustr(), rlen, right);
     return rtlCompareUnicodeUnicodeStrength(llen, uleft.getustr(), rlen, uright.getustr(), locale, strength);
 }
+#else
+int rtlCompareUtf8Utf8(size32_t llen, const char * left, size32_t rlen, const char * right, const char * locale)
+{
+    return rtlCompareStrStr(rtlUtf8Size(llen, left), left, rtlUtf8Size(rlen, right), right);
+}
+int rtlCompareUtf8Utf8Strength(size32_t llen, const char * left, size32_t rlen, const char * right, const char * locale, unsigned strength)
+{
+    return rtlCompareUtf8Utf8(llen, left, rlen, right, locale);
+}
+#endif
 
 void rtlDecPushUtf8(size32_t len, const char * data)
 {
@@ -4625,6 +4842,7 @@ ECLRTL_API void rtlUtf8ToLower(size32_t l, char * t, char const * locale)
     }
 }
 
+#ifdef _USE_ICU
 ECLRTL_API void rtlConcatUtf8(unsigned & tlen, char * * tgt, ...)
 {
     //Going to have to go via unicode because of normalization.  However, it might be worth optimizing the case where no special characters are present
@@ -4697,6 +4915,11 @@ ECLRTL_API void rtlUtf8SpaceFill(unsigned tlen, char * tgt, unsigned offset)
     //no special characters=>easy route.
     memset(tgt+offset, ' ', tlen*UTF8_MAXSIZE-offset);
 }
+#else
+
+ECLRTL_API void rtlConcatUtf8(unsigned & tlen, char * * tgt, ...) { throw MakeStringException(99, "System was built without Unicode support"); }
+
+#endif
 
 ECLRTL_API unsigned rtlHash32Utf8(unsigned length, const char * k, unsigned initval)
 {
@@ -4935,6 +5158,7 @@ ECLRTL_API size32_t rtlCountToSize(unsigned count, const void * data, IRecordSiz
 
 //---------------------------------------------------------------------------
 
+#ifdef _USE_ICU
 class rtlCodepageConverter
 {
 public:
@@ -5015,6 +5239,26 @@ unsigned rtlCodepageConvert(void * converter, unsigned targetLength, char * targ
 {
     return ((rtlCodepageConverter *)converter)->convert(targetLength, target, sourceLength, source, failed);
 }
+#else
+void * rtlOpenCodepageConverter(char const * sourceName, char const * targetName, bool & failed)
+{
+    throw MakeStringException(99, "System was built without Unicode support");
+}
+
+void rtlCloseCodepageConverter(void * converter)
+{
+}
+
+void rtlCodepageConvertX(void * converter, unsigned & targetLength, char * & target, unsigned sourceLength, char const * source, bool & failed, bool preflight)
+{
+}
+
+unsigned rtlCodepageConvert(void * converter, unsigned targetLength, char * target, unsigned sourceLength, char const * source, bool & failed)
+{
+    return 0;
+}
+
+#endif
 
 //---------------------------------------------------------------------------
 

+ 4 - 0
rtl/eclrtl/eclrtl.hpp

@@ -28,7 +28,11 @@
 #ifndef U_OVERRIDE_CXX_ALLOCATION
 #define U_OVERRIDE_CXX_ALLOCATION 0 // Enabling this forces all allocation of ICU objects to ICU's heap, but is incompatible with jmemleak
 #endif //U_OVERRIDE_CXX_ALLOCATION
+#ifdef _USE_ICU
 #include "unicode/utf.h"
+#else
+typedef unsigned short UChar;
+#endif
 #endif //CHEAP_UCHAR_DEF
 
 #if !defined(ECLRTL_LOCAL)

+ 0 - 8
rtl/eclrtl/rtlqstr.cpp

@@ -26,14 +26,6 @@
 #include "jptree.hpp"
 #include "eclrtl.hpp"
 #include "rtlbcd.hpp"
-#include "unicode/uchar.h"
-#include "unicode/ucol.h"
-#include "unicode/ustring.h"
-#include "unicode/ucnv.h"
-#include "unicode/schriter.h"
-#include "unicode/regex.h"
-#include "unicode/normlzr.h"
-#include "unicode/locid.h"
 #include "jlog.hpp"
 #include "jmd5.hpp"
 

+ 0 - 8
rtl/eclrtl/rtlxml.cpp

@@ -26,14 +26,6 @@
 #include "jptree.hpp"
 #include "eclrtl.hpp"
 #include "rtlbcd.hpp"
-#include "unicode/uchar.h"
-#include "unicode/ucol.h"
-#include "unicode/ustring.h"
-#include "unicode/ucnv.h"
-#include "unicode/schriter.h"
-#include "unicode/regex.h"
-#include "unicode/normlzr.h"
-#include "unicode/locid.h"
 #include "jlog.hpp"
 #include "jmd5.hpp"
 #include "rtlqstr.ipp"

+ 4 - 0
rtl/include/eclhelper.hpp

@@ -34,7 +34,11 @@ if the supplied pointer was not from the roxiemem heap. Usually an OwnedRoxieStr
 
 #include "jscm.hpp"
 #ifndef CHEAP_UCHAR_DEF
+#ifdef _USE_ICU
 #include "unicode/utf.h"
+#else
+typedef unsigned short UChar;
+#endif
 #endif
 
 //Should be incremented whenever the virtuals in the context or a helper are changed, so