diff options
author | Jose <jose@zeroc.com> | 2009-11-10 05:30:26 +0100 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2009-11-10 05:30:26 +0100 |
commit | 4247c9e2c2612394a5f4d63a65ba538f975906d4 (patch) | |
tree | 96d3308681d9b0684ce5dd763f5a5d415eaf09d7 /cpp | |
parent | Win32 64 bits compilation error (diff) | |
download | ice-4247c9e2c2612394a5f4d63a65ba538f975906d4.tar.bz2 ice-4247c9e2c2612394a5f4d63a65ba538f975906d4.tar.xz ice-4247c9e2c2612394a5f4d63a65ba538f975906d4.zip |
Fixed 3962 - Berkeley DB, problems with unicode paths.
Diffstat (limited to 'cpp')
73 files changed, 1339 insertions, 618 deletions
diff --git a/cpp/include/Ice/Application.h b/cpp/include/Ice/Application.h index 926ea24bf3c..d910eaa249f 100644 --- a/cpp/include/Ice/Application.h +++ b/cpp/include/Ice/Application.h @@ -67,12 +67,21 @@ public: // are printed if exceptions propagate to main(), and the // Communicator is always destroyed, regardless of exceptions. // - int main(int, char*[], const char*); int main(int, char*[], const Ice::InitializationData& = Ice::InitializationData()); - int main(int, char* const[], const char*); - int main(int, char* const[], const Ice::InitializationData& = Ice::InitializationData()); - int main(const StringSeq&, const char*); + int main(int, char*[], const char*); + + int main(int, char* const [], const Ice::InitializationData& = Ice::InitializationData()); + int main(int, char* const [], const char*); + +#ifdef _WIN32 + + int main(int, wchar_t*[], const Ice::InitializationData& = Ice::InitializationData()); + int main(int, wchar_t*[], const char*); + +#endif + int main(const StringSeq&, const Ice::InitializationData& = Ice::InitializationData()); + int main(const StringSeq&, const char*); virtual int run(int, char*[]) = 0; diff --git a/cpp/include/Ice/Initialize.h b/cpp/include/Ice/Initialize.h index b44e4d057a1..6c2798a866c 100644 --- a/cpp/include/Ice/Initialize.h +++ b/cpp/include/Ice/Initialize.h @@ -25,6 +25,15 @@ namespace Ice ICE_API void collectGarbage(); ICE_API StringSeq argsToStringSeq(int, char*[]); + +#ifdef _WIN32 + +ICE_API StringSeq argsToStringSeq(int, wchar_t*[]); + +ICE_API StringSeq argsToStringSeq(int, wchar_t*[], const StringConverterPtr&); + +#endif + // // This function assumes that the string sequence only contains // elements of the argument vector. The function shifts the diff --git a/cpp/include/Ice/Service.h b/cpp/include/Ice/Service.h index 8cf0a87e130..9f255384077 100644 --- a/cpp/include/Ice/Service.h +++ b/cpp/include/Ice/Service.h @@ -60,6 +60,13 @@ public: // EXIT_SUCCESS. // int main(int&, char*[], const InitializationData& = InitializationData()); + +#ifdef _WIN32 + + int main(int&, wchar_t*[], const InitializationData& = InitializationData()); + +#endif + int main(StringSeq&, const InitializationData& = InitializationData()); // diff --git a/cpp/include/Ice/StringConverter.h b/cpp/include/Ice/StringConverter.h index 4166ad7f781..501156ec8c7 100644 --- a/cpp/include/Ice/StringConverter.h +++ b/cpp/include/Ice/StringConverter.h @@ -124,5 +124,38 @@ public: virtual void destroy(); }; +// +// Converts the given string from the native narrow string encoding to +// UTF8 using the given converter. If the converter is null, returns +// the given string. +// +ICE_API std::string +nativeToUTF8(const Ice::StringConverterPtr&, const std::string&); + +// +// Converts the given string from the native narrow string encoding to +// UTF8 using the communicator's converter. If the converter is null, +// returns the given string. +// +ICE_API std::string +nativeToUTF8(const Ice::CommunicatorPtr&, const std::string&); + +// +// Converts the given string from UTF8 to the native narrow string +// encoding using the given converter. If the converter is null, +// returns the given string. +// +ICE_API std::string +UTF8ToNative(const Ice::StringConverterPtr&, const std::string&); + +// +// Converts the given string from UTF8 to the native narrow string +// encoding using the communicator's converter. If the converter is +// null, returns the given string. +// +ICE_API std::string +UTF8ToNative(const Ice::CommunicatorPtr&, const std::string&); + } + #endif diff --git a/cpp/include/IceUtil/FileUtil.h b/cpp/include/IceUtil/FileUtil.h index cb9199d2e1d..a4ae0d01af1 100644 --- a/cpp/include/IceUtil/FileUtil.h +++ b/cpp/include/IceUtil/FileUtil.h @@ -14,6 +14,7 @@ #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> +#include <fstream> namespace IceUtilInternal { @@ -60,7 +61,6 @@ typedef struct stat structstat; // OS stat // ICE_UTIL_API int stat(const std::string&, structstat*); - ICE_UTIL_API int remove(const std::string&); ICE_UTIL_API int rename(const std::string&, const std::string&); ICE_UTIL_API int rmdir(const std::string&); @@ -69,6 +69,54 @@ ICE_UTIL_API int mkdir(const std::string&, int); ICE_UTIL_API FILE* fopen(const std::string&, const std::string&); ICE_UTIL_API int open(const std::string&, int); ICE_UTIL_API int getcwd(std::string&); +ICE_UTIL_API int unlink(const std::string&); + +class ICE_UTIL_API ifstream : public std::ifstream +{ +public: + + ifstream(); + ifstream(const std::string&, std::ios_base::openmode mode = std::ios_base::in); +#ifdef _STLP_BEGIN_NAMESPACE + ~ifstream(); + void close(); +#endif + void open(const std::string&, std::ios_base::openmode mode = std::ios_base::in); + +private: + + // Hide const char* definitions since they shouldn't be used. + ifstream(const char*); + void open(const char*, std::ios_base::openmode mode = std::ios_base::in); + +#ifdef _STLP_BEGIN_NAMESPACE + int _fd; +#endif +}; + +class ICE_UTIL_API ofstream : public std::ofstream +{ +public: + + ofstream(); + ofstream(const std::string&, std::ios_base::openmode mode = std::ios_base::out); +#ifdef _STLP_BEGIN_NAMESPACE + ~ofstream(); + void close(); +#endif + void open(const std::string&, std::ios_base::openmode mode = std::ios_base::out); + +private: + + // Hide const char* definitions since they shouldn't be used. + ofstream(const char*); + void open(const char*, std::ios_base::openmode mode = std::ios_base::out); + +#ifdef _STLP_BEGIN_NAMESPACE + int _fd; +#endif +}; + }; #endif diff --git a/cpp/include/IceUtil/StringUtil.h b/cpp/include/IceUtil/StringUtil.h index 5ddf12b890d..4efd077dfb7 100644 --- a/cpp/include/IceUtil/StringUtil.h +++ b/cpp/include/IceUtil/StringUtil.h @@ -71,10 +71,14 @@ ICE_UTIL_API std::string errorToString(int); #endif // -// Functions to convert to to all lower/upper case +// Functions to convert to lower/upper case. These functions accept +// UTF8 string/characters but ignore non ASCII characters. Unlike, the +// C methods, these methods are not local dependent. // ICE_UTIL_API std::string toLower(const std::string&); ICE_UTIL_API std::string toUpper(const std::string&); +ICE_UTIL_API bool isAlpha(char); +ICE_UTIL_API bool isDigit(char); // // Remove all whitespace from a string diff --git a/cpp/include/IceXML/Parser.h b/cpp/include/IceXML/Parser.h index 1cab37b7eea..13004fc001b 100644 --- a/cpp/include/IceXML/Parser.h +++ b/cpp/include/IceXML/Parser.h @@ -144,7 +144,8 @@ public: class ICE_XML_API Parser { public: - static DocumentPtr parse(const std::string&); + + static DocumentPtr parse(const std::string&); // The given filename must be UTF-8 encoded static DocumentPtr parse(std::istream&); static void parse(const std::string&, Handler&); diff --git a/cpp/include/Slice/Preprocessor.h b/cpp/include/Slice/Preprocessor.h index b10333332a4..bff8b182a20 100644 --- a/cpp/include/Slice/Preprocessor.h +++ b/cpp/include/Slice/Preprocessor.h @@ -62,11 +62,7 @@ private: const std::string _fileName; const std::string _shortFileName; const std::vector<std::string> _args; -#ifdef _WIN32 - std::wstring _cppFile; -#else std::string _cppFile; -#endif FILE* _cppHandle; }; diff --git a/cpp/src/Freeze/EvictorI.cpp b/cpp/src/Freeze/EvictorI.cpp index 50e718ad3cd..5e6770fc713 100644 --- a/cpp/src/Freeze/EvictorI.cpp +++ b/cpp/src/Freeze/EvictorI.cpp @@ -15,6 +15,8 @@ #include <IceUtil/IceUtil.h> +#include <Ice/StringConverter.h> + #include <typeinfo> using namespace std; @@ -312,7 +314,8 @@ Freeze::EvictorIBase::allDbs() const try { Db db(_dbEnv->getEnv(), 0); - db.open(0, _filename.c_str(), 0, DB_UNKNOWN, DB_RDONLY, 0); + + db.open(0, Ice::nativeToUTF8(_communicator, _filename).c_str(), 0, DB_UNKNOWN, DB_RDONLY, 0); Dbc* dbc = 0; db.cursor(0, &dbc, 0); diff --git a/cpp/src/Freeze/IndexI.cpp b/cpp/src/Freeze/IndexI.cpp index 0115e58a7b2..9ae86a27f63 100644 --- a/cpp/src/Freeze/IndexI.cpp +++ b/cpp/src/Freeze/IndexI.cpp @@ -12,6 +12,8 @@ #include <Freeze/ObjectStore.h> #include <Freeze/EvictorI.h> +#include <Ice/StringConverter.h> + using namespace Freeze; using namespace Ice; using namespace std; @@ -354,7 +356,14 @@ Freeze::IndexI::associate(ObjectStoreBase* store, DbTxn* txn, flags = DB_CREATE; } - _db->open(txn, store->evictor()->filename().c_str(), _dbName.c_str(), DB_BTREE, flags, FREEZE_DB_MODE); + // + // We keep _dbName as a native string here, while it might have + // been better to convert it to UTF-8, changing this isn't + // possible without potentially breaking backward compatibility + // with deployed databases. + // + _db->open(txn, Ice::nativeToUTF8(store->communicator(), store->evictor()->filename()).c_str(), _dbName.c_str(), + DB_BTREE, flags, FREEZE_DB_MODE); flags = 0; if(populateIndex) diff --git a/cpp/src/Freeze/MapDb.cpp b/cpp/src/Freeze/MapDb.cpp index 1978575c40a..408d3ea19d6 100644 --- a/cpp/src/Freeze/MapDb.cpp +++ b/cpp/src/Freeze/MapDb.cpp @@ -14,6 +14,8 @@ #include <Freeze/CatalogIndexList.h> #include <algorithm> +#include <Ice/StringConverter.h> + using namespace std; using namespace Ice; using namespace Freeze; @@ -179,7 +181,8 @@ Freeze::MapDb::MapDb(const ConnectionIPtr& connection, { flags |= DB_CREATE; } - open(txn, _dbName.c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE); + + open(txn, Ice::nativeToUTF8(_communicator, _dbName).c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE); StringSeq oldIndices; @@ -420,7 +423,8 @@ Freeze::MapDb::MapDb(const Ice::CommunicatorPtr& communicator, const string& dbN } u_int32_t flags = DB_THREAD | DB_CREATE | DB_AUTO_COMMIT; - open(0, _dbName.c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE); + + open(0, Ice::nativeToUTF8(_communicator, _dbName).c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE); } catch(const ::DbException& dx) { diff --git a/cpp/src/Freeze/MapI.cpp b/cpp/src/Freeze/MapI.cpp index 9f92b12de32..443f353b402 100644 --- a/cpp/src/Freeze/MapI.cpp +++ b/cpp/src/Freeze/MapI.cpp @@ -17,6 +17,8 @@ #include <IceUtil/UUID.h> #include <stdlib.h> +#include <Ice/StringConverter.h> + using namespace std; using namespace Ice; using namespace Freeze; @@ -200,7 +202,10 @@ Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, // Fortunately, DB closes oldDb automatically when it goes out of scope // Db oldDb(connectionI->dbEnv()->getEnv(), 0); - oldDb.open(txn, oldDbName.c_str(), 0, DB_BTREE, DB_THREAD, FREEZE_DB_MODE); + + + oldDb.open(txn, Ice::nativeToUTF8(connectionI->communicator(), oldDbName).c_str(), 0, DB_BTREE, + DB_THREAD, FREEZE_DB_MODE); auto_ptr<MapDb> newDb(new MapDb(connectionI, dbName, key, value, keyCompare, indices, true)); @@ -1675,7 +1680,8 @@ Freeze::MapIndexI::MapIndexI(const ConnectionIPtr& connection, MapDb& db, out << "Opening index \"" << _dbName << "\""; } - _db->open(txn, _dbName.c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE); + _db->open(txn, Ice::nativeToUTF8(connection->communicator(), _dbName).c_str(), 0, DB_BTREE, flags, + FREEZE_DB_MODE); // // To populate empty indices diff --git a/cpp/src/Freeze/ObjectStore.cpp b/cpp/src/Freeze/ObjectStore.cpp index 8e433b9eae9..0811507bfb4 100644 --- a/cpp/src/Freeze/ObjectStore.cpp +++ b/cpp/src/Freeze/ObjectStore.cpp @@ -15,6 +15,8 @@ #include <Freeze/TransactionI.h> #include <Freeze/IndexI.h> +#include <Ice/StringConverter.h> + using namespace std; using namespace Ice; using namespace Freeze; @@ -120,7 +122,14 @@ Freeze::ObjectStoreBase::ObjectStoreBase(const string& facet, const string& face flags |= DB_CREATE; } - _db->open(txn, evictor->filename().c_str(), _dbName.c_str(), DB_BTREE, flags, FREEZE_DB_MODE); + // + // We keep _dbName as a native string here, while it might have + // been better to convert it to UTF-8, changing this isn't + // possible without potentially breaking backward compatibility + // with deployed databases. + // + _db->open(txn, Ice::nativeToUTF8(evictor->communicator(), evictor->filename()).c_str(), _dbName.c_str(), + DB_BTREE, flags, FREEZE_DB_MODE); for(size_t i = 0; i < _indices.size(); ++i) { diff --git a/cpp/src/Freeze/SharedDbEnv.cpp b/cpp/src/Freeze/SharedDbEnv.cpp index 87b596dc86e..764662d9386 100644 --- a/cpp/src/Freeze/SharedDbEnv.cpp +++ b/cpp/src/Freeze/SharedDbEnv.cpp @@ -19,6 +19,8 @@ #include <IceUtil/MutexPtrTryLock.h> #include <IceUtil/IceUtil.h> +#include <Ice/StringConverter.h> + #include <cstdlib> #include <memory> @@ -553,8 +555,8 @@ Freeze::SharedDbEnv::SharedDbEnv(const std::string& envName, string dbHome = properties->getPropertyWithDefault( propertyPrefix + ".DbHome", envName); - - _env->open(dbHome.c_str(), flags, FREEZE_DB_MODE); + + _env->open(Ice::nativeToUTF8(_communicator, dbHome).c_str(), flags, FREEZE_DB_MODE); // // Default checkpoint period is every 120 seconds diff --git a/cpp/src/FreezeScript/DumpDB.cpp b/cpp/src/FreezeScript/DumpDB.cpp index 3c4e8ad2871..9787261c473 100644 --- a/cpp/src/FreezeScript/DumpDB.cpp +++ b/cpp/src/FreezeScript/DumpDB.cpp @@ -12,9 +12,9 @@ #include <FreezeScript/Exception.h> #include <IceUtil/OutputUtil.h> #include <IceUtil/Options.h> +#include <IceUtil/FileUtil.h> #include <db_cxx.h> #include <sys/stat.h> -#include <fstream> #include <algorithm> using namespace std; @@ -77,7 +77,7 @@ private: } static void -usage(const char* n) +usage(const string& n) { cerr << "Usage:\n"; cerr << "\n"; @@ -123,7 +123,7 @@ printCatalogData(const string& dbName, const Freeze::CatalogData& data) } static int -run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) +run(const Ice::StringSeq& originalArgs, const Ice::CommunicatorPtr& communicator) { vector<string> cppArgs; bool debug; @@ -136,7 +136,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) string valueTypeName; string selectExpr; string dbEnvName, dbName; - + const string appName = originalArgs[0]; IceUtilInternal::Options opts; opts.addOpt("h", "help"); opts.addOpt("v", "version"); @@ -157,18 +157,18 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) vector<string> args; try { - args = opts.parse(argc, (const char**)argv); + args = opts.parse(originalArgs); } catch(const IceUtilInternal::BadOptException& e) { - cerr << argv[0] << ": " << e.reason << endl; - usage(argv[0]); + cerr << appName << ": " << e.reason << endl; + usage(appName); return EXIT_FAILURE; } if(opts.isSet("h")) { - usage(argv[0]); + usage(appName); return EXIT_SUCCESS; } if(opts.isSet("version")) @@ -180,13 +180,13 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) { if(args.empty()) { - cerr << argv[0] << ": no database environment specified." << endl; - usage(argv[0]); + cerr << appName << ": no database environment specified." << endl; + usage(appName); return EXIT_FAILURE; } else if(args.size() > 2) { - usage(argv[0]); + usage(appName); return EXIT_FAILURE; } try @@ -213,7 +213,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) FreezeScript::CatalogDataMap::const_iterator p = catalog.find(args[1]); if(p == catalog.end()) { - cerr << argv[0] << ": database `" << args[1] << "' not found in environment `" << args[0] << "'." + cerr << appName << ": database `" << args[1] << "' not found in environment `" << args[0] << "'." << endl; return EXIT_FAILURE; } @@ -226,7 +226,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } catch(const FreezeScript::FailureException& ex) { - cerr << argv[0] << ": " << ex.reason() << endl; + cerr << appName << ": " << ex.reason() << endl; return EXIT_FAILURE; } } @@ -290,7 +290,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) if(outputFile.empty() && args.size() != 2) { - usage(argv[0]); + usage(appName); return EXIT_FAILURE; } @@ -304,19 +304,19 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } else { - usage(argv[0]); + usage(appName); return EXIT_FAILURE; } if(!inputFile.empty() && !selectExpr.empty()) { - cerr << argv[0] << ": an input file cannot be specified with --select" << endl; + cerr << appName << ": an input file cannot be specified with --select" << endl; return EXIT_FAILURE; } Slice::UnitPtr unit = Slice::Unit::createUnit(true, true, ice); FreezeScript::Destroyer<Slice::UnitPtr> unitD(unit); - if(!FreezeScript::parseSlice(argv[0], unit, slice, cppArgs, debug)) + if(!FreezeScript::parseSlice(appName, unit, slice, cppArgs, debug)) { return EXIT_FAILURE; } @@ -334,8 +334,8 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) if((!keyTypeName.empty() && valueTypeName.empty()) || (keyTypeName.empty() && !valueTypeName.empty())) { - cerr << argv[0] << ": a key type and a value type must be specified" << endl; - usage(argv[0]); + cerr << appName << ": a key type and a value type must be specified" << endl; + usage(appName); return EXIT_FAILURE; } else if(!evictor && keyTypeName.empty() && valueTypeName.empty()) @@ -346,7 +346,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) FreezeScript::CatalogDataMap::iterator p = catalog.find(dbName); if(p == catalog.end()) { - cerr << argv[0] << ": database `" << dbName << "' not found in catalog." << endl; + cerr << appName << ": database `" << dbName << "' not found in catalog." << endl; cerr << "Current catalog databases:" << endl; for(p = catalog.begin(); p != catalog.end(); ++p) { @@ -369,7 +369,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } catch(const FreezeScript::FailureException& ex) { - cerr << argv[0] << ": " << ex.reason() << endl; + cerr << appName << ": " << ex.reason() << endl; return EXIT_FAILURE; } } @@ -386,7 +386,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) l = unit->lookupType(keyTypeName, false); if(l.empty()) { - cerr << argv[0] << ": unknown key type `" << keyTypeName << "'" << endl; + cerr << appName << ": unknown key type `" << keyTypeName << "'" << endl; return EXIT_FAILURE; } keyType = l.front(); @@ -394,7 +394,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) l = unit->lookupType(valueTypeName, false); if(l.empty()) { - cerr << argv[0] << ": unknown value type `" << valueTypeName << "'" << endl; + cerr << appName << ": unknown value type `" << valueTypeName << "'" << endl; return EXIT_FAILURE; } valueType = l.front(); @@ -413,10 +413,14 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) if(!outputFile.empty()) { - ofstream of(outputFile.c_str()); + // + // No nativeToUTF8 conversion necessary here, no string converter is installed + // by wmain() on Windows and args are assumbed to be UTF8 on Unix platforms. + // + IceUtilInternal::ofstream of(outputFile); if(!of.good()) { - cerr << argv[0] << ": unable to open file `" << outputFile << "'" << endl; + cerr << appName << ": unable to open file `" << outputFile << "'" << endl; return EXIT_FAILURE; } of << descriptors << endl; @@ -426,7 +430,11 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } else { - ifstream in(inputFile.c_str()); + // + // No nativeToUTF8 conversion necessary here, no string converter is installed + // by wmain() on Windows and args are assumbed to be UTF8 on Unix platforms. + // + IceUtilInternal::ifstream in(inputFile); char buff[1024]; while(true) { @@ -540,7 +548,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } catch(const DbException& ex) { - cerr << argv[0] << ": database error: " << ex.what() << endl; + cerr << appName << ": database error: " << ex.what() << endl; status = EXIT_FAILURE; } catch(...) @@ -555,7 +563,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } catch(const DbException& ex) { - cerr << argv[0] << ": database error: " << ex.what() << endl; + cerr << appName << ": database error: " << ex.what() << endl; } throw; } @@ -570,27 +578,40 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } catch(const DbException& ex) { - cerr << argv[0] << ": database error: " << ex.what() << endl; + cerr << appName << ": database error: " << ex.what() << endl; status = EXIT_FAILURE; } return status; } +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) + +#endif { + Ice::StringSeq args = Ice::argsToStringSeq(argc, argv); + assert(args.size() > 0); + const string appName = args[0]; Ice::CommunicatorPtr communicator; int status = EXIT_SUCCESS; try { - communicator = Ice::initialize(argc, argv); - status = run(argc, argv, communicator); + communicator = Ice::initialize(args); + status = run(args, communicator); } catch(const FreezeScript::FailureException& ex) { string reason = ex.reason(); - cerr << argv[0] << ": " << reason; + cerr << appName << ": " << reason; if(reason[reason.size() - 1] != '\n') { cerr << endl; @@ -599,7 +620,7 @@ main(int argc, char* argv[]) } catch(const IceUtil::Exception& ex) { - cerr << argv[0] << ": " << ex << endl; + cerr << appName << ": " << ex << endl; return EXIT_FAILURE; } diff --git a/cpp/src/FreezeScript/transformdb.cpp b/cpp/src/FreezeScript/transformdb.cpp index 060b7b7a26f..e68fdbe5475 100644 --- a/cpp/src/FreezeScript/transformdb.cpp +++ b/cpp/src/FreezeScript/transformdb.cpp @@ -15,9 +15,9 @@ #include <Freeze/Transaction.h> #include <Freeze/Catalog.h> #include <IceUtil/Options.h> +#include <IceUtil/FileUtil.h> #include <db_cxx.h> #include <sys/stat.h> -#include <fstream> #include <algorithm> using namespace std; @@ -29,9 +29,8 @@ using namespace std; #endif static void -usage(const char* n) +usage(const std::string& n) { - cerr << "Usage:\n"; cerr << "\n"; cerr << n << " -o FILE [-i] [slice-options] [type-options]\n"; @@ -212,7 +211,7 @@ transformDb(bool evictor, const Ice::CommunicatorPtr& communicator, } static int -run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) +run(const Ice::StringSeq& originalArgs, const Ice::CommunicatorPtr& communicator) { vector<string> oldCppArgs; vector<string> newCppArgs; @@ -253,21 +252,22 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) opts.addOpt("", "key", IceUtilInternal::Options::NeedArg); opts.addOpt("", "value", IceUtilInternal::Options::NeedArg); + const string appName = originalArgs[0]; vector<string> args; try { - args = opts.parse(argc, (const char**)argv); + args = opts.parse(originalArgs); } catch(const IceUtilInternal::BadOptException& e) { - cerr << argv[0] << ": " << e.reason << endl; - usage(argv[0]); + cerr << appName << ": " << e.reason << endl; + usage(appName); return EXIT_FAILURE; } if(opts.isSet("help")) { - usage(argv[0]); + usage(appName); return EXIT_SUCCESS; } if(opts.isSet("version")) @@ -357,7 +357,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } else if(args.size() != 3) { - usage(argv[0]); + usage(appName); return EXIT_FAILURE; } } @@ -369,20 +369,20 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } else if(args.size() != 0) { - usage(argv[0]); + usage(appName); return EXIT_FAILURE; } } if(allDb && (!keyTypeNames.empty() || !valueTypeNames.empty())) { - usage(argv[0]); + usage(appName); return EXIT_FAILURE; } if(inputFile.empty() && !allDb && !evictor && (keyTypeNames.empty() || valueTypeNames.empty())) { - usage(argv[0]); + usage(appName); return EXIT_FAILURE; } @@ -407,21 +407,21 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } if(args.size() > 3) { - cerr << argv[0] << ": too many arguments" << endl; - usage(argv[0]); + cerr << appName << ": too many arguments" << endl; + usage(appName); return EXIT_FAILURE; } Slice::UnitPtr oldUnit = Slice::Unit::createUnit(true, true, ice); FreezeScript::Destroyer<Slice::UnitPtr> oldD(oldUnit); - if(!FreezeScript::parseSlice(argv[0], oldUnit, oldSlice, oldCppArgs, debug)) + if(!FreezeScript::parseSlice(appName, oldUnit, oldSlice, oldCppArgs, debug)) { return EXIT_FAILURE; } Slice::UnitPtr newUnit = Slice::Unit::createUnit(true, true, ice); FreezeScript::Destroyer<Slice::UnitPtr> newD(newUnit); - if(!FreezeScript::parseSlice(argv[0], newUnit, newSlice, newCppArgs, debug)) + if(!FreezeScript::parseSlice(appName, newUnit, newSlice, newCppArgs, debug)) { return EXIT_FAILURE; } @@ -444,12 +444,12 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } catch(const FreezeScript::FailureException& ex) { - cerr << argv[0] << ": " << ex.reason() << endl; + cerr << appName << ": " << ex.reason() << endl; return EXIT_FAILURE; } if(catalog.empty()) { - cerr << argv[0] << ": no databases in environment `" << dbEnvName << "'" << endl; + cerr << appName << ": no databases in environment `" << dbEnvName << "'" << endl; return EXIT_FAILURE; } } @@ -496,25 +496,25 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) Slice::TypePtr oldKeyType = findType(oldUnit, keyName); if(!oldKeyType) { - cerr << argv[0] << ": type `" << keyName << "' from database `" << p->first + cerr << appName << ": type `" << keyName << "' from database `" << p->first << "' not found in old Slice definitions" << endl; } Slice::TypePtr newKeyType = findType(newUnit, keyName); if(!newKeyType) { - cerr << argv[0] << ": type `" << keyName << "' from database `" << p->first + cerr << appName << ": type `" << keyName << "' from database `" << p->first << "' not found in new Slice definitions" << endl; } Slice::TypePtr oldValueType = findType(oldUnit, valueName); if(!oldValueType) { - cerr << argv[0] << ": type `" << valueName << "' from database `" << p->first + cerr << appName << ": type `" << valueName << "' from database `" << p->first << "' not found in old Slice definitions" << endl; } Slice::TypePtr newValueType = findType(newUnit, valueName); if(!newValueType) { - cerr << argv[0] << ": type `" << valueName << "' from database `" << p->first + cerr << appName << ": type `" << valueName << "' from database `" << p->first << "' not found in new Slice definitions" << endl; } @@ -550,14 +550,14 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) if(keyTypeNames.empty() || valueTypeNames.empty()) { - usage(argv[0]); + usage(appName); return EXIT_FAILURE; } pos = keyTypeNames.find(','); if(pos == 0 || pos == keyTypeNames.size()) { - usage(argv[0]); + usage(appName); return EXIT_FAILURE; } if(pos == string::npos) @@ -574,7 +574,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) pos = valueTypeNames.find(','); if(pos == 0 || pos == valueTypeNames.size()) { - usage(argv[0]); + usage(appName); return EXIT_FAILURE; } if(pos == string::npos) @@ -595,22 +595,22 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) Slice::TypePtr oldKeyType = findType(oldUnit, oldKeyName); if(!oldKeyType) { - cerr << argv[0] << ": type `" << oldKeyName << "' not found in old Slice definitions" << endl; + cerr << appName << ": type `" << oldKeyName << "' not found in old Slice definitions" << endl; } Slice::TypePtr newKeyType = findType(newUnit, newKeyName); if(!newKeyType) { - cerr << argv[0] << ": type `" << newKeyName << "' not found in new Slice definitions" << endl; + cerr << appName << ": type `" << newKeyName << "' not found in new Slice definitions" << endl; } Slice::TypePtr oldValueType = findType(oldUnit, oldValueName); if(!oldValueType) { - cerr << argv[0] << ": type `" << oldValueName << "' not found in old Slice definitions" << endl; + cerr << appName << ": type `" << oldValueName << "' not found in old Slice definitions" << endl; } Slice::TypePtr newValueType = findType(newUnit, newValueName); if(!newValueType) { - cerr << argv[0] << ": type `" << newValueName << "' not found in new Slice definitions" << endl; + cerr << appName << ": type `" << newValueName << "' not found in new Slice definitions" << endl; } // @@ -630,7 +630,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) { for(vector<string>::const_iterator p = analyzeErrors.begin(); p != analyzeErrors.end(); ++p) { - cerr << argv[0] << ": " << *p << endl; + cerr << appName << ": " << *p << endl; } } @@ -658,10 +658,14 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) if(!outputFile.empty()) { - ofstream of(outputFile.c_str()); + // + // No nativeToUTF8 conversion necessary here, no string converter is installed + // by wmain() on Windows and args are assumbed to be UTF8 on Unix platforms. + // + IceUtilInternal::ofstream of(outputFile); if(!of.good()) { - cerr << argv[0] << ": unable to open file `" << outputFile << "'" << endl; + cerr << appName << ": unable to open file `" << outputFile << "'" << endl; return EXIT_FAILURE; } of << descriptors; @@ -674,7 +678,10 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) // // Read the input file. // - ifstream in(inputFile.c_str()); + // No nativeToUTF8 conversion necessary here, no string converter is installed + // by wmain() on Windows and args are assumbed to be UTF8 on Unix platforms. + // + IceUtilInternal::ifstream in(inputFile); char buff[1024]; while(true) { @@ -690,7 +697,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) if(dbEnvName == dbEnvNameNew) { - cerr << argv[0] << ": database environment names must be different" << endl; + cerr << appName << ": database environment names must be different" << endl; return EXIT_FAILURE; } @@ -776,7 +783,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } catch(const DbException& ex) { - cerr << argv[0] << ": database error: " << ex.what() << endl; + cerr << appName << ": database error: " << ex.what() << endl; status = EXIT_FAILURE; } catch(...) @@ -816,7 +823,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } catch(const DbException& ex) { - cerr << argv[0] << ": database error: " << ex.what() << endl; + cerr << appName << ": database error: " << ex.what() << endl; } throw; } @@ -848,7 +855,7 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) } catch(const DbException& ex) { - cerr << argv[0] << ": database error: " << ex.what() << endl; + cerr << appName << ": database error: " << ex.what() << endl; status = EXIT_FAILURE; } } @@ -880,20 +887,32 @@ run(int argc, char** argv, const Ice::CommunicatorPtr& communicator) return status; } +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) +#endif { + Ice::StringSeq args = Ice::argsToStringSeq(argc, argv); + assert(args.size() > 0); + const string appName = args[0]; Ice::CommunicatorPtr communicator; int status = EXIT_SUCCESS; try { - communicator = Ice::initialize(argc, argv); - status = run(argc, argv, communicator); + communicator = Ice::initialize(args); + status = run(args, communicator); } catch(const FreezeScript::FailureException& ex) { string reason = ex.reason(); - cerr << argv[0] << ": " << reason; + cerr << appName << ": " << reason; if(reason[reason.size() - 1] != '\n') { cerr << endl; @@ -902,17 +921,17 @@ main(int argc, char* argv[]) } catch(const IceUtil::Exception& ex) { - cerr << argv[0] << ": " << ex << endl; + cerr << appName << ": " << ex << endl; status = EXIT_FAILURE; } catch(const std::exception& ex) { - cerr << argv[0] << ": " << ex.what() << endl; + cerr << appName << ": " << ex.what() << endl; status = EXIT_FAILURE; } catch(...) { - cerr << argv[0] << ": unknown exception" << endl; + cerr << appName << ": unknown exception" << endl; status = EXIT_FAILURE; } @@ -923,3 +942,4 @@ main(int argc, char* argv[]) return status; } + diff --git a/cpp/src/Glacier2/Glacier2Router.cpp b/cpp/src/Glacier2/Glacier2Router.cpp index f0bfe9a9097..b4135fd076a 100644 --- a/cpp/src/Glacier2/Glacier2Router.cpp +++ b/cpp/src/Glacier2/Glacier2Router.cpp @@ -10,13 +10,13 @@ #include <IceUtil/DisableWarnings.h> #include <IceUtil/UUID.h> #include <IceUtil/Options.h> +#include <IceUtil/FileUtil.h> #include <Ice/Service.h> #include <Glacier2/Instance.h> #include <Glacier2/RouterI.h> #include <Glacier2/Session.h> #include <Glacier2/SessionRouterI.h> #include <Glacier2/CryptPermissionsVerifierI.h> -#include <fstream> using namespace std; using namespace Ice; @@ -269,7 +269,12 @@ Glacier2::RouterService::start(int argc, char* argv[], int& status) } else if(!passwordsProperty.empty()) { - ifstream passwordFile(passwordsProperty.c_str()); + // + // No nativeToUTF8 conversion necessary here, since no string + // converter is installed by Glacier2 the string is UTF-8. + // + IceUtilInternal::ifstream passwordFile(passwordsProperty); + if(!passwordFile) { string err = strerror(errno); @@ -607,8 +612,18 @@ Glacier2::RouterService::usage(const string& appName) print("Usage: " + appName + " [options]\n" + options); } +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) + +#endif { Glacier2::RouterService svc; return svc.main(argc, argv); diff --git a/cpp/src/Ice/Application.cpp b/cpp/src/Ice/Application.cpp index 91b77569524..a0598649082 100644 --- a/cpp/src/Ice/Application.cpp +++ b/cpp/src/Ice/Application.cpp @@ -337,6 +337,26 @@ Ice::Application::main(int argc, char* argv[], const char* configFile) return main(argc, argv, initData); } +#ifdef _WIN32 + +int +Ice::Application::main(int argc, wchar_t* argv[], const char* config) +{ + return main(argsToStringSeq(argc, argv), config); +} + +int +Ice::Application::main(int argc, wchar_t* argv[], const Ice::InitializationData& initData) +{ + // + // On Windows the given wchar_t* strings are UTF16 and therefore + // needs to be converted to native narow string encoding. + // + return main(argsToStringSeq(argc, argv, initData.stringConverter), initData); +} + +#endif + int Ice::Application::main(int argc, char* argv[], const InitializationData& initData) { @@ -687,7 +707,7 @@ Ice::Application::doMain(int argc, char* argv[], const InitializationData& initi } if(IceInternal::Application::_communicator != 0) - { + { try { IceInternal::Application::_communicator->destroy(); diff --git a/cpp/src/Ice/Initialize.cpp b/cpp/src/Ice/Initialize.cpp index f126fbe48ce..8afd1df630d 100644 --- a/cpp/src/Ice/Initialize.cpp +++ b/cpp/src/Ice/Initialize.cpp @@ -51,6 +51,29 @@ Ice::argsToStringSeq(int argc, char* argv[]) return result; } +#ifdef _WIN32 + +StringSeq +Ice::argsToStringSeq(int argc, wchar_t* argv[]) +{ + return argsToStringSeq(argc, argv, 0); +} + +StringSeq +Ice::argsToStringSeq(int argc, wchar_t* argv[], const StringConverterPtr& converter) +{ + StringSeq args; + for(int i=0; argv[i] != 0; i++) + { + string value = IceUtil::wstringToString(argv[i]); + value = Ice::UTF8ToNative(converter, value); + args.push_back(value); + } + return args; +} + +#endif + void Ice::stringSeqToArgs(const StringSeq& args, int& argc, char* argv[]) { diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp index 17ed6098795..4b03230f149 100644 --- a/cpp/src/Ice/Instance.cpp +++ b/cpp/src/Ice/Instance.cpp @@ -399,6 +399,15 @@ IceInternal::Instance::flushBatchRequests() Identity IceInternal::Instance::stringToIdentity(const string& s) const { + // + // This method only accepts printable ascii. Since printable ascii is a subset + // of all narrow string encodings, it is not necessary to convert the string + // from the native string encoding. Any characters other than printable-ASCII + // will cause an IllegalArgumentException. Note that it can contain Unicode + // encoded in the escaped form which is the reason why we call fromUTF8 after + // unespcaping the printable ASCII string. + // + Identity ident; // @@ -454,26 +463,8 @@ IceInternal::Instance::stringToIdentity(const string& s) const } } - if(_initData.stringConverter) - { - string tmpString; - if(!ident.name.empty()) - { - _initData.stringConverter->fromUTF8(reinterpret_cast<const Byte*>(ident.name.data()), - reinterpret_cast<const Byte*>(ident.name.data() + ident.name.size()), - tmpString); - ident.name = tmpString; - } - - if(!ident.category.empty()) - { - _initData.stringConverter->fromUTF8(reinterpret_cast<const Byte*>(ident.category.data()), - reinterpret_cast<const Byte*>(ident.category.data() + - ident.category.size()), - tmpString); - ident.category = tmpString; - } - } + ident.name = Ice::UTF8ToNative(_initData.stringConverter, ident.name); + ident.category = Ice::UTF8ToNative(_initData.stringConverter, ident.category); return ident; } @@ -481,27 +472,12 @@ IceInternal::Instance::stringToIdentity(const string& s) const string IceInternal::Instance::identityToString(const Identity& ident) const { - string name = ident.name; - string category = ident.category; - if(_initData.stringConverter) - { - UTF8BufferI buffer; - Byte* last; - if(!ident.name.empty()) - { - last = _initData.stringConverter->toUTF8(ident.name.data(), ident.name.data() + ident.name.size(), - buffer); - name = string(reinterpret_cast<const char*>(buffer.getBuffer()), last - buffer.getBuffer()); - } - - buffer.reset(); - if(!ident.category.empty()) - { - last = _initData.stringConverter->toUTF8(ident.category.data(), - ident.category.data() + ident.category.size(), buffer); - category = string(reinterpret_cast<const char*>(buffer.getBuffer()), last - buffer.getBuffer()); - } - } + // + // This method returns the stringified identity. The returned string only + // contains printable ascii. It can contain UTF8 in the escaped form. + // + string name = Ice::nativeToUTF8(_initData.stringConverter, ident.name); + string category = Ice::nativeToUTF8(_initData.stringConverter, ident.category); if(category.empty()) { @@ -802,8 +778,14 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi #ifdef _LARGEFILE64_SOURCE FILE* file = freopen64(stdOutFilename.c_str(), "a", stdout); #else +#ifdef _WIN32 + FILE* file = _wfreopen(IceUtil::stringToWstring(nativeToUTF8(_initData.stringConverter, + stdOutFilename)).c_str(), + L"a", stdout); +#else FILE* file = freopen(stdOutFilename.c_str(), "a", stdout); #endif +#endif if(file == 0) { FileException ex(__FILE__, __LINE__); @@ -818,8 +800,14 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi #ifdef _LARGEFILE64_SOURCE FILE* file = freopen64(stdErrFilename.c_str(), "a", stderr); #else +#ifdef _WIN32 + FILE* file = _wfreopen(IceUtil::stringToWstring(nativeToUTF8(_initData.stringConverter, + stdErrFilename)).c_str(), + L"a", stderr); +#else FILE* file = freopen(stdErrFilename.c_str(), "a", stderr); #endif +#endif if(file == 0) { FileException ex(__FILE__, __LINE__); @@ -924,7 +912,8 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi #endif if(!logfile.empty()) { - _initData.logger = new LoggerI(_initData.properties->getProperty("Ice.ProgramName"), logfile); + _initData.logger = new LoggerI(_initData.properties->getProperty("Ice.ProgramName"), + nativeToUTF8(_initData.stringConverter, logfile)); } else { diff --git a/cpp/src/Ice/LoggerI.cpp b/cpp/src/Ice/LoggerI.cpp index d270d2a3e4c..b218628f9c4 100644 --- a/cpp/src/Ice/LoggerI.cpp +++ b/cpp/src/Ice/LoggerI.cpp @@ -11,6 +11,7 @@ #include <Ice/LoggerI.h> #include <IceUtil/Mutex.h> #include <IceUtil/MutexPtrLock.h> +#include <Ice/StringConverter.h> #include <Ice/LocalException.h> using namespace std; @@ -51,8 +52,12 @@ Ice::LoggerI::LoggerI(const string& prefix, const string& file) if(!file.empty()) { + // + // The given file string is execpted to be encoded as UTF8 by + // the caller, so no need to convert it here. + // _file = file; - _out.open(_file.c_str(), fstream::out | fstream::app); + _out.open(file, fstream::out | fstream::app); if(!_out.is_open()) { throw InitializationException(__FILE__, __LINE__, "FileLogger: cannot open " + _file); diff --git a/cpp/src/Ice/LoggerI.h b/cpp/src/Ice/LoggerI.h index 880922b5150..42341698c8f 100644 --- a/cpp/src/Ice/LoggerI.h +++ b/cpp/src/Ice/LoggerI.h @@ -11,8 +11,7 @@ #define ICE_LOGGER_I_H #include <Ice/Logger.h> - -#include <fstream> +#include <IceUtil/FileUtil.h> namespace Ice { @@ -35,7 +34,7 @@ private: void write(const std::string&, bool); std::string _prefix; - std::fstream _out; + IceUtilInternal::ofstream _out; std::string _file; }; diff --git a/cpp/src/Ice/PropertiesI.cpp b/cpp/src/Ice/PropertiesI.cpp index 0939ee3eada..1973b5ffef4 100644 --- a/cpp/src/Ice/PropertiesI.cpp +++ b/cpp/src/Ice/PropertiesI.cpp @@ -9,6 +9,7 @@ #include <IceUtil/DisableWarnings.h> #include <IceUtil/StringUtil.h> +#include <IceUtil/FileUtil.h> #include <Ice/PropertiesI.h> #include <Ice/Initialize.h> #include <Ice/LocalException.h> @@ -16,7 +17,7 @@ #include <Ice/Logger.h> #include <Ice/LoggerUtil.h> #include <Ice/Communicator.h> -#include <fstream> +#include <Ice/StringConverter.h> using namespace std; using namespace Ice; @@ -162,16 +163,15 @@ Ice::PropertiesI::setProperty(const string& key, const string& value) { string pattern(IceInternal::PropertyNames::validProps[i].properties[0].pattern); - dotPos = pattern.find('.'); - // - // Each top level prefix describes a non-empty - // namespace. Having a string without a prefix followed by a - // dot is an error. - // + // + // Each top level prefix describes a non-empty + // namespace. Having a string without a prefix followed by a + // dot is an error. + // assert(dotPos != string::npos); - + string propPrefix = pattern.substr(0, dotPos); if(propPrefix != prefix) { @@ -196,7 +196,7 @@ Ice::PropertiesI::setProperty(const string& key, const string& value) } if(!found) { - logger->warning("unknown property: " + currentKey); + logger->warning("unknown property: `" + currentKey + "'"); } } } @@ -286,59 +286,105 @@ void Ice::PropertiesI::load(const std::string& file) { #ifdef _WIN32 - if(file.find("HKLM\\") == 0 || file.find("HKCU\\") == 0) + if(file.find("HKLM\\") == 0) { - HKEY key; - if(file.find("HKLM\\") == 0) - { - key = HKEY_LOCAL_MACHINE; - } - else - { - key = HKEY_CURRENT_USER; - } - HKEY iceKey; - if(RegOpenKey(key, file.substr(5).c_str(), &iceKey) != ERROR_SUCCESS) + const wstring keyName = IceUtil::stringToWstring(Ice::nativeToUTF8(_converter, file).substr(5)).c_str(); + LONG err; + if((err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName.c_str(), 0, KEY_QUERY_VALUE, &iceKey)) != ERROR_SUCCESS) { InitializationException ex(__FILE__, __LINE__); - ex.reason = "Could not open Windows registry key `" + file + "'"; + ex.reason = "could not open Windows registry key `" + file + "':\n" + IceUtilInternal::errorToString(err); throw ex; } + DWORD maxNameSize; // Size in characters not including terminating null character. + DWORD maxDataSize; // Size in bytes DWORD numValues; - if(RegQueryInfoKey(iceKey, NULL, NULL, NULL, NULL, NULL, NULL, &numValues, NULL, NULL, NULL, NULL) == - ERROR_SUCCESS) + try { - if(numValues > 0) + err = RegQueryInfoKey(iceKey, NULL, NULL, NULL, NULL, NULL, NULL, &numValues, &maxNameSize, &maxDataSize, + NULL, NULL); + if(err != ERROR_SUCCESS) + { + InitializationException ex(__FILE__, __LINE__); + ex.reason = "could not open Windows registry key `" + file + "':\n"; + ex.reason += IceUtilInternal::errorToString(err); + throw ex; + } + + for(DWORD i = 0; i < numValues; ++i) { - for(DWORD i = 0; i < numValues; ++i) + vector<wchar_t> nameBuf(maxNameSize + 1); + vector<BYTE> dataBuf(maxDataSize); + DWORD keyType; + DWORD nameBufSize = nameBuf.size(); + DWORD dataBufSize = dataBuf.size(); + err = RegEnumValueW(iceKey, i, &nameBuf[0], &nameBufSize, NULL, &keyType, &dataBuf[0], &dataBufSize); + if(err != ERROR_SUCCESS || nameBufSize == 0) { - char keyBuf[256]; - DWORD keyBufSize = sizeof(keyBuf); - if(RegEnumValue(iceKey, i, keyBuf, &keyBufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + ostringstream os; + os << "could not read Windows registry property name, key: `" + file + "', index: " << i << ":\n"; + if(nameBufSize == 0) { - char valueBuf[256]; - DWORD valueBufSize = sizeof(valueBuf); - DWORD keyType; - if(RegQueryValueEx(iceKey, keyBuf, 0, &keyType, (BYTE*)valueBuf, &valueBufSize) == - ERROR_SUCCESS) + os << "property name can't be the empty string"; + } + else + { + os << IceUtilInternal::errorToString(err); + } + getProcessLogger()->warning(os.str()); + continue; + } + string name = IceUtil::wstringToString(wstring(reinterpret_cast<wchar_t*>(&nameBuf[0]), nameBufSize)); + name = Ice::UTF8ToNative(_converter, name); + if(keyType != REG_SZ && keyType != REG_EXPAND_SZ) + { + ostringstream os; + os << "unsupported type for Windows registry property `" + name + "' key: `" + file + "'"; + getProcessLogger()->warning(os.str()); + continue; + } + + string value; + wstring valueW = wstring(reinterpret_cast<wchar_t*>(&dataBuf[0]), (dataBufSize / sizeof(wchar_t)) - 1); + if(keyType == REG_SZ) + { + value = IceUtil::wstringToString(valueW); + } + else // keyType == REG_EXPAND_SZ + { + vector<wchar_t> expandedValue(1024); + DWORD sz = ExpandEnvironmentStringsW(valueW.c_str(), &expandedValue[0], expandedValue.size()); + if(sz >= expandedValue.size()) + { + expandedValue.resize(sz + 1); + if(ExpandEnvironmentStringsW(valueW.c_str(), &expandedValue[0], expandedValue.size()) == 0) { - if(keyType == REG_SZ) - { - setProperty(keyBuf, valueBuf); - } + ostringstream os; + os << "could not expand variable in property `" << name << "', key: `" + file + "':\n"; + os << IceUtilInternal::lastErrorToString(); + getProcessLogger()->warning(os.str()); + continue; } } + value = IceUtil::wstringToString(wstring(&expandedValue[0], sz -1)); } + value = Ice::UTF8ToNative(_converter, value); + setProperty(name, value); } } + catch(...) + { + RegCloseKey(iceKey); + throw; + } RegCloseKey(iceKey); } else #endif { - ifstream in(file.c_str()); + IceUtilInternal::ifstream in(Ice::nativeToUTF8(_converter, file)); if(!in) { FileException ex(__FILE__, __LINE__); @@ -398,7 +444,6 @@ Ice::PropertiesI::PropertiesI(StringSeq& args, const PropertiesPtr& defaults, co StringSeq::iterator q = args.begin(); - map<string, PropertyValue>::iterator p = _properties.find("Ice.ProgramName"); if(p == _properties.end()) { @@ -627,21 +672,9 @@ Ice::PropertiesI::parseLine(const string& line, const StringConverterPtr& conver return; } - if(converter) - { - string tmp; - converter->fromUTF8(reinterpret_cast<const Byte*>(key.data()), - reinterpret_cast<const Byte*>(key.data() + key.size()), tmp); - key.swap(tmp); + key = Ice::UTF8ToNative(converter, key); + value = Ice::UTF8ToNative(converter, value); - if(!value.empty()) - { - converter->fromUTF8(reinterpret_cast<const Byte*>(value.data()), - reinterpret_cast<const Byte*>(value.data() + value.size()), tmp); - value.swap(tmp); - } - } - setProperty(key, value); } @@ -649,14 +682,31 @@ void Ice::PropertiesI::loadConfig() { string value = getProperty("Ice.Config"); - if(value.empty() || value == "1") { - const char* s = getenv("ICE_CONFIG"); - if(s && *s != '\0') +#ifdef _WIN32 + vector<wchar_t> v(256); + DWORD ret = GetEnvironmentVariableW(L"ICE_CONFIG", &v[0], v.size()); + if(ret >= v.size()) { - value = s; + v.resize(ret + 1); + ret = GetEnvironmentVariableW(L"ICE_CONFIG", &v[0], v.size()); } + if(ret > 0) + { + value = Ice::UTF8ToNative(_converter, IceUtil::wstringToString(wstring(&v[0], ret))); + } + else + { + value = ""; + } +#else + const char* s = getenv("ICE_CONFIG"); + if(s && *s != '\0') + { + value = s; + } +#endif } if(!value.empty()) @@ -693,7 +743,7 @@ Ice::PropertiesI::loadConfig() Ice::PropertiesAdminI::PropertiesAdminI(const PropertiesPtr& properties) : _properties(properties) -{ +{ } string diff --git a/cpp/src/Ice/Proxy.cpp b/cpp/src/Ice/Proxy.cpp index d8cbf2894f7..e13ea2ef1ab 100644 --- a/cpp/src/Ice/Proxy.cpp +++ b/cpp/src/Ice/Proxy.cpp @@ -109,6 +109,11 @@ IceProxy::Ice::Object::ice_getCommunicator() const string IceProxy::Ice::Object::ice_toString() const { + // + // Returns the stringified proxy. There's no need to convert the + // string to a native string: a stringified proxy only contains + // printable ASCII which is a subset of all native character sets. + // return _reference->toString(); } diff --git a/cpp/src/Ice/Reference.cpp b/cpp/src/Ice/Reference.cpp index 7bffecdd084..6c59ef62da7 100644 --- a/cpp/src/Ice/Reference.cpp +++ b/cpp/src/Ice/Reference.cpp @@ -220,14 +220,7 @@ IceInternal::Reference::toString() const // the reference parser uses as separators, then we enclose // the facet string in quotes. // - string fs = _facet; - if(_instance->initializationData().stringConverter) - { - UTF8BufferI buffer; - Byte* last = - _instance->initializationData().stringConverter->toUTF8(fs.data(), fs.data() + fs.size(), buffer); - fs = string(reinterpret_cast<const char*>(buffer.getBuffer()), last - buffer.getBuffer()); - } + string fs = Ice::nativeToUTF8(_instance->initializationData().stringConverter, _facet); fs = IceUtilInternal::escapeString(fs, ""); if(fs.find_first_of(" :@") != string::npos) { @@ -1114,14 +1107,7 @@ IceInternal::RoutableReference::toString() const // reference parser uses as separators, then we enclose the // adapter id string in quotes. // - string a = _adapterId; - StringConverterPtr stringConverter = getInstance()->initializationData().stringConverter; - if(stringConverter) - { - UTF8BufferI buffer; - Byte* last = stringConverter->toUTF8(a.data(), a.data() + a.size(), buffer); - a = string(reinterpret_cast<const char*>(buffer.getBuffer()), last - buffer.getBuffer()); - } + string a = Ice::nativeToUTF8(getInstance()->initializationData().stringConverter, _adapterId); a = IceUtilInternal::escapeString(a, ""); if(a.find_first_of(" :@") != string::npos) { @@ -1131,7 +1117,7 @@ IceInternal::RoutableReference::toString() const } else { - result.append(_adapterId); + result.append(a); } } else diff --git a/cpp/src/Ice/ReferenceFactory.cpp b/cpp/src/Ice/ReferenceFactory.cpp index 6dc659b9f63..fb6c0d0327d 100644 --- a/cpp/src/Ice/ReferenceFactory.cpp +++ b/cpp/src/Ice/ReferenceFactory.cpp @@ -279,15 +279,7 @@ IceInternal::ReferenceFactory::create(const string& str, const string& propertyP throw ex; } - if(_instance->initializationData().stringConverter) - { - string tmpFacet; - _instance->initializationData().stringConverter->fromUTF8( - reinterpret_cast<const Byte*>(facet.data()), - reinterpret_cast<const Byte*>(facet.data() + facet.size()), tmpFacet); - facet = tmpFacet; - } - + facet = Ice::UTF8ToNative(_instance->initializationData().stringConverter, facet); break; } @@ -515,15 +507,8 @@ IceInternal::ReferenceFactory::create(const string& str, const string& propertyP throw ex; } - if(_instance->initializationData().stringConverter && !adapter.empty()) - { - string tmpAdapter; - _instance->initializationData().stringConverter->fromUTF8( - reinterpret_cast<const Byte*>(adapter.data()), - reinterpret_cast<const Byte*>(adapter.data() + adapter.size()), tmpAdapter); - adapter = tmpAdapter; - } - + adapter = Ice::UTF8ToNative(_instance->initializationData().stringConverter, adapter); + return create(ident, facet, mode, secure, vector<EndpointIPtr>(), adapter, propertyPrefix); break; } diff --git a/cpp/src/Ice/ServantManager.cpp b/cpp/src/Ice/ServantManager.cpp index 080ba9ee042..3fbd1d1fc22 100644 --- a/cpp/src/Ice/ServantManager.cpp +++ b/cpp/src/Ice/ServantManager.cpp @@ -47,7 +47,8 @@ IceInternal::ServantManager::addServant(const ObjectPtr& object, const Identity& ex.id = _instance->identityToString(ident); if(!facet.empty()) { - ex.id += " -f " + IceUtilInternal::escapeString(facet, ""); + string fs = nativeToUTF8(_instance->initializationData().stringConverter, facet); + ex.id += " -f " + IceUtilInternal::escapeString(fs, ""); } throw ex; } @@ -106,7 +107,8 @@ IceInternal::ServantManager::removeServant(const Identity& ident, const string& ex.id = _instance->identityToString(ident); if(!facet.empty()) { - ex.id += " -f " + IceUtilInternal::escapeString(facet, ""); + string fs = nativeToUTF8(_instance->initializationData().stringConverter, facet); + ex.id += " -f " + IceUtilInternal::escapeString(fs, ""); } throw ex; } @@ -333,7 +335,7 @@ IceInternal::ServantManager::addServantLocator(const ServantLocatorPtr& locator, { AlreadyRegisteredException ex(__FILE__, __LINE__); ex.kindOfObject = "servant locator"; - ex.id = IceUtilInternal::escapeString(category, ""); + ex.id = category; throw ex; } @@ -365,7 +367,7 @@ IceInternal::ServantManager::removeServantLocator(const string& category) { NotRegisteredException ex(__FILE__, __LINE__); ex.kindOfObject = "servant locator"; - ex.id = IceUtilInternal::escapeString(category, ""); + ex.id = category; throw ex; } diff --git a/cpp/src/Ice/Service.cpp b/cpp/src/Ice/Service.cpp index 1e92791064d..7aa1217673b 100644 --- a/cpp/src/Ice/Service.cpp +++ b/cpp/src/Ice/Service.cpp @@ -14,9 +14,11 @@ #include <IceUtil/Monitor.h> #include <IceUtil/Mutex.h> #include <IceUtil/ArgVector.h> +#include <IceUtil/FileUtil.h> #include <Ice/Service.h> #include <Ice/LoggerI.h> #include <Ice/Initialize.h> +#include <Ice/StringConverter.h> #include <Ice/Communicator.h> #include <Ice/LocalException.h> #include <Ice/Properties.h> @@ -30,7 +32,6 @@ # include <sys/types.h> # include <sys/stat.h> # include <csignal> -# include <fstream> #endif using namespace std; @@ -835,6 +836,25 @@ Ice::Service::main(int& argc, char* argv[], const InitializationData& initializa return run(argc, argv, initData); } +#ifdef _WIN32 + +int +Ice::Service::main(int& argc, wchar_t* argv[], const InitializationData& initializationData) +{ +#ifdef __BCPLUSPLUS__ // COMPILER FIX + // + //BCC don't see the main overload if we don't create the temp args object here. + // + Ice::StringSeq args = Ice::argsToStringSeq(argc, argv, initializationData.stringConverter); + return main(args, initializationData); +#else + return main(Ice::argsToStringSeq(argc, argv, initializationData.stringConverter), initializationData); +#endif + +} + +#endif + int Ice::Service::main(StringSeq& args, const InitializationData& initData) { @@ -2125,7 +2145,7 @@ Ice::Service::runDaemon(int argc, char* argv[], const InitializationData& initDa // if(_pidFile.size() > 0) { - ofstream of(_pidFile.c_str()); + IceUtilInternal::ofstream of(Ice::nativeToUTF8(_communicator, _pidFile)); of << getpid() << endl; if(!of) diff --git a/cpp/src/Ice/StringConverter.cpp b/cpp/src/Ice/StringConverter.cpp index 3485a19c7e3..cf30a6ff9ce 100644 --- a/cpp/src/Ice/StringConverter.cpp +++ b/cpp/src/Ice/StringConverter.cpp @@ -252,7 +252,7 @@ createIceStringConverter(const CommunicatorPtr& communicator, const string& name { if(args[i].find("windows=") == 0) { - cp = atoi(args[i].substr(strlen("windows=")).c_str()); + cp = atoi(args[i].substr(strlen("windows=")).c_str()); } else if(args[i].find("iconv=") != 0) { @@ -342,3 +342,47 @@ createIceStringConverter(const CommunicatorPtr& communicator, const string& name } } +string +Ice::nativeToUTF8(const Ice::StringConverterPtr& converter, const string& str) +{ + if(!converter) + { + return str; + } + if(str.empty()) + { + return str; + } + IceInternal::UTF8BufferI buffer; + Ice::Byte* last = converter->toUTF8(str.data(), str.data() + str.size(), buffer); + return string(reinterpret_cast<const char*>(buffer.getBuffer()), last - buffer.getBuffer()); +} + +string +Ice::nativeToUTF8(const Ice::CommunicatorPtr& ic, const string& str) +{ + return nativeToUTF8(IceInternal::getInstance(ic)->initializationData().stringConverter, str); +} + +string +Ice::UTF8ToNative(const Ice::StringConverterPtr& converter, const string& str) +{ + if(!converter) + { + return str; + } + if(str.empty()) + { + return str; + } + string tmp; + converter->fromUTF8(reinterpret_cast<const Ice::Byte*>(str.data()), + reinterpret_cast<const Ice::Byte*>(str.data() + str.size()), tmp); + return tmp; +} + +string +Ice::UTF8ToNative(const Ice::CommunicatorPtr& ic, const std::string& str) +{ + return UTF8ToNative(IceInternal::getInstance(ic)->initializationData().stringConverter, str); +} diff --git a/cpp/src/IceBox/Admin.cpp b/cpp/src/IceBox/Admin.cpp index 2a77a8629ba..85a1bd8025a 100644 --- a/cpp/src/IceBox/Admin.cpp +++ b/cpp/src/IceBox/Admin.cpp @@ -23,13 +23,21 @@ public: virtual int run(int, char*[]); }; +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) + +#endif { Client app; - int rc = app.main(argc, argv); - - return rc; + return app.main(argc, argv); } void diff --git a/cpp/src/IceBox/Service.cpp b/cpp/src/IceBox/Service.cpp index 8c44fe7f37b..6a3d3614edb 100644 --- a/cpp/src/IceBox/Service.cpp +++ b/cpp/src/IceBox/Service.cpp @@ -136,8 +136,18 @@ IceBox::IceBoxService::usage(const string& appName) print("Usage: " + appName + " [options]\n" + options); } +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) + +#endif { IceBox::IceBoxService svc; diff --git a/cpp/src/IceGrid/Activator.cpp b/cpp/src/IceGrid/Activator.cpp index ff069bf89dd..800d095b1af 100644 --- a/cpp/src/IceGrid/Activator.cpp +++ b/cpp/src/IceGrid/Activator.cpp @@ -29,7 +29,6 @@ # include <sys/wait.h> # include <signal.h> #else -# include <direct.h> // For _getcwd #ifndef SIGKILL # define SIGKILL 9 #endif @@ -43,6 +42,8 @@ using namespace Ice; using namespace IceInternal; using namespace IceGrid; +#define ICE_STRING(X) #X + namespace IceGrid { @@ -67,13 +68,6 @@ private: Activator& _activator; }; -} - -#define ICE_STRING(X) #X - -namespace IceGrid -{ - #ifndef _WIN32 // // Helper function for async-signal safe error reporting @@ -268,6 +262,21 @@ stringToSignal(const string& str) } } +#ifdef _WIN32 +struct UnicodeStringLess +{ + +bool +operator()(const wstring& lhs, const wstring& rhs) const +{ + int r = CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, lhs.c_str(), -1, rhs.c_str(), -1); + assert(r > 0); + return r == CSTR_LESS_THAN; +} + +}; +#endif + } Activator::Activator(const TraceLevelsPtr& traceLevels) : @@ -355,10 +364,10 @@ Activator::activate(const string& name, // // Get the absolute pathname of the executable. // - char absbuf[_MAX_PATH]; - char* filePart; - string ext = path.size() <= 4 || path[path.size() - 4] != '.' ? ".exe" : ""; - if(SearchPath(NULL, path.c_str(), ext.c_str(), _MAX_PATH, absbuf, &filePart) == 0) + wchar_t absbuf[_MAX_PATH]; + wchar_t* fPart; + wstring ext = path.size() <= 4 || path[path.size() - 4] != '.' ? L".exe" : L""; + if(SearchPathW(NULL, IceUtil::stringToWstring(path).c_str(), ext.c_str(), _MAX_PATH, absbuf, &fPart) == 0) { if(_traceLevels->activator > 0) { @@ -367,7 +376,7 @@ Activator::activate(const string& name, } throw string("Couldn't find `" + path + "' executable."); } - path = absbuf; + path = IceUtil::wstringToString(absbuf); } else if(!pwd.empty()) { @@ -380,8 +389,8 @@ Activator::activate(const string& name, // if(!pwd.empty()) { - char absbuf[_MAX_PATH]; - if(_fullpath(absbuf, pwd.c_str(), _MAX_PATH) == NULL) + wchar_t absbuf[_MAX_PATH]; + if(_wfullpath(absbuf, IceUtil::stringToWstring(pwd).c_str(), _MAX_PATH) == NULL) { if(_traceLevels->activator > 0) { @@ -390,7 +399,7 @@ Activator::activate(const string& name, } throw string("The server working directory path `" + pwd + "' can't be converted into an absolute path."); } - pwd = absbuf; + pwd = IceUtil::wstringToString(absbuf); } #endif @@ -400,7 +409,7 @@ Activator::activate(const string& name, StringSeq args; args.push_back(path); args.insert(args.end(), options.begin(), options.end()); - + if(_traceLevels->activator > 0) { Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); @@ -411,15 +420,10 @@ Activator::activate(const string& name, out << "path = " << path << "\n"; if(pwd.empty()) { -#ifdef _WIN32 - char cwd[_MAX_PATH]; - if(_getcwd(cwd, _MAX_PATH) != NULL) -#else - char cwd[PATH_MAX]; - if(getcwd(cwd, PATH_MAX) != NULL) -#endif + string cwd; + if(IceUtilInternal::getcwd(cwd) == 0) { - out << "pwd = " << string(cwd) << "\n"; + out << "pwd = " << cwd << "\n"; } } else @@ -471,23 +475,16 @@ Activator::activate(const string& name, } } - const char* dir; - if(!pwd.empty()) - { - dir = pwd.c_str(); - } - else - { - dir = NULL; - } + wstring wpwd = IceUtil::stringToWstring(pwd); + const wchar_t* dir = !wpwd.empty() ? wpwd.c_str() : NULL; // // Make a copy of the command line. // #if defined(_MSC_VER) && (_MSC_VER >= 1400) - char* cmdbuf = _strdup(cmd.c_str()); + wchar_t* cmdbuf = _wcsdup(IceUtil::stringToWstring(cmd).c_str()); #else - char* cmdbuf = strdup(cmd.c_str()); + wchar_t* cmdbuf = wcsdup(IceUtil::stringToWstring(cmd).c_str()); #endif // @@ -496,75 +493,72 @@ Activator::activate(const string& name, // Since Windows is case insensitive wrt environment variables we convert the keys to // uppercase to ensure matches are found. // - const char* env = NULL; - string envbuf; + const wchar_t* env = NULL; + wstring envbuf; if(!envs.empty()) { - map<string, string> envMap; - LPVOID parentEnv = GetEnvironmentStrings(); - const char* var = reinterpret_cast<const char*>(parentEnv); - if(*var == '=') + map<wstring, wstring, UnicodeStringLess> envMap; + LPVOID parentEnv = GetEnvironmentStringsW(); + const wchar_t* var = reinterpret_cast<const wchar_t*>(parentEnv); + if(*var == L'=') { // // The environment block may start with some information about the // current drive and working directory. This is indicated by a leading // '=' character, so we skip to the first '\0' byte. // - while(*var) + while(*var != L'\0') var++; var++; } - while(*var) + while(*var != L'\0') { - string s(var); - string::size_type pos = s.find('='); - if(pos != string::npos) + wstring s(var); + wstring::size_type pos = s.find(L'='); + if(pos != wstring::npos) { - string key = IceUtilInternal::toUpper(s.substr(0, pos)); - envMap.insert(map<string, string>::value_type(key, s.substr(pos + 1))); + envMap[s.substr(0, pos)] = s.substr(pos + 1); } var += s.size(); var++; // Skip the '\0' byte } - FreeEnvironmentStrings(static_cast<char*>(parentEnv)); + FreeEnvironmentStringsW(static_cast<wchar_t*>(parentEnv)); for(p = envs.begin(); p != envs.end(); ++p) { - string s = *p; - string::size_type pos = s.find('='); - if(pos != string::npos) + wstring s = IceUtil::stringToWstring(*p); + wstring::size_type pos = s.find(L'='); + if(pos != wstring::npos) { - string key = IceUtilInternal::toUpper(s.substr(0, pos)); - envMap.erase(key); - envMap.insert(map<string, string>::value_type(key, s.substr(pos + 1))); + envMap[s.substr(0, pos)] = s.substr(pos + 1); } } - for(map<string, string>::const_iterator q = envMap.begin(); q != envMap.end(); ++q) + + for(map<wstring, wstring, UnicodeStringLess>::const_iterator q = envMap.begin(); q != envMap.end(); ++q) { envbuf.append(q->first); - envbuf.push_back('='); + envbuf.push_back(L'='); envbuf.append(q->second); - envbuf.push_back('\0'); + envbuf.push_back(L'\0'); } - envbuf.push_back('\0'); + envbuf.push_back(L'\0'); env = envbuf.c_str(); } Process process; - STARTUPINFO si; + STARTUPINFOW si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); - - BOOL b = CreateProcess( + BOOL b = CreateProcessW( NULL, // Executable cmdbuf, // Command line NULL, // Process attributes NULL, // Thread attributes FALSE, // Do NOT inherit handles - CREATE_NEW_PROCESS_GROUP, // Process creation flags + CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT, // Process creation flags (LPVOID)env, // Process environment dir, // Current directory &si, // Startup info @@ -583,7 +577,6 @@ Activator::activate(const string& name, // keep the thread handle, so we close it now. The process handle will be closed later. // CloseHandle(pi.hThread); - process.pid = pi.dwProcessId; process.hnd = pi.hProcess; diff --git a/cpp/src/IceGrid/Client.cpp b/cpp/src/IceGrid/Client.cpp index 7d107de0fa1..969fd81e248 100644 --- a/cpp/src/IceGrid/Client.cpp +++ b/cpp/src/IceGrid/Client.cpp @@ -156,8 +156,8 @@ class Client : public IceUtil::Monitor<IceUtil::Mutex> public: void usage(); - int main(int argc, char* argv[]); - int run(int, char*[]); + int main(Ice::StringSeq& args); + int run(Ice::StringSeq& args); void interrupted(); Ice::CommunicatorPtr communicator() const { return _communicator; } @@ -183,11 +183,22 @@ interruptCallback(int signal) } } +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) + +#endif { Client app; - return app.main(argc, argv); + Ice::StringSeq args = Ice::argsToStringSeq(argc, argv); + return app.main(args); } void @@ -208,15 +219,16 @@ Client::usage() ; } + int -Client::main(int argc, char* argv[]) +Client::main(Ice::StringSeq& args) { int status = EXIT_SUCCESS; try { - _appName = argv[0]; - _communicator = Ice::initialize(argc, argv); + _appName = args[0].c_str(); + _communicator = Ice::initialize(args); { IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(_staticMutex); @@ -226,7 +238,7 @@ Client::main(int argc, char* argv[]) try { - status = run(argc, argv); + status = run(args); } catch(const Ice::CommunicatorDestroyedException&) { @@ -310,7 +322,7 @@ Client::interrupted() } int -Client::run(int argc, char* argv[]) +Client::run(Ice::StringSeq& originalArgs) { string commands; bool debug; @@ -329,7 +341,7 @@ Client::run(int argc, char* argv[]) vector<string> args; try { - args = opts.parse(argc, (const char**)argv); + args = opts.parse(originalArgs); } catch(const IceUtilInternal::BadOptException& e) { @@ -339,7 +351,7 @@ Client::run(int argc, char* argv[]) } if(!args.empty()) { - cerr << argv[0] << ": too many arguments" << endl; + cerr << _appName << ": too many arguments" << endl; usage(); return EXIT_FAILURE; } @@ -416,13 +428,13 @@ Client::run(int argc, char* argv[]) router = Glacier2::RouterPrx::checkedCast(communicator()->getDefaultRouter()->ice_preferSecure(true)); if(!router) { - cerr << argv[0] << ": configured router is not a Glacier2 router" << endl; + cerr << _appName << ": configured router is not a Glacier2 router" << endl; return EXIT_FAILURE; } } catch(const Ice::LocalException& ex) { - cerr << argv[0] << ": could not contact the default router:" << endl << ex << endl; + cerr << _appName << ": could not contact the default router:" << endl << ex << endl; return EXIT_FAILURE; } @@ -431,7 +443,7 @@ Client::run(int argc, char* argv[]) session = AdminSessionPrx::uncheckedCast(router->createSessionFromSecureConnection()); if(!session) { - cerr << argv[0] + cerr << _appName << ": Glacier2 returned a null session, please set the Glacier2.SSLSessionManager property" << endl; return EXIT_FAILURE; @@ -469,7 +481,7 @@ Client::run(int argc, char* argv[]) } if(!session) { - cerr << argv[0] + cerr << _appName << ": Glacier2 returned a null session, please set the Glacier2.SessionManager property" << endl; return EXIT_FAILURE; @@ -502,14 +514,14 @@ Client::run(int argc, char* argv[]) locator = IceGrid::LocatorPrx::checkedCast(communicator()->getDefaultLocator()); if(!locator) { - cerr << argv[0] << ": configured locator is not an IceGrid locator" << endl; + cerr << _appName << ": configured locator is not an IceGrid locator" << endl; return EXIT_FAILURE; } localRegistry = locator->getLocalRegistry(); } catch(const Ice::LocalException& ex) { - cerr << argv[0] << ": could not contact the default locator:" << endl << ex << endl; + cerr << _appName << ": could not contact the default locator:" << endl << ex << endl; return EXIT_FAILURE; } @@ -530,19 +542,19 @@ Client::run(int argc, char* argv[]) registry = RegistryPrx::checkedCast(communicator()->stringToProxy(strId)); if(!registry) { - cerr << argv[0] << ": could not contact an IceGrid registry" << endl; + cerr << _appName << ": could not contact an IceGrid registry" << endl; } } catch(const Ice::NotRegisteredException&) { - cerr << argv[0] << ": no active registry replica named `" << replica << "'" << endl; + cerr << _appName << ": no active registry replica named `" << replica << "'" << endl; return EXIT_FAILURE; } catch(const Ice::LocalException& ex) { if(!replica.empty()) { - cerr << argv[0] << ": could not contact the registry replica named `" << replica << "':\n"; + cerr << _appName << ": could not contact the registry replica named `" << replica << "':\n"; cerr << ex << endl; return EXIT_FAILURE; } @@ -559,7 +571,7 @@ Client::run(int argc, char* argv[]) { name = name.substr(prefix.size()); } - cerr << argv[0] << ": warning: could not contact master, using slave `" << name << "'" << endl; + cerr << _appName << ": warning: could not contact master, using slave `" << name << "'" << endl; } } } @@ -622,7 +634,7 @@ Client::run(int argc, char* argv[]) } else // No default locator or router set. { - cerr << argv[0] << ": could not contact the registry:" << endl; + cerr << _appName << ": could not contact the registry:" << endl; cerr << "no default locator or router configured" << endl; return EXIT_FAILURE; } diff --git a/cpp/src/IceGrid/FileCache.cpp b/cpp/src/IceGrid/FileCache.cpp index ba232fe0289..2a813daf2d7 100644 --- a/cpp/src/IceGrid/FileCache.cpp +++ b/cpp/src/IceGrid/FileCache.cpp @@ -10,11 +10,12 @@ #include <Ice/Communicator.h> #include <Ice/Properties.h> +#include <IceUtil/FileUtil.h> + #include <IceGrid/FileCache.h> #include <IceGrid/Exception.h> #include <deque> -#include <fstream> using namespace std; using namespace IceGrid; @@ -27,7 +28,7 @@ FileCache::FileCache(const Ice::CommunicatorPtr& com) : Ice::Long FileCache::getOffsetFromEnd(const string& file, int originalCount) { - ifstream is(file.c_str()); + IceUtilInternal::ifstream is(file); // file is a UTF-8 string if(is.fail()) { throw FileNotAvailableException("failed to open file `" + file + "'"); @@ -139,7 +140,7 @@ FileCache::read(const string& file, Ice::Long offset, int size, Ice::Long& newOf throw FileNotAvailableException("maximum bytes per read request is too low"); } - ifstream is(file.c_str()); + IceUtilInternal::ifstream is(file); // file is a UTF-8 string if(is.fail()) { throw FileNotAvailableException("failed to open file `" + file + "'"); diff --git a/cpp/src/IceGrid/FileUserAccountMapperI.cpp b/cpp/src/IceGrid/FileUserAccountMapperI.cpp index 6fce0d6966f..247def1d6f2 100644 --- a/cpp/src/IceGrid/FileUserAccountMapperI.cpp +++ b/cpp/src/IceGrid/FileUserAccountMapperI.cpp @@ -8,16 +8,15 @@ // ********************************************************************** #include <IceUtil/DisableWarnings.h> +#include <IceUtil/FileUtil.h> #include <IceGrid/FileUserAccountMapperI.h> -#include <fstream> - using namespace std; using namespace IceGrid; FileUserAccountMapperI::FileUserAccountMapperI(const string& filename) { - ifstream file(filename.c_str()); + IceUtilInternal::ifstream file(filename); // filename is a UTF-8 string if(!file) { throw "cannot open `" + filename + "' for reading: " + strerror(errno); diff --git a/cpp/src/IceGrid/FreezeDB/FreezeDB.cpp b/cpp/src/IceGrid/FreezeDB/FreezeDB.cpp index ee0707d35d2..894d6e199a2 100644 --- a/cpp/src/IceGrid/FreezeDB/FreezeDB.cpp +++ b/cpp/src/IceGrid/FreezeDB/FreezeDB.cpp @@ -13,18 +13,7 @@ #include <IceGrid/FreezeDB/StringAdapterInfoDict.h> #include <IceGrid/FreezeDB/IdentityObjectInfoDict.h> -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef _WIN32 -# include <direct.h> -# ifdef _MSC_VER -# define S_ISDIR(mode) ((mode) & _S_IFDIR) -# define S_ISREG(mode) ((mode) & _S_IFREG) -# endif -#else -# include <unistd.h> -#endif +#include <IceUtil/FileUtil.h> using namespace IceGrid; using namespace std; @@ -146,8 +135,7 @@ FreezeDBPlugin::FreezeDBPlugin(const Ice::CommunicatorPtr& communicator) : _comm } else { - struct stat filestat; - if(stat(dbPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode)) + if(!IceUtilInternal::directoryExists(dbPath)) { ostringstream os; Ice::SyscallException ex(__FILE__, __LINE__); diff --git a/cpp/src/IceGrid/IceGridNode.cpp b/cpp/src/IceGrid/IceGridNode.cpp index 1e74f7800b7..15bc9b05a2f 100644 --- a/cpp/src/IceGrid/IceGridNode.cpp +++ b/cpp/src/IceGrid/IceGridNode.cpp @@ -10,6 +10,7 @@ #include <IceUtil/UUID.h> #include <IceUtil/Timer.h> #include <IceUtil/StringUtil.h> +#include <IceUtil/FileUtil.h> #include <Ice/Ice.h> #include <Ice/Locator.h> #include <Ice/Service.h> @@ -26,14 +27,7 @@ #ifdef _WIN32 # include <direct.h> # include <sys/types.h> -# include <sys/stat.h> # include <winsock2.h> -# ifdef _MSC_VER -# define S_ISDIR(mode) ((mode) & _S_IFDIR) -# define S_ISREG(mode) ((mode) & _S_IFREG) -# endif -#else -# include <sys/stat.h> #endif using namespace std; @@ -370,21 +364,7 @@ NodeService::startImpl(int argc, char* argv[], int& status) } else { -#ifdef _WIN32 - struct _stat filestat; - if(::_stat(dataPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode)) - { - ostringstream os; - FileException ex(__FILE__, __LINE__); - ex.path = dataPath; - ex.error = IceInternal::getSystemErrno(); - os << ex; - error("property `IceGrid.Node.Data' is set to an invalid path:\n" + os.str()); - return false; - } -#else - struct stat filestat; - if(::stat(dataPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode)) + if(!IceUtilInternal::directoryExists(dataPath)) { ostringstream os; FileException ex(__FILE__, __LINE__); @@ -393,8 +373,7 @@ NodeService::startImpl(int argc, char* argv[], int& status) os << ex; error("property `IceGrid.Node.Data' is set to an invalid path:\n" + os.str()); return false; - } -#endif + } // // Creates subdirectories. @@ -842,8 +821,18 @@ NodeService::usage(const string& appName) print("Usage: " + appName + " [options]\n" + options); } +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) + +#endif { NodeService svc; return svc.main(argc, argv); diff --git a/cpp/src/IceGrid/IceGridRegistry.cpp b/cpp/src/IceGrid/IceGridRegistry.cpp index 5a961147a0f..69970e60922 100644 --- a/cpp/src/IceGrid/IceGridRegistry.cpp +++ b/cpp/src/IceGrid/IceGridRegistry.cpp @@ -195,8 +195,18 @@ RegistryService::usage(const string& appName) print("Usage: " + appName + " [options]\n" + options); } +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) + +#endif { RegistryService svc; return svc.main(argc, argv); diff --git a/cpp/src/IceGrid/NodeI.cpp b/cpp/src/IceGrid/NodeI.cpp index 4911b4205da..432688aa925 100644 --- a/cpp/src/IceGrid/NodeI.cpp +++ b/cpp/src/IceGrid/NodeI.cpp @@ -1150,8 +1150,7 @@ NodeI::removeServer(const ServerIPtr& server, const std::string& application) _serversByApplication.erase(p); string appDir = _dataDir + "/distrib/" + application; - IceUtilInternal::structstat buf; - if(IceUtilInternal::stat(appDir, &buf) != -1 && S_ISDIR(buf.st_mode)) + if(IceUtilInternal::directoryExists(appDir)) { try { diff --git a/cpp/src/IceGrid/PlatformInfo.cpp b/cpp/src/IceGrid/PlatformInfo.cpp index 0f6eacd18a7..4e14fa0355c 100644 --- a/cpp/src/IceGrid/PlatformInfo.cpp +++ b/cpp/src/IceGrid/PlatformInfo.cpp @@ -21,7 +21,6 @@ #include <climits> #if defined(_WIN32) -# include <direct.h> // For _getcwd # include <pdhmsg.h> // For PDH_MORE_DATA #else # include <sys/utsname.h> @@ -268,13 +267,8 @@ PlatformInfo::PlatformInfo(const string& prefix, _endpoints = properties->getProperty(endpointsPrefix + ".Endpoints"); } -#ifdef _WIN32 - char cwd[_MAX_PATH]; - if(_getcwd(cwd, _MAX_PATH) == NULL) -#else - char cwd[PATH_MAX]; - if(getcwd(cwd, PATH_MAX) == NULL) -#endif + string cwd; + if(IceUtilInternal::getcwd(cwd) != 0) { throw "cannot get the current directory:\n" + IceUtilInternal::lastErrorToString(); } diff --git a/cpp/src/IceGrid/RegistryI.cpp b/cpp/src/IceGrid/RegistryI.cpp index b1c91aee0b5..c1486b71508 100644 --- a/cpp/src/IceGrid/RegistryI.cpp +++ b/cpp/src/IceGrid/RegistryI.cpp @@ -9,6 +9,7 @@ #include <IceUtil/DisableWarnings.h> #include <IceUtil/UUID.h> +#include <IceUtil/FileUtil.h> #include <Ice/Ice.h> #include <Ice/Network.h> #include <Ice/ProtocolPluginFacade.h> // Just to get the hostname @@ -41,15 +42,7 @@ #include <openssl/des.h> // For crypt() passwords -#ifdef _WIN32 -# include <direct.h> -# ifdef _MSC_VER -# define S_ISDIR(mode) ((mode) & _S_IFDIR) -# define S_ISREG(mode) ((mode) & _S_IFREG) -# endif -#else -# include <unistd.h> -#endif +#include <sys/types.h> using namespace std; using namespace Ice; @@ -1079,7 +1072,11 @@ RegistryI::getPermissionsVerifier(const ObjectAdapterPtr& adapter, } else if(!passwordsProperty.empty()) { - ifstream passwordFile(passwordsProperty.c_str()); + // + // No nativeToUTF8 conversion necessary here, since no string + // converter is installed by IceGrid the string is UTF-8. + // + IceUtilInternal::ifstream passwordFile(passwordsProperty); if(!passwordFile) { Error out(_communicator->getLogger()); diff --git a/cpp/src/IceGrid/ServerI.cpp b/cpp/src/IceGrid/ServerI.cpp index 3ab2938f7db..a42ed7c5ac8 100644 --- a/cpp/src/IceGrid/ServerI.cpp +++ b/cpp/src/IceGrid/ServerI.cpp @@ -7,7 +7,9 @@ // // ********************************************************************** +#include <IceUtil/FileUtil.h> #include <Ice/Ice.h> +#include <Ice/Instance.h> #include <IceGrid/ServerI.h> #include <IceGrid/TraceLevels.h> #include <IceGrid/Activator.h> @@ -20,7 +22,6 @@ #include <IceUtil/FileUtil.h> #include <sys/types.h> -#include <sys/stat.h> #ifdef _WIN32 # include <direct.h> @@ -33,8 +34,6 @@ # include <dirent.h> #endif -#include <fstream> - using namespace std; using namespace IceGrid; @@ -275,6 +274,7 @@ private: struct EnvironmentEval : std::unary_function<string, string> { + string operator()(const std::string& value) { @@ -289,7 +289,8 @@ struct EnvironmentEval : std::unary_function<string, string> string::size_type beg = 0; string::size_type end; #ifdef _WIN32 - char buf[32767]; + vector<wchar_t> buf; + buf.resize(32767); while((beg = v.find("%", beg)) != string::npos && beg < v.size() - 1) { end = v.find("%", beg + 1); @@ -298,8 +299,8 @@ struct EnvironmentEval : std::unary_function<string, string> break; } string variable = v.substr(beg + 1, end - beg - 1); - DWORD ret = GetEnvironmentVariable(variable.c_str(), buf, sizeof(buf)); - string valstr = (ret > 0 && ret < sizeof(buf)) ? string(buf) : string(""); + DWORD ret = GetEnvironmentVariableW(IceUtil::stringToWstring(variable).c_str(), &buf[0], buf.size()); + string valstr = (ret > 0 && ret < sizeof(buf.size())) ? IceUtil::wstringToString(&buf[0]) : string(""); v.replace(beg, end - beg + 1, valstr); beg += valstr.size(); } @@ -335,6 +336,7 @@ struct EnvironmentEval : std::unary_function<string, string> #endif return value.substr(0, assignment) + "=" + v; } + }; } @@ -2201,7 +2203,7 @@ ServerI::updateImpl(const InternalServerDescriptorPtr& descriptor) knownFiles.push_back(p->first); const string configFilePath = _serverDir + "/config/" + p->first; - ofstream configfile(configFilePath.c_str()); + IceUtilInternal::ofstream configfile(configFilePath); // configFilePath is a UTF-8 string if(!configfile.good()) { throw "couldn't create configuration file: " + configFilePath; @@ -2261,7 +2263,8 @@ ServerI::updateImpl(const InternalServerDescriptorPtr& descriptor) if(!(*q)->properties.empty()) { string file = dbEnvHome + "/DB_CONFIG"; - ofstream configfile(file.c_str()); + + IceUtilInternal::ofstream configfile(file); // file is a UTF-8 string if(!configfile.good()) { throw "couldn't create configuration file `" + file + "'"; @@ -2328,7 +2331,7 @@ ServerI::checkRevision(const string& replicaName, const string& uuid, int revisi else { string idFilePath = _serverDir + "/revision"; - ifstream is(idFilePath.c_str()); + IceUtilInternal::ifstream is(idFilePath); // idFilePath is a UTF-8 string if(!is.good()) { return; @@ -2366,7 +2369,7 @@ ServerI::updateRevision(const string& uuid, int revision) _desc->revision = revision; string idFilePath = _serverDir + "/revision"; - ofstream os(idFilePath.c_str()); + IceUtilInternal::ofstream os(idFilePath); // idFilePath is a UTF-8 string if(os.good()) { os << "#" << endl; diff --git a/cpp/src/IceGrid/SqlDB/SqlDB.cpp b/cpp/src/IceGrid/SqlDB/SqlDB.cpp index 327435d577c..a890d4cb9e7 100644 --- a/cpp/src/IceGrid/SqlDB/SqlDB.cpp +++ b/cpp/src/IceGrid/SqlDB/SqlDB.cpp @@ -8,6 +8,7 @@ // ********************************************************************** #include <IceUtil/ArgVector.h> +#include <IceUtil/FileUtil.h> #include <Ice/Communicator.h> #include <Ice/Locator.h> #include <Ice/Instance.h> @@ -17,19 +18,6 @@ #include <QtCore/QCoreApplication> #include <QtCore/QTextCodec> -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef _WIN32 -# include <direct.h> -# ifdef _MSC_VER -# define S_ISDIR(mode) ((mode) & _S_IFDIR) -# define S_ISREG(mode) ((mode) & _S_IFREG) -# endif -#else -# include <unistd.h> -#endif - using namespace IceGrid; using namespace std; @@ -190,8 +178,7 @@ SqlDBPlugin::initialize() } else { - struct stat filestat; - if(stat(dbPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode)) + if(IceUtilInternal::directoryExists(dbPath)) { ostringstream os; Ice::SyscallException ex(__FILE__, __LINE__); diff --git a/cpp/src/IceGrid/Util.cpp b/cpp/src/IceGrid/Util.cpp index cf6d248c1a4..d7fe5ef143f 100644 --- a/cpp/src/IceGrid/Util.cpp +++ b/cpp/src/IceGrid/Util.cpp @@ -12,8 +12,6 @@ #include <IceGrid/Util.h> #include <IceGrid/Admin.h> -#include <fstream> - using namespace std; using namespace IceGrid; diff --git a/cpp/src/IcePatch2/Calc.cpp b/cpp/src/IcePatch2/Calc.cpp index 2755afdec0f..401f318d010 100644 --- a/cpp/src/IcePatch2/Calc.cpp +++ b/cpp/src/IcePatch2/Calc.cpp @@ -96,7 +96,7 @@ public: }; void -usage(const char* appName) +usage(const string& appName) { cerr << "Usage: " << appName << " [options] DIR [FILES...]\n"; cerr << @@ -110,9 +110,22 @@ usage(const char* appName) ; } +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) + +#endif { + Ice::StringSeq originalArgs = Ice::argsToStringSeq(argc, argv); + assert(originalArgs.size() > 0); + const string appName = originalArgs[0]; string dataDir; StringSeq fileSeq; int compress = 1; @@ -130,18 +143,18 @@ main(int argc, char* argv[]) vector<string> args; try { - args = opts.parse(argc, (const char**)argv); + args = opts.parse(originalArgs); } catch(const IceUtilInternal::BadOptException& e) { cerr << e.reason << endl; - usage(argv[0]); + usage(appName); return EXIT_FAILURE; } if(opts.isSet("help")) { - usage(argv[0]); + usage(appName); return EXIT_SUCCESS; } if(opts.isSet("version")) @@ -153,8 +166,8 @@ main(int argc, char* argv[]) bool dontCompress = opts.isSet("no-compress"); if(doCompress && dontCompress) { - cerr << argv[0] << ": only one of -z and -Z are mutually exclusive" << endl; - usage(argv[0]); + cerr << appName << ": only one of -z and -Z are mutually exclusive" << endl; + usage(appName); return EXIT_FAILURE; } if(doCompress) @@ -170,8 +183,8 @@ main(int argc, char* argv[]) if(args.empty()) { - cerr << argv[0] << ": no data directory specified" << endl; - usage(argv[0]); + cerr << appName << ": no data directory specified" << endl; + usage(appName); return EXIT_FAILURE; } dataDir = simplify(args[0]); @@ -300,12 +313,12 @@ main(int argc, char* argv[]) } catch(const string& ex) { - cerr << argv[0] << ": " << ex << endl; + cerr << appName << ": " << ex << endl; return EXIT_FAILURE; } catch(const char* ex) { - cerr << argv[0] << ": " << ex << endl; + cerr << appName << ": " << ex << endl; return EXIT_FAILURE; } diff --git a/cpp/src/IcePatch2/Client.cpp b/cpp/src/IcePatch2/Client.cpp index 1d428d4af19..7b6fd50c134 100644 --- a/cpp/src/IcePatch2/Client.cpp +++ b/cpp/src/IcePatch2/Client.cpp @@ -326,8 +326,18 @@ Client::usage(const string& appName) cerr << options << endl; } +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) + +#endif { Client app; return app.main(argc, argv); diff --git a/cpp/src/IcePatch2/Server.cpp b/cpp/src/IcePatch2/Server.cpp index fdb68fdedb6..655ea552c0a 100644 --- a/cpp/src/IcePatch2/Server.cpp +++ b/cpp/src/IcePatch2/Server.cpp @@ -211,15 +211,34 @@ IcePatch2::PatcherService::usage(const string& appName) print("Usage: " + appName + " [options] [DIR]\n" + options); } +#ifdef _WIN32 + +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#ifdef __BCCPLUSPLUS__ + int main(int argc, char* argv[]) + +#else + +int +wmain(int argc, wchar_t* argv[]) + +#endif { IcePatch2::PatcherService svc; int status = EXIT_FAILURE; - -#ifdef _WIN32 status = svc.main(argc, argv); + return status; +} + #else + +int +main(int argc, char* argv[]) +{ + IcePatch2::PatcherService svc; + int status = EXIT_FAILURE; // // For UNIX, force --nochdir option, so the service isn't started // with / as the working directory. That way, if the data @@ -234,7 +253,7 @@ main(int argc, char* argv[]) args.push_back(argv[i]); } status = svc.main(args); -#endif - return status; } + +#endif diff --git a/cpp/src/IcePatch2Lib/ClientUtil.cpp b/cpp/src/IcePatch2Lib/ClientUtil.cpp index d5f13208698..120b5078a87 100644 --- a/cpp/src/IcePatch2Lib/ClientUtil.cpp +++ b/cpp/src/IcePatch2Lib/ClientUtil.cpp @@ -10,6 +10,7 @@ #include <IceUtil/Unicode.h> #include <IceUtil/StringUtil.h> #include <IceUtil/FileUtil.h> +#include <Ice/StringConverter.h> #define ICE_PATCH2_API_EXPORTS #include <IcePatch2/ClientUtil.h> #include <IcePatch2/Util.h> @@ -150,7 +151,7 @@ private: IcePatch2::Patcher::Patcher(const CommunicatorPtr& communicator, const PatcherFeedbackPtr& feedback) : _feedback(feedback), - _dataDir(simplify(communicator->getProperties()->getPropertyWithDefault("IcePatch2.Directory", "."))), + _dataDir(communicator->getProperties()->getPropertyWithDefault("IcePatch2.Directory", ".")), _thorough(communicator->getProperties()->getPropertyAsInt("IcePatch2.Thorough") > 0), _chunkSize(communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2.ChunkSize", 100)), _remove(communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2.Remove", 1)), @@ -186,7 +187,7 @@ IcePatch2::Patcher::Patcher(const FileServerPrx& server, Ice::Int chunkSize, Ice::Int remove) : _feedback(feedback), - _dataDir(simplify(dataDir)), + _dataDir(dataDir), _thorough(thorough), _chunkSize(chunkSize), _remove(remove) @@ -470,7 +471,7 @@ IcePatch2::Patcher::prepare() bool IcePatch2::Patcher::patch(const string& d) { - string dir = simplify(d); + string dir = simplify(nativeToUTF8(_serverNoCompress->ice_getCommunicator(), d)); if(dir.empty() || dir == ".") { @@ -593,12 +594,19 @@ IcePatch2::Patcher::init(const FileServerPrx& server) throw string("no data directory specified"); } + Ice::CommunicatorPtr communicator = server->ice_getCommunicator(); + + // + // Transform dataDir to a UTF8 string (it's either read from the properties or + // provided by the user application directly). + // + const_cast<string&>(_dataDir) = simplify(nativeToUTF8(communicator, _dataDir)); + // // Make sure that _chunkSize doesn't exceed MessageSizeMax, otherwise // it won't work at all. // - int sizeMax = - server->ice_getCommunicator()->getProperties()->getPropertyAsIntWithDefault("Ice.MessageSizeMax", 1024); + int sizeMax = communicator->getProperties()->getPropertyAsIntWithDefault("Ice.MessageSizeMax", 1024); if(_chunkSize < 1) { const_cast<Int&>(_chunkSize) = 1; diff --git a/cpp/src/IcePatch2Lib/Util.cpp b/cpp/src/IcePatch2Lib/Util.cpp index 41d422e8556..ca2510a119c 100644 --- a/cpp/src/IcePatch2Lib/Util.cpp +++ b/cpp/src/IcePatch2Lib/Util.cpp @@ -280,7 +280,7 @@ IcePatch2::simplify(const string& path) } if(result == "/." || - (result.size() == 4 && isalpha(static_cast<unsigned char>(result[0])) && result[1] == ':' && + (result.size() == 4 && IceUtilInternal::isAlpha(result[0]) && result[1] == ':' && result[2] == '/' && result[3] == '.')) { return result.substr(0, result.size() - 1); @@ -291,8 +291,8 @@ IcePatch2::simplify(const string& path) result.erase(result.size() - 2, 2); } - if(result == "/" || (result.size() == 3 && isalpha(static_cast<unsigned char>(result[0])) && result[1] == ':' && - result[2] == '/')) + if(result == "/" || (result.size() == 3 && IceUtilInternal::isAlpha(result[0]) && result[1] == ':' && + result[2] == '/')) { return result; } @@ -315,7 +315,7 @@ IcePatch2::isRoot(const string& pa) { string path = simplify(pa); #ifdef _WIN32 - return path == "/" || path.size() == 3 && isalpha(static_cast<unsigned char>(path[0])) && path[1] == ':' && + return path == "/" || path.size() == 3 && IceUtilInternal::isAlpha(path[0]) && path[1] == ':' && path[2] == '/'; #else return path == "/"; @@ -404,7 +404,6 @@ IcePatch2::rename(const string& fromPa, const string& toPa) const string toPath = simplify(toPa); IceUtilInternal::remove(toPath); // We ignore errors, as the file we are renaming to might not exist. - if(IceUtilInternal::rename(fromPath ,toPath) == -1) { throw "cannot rename `" + fromPath + "' to `" + toPath + "': " + IceUtilInternal::lastErrorToString(); @@ -1055,6 +1054,7 @@ getFileInfoSeqInt(const string& basePath, const string& relPath, int compress, G close(fd); const string pathBZ2Temp = path + ".bz2temp"; + FILE* stdioFile = IceUtilInternal::fopen(pathBZ2Temp, "wb"); if(fwrite(&compressedBytes[0], compressedLen, 1, stdioFile) != 1) { diff --git a/cpp/src/IceSSL/Instance.cpp b/cpp/src/IceSSL/Instance.cpp index de78f1115a9..40ca4cc0d7f 100644 --- a/cpp/src/IceSSL/Instance.cpp +++ b/cpp/src/IceSSL/Instance.cpp @@ -18,6 +18,7 @@ #include <Ice/LoggerUtil.h> #include <Ice/Properties.h> #include <Ice/ProtocolPluginFacade.h> +#include <Ice/StringConverter.h> #include <IceUtil/Mutex.h> #include <IceUtil/MutexPtrLock.h> @@ -208,7 +209,8 @@ IceSSL::Instance::Instance(const CommunicatorPtr& communicator) : { RAND_load_file(randFile, 1024); } - string randFiles = properties->getProperty("IceSSL.Random"); + string randFiles = Ice::nativeToUTF8(communicator, properties->getProperty("IceSSL.Random")); + if(!randFiles.empty()) { vector<string> files; @@ -217,7 +219,8 @@ IceSSL::Instance::Instance(const CommunicatorPtr& communicator) : #else const string sep = ":"; #endif - string defaultDir = properties->getProperty("IceSSL.DefaultDir"); + string defaultDir = Ice::nativeToUTF8(communicator, properties->getProperty("IceSSL.DefaultDir")); + if(!IceUtilInternal::splitString(randFiles, sep, files)) { PluginInitializationException ex(__FILE__, __LINE__); diff --git a/cpp/src/IceSSL/RFC2253.cpp b/cpp/src/IceSSL/RFC2253.cpp index d622969448b..fc446a9d5a3 100644 --- a/cpp/src/IceSSL/RFC2253.cpp +++ b/cpp/src/IceSSL/RFC2253.cpp @@ -7,6 +7,8 @@ // // ********************************************************************** +#include <IceUtil/StringUtil.h> + #include <IceSSL/Plugin.h> #include <IceSSL/RFC2253.h> @@ -270,10 +272,10 @@ parseAttributeType(const string& data, size_t& pos) // // First the OID case. // - if(isdigit(static_cast<unsigned char>(data[pos])) || + if(IceUtilInternal::isDigit(data[pos]) || (data.size() - pos >= 4 && (data.substr(pos, 4) == "oid." || data.substr(pos, 4) == "OID."))) { - if(!isdigit(static_cast<unsigned char>(data[pos]))) + if(!IceUtilInternal::isDigit(data[pos])) { result += data.substr(pos, 4); pos += 4; @@ -282,7 +284,7 @@ parseAttributeType(const string& data, size_t& pos) while(true) { // 1*DIGIT - while(pos < data.size() && isdigit(static_cast<unsigned char>(data[pos]))) + while(pos < data.size() && IceUtilInternal::isDigit(data[pos])) { result += data[pos]; ++pos; @@ -293,7 +295,7 @@ parseAttributeType(const string& data, size_t& pos) result += data[pos]; ++pos; // 1*DIGIT must follow "." - if(pos < data.size() && !isdigit(static_cast<unsigned char>(data[pos]))) + if(pos < data.size() && !IceUtilInternal::isDigit(data[pos])) { throw ParseException(__FILE__, __LINE__, "invalid attribute type (expected end of data)"); } @@ -304,7 +306,7 @@ parseAttributeType(const string& data, size_t& pos) } } } - else if(isalpha(static_cast<unsigned char>(data[pos]))) + else if(IceUtilInternal::isAlpha(data[pos])) { // // The grammar is wrong in this case. It should be ALPHA @@ -314,8 +316,8 @@ parseAttributeType(const string& data, size_t& pos) result += data[pos]; ++pos; // 1* KEYCHAR - while(pos < data.size() && (isalpha(static_cast<unsigned char>(data[pos])) || - isdigit(static_cast<unsigned char>(data[pos])) || data[pos] == '-')) + while(pos < data.size() && + (IceUtilInternal::isAlpha(data[pos]) || IceUtilInternal::isDigit(data[pos]) || data[pos] == '-')) { result += data[pos]; ++pos; diff --git a/cpp/src/IceSSL/Util.cpp b/cpp/src/IceSSL/Util.cpp index 54b9b9c3ebd..e82d58b3457 100644 --- a/cpp/src/IceSSL/Util.cpp +++ b/cpp/src/IceSSL/Util.cpp @@ -8,19 +8,13 @@ // ********************************************************************** #include <IceSSL/Util.h> +#include <IceUtil/FileUtil.h> #include <Ice/LocalException.h> #include <Ice/Network.h> #ifdef _WIN32 # include <direct.h> # include <sys/types.h> -# include <sys/stat.h> -# ifdef _MSC_VER -# define S_ISDIR(mode) ((mode) & _S_IFDIR) -# define S_ISREG(mode) ((mode) & _S_IFREG) -# endif -#else -# include <sys/stat.h> #endif #include <openssl/err.h> @@ -286,13 +280,8 @@ IceSSL::checkPath(string& path, const string& defaultDir, bool dir) // argument is modified and true is returned. Otherwise // false is returned. // -#ifdef _WIN32 - struct _stat st; - int err = ::_stat(path.c_str(), &st); -#else - struct stat st; - int err = ::stat(path.c_str(), &st); -#endif + IceUtilInternal::structstat st; + int err = IceUtilInternal::stat(path, &st); if(err == 0) { return dir ? S_ISDIR(st.st_mode) != 0 : S_ISREG(st.st_mode) != 0; @@ -302,11 +291,10 @@ IceSSL::checkPath(string& path, const string& defaultDir, bool dir) { #ifdef _WIN32 string s = defaultDir + "\\" + path; - err = ::_stat(s.c_str(), &st); #else string s = defaultDir + "/" + path; - err = ::stat(s.c_str(), &st); #endif + err = ::IceUtilInternal::stat(s.c_str(), &st); if(err == 0 && ((!dir && S_ISREG(st.st_mode)) || (dir && S_ISDIR(st.st_mode)))) { path = s; diff --git a/cpp/src/IceStorm/Admin.cpp b/cpp/src/IceStorm/Admin.cpp index 71a483796c4..63413847079 100644 --- a/cpp/src/IceStorm/Admin.cpp +++ b/cpp/src/IceStorm/Admin.cpp @@ -13,8 +13,6 @@ #include <Ice/SliceChecksums.h> #include <IceStorm/Parser.h> -#include <fstream> - using namespace std; using namespace Ice; using namespace IceStorm; @@ -27,8 +25,18 @@ public: virtual int run(int, char*[]); }; +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) + +#endif { Client app; int rc = app.main(argc, argv); diff --git a/cpp/src/IceStorm/FreezeDB/Migrate.cpp b/cpp/src/IceStorm/FreezeDB/Migrate.cpp index e9ed32ce6d0..210e23490a5 100644 --- a/cpp/src/IceStorm/FreezeDB/Migrate.cpp +++ b/cpp/src/IceStorm/FreezeDB/Migrate.cpp @@ -34,8 +34,18 @@ private: void v31migrate(const Freeze::ConnectionPtr&, SubscriberMap&); }; +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__) + +int +wmain(int argc, wchar_t* argv[]) + +#else + int main(int argc, char* argv[]) + +#endif { Client app; int rc = app.main(argc, argv); diff --git a/cpp/src/IceStorm/Service.cpp b/cpp/src/IceStorm/Service.cpp index 31fabe9381f..a18b9fd7f3c 100644 --- a/cpp/src/IceStorm/Service.cpp +++ b/cpp/src/IceStorm/Service.cpp @@ -301,12 +301,12 @@ ServiceI::start( // start of the node id, and then the end of the // digits). string::size_type start = instanceName.size(); - while(start < adapterid.size() && !isdigit(static_cast<unsigned char>(adapterid[start]))) + while(start < adapterid.size() && !IceUtilInternal::isDigit(adapterid[start])) { ++start; } string::size_type end = start; - while(end < adapterid.size() && isdigit(static_cast<unsigned char>(adapterid[end]))) + while(end < adapterid.size() && IceUtilInternal::isDigit(adapterid[end])) { ++end; } diff --git a/cpp/src/IceUtil/FileUtil.cpp b/cpp/src/IceUtil/FileUtil.cpp index 0bd0e7e46f6..f5254c6a38e 100644 --- a/cpp/src/IceUtil/FileUtil.cpp +++ b/cpp/src/IceUtil/FileUtil.cpp @@ -12,9 +12,12 @@ #include <IceUtil/Unicode.h> #include <climits> +#ifdef _WIN32 +# include <io.h> +#endif + #ifdef __BCPLUSPLUS__ # include <dir.h> -# include <io.h> #endif using namespace std; @@ -131,7 +134,14 @@ IceUtilInternal::fopen(const string& path, const string& mode) int IceUtilInternal::open(const string& path, int flags) { - return ::_wopen(IceUtil::stringToWstring(path).c_str(), flags); + if(flags & _O_CREAT) + { + return ::_wopen(IceUtil::stringToWstring(path).c_str(), flags, _S_IREAD | _S_IWRITE); + } + else + { + return ::_wopen(IceUtil::stringToWstring(path).c_str(), flags); + } } int @@ -146,6 +156,168 @@ IceUtilInternal::getcwd(string& cwd) return 0; } +int +IceUtilInternal::unlink(const string& path) +{ + return _wunlink(IceUtil::stringToWstring(path).c_str()); +} + +#ifdef _STLP_BEGIN_NAMESPACE +namespace +{ +int +toFileFlags(ios_base::openmode mode) +{ + int flags = 0; + if(mode & ios_base::app) + { + flags |= _O_APPEND; + } + if(mode & ios_base::trunc) + { + flags |= _O_TRUNC; + } + if(mode & ios_base::binary) + { + flags |= _O_BINARY; + } + if((mode & ios_base::in) && !(mode & ios_base::out)) + { + flags |= _O_RDONLY; + } + else if((mode & ios_base::out) && !(mode & ios_base::in)) + { + flags |= _O_WRONLY | _O_CREAT; + } + else + { + flags |= _O_RDWR; + if(mode & ios_base::trunc) + { + flags |= _O_CREAT; + } + } + return flags; +} +} +#endif + +IceUtilInternal::ifstream::ifstream() +{ +} + +#ifdef _STLP_BEGIN_NAMESPACE + +IceUtilInternal::ifstream::ifstream(const string& path, ios_base::openmode mode) : _fd(-1) +{ + open(path, mode); +} + +IceUtilInternal::ifstream::~ifstream() +{ + close(); +} + +void +IceUtilInternal::ifstream::close() +{ + if(!rdbuf()->close()) + { + setstate(ios_base::failbit); + } + if(_fd >= 0) + { + _close(_fd); + } +} + +void +IceUtilInternal::ifstream::open(const string& path, ios_base::openmode mode) +{ + mode |= ifstream::in; + _fd = IceUtilInternal::open(path, toFileFlags(mode)); + if(_fd < 0 || !rdbuf()->open(_fd, mode)) + { + setstate(ios_base::failbit); + } + if(mode & (ios_base::ate || ios_base::app)) + { + seekg(ios_base::end); + } +} + +#else + +IceUtilInternal::ifstream::ifstream(const string& path, ios_base::openmode mode) : std::ifstream(IceUtil::stringToWstring(path).c_str(), mode) +{ +} + +void +IceUtilInternal::ifstream::open(const string& path, ios_base::openmode mode) +{ + std::ifstream::open(IceUtil::stringToWstring(path).c_str(), mode); +} + +#endif + +IceUtilInternal::ofstream::ofstream() +{ +} + +#ifdef _STLP_BEGIN_NAMESPACE + +IceUtilInternal::ofstream::ofstream(const string& path, ios_base::openmode mode) : _fd(-1) +{ + open(path, mode); +} + +IceUtilInternal::ofstream::~ofstream() +{ + close(); +} + +void +IceUtilInternal::ofstream::close() +{ + if(!rdbuf()->close()) + { + setstate(ios_base::failbit); + } + if(_fd >= 0) + { + _close(_fd); + } +} + +void +IceUtilInternal::ofstream::open(const string& path, ios_base::openmode mode) +{ + mode |= ofstream::out; + _fd = IceUtilInternal::open(path, toFileFlags(mode)); + if(_fd < 0 || !rdbuf()->open(_fd, mode)) + { + setstate(ios_base::failbit); + } + if(mode & (ios_base::ate || ios_base::app)) + { + seekp(ios_base::end); + } +} + +#else + +IceUtilInternal::ofstream::ofstream(const string& path, ios_base::openmode mode) : std::ofstream(IceUtil::stringToWstring(path).c_str(), mode) +{ +} + +void +IceUtilInternal::ofstream::open(const string& path, ios_base::openmode mode) +{ + std::ofstream::open(IceUtil::stringToWstring(path).c_str(), mode); +} + +#endif + #else // @@ -154,7 +326,7 @@ IceUtilInternal::getcwd(string& cwd) int IceUtilInternal::stat(const string& path, structstat* buffer) { - return stat(path.c_str(), buffer); + return ::stat(path.c_str(), buffer); } int @@ -190,7 +362,15 @@ IceUtilInternal::fopen(const string& path, const string& mode) int IceUtilInternal::open(const string& path, int flags) { - return ::open(path.c_str(), flags); + if(flags & O_CREAT) + { + // By default, create with rw-rw-rw- modified by the user's umask (same as fopen). + return ::open(path.c_str(), flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + } + else + { + return ::open(path.c_str(), flags); + } } int @@ -205,4 +385,38 @@ IceUtilInternal::getcwd(string& cwd) return 0; } +int +IceUtilInternal::unlink(const string& path) +{ + return ::unlink(path.c_str()); +} + +IceUtilInternal::ifstream::ifstream() +{ +} + +IceUtilInternal::ifstream::ifstream(const string& path, ios_base::openmode mode) : std::ifstream(path.c_str(), mode) +{ +} + +void +IceUtilInternal::ifstream::open(const string& path, ios_base::openmode mode) +{ + std::ifstream::open(path.c_str(), mode); +} + +IceUtilInternal::ofstream::ofstream() +{ +} + +IceUtilInternal::ofstream::ofstream(const string& path, ios_base::openmode mode) : std::ofstream(path.c_str(), mode) +{ +} + +void +IceUtilInternal::ofstream::open(const string& path, ios_base::openmode mode) +{ + std::ofstream::open(path.c_str(), mode); +} + #endif diff --git a/cpp/src/IceUtil/Options.cpp b/cpp/src/IceUtil/Options.cpp index 86afccc3427..9870b1dc69d 100644 --- a/cpp/src/IceUtil/Options.cpp +++ b/cpp/src/IceUtil/Options.cpp @@ -8,6 +8,7 @@ // ********************************************************************** #include <IceUtil/Options.h> +#include <IceUtil/StringUtil.h> #include <iostream> #include <set> @@ -492,7 +493,7 @@ IceUtilInternal::Options::split(const string& line) case 'c': { c = l[++i]; - if(isalpha(static_cast<unsigned char>(c)) || c == '@' || (c >= '[' && c <= '_')) + if(IceUtilInternal::isAlpha(c) || c == '@' || (c >= '[' && c <= '_')) { arg.push_back(static_cast<char>(toupper(static_cast<unsigned char>(c)) - '@')); } diff --git a/cpp/src/IceUtil/OutputUtil.cpp b/cpp/src/IceUtil/OutputUtil.cpp index 5a398c84ce6..a3bef50d681 100644 --- a/cpp/src/IceUtil/OutputUtil.cpp +++ b/cpp/src/IceUtil/OutputUtil.cpp @@ -8,6 +8,7 @@ // ********************************************************************** #include <IceUtil/OutputUtil.h> +#include <IceUtil/FileUtil.h> #include <cstring> using namespace std; @@ -94,11 +95,7 @@ IceUtilInternal::OutputBase::open(const char* s) // Remove any existing file first. This prevents file name // mismatches on case-insensitive OSs. // -#ifdef _WIN32 - _unlink(s); -#else - unlink(s); -#endif + IceUtilInternal::unlink(s); _fout.open(s); } diff --git a/cpp/src/IceUtil/StringUtil.cpp b/cpp/src/IceUtil/StringUtil.cpp index 2b79f251360..3c65ad42dd7 100644 --- a/cpp/src/IceUtil/StringUtil.cpp +++ b/cpp/src/IceUtil/StringUtil.cpp @@ -746,6 +746,18 @@ IceUtilInternal::toUpper(const std::string& s) return result; } +bool +IceUtilInternal::isAlpha(char c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +bool +IceUtilInternal::isDigit(char c) +{ + return c >= '0' && c <= '9'; +} + string IceUtilInternal::removeWhitespace(const std::string& s) { diff --git a/cpp/src/IceXML/Parser.cpp b/cpp/src/IceXML/Parser.cpp index 5538074bd78..fd8338f5a8c 100644 --- a/cpp/src/IceXML/Parser.cpp +++ b/cpp/src/IceXML/Parser.cpp @@ -8,9 +8,10 @@ // ********************************************************************** #include <IceXML/Parser.h> +#include <IceUtil/Unicode.h> +#include <IceUtil/FileUtil.h> #include <expat.h> #include <list> -#include <fstream> using namespace std; using namespace IceXML; @@ -373,9 +374,9 @@ IceXML::Parser::parse(istream& in) } void -IceXML::Parser::parse(const string& file, Handler& handler) +IceXML::Parser::parse(const string& file, Handler& handler) // The given filename must be UTF-8 encoded { - ifstream in(file.c_str()); + IceUtilInternal::ifstream in(file); if(!in.good()) { ostringstream out; diff --git a/cpp/src/Slice/Preprocessor.cpp b/cpp/src/Slice/Preprocessor.cpp index 03403498703..72f9226c449 100644 --- a/cpp/src/Slice/Preprocessor.cpp +++ b/cpp/src/Slice/Preprocessor.cpp @@ -122,8 +122,8 @@ Slice::Preprocessor::normalizeIncludePath(const string& path) result.replace(pos, 2, "/"); } - if(result == "/" || (result.size() == 3 && isalpha(static_cast<unsigned char>(result[0])) && result[1] == ':' && - result[2] == '/')) + if(result == "/" || (result.size() == 3 && IceUtilInternal::isAlpha(result[0]) && result[1] == ':' && + result[2] == '/')) { return result; } @@ -205,9 +205,9 @@ Slice::Preprocessor::preprocess(bool keepComments) wchar_t* name = _wtempnam(NULL, L".preprocess"); if(name) { - _cppFile = wstring(name); + _cppFile = IceUtil::wstringToString(name); free(name); - _cppHandle = ::_wfopen(_cppFile.c_str(), L"w+"); + _cppHandle = IceUtilInternal::fopen(_cppFile, "w+"); } #else _cppHandle = tmpfile(); @@ -218,13 +218,8 @@ Slice::Preprocessor::preprocess(bool keepComments) // if(_cppHandle == 0) { -#ifdef _WIN32 - _cppFile = L".preprocess." + IceUtil::stringToWstring(IceUtil::generateUUID()); - _cppHandle = ::_wfopen(_cppFile.c_str(), L"w+"); -#else _cppFile = ".preprocess." + IceUtil::generateUUID(); - _cppHandle = ::fopen(_cppFile.c_str(), "w+"); -#endif + _cppHandle = IceUtilInternal::fopen(_cppFile, "w+"); } if(_cppHandle != 0) @@ -239,11 +234,7 @@ Slice::Preprocessor::preprocess(bool keepComments) { ostream& os = getErrorStream(); os << _path << ": error: could not open temporary file: "; -#ifdef _WIN32 - os << IceUtil::wstringToString(_cppFile); -#else os << _cppFile; -#endif os << endl; } } @@ -593,11 +584,7 @@ Slice::Preprocessor::close() if(_cppFile.size() != 0) { -#ifdef _WIN32 - _wunlink(_cppFile.c_str()); -#else - unlink(_cppFile.c_str()); -#endif + IceUtilInternal::unlink(_cppFile); } if(status != 0) diff --git a/cpp/src/Slice/Util.cpp b/cpp/src/Slice/Util.cpp index 3ea6b609c9e..e2c4049c2c7 100644 --- a/cpp/src/Slice/Util.cpp +++ b/cpp/src/Slice/Util.cpp @@ -87,29 +87,22 @@ normalizePath(const string& path) string Slice::fullPath(const string& path) { -#ifdef _WIN32 - if(!IceUtilInternal::isAbsolutePath(path)) - { - wchar_t cwdbuf[_MAX_PATH]; - if(_wgetcwd(cwdbuf, _MAX_PATH) != NULL) - { - return normalizePath(IceUtil::wstringToString(cwdbuf) + "/" + path); - } - } - return normalizePath(path); -#else string result = path; if(!IceUtilInternal::isAbsolutePath(result)) { - char cwdbuf[PATH_MAX]; - if(::getcwd(cwdbuf, PATH_MAX) != NULL) + string cwd; + if(IceUtilInternal::getcwd(cwd) == 0) { - result = string(cwdbuf) + '/' + result; + result = string(cwd) + '/' + result; } } result = normalizePath(result); +#ifdef _WIN32 + return result; +#else + string::size_type beg = 0; string::size_type next; do diff --git a/cpp/src/iceserviceinstall/Install.cpp b/cpp/src/iceserviceinstall/Install.cpp index 209f994b87f..9fccbd9fa22 100644 --- a/cpp/src/iceserviceinstall/Install.cpp +++ b/cpp/src/iceserviceinstall/Install.cpp @@ -34,8 +34,18 @@ private: bool _pause; }; +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#ifdef __BCPLUSPLUS__ + int main(int argc, char* argv[]) + +#else + +int +wmain(int argc, wchar_t* argv[]) + +#endif { Install app; int status = app.main(argc, argv); diff --git a/cpp/src/iceserviceinstall/ServiceInstaller.cpp b/cpp/src/iceserviceinstall/ServiceInstaller.cpp index 127d7a84070..0b12cb05cd9 100644 --- a/cpp/src/iceserviceinstall/ServiceInstaller.cpp +++ b/cpp/src/iceserviceinstall/ServiceInstaller.cpp @@ -16,8 +16,7 @@ #include <ServiceInstaller.h> #include <IceUtil/StringUtil.h> #include <IceUtil/FileUtil.h> -#include <sys/types.h> -#include <sys/stat.h> + #include <Aclapi.h> @@ -112,12 +111,6 @@ IceServiceInstaller::IceServiceInstaller(int serviceType, const string& configFi } } - -IceServiceInstaller::~IceServiceInstaller() -{ - free(_sid); -} - void IceServiceInstaller::install(const PropertiesPtr& properties) { @@ -301,20 +294,20 @@ IceServiceInstaller::install(const PropertiesPtr& properties) bool autoStart = properties->getPropertyAsIntWithDefault("AutoStart", 1) != 0; string password = properties->getProperty("Password"); - SC_HANDLE service = CreateService( + SC_HANDLE service = CreateServiceW( scm, - _serviceName.c_str(), - displayName.c_str(), + IceUtil::stringToWstring(_serviceName).c_str(), + IceUtil::stringToWstring(displayName).c_str(), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, autoStart ? SERVICE_AUTO_START : SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, - command.c_str(), + IceUtil::stringToWstring(command).c_str(), 0, 0, - deps.c_str(), - _sidName.c_str(), - password.c_str()); + IceUtil::stringToWstring(deps).c_str(), + IceUtil::stringToWstring(_sidName).c_str(), + IceUtil::stringToWstring(password).c_str()); if(service == 0) { @@ -327,7 +320,7 @@ IceServiceInstaller::install(const PropertiesPtr& properties) // Set description // - SERVICE_DESCRIPTION sd = { const_cast<char*>(description.c_str()) }; + SERVICE_DESCRIPTIONW sd = { const_cast<wchar_t*>(IceUtil::stringToWstring(description).c_str()) }; if(!ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &sd)) { @@ -351,7 +344,7 @@ IceServiceInstaller::uninstall() throw "Cannot open SCM: " + IceUtilInternal::errorToString(res); } - SC_HANDLE service = OpenService(scm, _serviceName.c_str(), SERVICE_ALL_ACCESS); + SC_HANDLE service = OpenServiceW(scm, IceUtil::stringToWstring(_serviceName).c_str(), SERVICE_ALL_ACCESS); if(service == 0) { DWORD res = GetLastError(); @@ -394,7 +387,7 @@ IceServiceInstaller::uninstall() } } -/* static */ vector<string> +vector<string> IceServiceInstaller::getPropertyNames() { static const string propertyNames[] = { "ImagePath", "DisplayName", "ObjectName", "Password", @@ -405,7 +398,7 @@ IceServiceInstaller::getPropertyNames() return result; } -/*static*/ string +string IceServiceInstaller::serviceTypeToString(int serviceType) { static const string serviceTypeArray[] = { "IceGridRegistry", "IceGridNode", "Glacier2Router" }; @@ -420,7 +413,7 @@ IceServiceInstaller::serviceTypeToString(int serviceType) } } -/*static*/ string +string IceServiceInstaller::serviceTypeToLowerString(int serviceType) { static const string serviceTypeArray[] = { "icegridregistry", "icegridnode", "glacier2router" }; @@ -440,35 +433,25 @@ IceServiceInstaller::initializeSid(const string& name) { { DWORD sidSize = 32; - _sid = static_cast<SID*>(malloc(sidSize)); - memset(_sid, 0, sidSize); + _sid = auto_ptr<SID>(new SID[sidSize]); DWORD domainNameSize = 32; - char* domainName = static_cast<char*>(malloc(domainNameSize)); - memset(domainName, 0, domainNameSize); + auto_ptr<wchar_t> domainName(new wchar_t[domainNameSize]); SID_NAME_USE nameUse; - while(LookupAccountName(0, name.c_str(), _sid, &sidSize, domainName, &domainNameSize, &nameUse) == false) + while(LookupAccountNameW(0, IceUtil::stringToWstring(name).c_str(), _sid.get(), &sidSize, domainName.get(), + &domainNameSize, &nameUse) == false) { DWORD res = GetLastError(); if(res == ERROR_INSUFFICIENT_BUFFER) { - _sid = static_cast<SID*>(realloc(_sid, sidSize)); - memset(_sid, 0, sidSize); - domainName = static_cast<char*>(realloc(domainName, domainNameSize)); - memset(domainName, 0, domainNameSize); - } - else - { - free(_sid); - _sid = 0; - free(domainName); - - throw "Could not retrieve Security ID for " + name + ": " + IceUtilInternal::errorToString(res); + _sid = auto_ptr<SID>(new SID[sidSize]); + domainName = auto_ptr<wchar_t>(new wchar_t[domainNameSize]); + continue; } + throw "Could not retrieve Security ID for " + name + ": " + IceUtilInternal::errorToString(res); } - free(domainName); } // @@ -487,21 +470,21 @@ IceServiceInstaller::initializeSid(const string& name) } else { - char accountName[1024]; + wchar_t accountName[1024]; DWORD accountNameLen = 1024; - char domainName[1024]; + wchar_t domainName[1024]; DWORD domainLen = 1024; SID_NAME_USE nameUse; - if(LookupAccountSid(0, _sid, accountName, &accountNameLen, domainName, + if(LookupAccountSidW(0, _sid.get(), accountName, &accountNameLen, domainName, &domainLen, &nameUse) == false) { DWORD res = GetLastError(); throw "Could not retrieve full account name for " + name + ": " + IceUtilInternal::errorToString(res); } - _sidName = string(domainName) + "\\" + accountName; + _sidName = IceUtil::wstringToString(domainName) + "\\" + IceUtil::wstringToString(accountName); } if(_debug) @@ -509,9 +492,9 @@ IceServiceInstaller::initializeSid(const string& name) Trace trace(_communicator->getLogger(), "IceServiceInstaller"); #if defined(_MSC_VER) && _MSC_VER >= 1300 - char* sidString = 0; - ConvertSidToStringSid(_sid, &sidString); - trace << "SID: " << sidString << "; "; + wchar_t* sidString = 0; + ConvertSidToStringSidW(_sid.get(), &sidString); + trace << "SID: " << IceUtil::wstringToString(sidString) << "; "; LocalFree(sidString); #endif trace << "Full name: " << _sidName; @@ -521,12 +504,12 @@ IceServiceInstaller::initializeSid(const string& name) bool IceServiceInstaller::fileExists(const string& path) const { - struct _stat buffer = { 0 }; - int err = _stat(path.c_str(), &buffer); + IceUtilInternal::structstat st = {0}; + int err = IceUtilInternal::stat(path, &st); if(err == 0) { - if((buffer.st_mode & _S_IFREG) == 0) + if((S_ISREG(st.st_mode)) == 0) { throw path + " is not a regular file"; } @@ -555,7 +538,7 @@ IceServiceInstaller::grantPermissions(const string& path, SE_OBJECT_TYPE type, b PACL acl = 0; PACL newAcl = 0; PSECURITY_DESCRIPTOR sd = 0; - DWORD res = GetNamedSecurityInfo(const_cast<char*>(path.c_str()), type, + DWORD res = GetNamedSecurityInfoW(const_cast<wchar_t*>(IceUtil::stringToWstring(path).c_str()), type, DACL_SECURITY_INFORMATION, 0, 0, &acl, 0, &sd); if(res != ERROR_SUCCESS) @@ -568,15 +551,16 @@ IceServiceInstaller::grantPermissions(const string& path, SE_OBJECT_TYPE type, b // // Now check if _sid can read this file/dir/key // - TRUSTEE trustee; - BuildTrusteeWithSid(&trustee, _sid); + TRUSTEE_W trustee; + BuildTrusteeWithSidW(&trustee, _sid.get()); ACCESS_MASK accessMask = 0; - res = GetEffectiveRightsFromAcl(acl, &trustee, &accessMask); + res = GetEffectiveRightsFromAclW(acl, &trustee, &accessMask); if(res != ERROR_SUCCESS) { - throw "Could not retrieve effective rights for " + _sidName + " on " + path + ": " + IceUtilInternal::errorToString(res); + throw "Could not retrieve effective rights for " + _sidName + " on " + path + ": " + + IceUtilInternal::errorToString(res); } bool done = false; @@ -608,7 +592,7 @@ IceServiceInstaller::grantPermissions(const string& path, SE_OBJECT_TYPE type, b } else { - EXPLICIT_ACCESS ea = { 0 }; + EXPLICIT_ACCESS_W ea = { 0 }; if(type == SE_FILE_OBJECT && fullControl) { @@ -632,18 +616,19 @@ IceServiceInstaller::grantPermissions(const string& path, SE_OBJECT_TYPE type, b // // Create new ACL // - res = SetEntriesInAcl(1, &ea, acl, &newAcl); + res = SetEntriesInAclW(1, &ea, acl, &newAcl); if(res != ERROR_SUCCESS) { throw "Could not modify ACL for " + path + ": " + IceUtilInternal::errorToString(res); } - res = SetNamedSecurityInfo(const_cast<char*>(path.c_str()), type, + res = SetNamedSecurityInfoW(const_cast<wchar_t*>(IceUtil::stringToWstring(path).c_str()), type, DACL_SECURITY_INFORMATION, 0, 0, newAcl, 0); if(res != ERROR_SUCCESS) { - throw "Could not grant access to " + _sidName + " on " + path + ": " + IceUtilInternal::errorToString(res); + throw "Could not grant access to " + _sidName + " on " + path + ": " + + IceUtilInternal::errorToString(res); } if(_debug) @@ -667,7 +652,7 @@ IceServiceInstaller::grantPermissions(const string& path, SE_OBJECT_TYPE type, b bool IceServiceInstaller::mkdir(const string& path) const { - if(CreateDirectory(path.c_str(), 0) == 0) + if(CreateDirectoryW(IceUtil::stringToWstring(path).c_str(), 0) == 0) { DWORD res = GetLastError(); if(res == ERROR_ALREADY_EXISTS) @@ -702,8 +687,8 @@ IceServiceInstaller::addLog(const string& log) const HKEY key = 0; DWORD disposition = 0; - LONG res = RegCreateKeyEx(HKEY_LOCAL_MACHINE, createLog(log).c_str(), - 0, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, + LONG res = RegCreateKeyExW(HKEY_LOCAL_MACHINE, IceUtil::stringToWstring(createLog(log)).c_str(), + 0, L"REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &key, &disposition); if(res != ERROR_SUCCESS) @@ -721,7 +706,7 @@ IceServiceInstaller::addLog(const string& log) const void IceServiceInstaller::removeLog(const string& log) const { - LONG res = RegDeleteKey(HKEY_LOCAL_MACHINE, createLog(log).c_str()); + LONG res = RegDeleteKeyW(HKEY_LOCAL_MACHINE, IceUtil::stringToWstring(createLog(log)).c_str()); // // We get ERROR_ACCESS_DENIED when the log is shared by several sources @@ -737,8 +722,8 @@ IceServiceInstaller::addSource(const string& source, const string& log, const st { HKEY key = 0; DWORD disposition = 0; - LONG res = RegCreateKeyEx(HKEY_LOCAL_MACHINE, createSource(source, log).c_str(), - 0, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, + LONG res = RegCreateKeyExW(HKEY_LOCAL_MACHINE, IceUtil::stringToWstring(createSource(source, log)).c_str(), + 0, L"REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &key, &disposition); if(res != ERROR_SUCCESS) { @@ -750,9 +735,9 @@ IceServiceInstaller::addSource(const string& source, const string& log, const st // the "EventMessageFile" key should contain the path to this // DLL. // - res = RegSetValueEx(key, "EventMessageFile", 0, REG_EXPAND_SZ, - reinterpret_cast<const BYTE*>(resourceFile.c_str()), - static_cast<DWORD>(resourceFile.length() + 1)); + res = RegSetValueExW(key, L"EventMessageFile", 0, REG_EXPAND_SZ, + reinterpret_cast<const BYTE*>(IceUtil::stringToWstring(resourceFile).c_str()), + static_cast<DWORD>(resourceFile.length() + 1) * sizeof(wchar_t)); if(res == ERROR_SUCCESS) { @@ -762,7 +747,7 @@ IceServiceInstaller::addSource(const string& source, const string& log, const st // DWORD typesSupported = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; - res = RegSetValueEx(key, "TypesSupported", 0, REG_DWORD, + res = RegSetValueExW(key, L"TypesSupported", 0, REG_DWORD, reinterpret_cast<BYTE*>(&typesSupported), sizeof(typesSupported)); } @@ -788,7 +773,7 @@ IceServiceInstaller::removeSource(const string& source) const HKEY key = 0; - LONG res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\EventLog", 0, + LONG res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\EventLog", 0, KEY_ENUMERATE_SUB_KEYS, &key); if(res != ERROR_SUCCESS) @@ -799,17 +784,19 @@ IceServiceInstaller::removeSource(const string& source) const DWORD index = 0; do { - char subkey[4096]; DWORD subkeySize = 4096; + wchar_t subkey[4096]; - res = RegEnumKeyEx(key, index, subkey, &subkeySize, 0, 0, 0, 0); + res = RegEnumKeyExW(key, index, subkey, &subkeySize, 0, 0, 0, 0); if(res == ERROR_SUCCESS) { // // Check if we can delete the source sub-key // - LONG delRes = RegDeleteKey(HKEY_LOCAL_MACHINE, createSource(source, subkey).c_str()); + LONG delRes = RegDeleteKeyW(HKEY_LOCAL_MACHINE, + IceUtil::stringToWstring(createSource(source, + IceUtil::wstringToString(subkey))).c_str()); if(delRes == ERROR_SUCCESS) { res = RegCloseKey(key); @@ -817,12 +804,12 @@ IceServiceInstaller::removeSource(const string& source) const { throw "Could not close registry key handle: " + IceUtilInternal::errorToString(res); } - return string(subkey); + return IceUtil::wstringToString(subkey); } ++index; } - } while(res == ERROR_SUCCESS); + }while(res == ERROR_SUCCESS); if(res == ERROR_NO_MORE_ITEMS) diff --git a/cpp/src/iceserviceinstall/ServiceInstaller.h b/cpp/src/iceserviceinstall/ServiceInstaller.h index 2ca626a64b9..d23df8f3e3c 100644 --- a/cpp/src/iceserviceinstall/ServiceInstaller.h +++ b/cpp/src/iceserviceinstall/ServiceInstaller.h @@ -32,7 +32,6 @@ public: #endif IceServiceInstaller(int, const std::string&, const Ice::CommunicatorPtr&); - ~IceServiceInstaller(); void install(const Ice::PropertiesPtr&); @@ -73,7 +72,7 @@ private: std::string _nodeName; std::string _glacier2InstanceName; - SID* _sid; + std::auto_ptr<SID> _sid; std::string _sidName; bool _debug; diff --git a/cpp/src/slice2freeze/Main.cpp b/cpp/src/slice2freeze/Main.cpp index 1cdfc130779..d5792982af5 100644 --- a/cpp/src/slice2freeze/Main.cpp +++ b/cpp/src/slice2freeze/Main.cpp @@ -246,7 +246,7 @@ usage(const char* n) void checkIdentifier(string t, string s) { - if(s.empty() || (!isalpha(static_cast<unsigned char>(s[0])) && s[0] != '_')) + if(s.empty() || (!IceUtilInternal::isAlpha(s[0]) && s[0] != '_')) { ostringstream os; os << t << "' is not a valid type name"; diff --git a/cpp/test/IceGrid/deployer/AllTests.cpp b/cpp/test/IceGrid/deployer/AllTests.cpp index 8afe27e2aee..d340b0188ff 100644 --- a/cpp/test/IceGrid/deployer/AllTests.cpp +++ b/cpp/test/IceGrid/deployer/AllTests.cpp @@ -12,6 +12,7 @@ #include <IceGrid/Query.h> #include <IceGrid/Admin.h> #include <IceGrid/Registry.h> +#include <IceUtil/FileUtil.h> #include <IceUtil/Thread.h> #include <TestCommon.h> #include <Test.h> @@ -179,7 +180,7 @@ logTests(const Ice::CommunicatorPtr& comm, const AdminSessionPrx& session) // // Test with empty file. // - ofstream os((testDir + "/log1.txt").c_str()); + IceUtilInternal::ofstream os((testDir + "/log1.txt")); os.close(); it = session->openServerLog("LogServer", testDir + "/log1.txt", -1); @@ -208,7 +209,7 @@ logTests(const Ice::CommunicatorPtr& comm, const AdminSessionPrx& session) // // Test with log file with one line with no EOL on last line. // - ofstream os((testDir + "/log2.txt").c_str()); + IceUtilInternal::ofstream os((testDir + "/log2.txt")); os << "one line file with no EOL on last line"; os.close(); @@ -246,7 +247,7 @@ logTests(const Ice::CommunicatorPtr& comm, const AdminSessionPrx& session) // // Test with log file with one line with EOL on last line. // - ofstream os((testDir + "/log3.txt").c_str()); + IceUtilInternal::ofstream os((testDir + "/log3.txt")); os << "one line file with EOL on last line" << endl; os.close(); @@ -292,7 +293,7 @@ logTests(const Ice::CommunicatorPtr& comm, const AdminSessionPrx& session) // // Test with log file with multiple lines // - ofstream os((testDir + "/log4.txt").c_str()); + IceUtilInternal::ofstream os((testDir + "/log4.txt")); os << "line 1" << endl; os << "line 2" << endl; os << "line 3" << endl; @@ -341,7 +342,7 @@ logTests(const Ice::CommunicatorPtr& comm, const AdminSessionPrx& session) try { - ofstream os((testDir + "/log1.txt").c_str(), ios_base::out | ios_base::trunc); + IceUtilInternal::ofstream os((testDir + "/log1.txt").c_str(), ios_base::out | ios_base::trunc); os << flush; it = session->openServerLog("LogServer", testDir + "/log1.txt", -1); diff --git a/cpp/test/IceGrid/deployer/Server.cpp b/cpp/test/IceGrid/deployer/Server.cpp index 3f731848996..48d55d5bd77 100644 --- a/cpp/test/IceGrid/deployer/Server.cpp +++ b/cpp/test/IceGrid/deployer/Server.cpp @@ -11,6 +11,7 @@ #include <Ice/Ice.h> #include <TestI.h> #include <TestCommon.h> +#include <fstream> using namespace std; @@ -31,7 +32,6 @@ Server::run(int argc, char* argv[]) Ice::stringSeqToArgs(args, argc, argv); string name = properties->getProperty("Ice.ProgramName"); - Ice::ObjectAdapterPtr adapter; if(!properties->getProperty("ReplicatedAdapter").empty()) @@ -43,7 +43,6 @@ Server::run(int argc, char* argv[]) adapter = communicator()->createObjectAdapter("Server"); Ice::ObjectPtr object = new TestI(properties); adapter->add(object, communicator()->stringToIdentity(name)); - shutdownOnInterrupt(); try { @@ -66,6 +65,48 @@ main(int argc, char* argv[]) char* value = getenv("MY_ENV_VARIABLE"); test(value != 0 && string(value) == "12"); + ifstream in("envs"); + if(!in) + { + test(false); + } + string unicodeVar; + string varname1; + string varname2; + if(!getline(in, unicodeVar) || !getline(in, varname1) || !getline(in, varname2)) + { + test(false); + } + +#if defined(_WIN32) + + // + // COMPILERFIX: Unicode environments don't work well with VC6 applications, + // for some reasons, the wstring returned by _wgetenv are incorrect. + // +#if (!defined(_MSC_VER) || _MSC_VER >= 1300) + wchar_t* value2 = _wgetenv(L"MY_ENV_UNICODE_VARIABLE"); + test(value2 != 0 && wstring(value2) == IceUtil::stringToWstring(unicodeVar)); + + wchar_t* value3 = _wgetenv(IceUtil::stringToWstring(varname1).c_str()); + test(value3 != 0 && wstring(value3) == L"2"); + + // Environment variables are case insensitive on Windows. + wchar_t* value4 = _wgetenv(IceUtil::stringToWstring(varname1).c_str()); + test(value4 != 0 && wstring(value4) == L"2"); +#endif + +#else + char* value2 = getenv("MY_ENV_UNICODE_VARIABLE"); + test(value2 !=0 && string(value2) == unicodeVar); + + char* value3 = getenv(varname1.c_str()); + test(value3 != 0 && string(value3) == "1"); + + char* value4 = getenv(varname2.c_str()); + test(value4 != 0 && string(value4) == "2"); +#endif + Server app; int rc = app.main(argc, argv); return rc; diff --git a/cpp/test/IceGrid/deployer/application.xml b/cpp/test/IceGrid/deployer/application.xml index 646f2116a58..672ba853fd3 100644 --- a/cpp/test/IceGrid/deployer/application.xml +++ b/cpp/test/IceGrid/deployer/application.xml @@ -112,6 +112,9 @@ </dbenv> <option>--Test.Test=2</option> <env>MY_ENV_VARIABLE=12</env> + <env>MY_ENV_UNICODE_VARIABLE=A Coruña</env> + <env>MY_ENV_VÄRIABLE=1</env> + <env>my_env_väriable=2</env> <properties> <properties refid="AppProperties"/> <properties refid="NodeProperties"/> @@ -150,6 +153,9 @@ <log path="${test.dir}/log3.txt"/> <log path="${test.dir}/log4.txt"/> <env>MY_ENV_VARIABLE=12</env> + <env>MY_ENV_UNICODE_VARIABLE=A Coruña</env> + <env>MY_ENV_VÄRIABLE=1</env> + <env>my_env_väriable=2</env> <properties> <property name="Ice.StdErr" value="${node.datadir}/servers/${server}.out"/> <property name="Ice.StdOut" value="${node.datadir}/servers/${server}.err"/> diff --git a/cpp/test/IceGrid/deployer/envs b/cpp/test/IceGrid/deployer/envs new file mode 100644 index 00000000000..df8792a52df --- /dev/null +++ b/cpp/test/IceGrid/deployer/envs @@ -0,0 +1,3 @@ +A Coruña +MY_ENV_VÄRIABLE +my_env_väriable diff --git a/cpp/test/IceGrid/deployer/server.xml b/cpp/test/IceGrid/deployer/server.xml index 0e10ade7826..29860603b34 100644 --- a/cpp/test/IceGrid/deployer/server.xml +++ b/cpp/test/IceGrid/deployer/server.xml @@ -51,6 +51,9 @@ </properties> <env>MY_ENV_VARIABLE=12</env> + <env>MY_ENV_UNICODE_VARIABLE=A Coruña</env> + <env>MY_ENV_VÄRIABLE=1</env> + <env>my_env_väriable=2</env> <target name="moreproperties"> <property name="TargetProp" value="1"/> diff --git a/cpp/test/IceUtil/unicode/Client.cpp b/cpp/test/IceUtil/unicode/Client.cpp index a8b99a4d02b..622bbe79818 100644 --- a/cpp/test/IceUtil/unicode/Client.cpp +++ b/cpp/test/IceUtil/unicode/Client.cpp @@ -8,8 +8,12 @@ // ********************************************************************** #include <IceUtil/Unicode.h> +#include <IceUtil/FileUtil.h> #include <TestCommon.h> -#include <fstream> + +#ifdef _WIN32 +# include <io.h> +#endif using namespace IceUtil; using namespace std; @@ -18,17 +22,34 @@ using namespace std; // Note that each file starts with a BOM; stringToWstring and wstringToString // converts these BOMs back and forth. // + +//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications. +#if defined(_WIN32) && !defined(__BCPLUSPLUS__) + int -main(int argc, char** argv) +wmain(int argc, wchar_t* argv[]) + +#else + +int +main(int argc, char* argv[]) + +#endif { string dir = ""; if(argc > 1) { +#ifdef _WIN32 + +#ifndef __BCPLUSPLUS__ dir = argv[1]; -#ifdef _WIN32 +#else + dir = IceUtil::wstringToString(argv[1]); +#endif dir += "\\"; #else + dir = argv[1]; dir += "/"; #endif } @@ -45,11 +66,10 @@ main(int argc, char** argv) string wcoeurFile = string("coeur.") + wstringEncoding; { - cout << "testing UTF-8 to wstring (" << wstringEncoding << ") conversion..."; - - ifstream is((dir + "coeur.utf8").c_str()); + cout << "testing UTF-8 to wstring (" << wstringEncoding << ") conversion... "; + IceUtilInternal::ifstream is((dir + "coeur.utf8")); test(is.good()); - ifstream bis((dir + wcoeurFile).c_str(), ios_base::binary); + IceUtilInternal::ifstream bis((dir + wcoeurFile), ios_base::binary); test(bis.good()); int lineNumber = 0; @@ -105,9 +125,9 @@ main(int argc, char** argv) } { - cout << "wstring (" << wstringEncoding << ") to UTF-8 conversion..."; + cout << "wstring (" << wstringEncoding << ") to UTF-8 conversion... "; - ifstream bis((dir + wcoeurFile).c_str(), ios_base::binary); + IceUtilInternal::ifstream bis((dir + wcoeurFile), ios_base::binary); test(bis.good()); wstring ws; @@ -136,7 +156,7 @@ main(int argc, char** argv) string s = wstringToString(ws); - ifstream nbis((dir + "coeur.utf8").c_str(), ios_base::binary); + IceUtilInternal::ifstream nbis((dir + "coeur.utf8"), ios_base::binary); test(nbis.good()); for(size_t i = 0; i < s.size(); ++i) @@ -160,5 +180,77 @@ main(int argc, char** argv) cout << "ok" << endl; } + { + cout << "testing UTF-8 filename... "; + IceUtilInternal::ifstream fn(dir + "filename.txt"); + string filename; + getline(fn, filename); + fn.close(); + + string filepath = dir + filename; + + { + IceUtilInternal::ofstream os(filepath); + test(os.is_open()); + os << "dummy"; + os.close(); + } + + IceUtilInternal::isAbsolutePath(filepath); + IceUtilInternal::structstat st; + test(IceUtilInternal::stat(filepath, &st) == 0); + + test(IceUtilInternal::mkdir(filepath + ".directory", 0777) == 0); + test(IceUtilInternal::directoryExists(filepath + ".directory")); + test(IceUtilInternal::rmdir(filepath + ".directory") == 0); + + int fd = IceUtilInternal::open(filepath, O_RDONLY); + test(fd > 0); +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + test(_close(fd) == 0); +#else + test(close(fd) == 0); +#endif + + FILE* f = IceUtilInternal::fopen(filepath, "r"); + test(f != 0); + test(::fclose(f) == 0); + + IceUtilInternal::ifstream is(filepath); + string str; + getline(is, str); + test(str == "dummy"); + is.close(); + + IceUtilInternal::ifstream is2; + is2.open(filepath); + getline(is2, str); + test(str == "dummy"); + is2.close(); + + IceUtilInternal::ofstream os(filepath + ".out"); + os << "dummy" << endl; + os.close(); + + IceUtilInternal::ofstream os2; + os2.open(filepath + ".out", ios_base::app); + os2 << "dummy2" << endl; + os2.close(); + + IceUtilInternal::ifstream is3; + is3.open(filepath + ".out"); + getline(is3, str); + test(str == "dummy"); + getline(is3, str); + test(str == "dummy2"); + is3.close(); + + test(IceUtilInternal::unlink(filepath + ".out") == 0); + + IceUtilInternal::unlink(filepath); + + cout << "ok" << endl; + } + return EXIT_SUCCESS; } diff --git a/cpp/test/IceUtil/unicode/filename.txt b/cpp/test/IceUtil/unicode/filename.txt new file mode 100644 index 00000000000..e6373bde83b --- /dev/null +++ b/cpp/test/IceUtil/unicode/filename.txt @@ -0,0 +1 @@ +cœur.txt
\ No newline at end of file |