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 | |
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')
26 files changed, 1144 insertions, 1031 deletions
diff --git a/cpp/config/Make.rules b/cpp/config/Make.rules index bbd102a1dba..e3430d15bd0 100644 --- a/cpp/config/Make.rules +++ b/cpp/config/Make.rules @@ -204,14 +204,14 @@ endif include $(top_srcdir)/config/Make.rules.$(UNAME) install_includedir := $(prefix)/include -install_docdir := $(prefix)/doc install_bindir := $(prefix)/$(binsubdir)$(cpp11suffix) install_libdir := $(prefix)/$(libsubdir)$(cpp11suffix) -install_configdir := $(prefix)/config -ifneq ($(prefix),/usr) +ifndef usr_dir_install install_mandir := $(prefix)/man/man1 +install_configdir := $(prefix)/config else +install_configdir := $(prefix)/share/config install_mandir := $(prefix)/share/man/man1 endif @@ -229,7 +229,9 @@ ifeq ($(SSL_OS_LIBS),) SSL_OS_LIBS = $(OPENSSL_LIBS) endif -BZIP2_FLAGS = $(if $(BZIP2_HOME),-I$(BZIP2_HOME)/include) +ifneq ($(BZIP2_HOME),) + BZIP2_FLAGS = I$(BZIP2_HOME)/include) +endif ifeq ($(BZIP2_LIBS),) BZIP2_LIBS = $(if $(BZIP2_HOME),-L$(BZIP2_HOME)/$(libsubdir)) -lbz2 endif @@ -289,7 +291,7 @@ ICECPPFLAGS = -I$(slicedir) SLICE2CPPFLAGS = $(ICECPPFLAGS) -ifeq ($(ice_dir), /usr) +ifeq ($(ice_dir), $(usr_dir)) LDFLAGS = $(LDPLATFORMFLAGS) $(CXXFLAGS) ifeq ($(CPP11),yes) LDFLAGS = $(LDPLATFORMFLAGS) $(CXXFLAGS) -L$(ice_dir)/$(libsubdir)$(cpp11libdirsuffix) @@ -328,7 +330,11 @@ ifeq ($(mktest),) endif ifdef ice_src_dist +ifeq ($(STATICLIBS),yes) + SLICEPARSERLIB = +else SLICEPARSERLIB = $(libdir)/$(call mklibfilename,Slice,$(VERSION)) +endif SLICE2CPP = $(bindir)/slice2cpp SLICE2FREEZE = $(bindir)/slice2freeze else @@ -352,8 +358,8 @@ ifeq ($(ICESSL_LIBS),) ICESSL_LIBS = -lIceSSL endif -EVERYTHING = all clean install -EVERYTHING_EXCEPT_ALL = clean install +EVERYTHING = all clean install compile-slice +EVERYTHING_EXCEPT_ALL = clean install compile-slice .SUFFIXES: .SUFFIXES: .cpp .c .o @@ -396,7 +402,7 @@ $(HDIR)/%F.h: $(SDIR)/%F.ice $(SLICE2CPP) $(SLICEPARSERLIB) mv $(*F)F.h $(HDIR) @touch $(*F)F.cpp @mkdir -p .depend - @$(SLICE2CPP) $(SLICE2CPPFLAGS) --depend $< | $(ice_dir)/config/makedepend.py "\$$(HDIR)/" > .depend/$(*F)F.ice.d + @$(SLICE2CPP) $(SLICE2CPPFLAGS) --depend $< | sed 's/\(.*: \\\)/\$$(HDIR)\/\1/' > .depend/$(*F)F.ice.d $(HDIR)/%.h %.cpp: $(SDIR)/%.ice $(SLICE2CPP) $(SLICEPARSERLIB) rm -f $(HDIR)/$(*F).h $(*F).cpp @@ -404,9 +410,11 @@ $(HDIR)/%.h %.cpp: $(SDIR)/%.ice $(SLICE2CPP) $(SLICEPARSERLIB) mv $(*F).h $(HDIR) @touch $(*F).cpp @mkdir -p .depend - @$(SLICE2CPP) $(SLICE2CPPFLAGS) --depend $< | $(ice_dir)/config/makedepend.py "\$$(HDIR)/" > .depend/$(*F).ice.d + @$(SLICE2CPP) $(SLICE2CPPFLAGS) --depend $< | sed 's/\(.*: \\\)/\$$(HDIR)\/\1/' > .depend/$(*F).ice.d -%.h %.cpp: %.ice $(SLICE2CPP) $(SLICEPARSERLIB) +#%.h %.cpp: %.ice $(SLICE2CPP) $(SLICEPARSERLIB) + +%.h %.cpp: %.ice $(SLICE2CPP) rm -f $(*F).h $(*F).cpp $(SLICE2CPP) $(SLICE2CPPFLAGS) $(*F).ice @touch $(*F).cpp @@ -447,4 +455,10 @@ clean:: rm -f $(addprefix $(HDIR)/, $(addsuffix .h, $(basename $(SLICE_OBJS)))) endif +ifneq ($(SLICE_OBJS),) +compile-slice:: $(SLICE_OBJS:.o=.cpp) +else +compile-slice:: +endif + install:: diff --git a/cpp/config/Make.rules.Darwin b/cpp/config/Make.rules.Darwin index 2a8cae9aee5..cf8d8b7a8fa 100644 --- a/cpp/config/Make.rules.Darwin +++ b/cpp/config/Make.rules.Darwin @@ -74,7 +74,7 @@ ifeq ($(embedded_runpath),yes) # # Clear rpath setting when doing a system install # - ifeq ($(ice_dir),/usr) + ifeq ($(ice_dir), $(usr_dir)) RPATH_DIR = endif diff --git a/cpp/config/Make.rules.Linux b/cpp/config/Make.rules.Linux index bb6fa2dbd92..6de191f0702 100644 --- a/cpp/config/Make.rules.Linux +++ b/cpp/config/Make.rules.Linux @@ -121,7 +121,7 @@ ifeq ($(CXX),g++) # # Clear the rpath dir when doing a system install. # - ifeq ($(ice_dir), /usr) + ifeq ($(ice_dir), $(usr_dir)) RPATH_DIR = endif diff --git a/cpp/config/Make.rules.MINGW b/cpp/config/Make.rules.MINGW index 65210c65822..e1d71a5f41f 100644 --- a/cpp/config/Make.rules.MINGW +++ b/cpp/config/Make.rules.MINGW @@ -14,9 +14,7 @@ # # Default compiler is c++ (aka g++). # -ifeq ($(CXX),) - CXX = c++ -endif +CXX = c++ # ICE_WIN32_WINNT sets the minimum version of Windows supported by this build # 0x600 = Windows Vista / Windows Server 2008 @@ -24,8 +22,11 @@ endif # 0x602 = Windows 8 / Windows Server 2012 ICE_WIN32_WINNT := 0x601 -CXXFLAGS = $(CXXARCHFLAGS) -mthreads -fvisibility=hidden -Wall -Werror -D_WIN32_WINNT=$(ICE_WIN32_WINNT) -DWIN32_LEAN_AND_MEAN -LDFLAGS = -Wl,-no-undefined +CXXFLAGS = $(CXXARCHFLAGS) -mthreads -Wall -Werror -D_WIN32_WINNT=$(ICE_WIN32_WINNT) -DWIN32_LEAN_AND_MEAN -DICE_STATIC_LIBS +ifeq ($(STATICLIBS),yes) +CXXFLAGS += -DICE_STATIC_LIBS +endif +LDFLAGS = -Wl,-no-undefined -static-libgcc -static-libstdc++ ifeq ($(OPTIMIZE),yes) CXXFLAGS += -O2 -DNDEBUG @@ -36,18 +37,8 @@ endif COMPSUFFIX = _mingw mklibfilename = $(shell echo $(1) | tr A-Z a-z)$(SOVERSION)$(COMPSUFFIX).dll +mklibtargets = $(3) -ifeq ($(STATICLIBS),yes) - mklibtargets = $(3) -else - mklibtargets = $(1) -endif - -# -# Shared library linking command. We transform -lxxx parameters into -# -lxxx<ver>$(COMPSUFFIX).dll here to avoid having to fix all the Makefiles -# which need to link with the MinGW libraries. -# mkshlib = $(CXX) -shared $(LDFLAGS) -o $(1) $(3) \ $(subst cpp/lib,cpp/bin, \ $(subst -lIce,-lice$(SOVERSION)$(COMPSUFFIX), \ @@ -57,16 +48,15 @@ mkshlib = $(CXX) -shared $(LDFLAGS) -o $(1) $(3) \ mklib = ar cr $(1) $(2) -ifeq ($(LP64),yes) - libsubdir := bin$(lp64suffix) - binsubdir := bin$(lp64suffix) +ifeq ($(STATICLIBS),yes) +libsubdir := lib else - libsubdir := bin - binsubdir := bin +libsubdir := bin endif +binsubdir := bin libdir := $(top_srcdir)/$(libsubdir) -bindir := $(top_srcdir)/$(libsubdir) +bindir := $(top_srcdir)/$(binsubdir) installlib = $(INSTALL) $(2)/$(3) $(1); \ chmod a+rx $(1)/$(3) @@ -81,19 +71,26 @@ SSL_OS_LIBS = -lsecur32 -lcrypt32 -lws2_32 ICEWS_OS_LIBS = -lws2_32 -ifeq ($(LP64),yes) - MCPP_LIBS = -L"$(THIRDPARTY_HOME)/lib/mingw$(lp64suffix)" -lmcpp -else - MCPP_LIBS = -L"$(THIRDPARTY_HOME)/lib/mingw" -lmcpp -endif +MCPP_LIBS = -lmcpp -BZIP2_LIBS = -lbzip2$(COMPSUFFIX) +BZIP2_LIBS = -lbz2 -BASELIBS = -liceutil$(SOVERSION)$(COMPSUFFIX) +ifeq ($(STATICLIBS),yes) +BASELIBS = -liceutil $(ICEUTIL_OS_LIBS) +LIBS = -lice $(BASELIBS) +ICESSL_LIBS = -licessl +ICEWS_LIBS = -licews +SLICE_LIBS = -lslice $(BASELIBS) +else +BASELIBS = -liceutil$(SOVERSION)$(COMPSUFFIX) $(ICEUTIL_OS_LIBS) LIBS = -lice$(SOVERSION)$(COMPSUFFIX) $(BASELIBS) ICESSL_LIBS = -licessl$(SOVERSION)$(COMPSUFFIX) ICEWS_LIBS = -licews$(SOVERSION)$(COMPSUFFIX) SLICE_LIBS = -lslice$(SOVERSION)$(COMPSUFFIX) $(BASELIBS) +endif + +MCPP_RPATH_LINK = -lmcpp +BZIP2_FLAGS = -I../../../bzip2 ICEUTIL_OS_LIBS = -lrpcrt4 -ladvapi32 ICE_OS_LIBS = $(ICEUTIL_OS_LIBS) -lIphlpapi -lws2_32 diff --git a/cpp/config/Make.rules.mak b/cpp/config/Make.rules.mak index ffb2b9a9520..c0b2b14531e 100755 --- a/cpp/config/Make.rules.mak +++ b/cpp/config/Make.rules.mak @@ -120,7 +120,6 @@ includedir = $(ice_dir)\include install_bindir = $(prefix)\bin$(x64suffix) install_libdir = $(prefix)\lib$(x64suffix) install_includedir = $(prefix)\include -install_docdir = $(prefix)\doc install_configdir = $(prefix)\config SETARGV = setargv.obj diff --git a/cpp/include/Ice/Config.h b/cpp/include/Ice/Config.h index c5ecce318c4..6acc0784de3 100644 --- a/cpp/include/Ice/Config.h +++ b/cpp/include/Ice/Config.h @@ -35,7 +35,7 @@ // // Automatically link Ice[D].lib with Visual C++ // -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(ICE_NO_PRAGMA_COMMENT) # if defined(ICE_STATIC_LIBS) # pragma comment(lib, "Ice.lib") # elif !defined(ICE_API_EXPORTS) diff --git a/cpp/include/IceSSL/Plugin.h b/cpp/include/IceSSL/Plugin.h index c5186c413cf..5a7e7ea86cc 100644 --- a/cpp/include/IceSSL/Plugin.h +++ b/cpp/include/IceSSL/Plugin.h @@ -21,10 +21,8 @@ // // Automatically link IceSSL[D].lib with Visual C++ // -#ifdef _MSC_VER -# if defined(ICE_STATIC_LIBS) -# error("IceSSL Plugin does not support static libraries") -# elif !defined(ICE_SSL_API_EXPORTS) +#if defined(_MSC_VER) && !defined(ICE_NO_PRAGMA_COMMENT) +# if !defined(ICE_STATIC_LIBS) && !defined(ICE_SSL_API_EXPORTS) # if defined(_DEBUG) # pragma comment(lib, "IceSSLD.lib") # else diff --git a/cpp/include/IceUtil/Config.h b/cpp/include/IceUtil/Config.h index 33408be817d..2436f620f97 100644 --- a/cpp/include/IceUtil/Config.h +++ b/cpp/include/IceUtil/Config.h @@ -170,7 +170,7 @@ # include <errno.h> #endif -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(ICE_NO_PRAGMA_COMMENT) # if !defined(ICE_STATIC_LIBS) && (!defined(_DLL) || !defined(_MT)) # error "Only multi-threaded DLL libraries can be used with Ice!" # endif diff --git a/cpp/include/Slice/Parser.h b/cpp/include/Slice/Parser.h index 19199e58613..d416ca6f18c 100644 --- a/cpp/include/Slice/Parser.h +++ b/cpp/include/Slice/Parser.h @@ -23,7 +23,7 @@ // // Automatically link Slice[D].lib with Visual C++ // -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(ICE_NO_PRAGMA_COMMENT) # if defined(ICE_STATIC_LIBS) # pragma comment(lib, "Slice.lib") # elif !defined(SLICE_API_EXPORTS) diff --git a/cpp/include/Slice/PythonUtil.h b/cpp/include/Slice/PythonUtil.h index 8930bc42664..9d5db3c6c99 100644 --- a/cpp/include/Slice/PythonUtil.h +++ b/cpp/include/Slice/PythonUtil.h @@ -56,6 +56,8 @@ SLICE_API std::string getAbsolute(const Slice::ContainedPtr&, const std::string& // SLICE_API void printHeader(IceUtilInternal::Output&); +SLICE_API int compile(int, char*[]); + } } diff --git a/cpp/include/Slice/RubyUtil.h b/cpp/include/Slice/RubyUtil.h index 0095d286c55..4cb97a8826f 100644 --- a/cpp/include/Slice/RubyUtil.h +++ b/cpp/include/Slice/RubyUtil.h @@ -46,6 +46,8 @@ SLICE_API std::string getAbsolute(const Slice::ContainedPtr&, IdentStyle, const // SLICE_API void printHeader(IceUtilInternal::Output&); +SLICE_API int compile(int, char*[]); + } } 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) { |