summaryrefslogtreecommitdiff
path: root/ruby/src/IceRuby/Slice.cpp
diff options
context:
space:
mode:
authorMatthew Newhook <matthew@zeroc.com>2015-03-21 15:35:40 -0230
committerMatthew Newhook <matthew@zeroc.com>2015-03-21 15:35:40 -0230
commit630a37d2fe66f24518299e705f958b571803c522 (patch)
tree969723791bdc4d73bb099c19d45554d0ca241ad9 /ruby/src/IceRuby/Slice.cpp
parentFix some README.md markdown formatting (diff)
downloadice-630a37d2fe66f24518299e705f958b571803c522.tar.bz2
ice-630a37d2fe66f24518299e705f958b571803c522.tar.xz
ice-630a37d2fe66f24518299e705f958b571803c522.zip
py -> python
rb -> ruby objc -> objective-c cs -> csharp
Diffstat (limited to 'ruby/src/IceRuby/Slice.cpp')
-rw-r--r--ruby/src/IceRuby/Slice.cpp223
1 files changed, 223 insertions, 0 deletions
diff --git a/ruby/src/IceRuby/Slice.cpp b/ruby/src/IceRuby/Slice.cpp
new file mode 100644
index 00000000000..06f1d232866
--- /dev/null
+++ b/ruby/src/IceRuby/Slice.cpp
@@ -0,0 +1,223 @@
+// **********************************************************************
+//
+// 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.
+//
+// **********************************************************************
+
+#include <Slice.h>
+#include <Util.h>
+#include <Slice/Preprocessor.h>
+#include <Slice/RubyUtil.h>
+#include <Slice/Util.h>
+#include <IceUtil/Options.h>
+
+using namespace std;
+using namespace IceRuby;
+using namespace Slice;
+using namespace Slice::Ruby;
+
+extern "C"
+VALUE
+IceRuby_loadSlice(int argc, VALUE* argv, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ if(argc < 1 || argc > 2)
+ {
+ throw RubyException(rb_eArgError, "wrong number of arguments");
+ }
+
+ string cmd = getString(argv[0]);
+ vector<string> argSeq;
+ try
+ {
+ argSeq = IceUtilInternal::Options::split(cmd);
+ }
+ catch(const IceUtilInternal::BadOptException& ex)
+ {
+ throw RubyException(rb_eArgError, "error in Slice options: %s", ex.reason.c_str());
+ }
+ catch(const IceUtilInternal::APIException& ex)
+ {
+ throw RubyException(rb_eArgError, "error in Slice options: %s", ex.reason.c_str());
+ }
+
+ if(argc > 1)
+ {
+ if(!arrayToStringSeq(argv[1], argSeq))
+ {
+ throw RubyException(rb_eTypeError, "argument 2 is not an array");
+ }
+ }
+
+ IceUtilInternal::Options opts;
+ 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("d", "debug");
+ opts.addOpt("", "ice");
+ opts.addOpt("", "underscore");
+ opts.addOpt("", "checksum");
+ opts.addOpt("", "all");
+
+ vector<string> files;
+ try
+ {
+ argSeq.insert(argSeq.begin(), ""); // dummy argv[0]
+ files = opts.parse(argSeq);
+ if(files.empty())
+ {
+ throw RubyException(rb_eArgError, "no Slice files specified in `%s'", cmd.c_str());
+ }
+ }
+ catch(const IceUtilInternal::BadOptException& ex)
+ {
+ throw RubyException(rb_eArgError, "error in Slice options: %s", ex.reason.c_str());
+ }
+ catch(const IceUtilInternal::APIException& ex)
+ {
+ throw RubyException(rb_eArgError, "error in Slice options: %s", ex.reason.c_str());
+ }
+
+ vector<string> cppArgs;
+ vector<string> includePaths;
+ bool debug = false;
+ bool ice = true; // This must be true so that we can create Ice::Identity when necessary.
+ bool underscore = opts.isSet("underscore");
+ bool all = false;
+ bool checksum = false;
+ if(opts.isSet("D"))
+ {
+ vector<string> optargs = opts.argVec("D");
+ for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs.push_back("-D" + *i);
+ }
+ }
+ if(opts.isSet("U"))
+ {
+ vector<string> optargs = opts.argVec("U");
+ for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs.push_back("-U" + *i);
+ }
+ }
+ if(opts.isSet("I"))
+ {
+ includePaths = opts.argVec("I");
+ for(vector<string>::const_iterator i = includePaths.begin(); i != includePaths.end(); ++i)
+ {
+ cppArgs.push_back("-I" + *i);
+ }
+ }
+ debug = opts.isSet("d") || opts.isSet("debug");
+ all = opts.isSet("all");
+ checksum = opts.isSet("checksum");
+
+ bool ignoreRedefs = false;
+
+ for(vector<string>::const_iterator p = files.begin(); p != files.end(); ++p)
+ {
+ string file = *p;
+ Slice::PreprocessorPtr icecpp = Slice::Preprocessor::create("icecpp", file, cppArgs);
+ FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2RB__");
+
+ if(cppHandle == 0)
+ {
+ throw RubyException(rb_eArgError, "Slice preprocessing failed for `%s'", cmd.c_str());
+ }
+
+ UnitPtr u = Slice::Unit::createUnit(ignoreRedefs, all, ice, underscore);
+ int parseStatus = u->parse(file, cppHandle, debug);
+
+ if(!icecpp->close() || parseStatus == EXIT_FAILURE)
+ {
+ u->destroy();
+ throw RubyException(rb_eArgError, "Slice parsing failed for `%s'", cmd.c_str());
+ }
+
+ //
+ // Generate the Ruby code into a string stream.
+ //
+ ostringstream codeStream;
+ IceUtilInternal::Output out(codeStream);
+ out.setUseTab(false);
+ generate(u, all, checksum, includePaths, out);
+ u->destroy();
+
+ string code = codeStream.str();
+ callRuby(rb_eval_string, code.c_str());
+ }
+ }
+ ICE_RUBY_CATCH
+
+ return Qnil;
+}
+
+extern "C"
+VALUE
+IceRuby_compile(int argc, VALUE* argv, VALUE self)
+{
+ ICE_RUBY_TRY
+ {
+ if(argc != 1)
+ {
+ throw RubyException(rb_eArgError, "wrong number of arguments");
+ }
+
+ vector<string> argSeq;
+ if(!arrayToStringSeq(argv[0], argSeq))
+ {
+ throw RubyException(rb_eTypeError, "argument is not an array");
+ }
+ char** argv = new char*[argSeq.size()+1];
+ // Manufacture a fake argv[0].
+ argv[0] = const_cast<char*>("slice2rb");
+ for(size_t i = 0; i < argSeq.size(); ++i)
+ {
+ argv[i+1] = const_cast<char*>(argSeq[i].c_str());
+ }
+
+ int rc;
+ try
+ {
+ rc = Slice::Ruby::compile(argSeq.size()+1, argv);
+ }
+ catch(const std::exception& ex)
+ {
+ getErrorStream() << argv[0] << ": error:" << ex.what() << endl;
+ rc = EXIT_FAILURE;
+ }
+ catch(const std::string& msg)
+ {
+ getErrorStream() << argv[0] << ": error:" << msg << endl;
+ rc = EXIT_FAILURE;
+ }
+ catch(const char* msg)
+ {
+ getErrorStream() << argv[0] << ": error:" << msg << endl;
+ rc = EXIT_FAILURE;
+ }
+ catch(...)
+ {
+ getErrorStream() << argv[0] << ": error:" << "unknown exception" << endl;
+ rc = EXIT_FAILURE;
+ }
+
+ delete[] argv;
+ return INT2FIX(rc);
+ }
+ ICE_RUBY_CATCH
+
+ return Qnil;
+}
+
+void
+IceRuby::initSlice(VALUE iceModule)
+{
+ rb_define_module_function(iceModule, "loadSlice", CAST_METHOD(IceRuby_loadSlice), -1);
+ rb_define_module_function(iceModule, "compile", CAST_METHOD(IceRuby_compile), -1);
+}