diff options
author | Matthew Newhook <matthew@zeroc.com> | 2015-02-18 10:29:49 -0330 |
---|---|---|
committer | Matthew Newhook <matthew@zeroc.com> | 2015-02-18 10:29:49 -0330 |
commit | b55ce15878456e3d2f0656bcd6abd5a55c6774b1 (patch) | |
tree | e7e771a3d90ae7295f20bf0622b72c72cc3a85e0 /cpp/src | |
parent | Fixed ObjC build (diff) | |
download | ice-b55ce15878456e3d2f0656bcd6abd5a55c6774b1.tar.bz2 ice-b55ce15878456e3d2f0656bcd6abd5a55c6774b1.tar.xz ice-b55ce15878456e3d2f0656bcd6abd5a55c6774b1.zip |
Changes for brew, python PyPI packaging and ruby gem packaging.
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Glacier2/Makefile | 4 | ||||
-rw-r--r-- | cpp/src/Ice/EventLoggerMsg.h | 53 | ||||
-rw-r--r-- | cpp/src/Ice/EventLoggerMsg.rc | 2 | ||||
-rw-r--r-- | cpp/src/Ice/WSTransceiver.cpp | 6 | ||||
-rw-r--r-- | cpp/src/IceGrid/Makefile | 6 | ||||
-rw-r--r-- | cpp/src/IceGridLib/Makefile | 7 | ||||
-rw-r--r-- | cpp/src/IceLocatorDiscovery/PluginI.cpp | 7 | ||||
-rw-r--r-- | cpp/src/IcePatch2/Makefile | 2 | ||||
-rw-r--r-- | cpp/src/IcePatch2Lib/Makefile | 4 | ||||
-rw-r--r-- | cpp/src/Slice/Makefile | 2 | ||||
-rw-r--r-- | cpp/src/Slice/Makefile.mak | 4 | ||||
-rw-r--r-- | cpp/src/Slice/Python.cpp | 675 | ||||
-rw-r--r-- | cpp/src/Slice/Ruby.cpp | 317 | ||||
-rw-r--r-- | cpp/src/slice2py/Main.cpp | 661 | ||||
-rw-r--r-- | cpp/src/slice2rb/Main.cpp | 315 |
15 files changed, 1083 insertions, 982 deletions
diff --git a/cpp/src/Glacier2/Makefile b/cpp/src/Glacier2/Makefile index e9ffdb50abc..0b73adca2a7 100644 --- a/cpp/src/Glacier2/Makefile +++ b/cpp/src/Glacier2/Makefile @@ -33,12 +33,12 @@ RPATH_DIR = $(LOADER_PATH)/../$(libsubdir) include $(top_srcdir)/config/Make.rules -CPPFLAGS := -I.. $(CPPFLAGS) $(OPENSSL_FLAGS) +CPPFLAGS := -I.. $(CPPFLAGS) SLICE2CPPFLAGS := --include-dir Glacier2 $(SLICE2CPPFLAGS) $(ROUTER): $(OBJS) rm -f $@ - $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(OBJS) -lGlacier2 $(LIBS) -lIceSSL $(OPENSSL_LIBS) + $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(OBJS) -lGlacier2 $(LIBS) -lIceSSL $(OPENSSL_RPATH_LINK) install:: all $(call installprogram,$(ROUTER),$(DESTDIR)$(install_bindir)) diff --git a/cpp/src/Ice/EventLoggerMsg.h b/cpp/src/Ice/EventLoggerMsg.h new file mode 100644 index 00000000000..add0bdde9e0 --- /dev/null +++ b/cpp/src/Ice/EventLoggerMsg.h @@ -0,0 +1,53 @@ + // ********************************************************************** + // + // Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. + // + // This copy of Ice is licensed to you under the terms described in the + // ICE_LICENSE file included in this distribution. + // + // ********************************************************************** +// +// Values are 32 bit values laid out as follows: +// +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +// +---+-+-+-----------------------+-------------------------------+ +// |Sev|C|R| Facility | Code | +// +---+-+-+-----------------------+-------------------------------+ +// +// where +// +// Sev - is the severity code +// +// 00 - Success +// 01 - Informational +// 10 - Warning +// 11 - Error +// +// C - is the Customer code flag +// +// R - is a reserved bit +// +// Facility - is the facility code +// +// Code - is the facility's status code +// +// +// Define the facility codes +// + + +// +// Define the severity codes +// + + +// +// MessageId: EVENT_LOGGER_MSG +// +// MessageText: +// +// %1 +// +#define EVENT_LOGGER_MSG 0x00000000L + diff --git a/cpp/src/Ice/EventLoggerMsg.rc b/cpp/src/Ice/EventLoggerMsg.rc new file mode 100644 index 00000000000..0abcb0fa2c5 --- /dev/null +++ b/cpp/src/Ice/EventLoggerMsg.rc @@ -0,0 +1,2 @@ +LANGUAGE 0x9,0x1 +1 11 "MSG00001.bin" diff --git a/cpp/src/Ice/WSTransceiver.cpp b/cpp/src/Ice/WSTransceiver.cpp index 4f17d4e8b81..d83e553308d 100644 --- a/cpp/src/Ice/WSTransceiver.cpp +++ b/cpp/src/Ice/WSTransceiver.cpp @@ -23,7 +23,13 @@ #include <IceUtil/DisableWarnings.h> +// Python 2.7 under Windows. +#if _MSC_VER == 1500 +typedef unsigned short uint16_t; +#else #include <stdint.h> +#endif + #include <climits> using namespace std; diff --git a/cpp/src/IceGrid/Makefile b/cpp/src/IceGrid/Makefile index cc587d7107f..90292dcb1c1 100644 --- a/cpp/src/IceGrid/Makefile +++ b/cpp/src/IceGrid/Makefile @@ -101,7 +101,7 @@ RPATH_DIR = $(LOADER_PATH)/../$(libsubdir) include $(top_srcdir)/config/Make.rules -CPPFLAGS := $(CPPFLAGS) -I.. $(OPENSSL_FLAGS) $(READLINE_FLAGS) +CPPFLAGS := $(CPPFLAGS) -I.. $(READLINE_FLAGS) ICECPPFLAGS := $(ICECPPFLAGS) -I.. SLICE2CPPFLAGS := --checksum --ice --include-dir IceGrid $(SLICE2CPPFLAGS) SLICE2FREEZECMD := $(SLICE2FREEZE) --ice --include-dir IceGrid $(ICECPPFLAGS) @@ -114,12 +114,12 @@ $(ADMIN): $(ADMIN_OBJS) $(LIBTARGETS) $(REGISTRY_SERVER): $(REGISTRY_SVR_OBJS) $(LIBTARGETS) rm -f $@ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(REGISTRY_SVR_OBJS) -lIceGrid -lIceStorm -lIceStormService -lGlacier2 -lIcePatch2 \ - -lFreeze -lIceBox $(EXPAT_RPATH_LINK) -lIceXML -lIceSSL $(OPENSSL_LIBS) $(LIBS) + -lFreeze -lIceBox $(EXPAT_RPATH_LINK) -lIceXML -lIceSSL $(OPENSSL_RPATH_LINK) $(LIBS) $(NODE_SERVER): $(NODE_SVR_OBJS) $(LIBTARGETS) rm -f $@ $(CXX) $(LDFLAGS) $(LDEXEFLAGS) -o $@ $(NODE_SVR_OBJS) -lIceGrid -lIceStorm -lIceStormService -lIceBox -lGlacier2 \ - -lFreeze -lIcePatch2 $(EXPAT_RPATH_LINK) -lIceXML -lIceSSL $(OPENSSL_LIBS) $(LIBS) + -lFreeze -lIcePatch2 $(EXPAT_RPATH_LINK) -lIceXML -lIceSSL $(OPENSSL_RPATH_LINK) $(LIBS) ../IceGrid/IceLocatorDiscovery.h IceLocatorDiscovery.cpp: \ $(slicedir)/IceLocatorDiscovery/IceLocatorDiscovery.ice $(SLICE2CPP) $(SLICEPARSERLIB) diff --git a/cpp/src/IceGridLib/Makefile b/cpp/src/IceGridLib/Makefile index 8fce12114df..05410c99580 100644 --- a/cpp/src/IceGridLib/Makefile +++ b/cpp/src/IceGridLib/Makefile @@ -42,6 +42,12 @@ ICECPPFLAGS := $(ICECPPFLAGS) -I.. SLICE2CPPFLAGS := --checksum --ice --include-dir IceGrid --dll-export ICE_GRID_API $(SLICE2CPPFLAGS) LINKWITH := -lGlacier2 $(BZIP2_RPATH_LINK) -lIce -lIceUtil +ifeq ($(STATICLIBS),yes) +$(libdir)/$(LIBNAME): $(OBJS) + @mkdir -p $(dir $@) + rm -f $@ + $(call mklib,$@,$(OBJS)) +else $(libdir)/$(LIBFILENAME): $(OBJS) @mkdir -p $(dir $@) rm -f $@ @@ -55,6 +61,7 @@ $(libdir)$(cpp11libdirsuffix)/$(LIBNAME): $(libdir)/$(SONAME) @mkdir -p $(libdir)$(cpp11libdirsuffix) rm -f $@ ln -s $(cpp11sonamedir)$(SONAME) $@ +endif install:: all $(call installlib,$(DESTDIR)$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME)) diff --git a/cpp/src/IceLocatorDiscovery/PluginI.cpp b/cpp/src/IceLocatorDiscovery/PluginI.cpp index 57f27179510..798ad323974 100644 --- a/cpp/src/IceLocatorDiscovery/PluginI.cpp +++ b/cpp/src/IceLocatorDiscovery/PluginI.cpp @@ -121,6 +121,13 @@ private: const LocatorIPtr _locator; }; +const ::std::string IceGrid_Locator_ids[3] = +{ + "::Ice::Locator", + "::Ice::Object", + "::IceGrid::Locator" +}; + // // The void locator implementation below is used when no locator is found. // diff --git a/cpp/src/IcePatch2/Makefile b/cpp/src/IcePatch2/Makefile index bbc39622404..dfc5fa2fb8a 100644 --- a/cpp/src/IcePatch2/Makefile +++ b/cpp/src/IcePatch2/Makefile @@ -30,7 +30,7 @@ RPATH_DIR = $(LOADER_PATH)/../$(libsubdir) include $(top_srcdir)/config/Make.rules -CPPFLAGS := -I. -I.. $(CPPFLAGS) $(OPENSSL_FLAGS) $(BZIP2_FLAGS) +CPPFLAGS := -I. -I.. $(CPPFLAGS) $(BZIP2_FLAGS) $(SERVER): $(SOBJS) $(LIBTARGETS) rm -f $@ diff --git a/cpp/src/IcePatch2Lib/Makefile b/cpp/src/IcePatch2Lib/Makefile index 80a59f38bfb..3a192a29f3c 100644 --- a/cpp/src/IcePatch2Lib/Makefile +++ b/cpp/src/IcePatch2Lib/Makefile @@ -27,9 +27,9 @@ SDIR = $(slicedir)/IcePatch2 include $(top_srcdir)/config/Make.rules -CPPFLAGS := -I. -I.. $(CPPFLAGS) $(OPENSSL_FLAGS) $(BZIP2_FLAGS) -Wno-deprecated-declarations +CPPFLAGS := -I. -I.. $(CPPFLAGS) $(BZIP2_FLAGS) -Wno-deprecated-declarations SLICE2CPPFLAGS := --ice --include-dir IcePatch2 --dll-export ICE_PATCH2_API $(SLICE2CPPFLAGS) -LINKWITH := $(BZIP2_RPATH_LINK) -lIce -lIceUtil $(OPENSSL_LIBS) $(BZIP2_LIBS) +LINKWITH := $(BZIP2_RPATH_LINK) -lIce -lIceUtil $(BZIP2_LIBS) $(libdir)/$(LIBFILENAME): $(OBJS) @mkdir -p $(dir $@) diff --git a/cpp/src/Slice/Makefile b/cpp/src/Slice/Makefile index 237d6f0d686..5f04ffd7361 100644 --- a/cpp/src/Slice/Makefile +++ b/cpp/src/Slice/Makefile @@ -27,7 +27,9 @@ OBJS = Checksum.o \ PHPUtil.o \ Preprocessor.o \ PythonUtil.o \ + Python.o \ RubyUtil.o \ + Ruby.o \ Scanner.o \ Util.o \ ../Slice/Grammar.o diff --git a/cpp/src/Slice/Makefile.mak b/cpp/src/Slice/Makefile.mak index 1d932539f7d..35418099782 100644 --- a/cpp/src/Slice/Makefile.mak +++ b/cpp/src/Slice/Makefile.mak @@ -29,8 +29,12 @@ OBJS = .\Checksum.obj \ .\PHPUtil.obj \ .\Preprocessor.obj \ .\PythonUtil.obj \ + .\Python.obj \ .\RubyUtil.obj \ .\Util.obj \ + .\Ruby.obj \ + .\Scanner.obj \ + .\Util.obj $(BISON_FLEX_OBJS) !include $(top_srcdir)/config/Make.rules.mak diff --git a/cpp/src/Slice/Python.cpp b/cpp/src/Slice/Python.cpp new file mode 100644 index 00000000000..a14dcd4a5a2 --- /dev/null +++ b/cpp/src/Slice/Python.cpp @@ -0,0 +1,675 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/DisableWarnings.h> +#include <IceUtil/IceUtil.h> +#include <IceUtil/Options.h> +#include <IceUtil/StringUtil.h> +#include <IceUtil/CtrlCHandler.h> +#include <IceUtil/Mutex.h> +#include <IceUtil/MutexPtrLock.h> +#include <Slice/Preprocessor.h> +#include <Slice/FileTracker.h> +#include <Slice/PythonUtil.h> +#include <Slice/Util.h> +#include <cstring> + +#include <fstream> + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef _WIN32 +#include <direct.h> +#endif + +#ifndef _WIN32 +#include <unistd.h> +#endif + +using namespace std; +using namespace Slice; +using namespace Slice::Python; + +namespace +{ + +IceUtil::Mutex* globalMutex = 0; +bool interrupted = false; + +class Init +{ +public: + + Init() + { + globalMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete globalMutex; + globalMutex = 0; + } +}; + +Init init; + +void +interruptedCallback(int /*signal*/) +{ + IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex); + + interrupted = true; +} + + +// +// For each Slice file Foo.ice we generate Foo_ice.py containing the Python +// mappings. Furthermore, for each Slice module M in Foo.ice, we create a +// Python package of the same name. This package is simply a subdirectory +// containing the special file "__init__.py" that is executed when a Python +// script executes the statement "import M". +// +// Inside __init__.py we add an import statement for Foo_ice, causing +// Foo_ice to be imported implicitly when M is imported. +// +// Of course, another Slice file Bar.ice may contain definitions for the +// same Slice module M, in which case the __init__.py file for M is modified +// to contain an additional import statement for Bar_ice. Therefore a +// Python script executing "import M" implicitly imports the definitions +// from both Foo_ice and Bar_ice. +// +// The __init__.py file also contains import statements for submodules, +// so that importing the top-level module automatically imports all of +// its submodules. +// +// The PackageVisitor class creates the directory hierarchy to mirror the +// Slice module hierarchy, and updates the __init__.py files as necessary. +// +class PackageVisitor : public ParserVisitor +{ +public: + + static void createModules(const UnitPtr&, const string&, const string&); + + virtual void visitModuleEnd(const ModulePtr&); + +private: + + PackageVisitor(StringList&); + + enum ReadState { PreModules, InModules, InSubmodules }; + + static const char* _moduleTag; + static const char* _submoduleTag; + + static void createDirectory(const string&); + + static void addModule(const string&, const string&, const string&); + static void addSubmodule(const string&, const string&, const string&); + + static void readInit(const string&, StringList&, StringList&); + static void writeInit(const string&, const string&, const StringList&, const StringList&); + + StringList& _modules; +}; + +const char* PackageVisitor::_moduleTag = "# Modules:"; +const char* PackageVisitor::_submoduleTag = "# Submodules:"; + +PackageVisitor::PackageVisitor(StringList& modules) : + _modules(modules) +{ +} + +void +PackageVisitor::createModules(const UnitPtr& unit, const string& module, const string& dir) +{ + StringList modules; + PackageVisitor v(modules); + unit->visit(&v, false); + + for(StringList::iterator p = modules.begin(); p != modules.end(); ++p) + { + vector<string> v; + if(!IceUtilInternal::splitString(*p, ".", v)) + { + assert(false); + } + string currentModule; + string path = dir.empty() ? "." : dir; + for(vector<string>::iterator q = v.begin(); q != v.end(); ++q) + { + if(q != v.begin()) + { + addSubmodule(path, currentModule, *q); + currentModule += "."; + } + + currentModule += *q; + path += "/" + *q; + createDirectory(path); + + addModule(path, currentModule, module); + } + } +} + +void +PackageVisitor::visitModuleEnd(const ModulePtr& p) +{ + // + // Collect the most deeply-nested modules. For example, if we have a + // module named M.N.O, then we don't need to keep M or M.N in the list. + // + string abs = getAbsolute(p); + if(find(_modules.begin(), _modules.end(), abs) == _modules.end()) + { + _modules.push_back(abs); + } + string::size_type pos = abs.rfind('.'); + if(pos != string::npos) + { + string parent = abs.substr(0, pos); + _modules.remove(parent); + } +} + +void +PackageVisitor::createDirectory(const string& dir) +{ + struct stat st; + int result; + result = stat(dir.c_str(), &st); + if(result == 0) + { + if(!(st.st_mode & S_IFDIR)) + { + ostringstream os; + os << "failed to create package directory `" << dir + << "': file already exists and is not a directory"; + throw FileException(__FILE__, __LINE__, os.str()); + } + return; + } +#ifdef _WIN32 + result = _mkdir(dir.c_str()); +#else + result = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); +#endif + + if(result != 0) + { + ostringstream os; + os << "cannot create directory `" << dir << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); + } + + FileTracker::instance()->addDirectory(dir); +} + +void +PackageVisitor::addModule(const string& dir, const string& module, const string& name) +{ + // + // Add a module to the set of imported modules in __init__.py. + // + StringList modules, submodules; + readInit(dir, modules, submodules); + StringList::iterator p = find(modules.begin(), modules.end(), name); + if(p == modules.end()) + { + modules.push_back(name); + writeInit(dir, module, modules, submodules); + } +} + +void +PackageVisitor::addSubmodule(const string& dir, const string& module, const string& name) +{ + // + // Add a submodule to the set of imported modules in __init__.py. + // + StringList modules, submodules; + readInit(dir, modules, submodules); + StringList::iterator p = find(submodules.begin(), submodules.end(), name); + if(p == submodules.end()) + { + submodules.push_back(name); + writeInit(dir, module, modules, submodules); + } +} + +void +PackageVisitor::readInit(const string& dir, StringList& modules, StringList& submodules) +{ + string initPath = dir + "/__init__.py"; + + struct stat st; + if(stat(initPath.c_str(), &st) == 0) + { + ifstream in(initPath.c_str()); + if(!in) + { + ostringstream os; + os << "cannot open file `" << initPath << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); + } + + ReadState state = PreModules; + char line[1024]; + while(in.getline(line, 1024)) + { + string s = line; + if(s.find(_moduleTag) == 0) + { + if(state != PreModules) + { + break; + } + state = InModules; + } + else if(s.find(_submoduleTag) == 0) + { + if(state != InModules) + { + break; + } + state = InSubmodules; + } + else if(s.find("import") == 0) + { + if(state == PreModules) + { + continue; + } + + if(s.size() < 8) + { + ostringstream os; + os << "invalid line `" << s << "' in `" << initPath << "'"; + throw os.str(); + } + + string name = s.substr(7); + if(state == InModules) + { + modules.push_back(name); + } + else + { + // + // This case occurs in old (Ice <= 3.5.1) code that used implicit + // relative imports, such as: + // + // File: outer/__init__.py + // + // import inner + // + // These aren't supported in Python 3. We'll translate these into + // explicit relative imports: + // + // from . import inner + // + submodules.push_back(name); + } + } + else if(s.find("from . import") == 0) + { + if(state != InSubmodules) + { + ostringstream os; + os << "invalid line `" << s << "' in `" << initPath << "'"; + throw os.str(); + } + + if(s.size() < 15) + { + ostringstream os; + os << "invalid line `" << s << "' in `" << initPath << "'"; + throw os.str(); + } + + submodules.push_back(s.substr(14)); + } + } + + if(state != InSubmodules) + { + ostringstream os; + os << "invalid format in `" << initPath << "'" << endl; + throw os.str(); + } + } +} + +void +PackageVisitor::writeInit(const string& dir, const string& name, const StringList& modules, + const StringList& submodules) +{ + string initPath = dir + "/__init__.py"; + + ofstream os(initPath.c_str()); + if(!os) + { + ostringstream os; + os << "cannot open file `" << initPath << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); + } + FileTracker::instance()->addFile(initPath); + + os << "# Generated by slice2py - DO NOT EDIT!" << endl + << "#" << endl; + os << endl + << "import Ice" << endl + << "Ice.updateModule(\"" << name << "\")" << endl + << endl; + os << _moduleTag << endl; + for(StringList::const_iterator p = modules.begin(); p != modules.end(); ++p) + { + os << "import " << *p << endl; + } + + os << endl; + os << _submoduleTag << endl; + for(StringList::const_iterator p = submodules.begin(); p != submodules.end(); ++p) + { + os << "from . import " << *p << endl; + } +} + +void +usage(const char* n) +{ + getErrorStream() << "Usage: " << n << " [options] slice-files...\n"; + getErrorStream() << + "Options:\n" + "-h, --help Show this message.\n" + "-v, --version Display the Ice version.\n" + "-DNAME Define NAME as 1.\n" + "-DNAME=DEF Define NAME as DEF.\n" + "-UNAME Remove any definition for NAME.\n" + "-IDIR Put DIR in the include file search path.\n" + "-E Print preprocessor output on stdout.\n" + "--output-dir DIR Create files in the directory DIR.\n" + "--depend Generate Makefile dependencies.\n" + "-d, --debug Print debug messages.\n" + "--ice Permit `Ice' prefix (for building Ice source code only).\n" + "--underscore Permit underscores in Slice identifiers.\n" + "--all Generate code for Slice definitions in included files.\n" + "--checksum Generate checksums for Slice definitions.\n" + "--prefix PREFIX Prepend filenames of Python modules with PREFIX.\n" + ; +} + +} + +int +Slice::Python::compile(int argc, char* argv[]) +{ + IceUtilInternal::Options opts; + opts.addOpt("h", "help"); + opts.addOpt("v", "version"); + opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); + opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); + opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); + opts.addOpt("E"); + opts.addOpt("", "output-dir", IceUtilInternal::Options::NeedArg); + opts.addOpt("", "depend"); + opts.addOpt("d", "debug"); + opts.addOpt("", "ice"); + opts.addOpt("", "underscore"); + opts.addOpt("", "all"); + opts.addOpt("", "no-package"); + opts.addOpt("", "checksum"); + opts.addOpt("", "prefix", IceUtilInternal::Options::NeedArg); + + vector<string> args; + try + { + args = opts.parse(argc, const_cast<const char**>(argv)); + } + catch(const IceUtilInternal::BadOptException& e) + { + getErrorStream() << argv[0] << ": error: " << e.reason << endl; + usage(argv[0]); + return EXIT_FAILURE; + } + + if(opts.isSet("help")) + { + usage(argv[0]); + return EXIT_SUCCESS; + } + + if(opts.isSet("version")) + { + getErrorStream() << ICE_STRING_VERSION << endl; + return EXIT_SUCCESS; + } + + vector<string> cppArgs; + vector<string> optargs = opts.argVec("D"); + for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) + { + cppArgs.push_back("-D" + *i); + } + + optargs = opts.argVec("U"); + for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) + { + cppArgs.push_back("-U" + *i); + } + + vector<string> includePaths = opts.argVec("I"); + for(vector<string>::const_iterator i = includePaths.begin(); i != includePaths.end(); ++i) + { + cppArgs.push_back("-I" + Preprocessor::normalizeIncludePath(*i)); + } + + bool preprocess = opts.isSet("E"); + + string output = opts.optArg("output-dir"); + + bool depend = opts.isSet("depend"); + + bool debug = opts.isSet("debug"); + + bool ice = opts.isSet("ice"); + + bool underscore = opts.isSet("underscore"); + + bool all = opts.isSet("all"); + + bool noPackage = opts.isSet("no-package"); + + bool checksum = opts.isSet("checksum"); + + string prefix = opts.optArg("prefix"); + + if(args.empty()) + { + getErrorStream() << argv[0] << ": error: no input file" << endl; + usage(argv[0]); + return EXIT_FAILURE; + } + + int status = EXIT_SUCCESS; + + IceUtil::CtrlCHandler ctrlCHandler; + ctrlCHandler.setCallback(interruptedCallback); + + bool keepComments = true; + + for(vector<string>::const_iterator i = args.begin(); i != args.end(); ++i) + { + // + // Ignore duplicates. + // + vector<string>::iterator p = find(args.begin(), args.end(), *i); + if(p != i) + { + continue; + } + + if(depend) + { + PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); + FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2PY__"); + + if(cppHandle == 0) + { + return EXIT_FAILURE; + } + + UnitPtr u = Unit::createUnit(false, false, ice, underscore); + int parseStatus = u->parse(*i, cppHandle, debug); + u->destroy(); + + if(parseStatus == EXIT_FAILURE) + { + return EXIT_FAILURE; + } + + if(!icecpp->printMakefileDependencies(Preprocessor::Python, includePaths, + "-D__SLICE2PY__", "", prefix)) + { + return EXIT_FAILURE; + } + + if(!icecpp->close()) + { + return EXIT_FAILURE; + } + } + else + { + PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); + FILE* cppHandle = icecpp->preprocess(keepComments, "-D__SLICE2PY__"); + + if(cppHandle == 0) + { + return EXIT_FAILURE; + } + + if(preprocess) + { + char buf[4096]; + while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL) + { + if(fputs(buf, stdout) == EOF) + { + return EXIT_FAILURE; + } + } + if(!icecpp->close()) + { + return EXIT_FAILURE; + } + } + else + { + UnitPtr u = Unit::createUnit(false, all, ice, underscore); + int parseStatus = u->parse(*i, cppHandle, debug); + + if(!icecpp->close()) + { + u->destroy(); + return EXIT_FAILURE; + } + + if(parseStatus == EXIT_FAILURE) + { + status = EXIT_FAILURE; + } + else + { + string base = icecpp->getBaseName(); + string::size_type pos = base.find_last_of("/\\"); + if(pos != string::npos) + { + base.erase(0, pos + 1); + } + + // + // Append the suffix "_ice" to the filename in order to avoid any conflicts + // with Slice module names. For example, if the file Test.ice defines a + // Slice module named "Test", then we couldn't create a Python package named + // "Test" and also call the generated file "Test.py". + // + string file = prefix + base + "_ice.py"; + if(!output.empty()) + { + file = output + '/' + file; + } + + try + { + IceUtilInternal::Output out; + out.open(file.c_str()); + if(!out) + { + ostringstream os; + os << "cannot open`" << file << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); + } + FileTracker::instance()->addFile(file); + + printHeader(out); + printGeneratedHeader(out, base + ".ice", "#"); + // + // Generate the Python mapping. + // + generate(u, all, checksum, includePaths, out); + + out.close(); + + // + // Create or update the Python package hierarchy. + // + if(!noPackage) + { + PackageVisitor::createModules(u, prefix + base + "_ice", output); + } + } + catch(const Slice::FileException& ex) + { + // If a file could not be created, then cleanup any + // created files. + FileTracker::instance()->cleanup(); + u->destroy(); + getErrorStream() << argv[0] << ": error: " << ex.reason() << endl; + return EXIT_FAILURE; + } + catch(const string& err) + { + FileTracker::instance()->cleanup(); + getErrorStream() << argv[0] << ": error: " << err << endl; + status = EXIT_FAILURE; + } + } + + u->destroy(); + } + } + + { + IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex); + + if(interrupted) + { + FileTracker::instance()->cleanup(); + return EXIT_FAILURE; + } + } + } + + return status; +} diff --git a/cpp/src/Slice/Ruby.cpp b/cpp/src/Slice/Ruby.cpp new file mode 100644 index 00000000000..c623bfc8696 --- /dev/null +++ b/cpp/src/Slice/Ruby.cpp @@ -0,0 +1,317 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/DisableWarnings.h> +#include <IceUtil/Options.h> +#include <IceUtil/CtrlCHandler.h> +#include <IceUtil/Mutex.h> +#include <IceUtil/MutexPtrLock.h> +#include <Slice/Preprocessor.h> +#include <Slice/FileTracker.h> +#include <Slice/RubyUtil.h> +#include <Slice/Util.h> + +#include <string.h> + +using namespace std; +using namespace Slice; +using namespace Slice::Ruby; + +namespace +{ + +IceUtil::Mutex* globalMutex = 0; +bool interrupted = false; + +class Init +{ +public: + + Init() + { + globalMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete globalMutex; + globalMutex = 0; + } +}; + +Init init; + +void +interruptedCallback(int /*signal*/) +{ + IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex); + + interrupted = true; +} + +void +usage(const char* n) +{ + getErrorStream() << "Usage: " << n << " [options] slice-files...\n"; + getErrorStream() << + "Options:\n" + "-h, --help Show this message.\n" + "-v, --version Display the Ice version.\n" + "-DNAME Define NAME as 1.\n" + "-DNAME=DEF Define NAME as DEF.\n" + "-UNAME Remove any definition for NAME.\n" + "-IDIR Put DIR in the include file search path.\n" + "-E Print preprocessor output on stdout.\n" + "--output-dir DIR Create files in the directory DIR.\n" + "--depend Generate Makefile dependencies.\n" + "-d, --debug Print debug messages.\n" + "--ice Permit `Ice' prefix (for building Ice source code only).\n" + "--underscore Permit underscores in Slice identifiers.\n" + "--all Generate code for Slice definitions in included files.\n" + "--checksum Generate checksums for Slice definitions.\n" + ; +} + +} + +int +Slice::Ruby::compile(int argc, char* argv[]) +{ + IceUtilInternal::Options opts; + opts.addOpt("h", "help"); + opts.addOpt("v", "version"); + opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); + opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); + opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); + opts.addOpt("E"); + opts.addOpt("", "output-dir", IceUtilInternal::Options::NeedArg); + opts.addOpt("", "depend"); + opts.addOpt("d", "debug"); + opts.addOpt("", "ice"); + opts.addOpt("", "underscore"); + opts.addOpt("", "all"); + opts.addOpt("", "checksum"); + + vector<string> args; + try + { + args = opts.parse(argc, const_cast<const char**>(argv)); + } + catch(const IceUtilInternal::BadOptException& e) + { + getErrorStream() << argv[0] << ": error: " << e.reason << endl; + usage(argv[0]); + return EXIT_FAILURE; + } + + if(opts.isSet("help")) + { + usage(argv[0]); + return EXIT_SUCCESS; + } + + if(opts.isSet("version")) + { + getErrorStream() << ICE_STRING_VERSION << endl; + return EXIT_SUCCESS; + } + + vector<string> cppArgs; + vector<string> optargs = opts.argVec("D"); + for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) + { + cppArgs.push_back("-D" + *i); + } + + optargs = opts.argVec("U"); + for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) + { + cppArgs.push_back("-U" + *i); + } + + vector<string> includePaths = opts.argVec("I"); + for(vector<string>::const_iterator i = includePaths.begin(); i != includePaths.end(); ++i) + { + cppArgs.push_back("-I" + Preprocessor::normalizeIncludePath(*i)); + } + + bool preprocess = opts.isSet("E"); + + string output = opts.optArg("output-dir"); + + bool depend = opts.isSet("depend"); + + bool debug = opts.isSet("debug"); + + bool ice = opts.isSet("ice"); + + bool underscore = opts.isSet("underscore"); + + bool all = opts.isSet("all"); + + bool checksum = opts.isSet("checksum"); + + if(args.empty()) + { + getErrorStream() << argv[0] << ": error: no input file" << endl; + usage(argv[0]); + return EXIT_FAILURE; + } + + int status = EXIT_SUCCESS; + + IceUtil::CtrlCHandler ctrlCHandler; + ctrlCHandler.setCallback(interruptedCallback); + + for(vector<string>::const_iterator i = args.begin(); i != args.end(); ++i) + { + // + // Ignore duplicates. + // + vector<string>::iterator p = find(args.begin(), args.end(), *i); + if(p != i) + { + continue; + } + + if(depend) + { + PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); + FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2RB__"); + + if(cppHandle == 0) + { + return EXIT_FAILURE; + } + + UnitPtr u = Unit::createUnit(false, false, ice, underscore); + int parseStatus = u->parse(*i, cppHandle, debug); + u->destroy(); + + if(parseStatus == EXIT_FAILURE) + { + return EXIT_FAILURE; + } + + if(!icecpp->printMakefileDependencies(Preprocessor::Ruby, includePaths, + "-D__SLICE2RB__")) + { + return EXIT_FAILURE; + } + + if(!icecpp->close()) + { + return EXIT_FAILURE; + } + } + else + { + PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); + FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2RB__"); + + if(cppHandle == 0) + { + return EXIT_FAILURE; + } + + if(preprocess) + { + char buf[4096]; + while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL) + { + if(fputs(buf, stdout) == EOF) + { + return EXIT_FAILURE; + } + } + if(!icecpp->close()) + { + return EXIT_FAILURE; + } + } + else + { + UnitPtr u = Unit::createUnit(false, all, ice, underscore); + int parseStatus = u->parse(*i, cppHandle, debug); + + if(!icecpp->close()) + { + u->destroy(); + return EXIT_FAILURE; + } + + if(parseStatus == EXIT_FAILURE) + { + status = EXIT_FAILURE; + } + else + { + string base = icecpp->getBaseName(); + string::size_type pos = base.find_last_of("/\\"); + if(pos != string::npos) + { + base.erase(0, pos + 1); + } + + string file = base + ".rb"; + if(!output.empty()) + { + file = output + '/' + file; + } + + try + { + IceUtilInternal::Output out; + out.open(file.c_str()); + if(!out) + { + ostringstream os; + os << "cannot open`" << file << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); + } + FileTracker::instance()->addFile(file); + + printHeader(out); + printGeneratedHeader(out, base + ".ice", "#"); + + // + // Generate the Ruby mapping. + // + generate(u, all, checksum, includePaths, out); + + out.close(); + } + catch(const Slice::FileException& ex) + { + // If a file could not be created, then cleanup + // any created files. + FileTracker::instance()->cleanup(); + u->destroy(); + getErrorStream() << argv[0] << ": error: " << ex.reason() << endl; + return EXIT_FAILURE; + } + } + + u->destroy(); + } + } + + { + IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex); + + if(interrupted) + { + FileTracker::instance()->cleanup(); + return EXIT_FAILURE; + } + } + } + + return status; +} diff --git a/cpp/src/slice2py/Main.cpp b/cpp/src/slice2py/Main.cpp index 3e9a634ac46..749749ff1bd 100644 --- a/cpp/src/slice2py/Main.cpp +++ b/cpp/src/slice2py/Main.cpp @@ -7,678 +7,19 @@ // // ********************************************************************** -#include <IceUtil/DisableWarnings.h> -#include <IceUtil/IceUtil.h> -#include <IceUtil/Options.h> -#include <IceUtil/StringUtil.h> -#include <IceUtil/CtrlCHandler.h> -#include <IceUtil/Mutex.h> -#include <IceUtil/MutexPtrLock.h> -#include <Slice/Preprocessor.h> -#include <Slice/FileTracker.h> #include <Slice/PythonUtil.h> #include <Slice/Util.h> -#include <cstring> - -#include <fstream> - -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef _WIN32 -#include <direct.h> -#endif - -#ifndef _WIN32 -#include <unistd.h> -#endif using namespace std; using namespace Slice; using namespace Slice::Python; -namespace -{ - -IceUtil::Mutex* globalMutex = 0; -bool interrupted = false; - -class Init -{ -public: - - Init() - { - globalMutex = new IceUtil::Mutex; - } - - ~Init() - { - delete globalMutex; - globalMutex = 0; - } -}; - -Init init; - -} - -void -interruptedCallback(int /*signal*/) -{ - IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex); - - interrupted = true; -} - -// -// For each Slice file Foo.ice we generate Foo_ice.py containing the Python -// mappings. Furthermore, for each Slice module M in Foo.ice, we create a -// Python package of the same name. This package is simply a subdirectory -// containing the special file "__init__.py" that is executed when a Python -// script executes the statement "import M". -// -// Inside __init__.py we add an import statement for Foo_ice, causing -// Foo_ice to be imported implicitly when M is imported. -// -// Of course, another Slice file Bar.ice may contain definitions for the -// same Slice module M, in which case the __init__.py file for M is modified -// to contain an additional import statement for Bar_ice. Therefore a -// Python script executing "import M" implicitly imports the definitions -// from both Foo_ice and Bar_ice. -// -// The __init__.py file also contains import statements for submodules, -// so that importing the top-level module automatically imports all of -// its submodules. -// -// The PackageVisitor class creates the directory hierarchy to mirror the -// Slice module hierarchy, and updates the __init__.py files as necessary. -// -class PackageVisitor : public ParserVisitor -{ -public: - - static void createModules(const UnitPtr&, const string&, const string&); - - virtual void visitModuleEnd(const ModulePtr&); - -private: - - PackageVisitor(StringList&); - - enum ReadState { PreModules, InModules, InSubmodules }; - - static const char* _moduleTag; - static const char* _submoduleTag; - - static void createDirectory(const string&); - - static void addModule(const string&, const string&, const string&); - static void addSubmodule(const string&, const string&, const string&); - - static void readInit(const string&, StringList&, StringList&); - static void writeInit(const string&, const string&, const StringList&, const StringList&); - - StringList& _modules; -}; - -const char* PackageVisitor::_moduleTag = "# Modules:"; -const char* PackageVisitor::_submoduleTag = "# Submodules:"; - -PackageVisitor::PackageVisitor(StringList& modules) : - _modules(modules) -{ -} - -void -PackageVisitor::createModules(const UnitPtr& unit, const string& module, const string& dir) -{ - StringList modules; - PackageVisitor v(modules); - unit->visit(&v, false); - - for(StringList::iterator p = modules.begin(); p != modules.end(); ++p) - { - vector<string> v; - if(!IceUtilInternal::splitString(*p, ".", v)) - { - assert(false); - } - string currentModule; - string path = dir.empty() ? "." : dir; - for(vector<string>::iterator q = v.begin(); q != v.end(); ++q) - { - if(q != v.begin()) - { - addSubmodule(path, currentModule, *q); - currentModule += "."; - } - - currentModule += *q; - path += "/" + *q; - createDirectory(path); - - addModule(path, currentModule, module); - } - } -} - -void -PackageVisitor::visitModuleEnd(const ModulePtr& p) -{ - // - // Collect the most deeply-nested modules. For example, if we have a - // module named M.N.O, then we don't need to keep M or M.N in the list. - // - string abs = getAbsolute(p); - if(find(_modules.begin(), _modules.end(), abs) == _modules.end()) - { - _modules.push_back(abs); - } - string::size_type pos = abs.rfind('.'); - if(pos != string::npos) - { - string parent = abs.substr(0, pos); - _modules.remove(parent); - } -} - -void -PackageVisitor::createDirectory(const string& dir) -{ - struct stat st; - int result; - result = stat(dir.c_str(), &st); - if(result == 0) - { - if(!(st.st_mode & S_IFDIR)) - { - ostringstream os; - os << "failed to create package directory `" << dir - << "': file already exists and is not a directory"; - throw FileException(__FILE__, __LINE__, os.str()); - } - return; - } -#ifdef _WIN32 - result = _mkdir(dir.c_str()); -#else - result = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); -#endif - - if(result != 0) - { - ostringstream os; - os << "cannot create directory `" << dir << "': " << strerror(errno); - throw FileException(__FILE__, __LINE__, os.str()); - } - - FileTracker::instance()->addDirectory(dir); -} - -void -PackageVisitor::addModule(const string& dir, const string& module, const string& name) -{ - // - // Add a module to the set of imported modules in __init__.py. - // - StringList modules, submodules; - readInit(dir, modules, submodules); - StringList::iterator p = find(modules.begin(), modules.end(), name); - if(p == modules.end()) - { - modules.push_back(name); - writeInit(dir, module, modules, submodules); - } -} - -void -PackageVisitor::addSubmodule(const string& dir, const string& module, const string& name) -{ - // - // Add a submodule to the set of imported modules in __init__.py. - // - StringList modules, submodules; - readInit(dir, modules, submodules); - StringList::iterator p = find(submodules.begin(), submodules.end(), name); - if(p == submodules.end()) - { - submodules.push_back(name); - writeInit(dir, module, modules, submodules); - } -} - -void -PackageVisitor::readInit(const string& dir, StringList& modules, StringList& submodules) -{ - string initPath = dir + "/__init__.py"; - - struct stat st; - if(stat(initPath.c_str(), &st) == 0) - { - ifstream in(initPath.c_str()); - if(!in) - { - ostringstream os; - os << "cannot open file `" << initPath << "': " << strerror(errno); - throw FileException(__FILE__, __LINE__, os.str()); - } - - ReadState state = PreModules; - char line[1024]; - while(in.getline(line, 1024)) - { - string s = line; - if(s.find(_moduleTag) == 0) - { - if(state != PreModules) - { - break; - } - state = InModules; - } - else if(s.find(_submoduleTag) == 0) - { - if(state != InModules) - { - break; - } - state = InSubmodules; - } - else if(s.find("import") == 0) - { - if(state == PreModules) - { - continue; - } - - if(s.size() < 8) - { - ostringstream os; - os << "invalid line `" << s << "' in `" << initPath << "'"; - throw os.str(); - } - - string name = s.substr(7); - if(state == InModules) - { - modules.push_back(name); - } - else - { - // - // This case occurs in old (Ice <= 3.5.1) code that used implicit - // relative imports, such as: - // - // File: outer/__init__.py - // - // import inner - // - // These aren't supported in Python 3. We'll translate these into - // explicit relative imports: - // - // from . import inner - // - submodules.push_back(name); - } - } - else if(s.find("from . import") == 0) - { - if(state != InSubmodules) - { - ostringstream os; - os << "invalid line `" << s << "' in `" << initPath << "'"; - throw os.str(); - } - - if(s.size() < 15) - { - ostringstream os; - os << "invalid line `" << s << "' in `" << initPath << "'"; - throw os.str(); - } - - submodules.push_back(s.substr(14)); - } - } - - if(state != InSubmodules) - { - ostringstream os; - os << "invalid format in `" << initPath << "'" << endl; - throw os.str(); - } - } -} - -void -PackageVisitor::writeInit(const string& dir, const string& name, const StringList& modules, - const StringList& submodules) -{ - string initPath = dir + "/__init__.py"; - - ofstream os(initPath.c_str()); - if(!os) - { - ostringstream os; - os << "cannot open file `" << initPath << "': " << strerror(errno); - throw FileException(__FILE__, __LINE__, os.str()); - } - FileTracker::instance()->addFile(initPath); - - os << "# Generated by slice2py - DO NOT EDIT!" << endl - << "#" << endl; - os << endl - << "import Ice" << endl - << "Ice.updateModule(\"" << name << "\")" << endl - << endl; - os << _moduleTag << endl; - for(StringList::const_iterator p = modules.begin(); p != modules.end(); ++p) - { - os << "import " << *p << endl; - } - - os << endl; - os << _submoduleTag << endl; - for(StringList::const_iterator p = submodules.begin(); p != submodules.end(); ++p) - { - os << "from . import " << *p << endl; - } -} - -void -usage(const char* n) -{ - getErrorStream() << "Usage: " << n << " [options] slice-files...\n"; - getErrorStream() << - "Options:\n" - "-h, --help Show this message.\n" - "-v, --version Display the Ice version.\n" - "-DNAME Define NAME as 1.\n" - "-DNAME=DEF Define NAME as DEF.\n" - "-UNAME Remove any definition for NAME.\n" - "-IDIR Put DIR in the include file search path.\n" - "-E Print preprocessor output on stdout.\n" - "--output-dir DIR Create files in the directory DIR.\n" - "--depend Generate Makefile dependencies.\n" - "-d, --debug Print debug messages.\n" - "--ice Permit `Ice' prefix (for building Ice source code only).\n" - "--underscore Permit underscores in Slice identifiers.\n" - "--all Generate code for Slice definitions in included files.\n" - "--checksum Generate checksums for Slice definitions.\n" - "--prefix PREFIX Prepend filenames of Python modules with PREFIX.\n" - ; -} - -int -compile(int argc, char* argv[]) -{ - IceUtilInternal::Options opts; - opts.addOpt("h", "help"); - opts.addOpt("v", "version"); - opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("E"); - opts.addOpt("", "output-dir", IceUtilInternal::Options::NeedArg); - opts.addOpt("", "depend"); - opts.addOpt("d", "debug"); - opts.addOpt("", "ice"); - opts.addOpt("", "underscore"); - opts.addOpt("", "all"); - opts.addOpt("", "no-package"); - opts.addOpt("", "checksum"); - opts.addOpt("", "prefix", IceUtilInternal::Options::NeedArg); - - vector<string> args; - try - { - args = opts.parse(argc, const_cast<const char**>(argv)); - } - catch(const IceUtilInternal::BadOptException& e) - { - getErrorStream() << argv[0] << ": error: " << e.reason << endl; - usage(argv[0]); - return EXIT_FAILURE; - } - - if(opts.isSet("help")) - { - usage(argv[0]); - return EXIT_SUCCESS; - } - - if(opts.isSet("version")) - { - getErrorStream() << ICE_STRING_VERSION << endl; - return EXIT_SUCCESS; - } - - vector<string> cppArgs; - vector<string> optargs = opts.argVec("D"); - for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) - { - cppArgs.push_back("-D" + *i); - } - - optargs = opts.argVec("U"); - for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) - { - cppArgs.push_back("-U" + *i); - } - - vector<string> includePaths = opts.argVec("I"); - for(vector<string>::const_iterator i = includePaths.begin(); i != includePaths.end(); ++i) - { - cppArgs.push_back("-I" + Preprocessor::normalizeIncludePath(*i)); - } - - bool preprocess = opts.isSet("E"); - - string output = opts.optArg("output-dir"); - - bool depend = opts.isSet("depend"); - - bool debug = opts.isSet("debug"); - - bool ice = opts.isSet("ice"); - - bool underscore = opts.isSet("underscore"); - - bool all = opts.isSet("all"); - - bool noPackage = opts.isSet("no-package"); - - bool checksum = opts.isSet("checksum"); - - string prefix = opts.optArg("prefix"); - - if(args.empty()) - { - getErrorStream() << argv[0] << ": error: no input file" << endl; - usage(argv[0]); - return EXIT_FAILURE; - } - - int status = EXIT_SUCCESS; - - IceUtil::CtrlCHandler ctrlCHandler; - ctrlCHandler.setCallback(interruptedCallback); - - bool keepComments = true; - - for(vector<string>::const_iterator i = args.begin(); i != args.end(); ++i) - { - // - // Ignore duplicates. - // - vector<string>::iterator p = find(args.begin(), args.end(), *i); - if(p != i) - { - continue; - } - - if(depend) - { - PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); - FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2PY__"); - - if(cppHandle == 0) - { - return EXIT_FAILURE; - } - - UnitPtr u = Unit::createUnit(false, false, ice, underscore); - int parseStatus = u->parse(*i, cppHandle, debug); - u->destroy(); - - if(parseStatus == EXIT_FAILURE) - { - return EXIT_FAILURE; - } - - if(!icecpp->printMakefileDependencies(Preprocessor::Python, includePaths, - "-D__SLICE2PY__", "", prefix)) - { - return EXIT_FAILURE; - } - - if(!icecpp->close()) - { - return EXIT_FAILURE; - } - } - else - { - PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); - FILE* cppHandle = icecpp->preprocess(keepComments, "-D__SLICE2PY__"); - - if(cppHandle == 0) - { - return EXIT_FAILURE; - } - - if(preprocess) - { - char buf[4096]; - while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL) - { - if(fputs(buf, stdout) == EOF) - { - return EXIT_FAILURE; - } - } - if(!icecpp->close()) - { - return EXIT_FAILURE; - } - } - else - { - UnitPtr u = Unit::createUnit(false, all, ice, underscore); - int parseStatus = u->parse(*i, cppHandle, debug); - - if(!icecpp->close()) - { - u->destroy(); - return EXIT_FAILURE; - } - - if(parseStatus == EXIT_FAILURE) - { - status = EXIT_FAILURE; - } - else - { - string base = icecpp->getBaseName(); - string::size_type pos = base.find_last_of("/\\"); - if(pos != string::npos) - { - base.erase(0, pos + 1); - } - - // - // Append the suffix "_ice" to the filename in order to avoid any conflicts - // with Slice module names. For example, if the file Test.ice defines a - // Slice module named "Test", then we couldn't create a Python package named - // "Test" and also call the generated file "Test.py". - // - string file = prefix + base + "_ice.py"; - if(!output.empty()) - { - file = output + '/' + file; - } - - try - { - IceUtilInternal::Output out; - out.open(file.c_str()); - if(!out) - { - ostringstream os; - os << "cannot open`" << file << "': " << strerror(errno); - throw FileException(__FILE__, __LINE__, os.str()); - } - FileTracker::instance()->addFile(file); - - printHeader(out); - printGeneratedHeader(out, base + ".ice", "#"); - // - // Generate the Python mapping. - // - generate(u, all, checksum, includePaths, out); - - out.close(); - - // - // Create or update the Python package hierarchy. - // - if(!noPackage) - { - PackageVisitor::createModules(u, prefix + base + "_ice", output); - } - } - catch(const Slice::FileException& ex) - { - // If a file could not be created, then cleanup any - // created files. - FileTracker::instance()->cleanup(); - u->destroy(); - getErrorStream() << argv[0] << ": error: " << ex.reason() << endl; - return EXIT_FAILURE; - } - catch(const string& err) - { - FileTracker::instance()->cleanup(); - getErrorStream() << argv[0] << ": error: " << err << endl; - status = EXIT_FAILURE; - } - } - - u->destroy(); - } - } - - { - IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex); - - if(interrupted) - { - FileTracker::instance()->cleanup(); - return EXIT_FAILURE; - } - } - } - - return status; -} - int main(int argc, char* argv[]) { try { - return compile(argc, argv); + return Slice::Python::compile(argc, argv); } catch(const std::exception& ex) { diff --git a/cpp/src/slice2rb/Main.cpp b/cpp/src/slice2rb/Main.cpp index 11714d2263e..337e01044c2 100644 --- a/cpp/src/slice2rb/Main.cpp +++ b/cpp/src/slice2rb/Main.cpp @@ -7,332 +7,19 @@ // // ********************************************************************** -#include <IceUtil/DisableWarnings.h> -#include <IceUtil/Options.h> -#include <IceUtil/CtrlCHandler.h> -#include <IceUtil/Mutex.h> -#include <IceUtil/MutexPtrLock.h> -#include <Slice/Preprocessor.h> -#include <Slice/FileTracker.h> #include <Slice/RubyUtil.h> #include <Slice/Util.h> -#include <fstream> - -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef _WIN32 -# include <direct.h> -#else -# include <unistd.h> -#endif - -#include <string.h> - using namespace std; using namespace Slice; using namespace Slice::Ruby; -namespace -{ - -IceUtil::Mutex* globalMutex = 0; -bool interrupted = false; - -class Init -{ -public: - - Init() - { - globalMutex = new IceUtil::Mutex; - } - - ~Init() - { - delete globalMutex; - globalMutex = 0; - } -}; - -Init init; - -} - -void -interruptedCallback(int /*signal*/) -{ - IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex); - - interrupted = true; -} - -void -usage(const char* n) -{ - getErrorStream() << "Usage: " << n << " [options] slice-files...\n"; - getErrorStream() << - "Options:\n" - "-h, --help Show this message.\n" - "-v, --version Display the Ice version.\n" - "-DNAME Define NAME as 1.\n" - "-DNAME=DEF Define NAME as DEF.\n" - "-UNAME Remove any definition for NAME.\n" - "-IDIR Put DIR in the include file search path.\n" - "-E Print preprocessor output on stdout.\n" - "--output-dir DIR Create files in the directory DIR.\n" - "--depend Generate Makefile dependencies.\n" - "-d, --debug Print debug messages.\n" - "--ice Permit `Ice' prefix (for building Ice source code only).\n" - "--underscore Permit underscores in Slice identifiers.\n" - "--all Generate code for Slice definitions in included files.\n" - "--checksum Generate checksums for Slice definitions.\n" - ; -} - -int -compile(int argc, char* argv[]) -{ - IceUtilInternal::Options opts; - opts.addOpt("h", "help"); - opts.addOpt("v", "version"); - opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("E"); - opts.addOpt("", "output-dir", IceUtilInternal::Options::NeedArg); - opts.addOpt("", "depend"); - opts.addOpt("d", "debug"); - opts.addOpt("", "ice"); - opts.addOpt("", "underscore"); - opts.addOpt("", "all"); - opts.addOpt("", "checksum"); - - vector<string> args; - try - { - args = opts.parse(argc, const_cast<const char**>(argv)); - } - catch(const IceUtilInternal::BadOptException& e) - { - getErrorStream() << argv[0] << ": error: " << e.reason << endl; - usage(argv[0]); - return EXIT_FAILURE; - } - - if(opts.isSet("help")) - { - usage(argv[0]); - return EXIT_SUCCESS; - } - - if(opts.isSet("version")) - { - getErrorStream() << ICE_STRING_VERSION << endl; - return EXIT_SUCCESS; - } - - vector<string> cppArgs; - vector<string> optargs = opts.argVec("D"); - for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) - { - cppArgs.push_back("-D" + *i); - } - - optargs = opts.argVec("U"); - for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) - { - cppArgs.push_back("-U" + *i); - } - - vector<string> includePaths = opts.argVec("I"); - for(vector<string>::const_iterator i = includePaths.begin(); i != includePaths.end(); ++i) - { - cppArgs.push_back("-I" + Preprocessor::normalizeIncludePath(*i)); - } - - bool preprocess = opts.isSet("E"); - - string output = opts.optArg("output-dir"); - - bool depend = opts.isSet("depend"); - - bool debug = opts.isSet("debug"); - - bool ice = opts.isSet("ice"); - - bool underscore = opts.isSet("underscore"); - - bool all = opts.isSet("all"); - - bool checksum = opts.isSet("checksum"); - - if(args.empty()) - { - getErrorStream() << argv[0] << ": error: no input file" << endl; - usage(argv[0]); - return EXIT_FAILURE; - } - - int status = EXIT_SUCCESS; - - IceUtil::CtrlCHandler ctrlCHandler; - ctrlCHandler.setCallback(interruptedCallback); - - for(vector<string>::const_iterator i = args.begin(); i != args.end(); ++i) - { - // - // Ignore duplicates. - // - vector<string>::iterator p = find(args.begin(), args.end(), *i); - if(p != i) - { - continue; - } - - if(depend) - { - PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); - FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2RB__"); - - if(cppHandle == 0) - { - return EXIT_FAILURE; - } - - UnitPtr u = Unit::createUnit(false, false, ice, underscore); - int parseStatus = u->parse(*i, cppHandle, debug); - u->destroy(); - - if(parseStatus == EXIT_FAILURE) - { - return EXIT_FAILURE; - } - - if(!icecpp->printMakefileDependencies(Preprocessor::Ruby, includePaths, - "-D__SLICE2RB__")) - { - return EXIT_FAILURE; - } - - if(!icecpp->close()) - { - return EXIT_FAILURE; - } - } - else - { - PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); - FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2RB__"); - - if(cppHandle == 0) - { - return EXIT_FAILURE; - } - - if(preprocess) - { - char buf[4096]; - while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL) - { - if(fputs(buf, stdout) == EOF) - { - return EXIT_FAILURE; - } - } - if(!icecpp->close()) - { - return EXIT_FAILURE; - } - } - else - { - UnitPtr u = Unit::createUnit(false, all, ice, underscore); - int parseStatus = u->parse(*i, cppHandle, debug); - - if(!icecpp->close()) - { - u->destroy(); - return EXIT_FAILURE; - } - - if(parseStatus == EXIT_FAILURE) - { - status = EXIT_FAILURE; - } - else - { - string base = icecpp->getBaseName(); - string::size_type pos = base.find_last_of("/\\"); - if(pos != string::npos) - { - base.erase(0, pos + 1); - } - - string file = base + ".rb"; - if(!output.empty()) - { - file = output + '/' + file; - } - - try - { - IceUtilInternal::Output out; - out.open(file.c_str()); - if(!out) - { - ostringstream os; - os << "cannot open`" << file << "': " << strerror(errno); - throw FileException(__FILE__, __LINE__, os.str()); - } - FileTracker::instance()->addFile(file); - - printHeader(out); - printGeneratedHeader(out, base + ".ice", "#"); - - // - // Generate the Ruby mapping. - // - generate(u, all, checksum, includePaths, out); - - out.close(); - } - catch(const Slice::FileException& ex) - { - // If a file could not be created, then cleanup - // any created files. - FileTracker::instance()->cleanup(); - u->destroy(); - getErrorStream() << argv[0] << ": error: " << ex.reason() << endl; - return EXIT_FAILURE; - } - } - - u->destroy(); - } - } - - { - IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex); - - if(interrupted) - { - FileTracker::instance()->cleanup(); - return EXIT_FAILURE; - } - } - } - - return status; -} - int main(int argc, char* argv[]) { try { - return compile(argc, argv); + return Slice::Ruby::compile(argc, argv); } catch(const std::exception& ex) { |