summaryrefslogtreecommitdiff
path: root/cpp/src/slice2py
diff options
context:
space:
mode:
authorMatthew Newhook <matthew@zeroc.com>2015-02-18 10:29:49 -0330
committerMatthew Newhook <matthew@zeroc.com>2015-02-18 10:29:49 -0330
commitb55ce15878456e3d2f0656bcd6abd5a55c6774b1 (patch)
treee7e771a3d90ae7295f20bf0622b72c72cc3a85e0 /cpp/src/slice2py
parentFixed ObjC build (diff)
downloadice-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/slice2py')
-rw-r--r--cpp/src/slice2py/Main.cpp661
1 files changed, 1 insertions, 660 deletions
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)
{