diff options
author | Matthew Newhook <matthew@zeroc.com> | 2009-01-13 17:58:32 -0330 |
---|---|---|
committer | Matthew Newhook <matthew@zeroc.com> | 2009-01-13 17:58:32 -0330 |
commit | efea74327637afce0a7f83b24d8c2f8b1d224f73 (patch) | |
tree | fda54ee1f4361dd3448c96753593fda264ce26cc /cpp/src | |
parent | Added patch for mcpp 2.7.2 (diff) | |
download | ice-efea74327637afce0a7f83b24d8c2f8b1d224f73.tar.bz2 ice-efea74327637afce0a7f83b24d8c2f8b1d224f73.tar.xz ice-efea74327637afce0a7f83b24d8c2f8b1d224f73.zip |
http://bugzilla.zeroc.com/bugzilla/show_bug.cgi?id=3640 - If slice2java errors out generated files are left behind
- Added file tracker
- Added calls to file tracker when files or directories are created.
- All translators cleanup created files if interrupted, or if they fail.
- Normalized various error messages.
- Fixed bug with slice2cs which would not correctly check if the impl files were created.
Squashed commit of the following:
commit 0fec143af219d59dcec5b91cb96a79179f73bd0d
Author: Matthew Newhook <matthew@zeroc.com>
Date: Tue Jan 13 17:57:25 2009 -0330
Fixed FileException for VC6.
commit 38b22497c751ad9b2f86af2d44e87a23c0049d9c
Merge: df29064... 4421a3d...
Author: Matthew Newhook <matthew@zeroc.com>
Date: Tue Jan 13 17:55:49 2009 -0330
Merged R3_3_branch.
commit df290649637685bfff4f777ccf53f4f04fda71a0
Author: Matthew Newhook <matthew@zeroc.com>
Date: Tue Jan 13 17:45:18 2009 -0330
move checksum writing outside loop
commit a9bb2356167b1f9259ce2d1f1b43d40b7fd0ce82
Author: Matthew Newhook <matthew@zeroc.com>
Date: Tue Jan 13 17:35:00 2009 -0330
added quotes
commit a2f3d7a2414d08ebdc290222b8e97d8b203cc9ab
Author: Matthew Newhook <matthew@zeroc.com>
Date: Tue Jan 13 17:21:27 2009 -0330
can't -> cannot
commit c3113e33a3687cae369bf7803e4f1d18c9141762
Author: Matthew Newhook <matthew@zeroc.com>
Date: Tue Jan 13 17:10:12 2009 -0330
minor fixes to output.
commit 2a17d6e1b6c0e5eed8be79b8353ca3c06572e19c
Author: U-WIN-5WBK5GD0FYQ\matthew <matthew@WIN-5WBK5GD0FYQ.(none)>
Date: Tue Jan 13 12:05:46 2009 -0800
windows fixes.
commit d8d4f6dc35043fb71b599dac7171fee0c2bb87bf
Author: Matthew Newhook <matthew@zeroc.com>
Date: Tue Jan 13 15:58:21 2009 -0330
remove debugging.
commit f1e4d7a55e13fea4c0b84244fb437bd391fbe538
Author: Matthew Newhook <matthew@zeroc.com>
Date: Tue Jan 13 15:53:37 2009 -0330
Added FileTracker. Added file tracking, and cleanup to lots of translators.
commit 33dbfb0124509779bd2d95bbac06a02ca9b907ac
Author: Matthew Newhook <matthew@zeroc.com>
Date: Tue Jan 13 09:42:16 2009 -0330
http://bugzilla/bugzilla/show_bug.cgi?id=3640 If slice2java errors out generated files are left behind
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Slice/FileTracker.cpp | 117 | ||||
-rw-r--r-- | cpp/src/Slice/JavaUtil.cpp | 47 | ||||
-rw-r--r-- | cpp/src/Slice/Makefile | 1 | ||||
-rw-r--r-- | cpp/src/Slice/Makefile.mak | 1 | ||||
-rw-r--r-- | cpp/src/Slice/Preprocessor.cpp | 2 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 54 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.h | 3 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Main.cpp | 17 | ||||
-rw-r--r-- | cpp/src/slice2cs/Gen.cpp | 28 | ||||
-rw-r--r-- | cpp/src/slice2cs/Gen.h | 3 | ||||
-rw-r--r-- | cpp/src/slice2cs/Main.cpp | 52 | ||||
-rw-r--r-- | cpp/src/slice2docbook/Gen.cpp | 15 | ||||
-rw-r--r-- | cpp/src/slice2docbook/Gen.h | 4 | ||||
-rw-r--r-- | cpp/src/slice2docbook/Main.cpp | 15 | ||||
-rw-r--r-- | cpp/src/slice2freeze/Main.cpp | 428 | ||||
-rw-r--r-- | cpp/src/slice2freezej/Main.cpp | 129 | ||||
-rw-r--r-- | cpp/src/slice2html/Gen.cpp | 37 | ||||
-rw-r--r-- | cpp/src/slice2html/Main.cpp | 13 | ||||
-rw-r--r-- | cpp/src/slice2java/Main.cpp | 24 | ||||
-rw-r--r-- | cpp/src/slice2py/Main.cpp | 208 | ||||
-rw-r--r-- | cpp/src/slice2rb/Main.cpp | 43 |
21 files changed, 726 insertions, 515 deletions
diff --git a/cpp/src/Slice/FileTracker.cpp b/cpp/src/Slice/FileTracker.cpp new file mode 100644 index 00000000000..438670cf2f8 --- /dev/null +++ b/cpp/src/Slice/FileTracker.cpp @@ -0,0 +1,117 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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/FileTracker.h> + +#ifdef _WIN32 +# include <direct.h> +#endif + +using namespace std; + +Slice::FileException::FileException(const char* file, int line, const string& r) : + Exception(file, line), + _reason(r) +{ +} + +Slice::FileException::~FileException() throw() +{ +} + +const char* Slice::FileException::_name = "Slice::FileException"; + +string +Slice::FileException::ice_name() const +{ + return _name; +} + +void +Slice::FileException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ": " << _reason; +} + +IceUtil::Exception* +Slice::FileException::ice_clone() const +{ + return new FileException(*this); +} + +void +Slice::FileException::ice_throw() const +{ + throw *this; +} + +string +Slice::FileException::reason() const +{ + return _reason; +} + + +static Slice::FileTrackerPtr Instance; + +Slice::FileTracker::FileTracker() +{ +} + +Slice::FileTracker::~FileTracker() +{ +} + +// The file tracker is not supposed to be thread safe. +Slice::FileTrackerPtr +Slice::FileTracker::instance() +{ + if(!Instance) + { + Instance = new FileTracker(); + } + return Instance; +} + +void +Slice::FileTracker::addFile(const string& file) +{ + _files.push_front(make_pair(file, false)); +} + +void +Slice::FileTracker::addDirectory(const string& dir) +{ + _files.push_front(make_pair(dir, true)); +} + +void +Slice::FileTracker::cleanup() +{ + for(list<pair<string, bool> >::const_iterator p = _files.begin(); p != _files.end(); ++p) + { + if(!p->second) + { +#ifdef _WIN32 + _unlink(p->first.c_str()); +#else + unlink(p->first.c_str()); +#endif + } + else + { +#ifdef _WIN32 + _rmdir(p->first.c_str()); +#else + rmdir(p->first.c_str()); +#endif + } + } +} diff --git a/cpp/src/Slice/JavaUtil.cpp b/cpp/src/Slice/JavaUtil.cpp index 2a1114aa064..7c73227bc55 100644 --- a/cpp/src/Slice/JavaUtil.cpp +++ b/cpp/src/Slice/JavaUtil.cpp @@ -7,7 +7,9 @@ // // ********************************************************************** +#include <IceUtil/DisableWarnings.h> #include <Slice/JavaUtil.h> +#include <Slice/FileTracker.h> #include <IceUtil/Functional.h> #include <IceUtil/DisableWarnings.h> @@ -28,49 +30,6 @@ using namespace Slice; using namespace IceUtil; using namespace IceUtilInternal; -Slice::FileException::FileException(const char* file, int line, const string& r) : - Exception(file, line), - _reason(r) -{ -} - -Slice::FileException::~FileException() throw() -{ -} - -const char* Slice::FileException::_name = "Slice::FileException"; - -string -Slice::FileException::ice_name() const -{ - return _name; -} - -void -Slice::FileException::ice_print(ostream& out) const -{ - Exception::ice_print(out); - out << ": " << _reason; -} - -IceUtil::Exception* -Slice::FileException::ice_clone() const -{ - return new FileException(*this); -} - -void -Slice::FileException::ice_throw() const -{ - throw *this; -} - -string -Slice::FileException::reason() const -{ - return _reason; -} - Slice::JavaOutput::JavaOutput() { } @@ -146,6 +105,7 @@ Slice::JavaOutput::openClass(const string& cls, const string& prefix) os << "cannot create directory `" << path << "': " << strerror(errno); throw FileException(__FILE__, __LINE__, os.str()); } + FileTracker::instance()->addDirectory(path); } while(pos != string::npos); } @@ -167,6 +127,7 @@ Slice::JavaOutput::openClass(const string& cls, const string& prefix) open(path.c_str()); if(isOpen()) { + FileTracker::instance()->addFile(path); printHeader(); if(!package.empty()) diff --git a/cpp/src/Slice/Makefile b/cpp/src/Slice/Makefile index fb5c0d5268d..7232e2fe64a 100644 --- a/cpp/src/Slice/Makefile +++ b/cpp/src/Slice/Makefile @@ -27,6 +27,7 @@ OBJS = Scanner.o \ DotNetNames.o \ RubyUtil.o \ Util.o \ + FileTracker.o \ MD5.o \ MD5I.o diff --git a/cpp/src/Slice/Makefile.mak b/cpp/src/Slice/Makefile.mak index e9312581b07..ad3e5a89611 100644 --- a/cpp/src/Slice/Makefile.mak +++ b/cpp/src/Slice/Makefile.mak @@ -26,6 +26,7 @@ OBJS = Scanner.obj \ DotNetNames.obj \
RubyUtil.obj \
Util.obj \
+ FileTracker.obj \
MD5.obj \
MD5I.obj
diff --git a/cpp/src/Slice/Preprocessor.cpp b/cpp/src/Slice/Preprocessor.cpp index b61d43cc5c0..dd1260f2fa0 100644 --- a/cpp/src/Slice/Preprocessor.cpp +++ b/cpp/src/Slice/Preprocessor.cpp @@ -517,7 +517,7 @@ Slice::Preprocessor::checkInputFile() ifstream test(_fileName.c_str()); if(!test) { - cerr << _path << ": can't open `" << _fileName << "' for reading" << endl; + cerr << _path << ": cannot open `" << _fileName << "' for reading" << endl; return false; } test.close(); diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index a577c67541f..c593e3dcd21 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -7,12 +7,14 @@ // // ********************************************************************** +#include <IceUtil/DisableWarnings.h> #include <Gen.h> #include <Slice/Util.h> #include <Slice/CPlusPlusUtil.h> #include <IceUtil/Functional.h> #include <IceUtil/Iterator.h> #include <Slice/Checksum.h> +#include <Slice/FileTracker.h> #include <limits> #include <sys/stat.h> @@ -34,8 +36,8 @@ getDeprecateSymbol(const ContainedPtr& p1, const ContainedPtr& p2) return deprecateSymbol; } -Slice::Gen::Gen(const string& name, const string& base, const string& headerExtension, - const string& sourceExtension, const vector<string>& extraHeaders, const string& include, +Slice::Gen::Gen(const string& base, const string& headerExtension, const string& sourceExtension, + const vector<string>& extraHeaders, const string& include, const vector<string>& includePaths, const string& dllExport, const string& dir, bool imp, bool checksum, bool stream, bool ice) : _base(base), @@ -74,28 +76,34 @@ Slice::Gen::Gen(const string& name, const string& base, const string& headerExte struct stat st; if(stat(fileImplH.c_str(), &st) == 0) { - cerr << name << ": `" << fileImplH << "' already exists - will not overwrite" << endl; - return; + ostringstream os; + os << fileImplH << "' already exists - will not overwrite"; + throw FileException(__FILE__, __LINE__, os.str()); } if(stat(fileImplC.c_str(), &st) == 0) { - cerr << name << ": `" << fileImplC << "' already exists - will not overwrite" << endl; - return; + ostringstream os; + os << fileImplC << "' already exists - will not overwrite"; + throw FileException(__FILE__, __LINE__, os.str()); } implH.open(fileImplH.c_str()); if(!implH) { - cerr << name << ": can't open `" << fileImplH << "' for writing" << endl; - return; + ostringstream os; + os << "cannot open `" << fileImplH << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } + FileTracker::instance()->addFile(fileImplH); implC.open(fileImplC.c_str()); if(!implC) { - cerr << name << ": can't open `" << fileImplC << "' for writing" << endl; - return; + ostringstream os; + os << "cannot open `" << fileImplC << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } + FileTracker::instance()->addFile(fileImplC); string s = fileImplH; if(_include.size()) @@ -119,16 +127,20 @@ Slice::Gen::Gen(const string& name, const string& base, const string& headerExte H.open(fileH.c_str()); if(!H) { - cerr << name << ": can't open `" << fileH << "' for writing" << endl; - return; + ostringstream os; + os << "cannot open `" << fileH << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } + FileTracker::instance()->addFile(fileH); C.open(fileC.c_str()); if(!C) { - cerr << name << ": can't open `" << fileC << "' for writing" << endl; - return; + ostringstream os; + os << "cannot open `" << fileC << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } + FileTracker::instance()->addFile(fileC); printHeader(H); printHeader(C); @@ -158,20 +170,6 @@ Slice::Gen::~Gen() } } -bool -Slice::Gen::operator!() const -{ - if(!H || !C) - { - return true; - } - if(_impl && (!implH || !implC)) - { - return true; - } - return false; -} - void Slice::Gen::generate(const UnitPtr& p) { diff --git a/cpp/src/slice2cpp/Gen.h b/cpp/src/slice2cpp/Gen.h index c91b3ed34c7..e3c1c9afc01 100644 --- a/cpp/src/slice2cpp/Gen.h +++ b/cpp/src/slice2cpp/Gen.h @@ -23,7 +23,6 @@ public: Gen(const std::string&, const std::string&, const std::string&, - const std::string&, const std::vector<std::string>&, const std::string&, const std::vector<std::string>&, @@ -35,8 +34,6 @@ public: bool); ~Gen(); - bool operator!() const; // Returns true if there was a constructor error - void generate(const UnitPtr&); void closeOutput(); diff --git a/cpp/src/slice2cpp/Main.cpp b/cpp/src/slice2cpp/Main.cpp index 0f053917b0b..4ca202872c7 100644 --- a/cpp/src/slice2cpp/Main.cpp +++ b/cpp/src/slice2cpp/Main.cpp @@ -11,6 +11,7 @@ #include <IceUtil/CtrlCHandler.h> #include <IceUtil/StaticMutex.h> #include <Slice/Preprocessor.h> +#include <Slice/FileTracker.h> #include <Gen.h> using namespace std; @@ -216,14 +217,21 @@ main(int argc, char* argv[]) } else { - Gen gen(argv[0], icecpp.getBaseName(), headerExtension, sourceExtension, extraHeaders, include, - includePaths, dllExport, output, impl, checksum, stream, ice); - if(!gen) + try { + Gen gen(icecpp.getBaseName(), headerExtension, sourceExtension, extraHeaders, include, + includePaths, dllExport, output, impl, checksum, stream, ice); + gen.generate(u); + } + catch(const Slice::FileException& ex) + { + // If a file could not be created, then + // cleanup any created files. + FileTracker::instance()->cleanup(); u->destroy(); + cerr << argv[0] << ": " << ex.reason() << endl; return EXIT_FAILURE; } - gen.generate(u); } u->destroy(); @@ -235,6 +243,7 @@ main(int argc, char* argv[]) if(_interrupted) { + FileTracker::instance()->cleanup(); return EXIT_FAILURE; } } diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp index def7ed38beb..633ba2d7ac9 100644 --- a/cpp/src/slice2cs/Gen.cpp +++ b/cpp/src/slice2cs/Gen.cpp @@ -21,6 +21,7 @@ #include <IceUtil/UUID.h> #include <Slice/Checksum.h> #include <Slice/DotNetNames.h> +#include <Slice/FileTracker.h> using namespace std; using namespace Slice; @@ -1053,7 +1054,7 @@ Slice::CsVisitor::writeValue(const TypePtr& type) } -Slice::Gen::Gen(const string& name, const string& base, const vector<string>& includePaths, const string& dir, +Slice::Gen::Gen(const string& base, const vector<string>& includePaths, const string& dir, bool impl, bool implTie, bool stream) : _includePaths(includePaths), _stream(stream) @@ -1076,9 +1077,11 @@ Slice::Gen::Gen(const string& name, const string& base, const vector<string>& in _out.open(file.c_str()); if(!_out) { - cerr << name << ": can't open `" << file << "' for writing" << endl; - return; + ostringstream os; + os << "cannot open `" << file << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } + FileTracker::instance()->addFile(file); printHeader(); _out << nl << "// Generated from file `" << fileBase << ".ice'"; @@ -1105,16 +1108,20 @@ Slice::Gen::Gen(const string& name, const string& base, const vector<string>& in struct stat st; if(stat(fileImpl.c_str(), &st) == 0) { - cerr << name << ": `" << fileImpl << "' already exists--will not overwrite" << endl; - return; + ostringstream os; + os << fileImpl << "' already exists - will not overwrite"; + throw FileException(__FILE__, __LINE__, os.str()); } _impl.open(fileImpl.c_str()); if(!_impl) { - cerr << name << ": can't open `" << fileImpl << "' for writing" << endl; - return; + ostringstream os; + os << ": cannot open `" << fileImpl << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } + + FileTracker::instance()->addFile(fileImpl); } } @@ -1130,16 +1137,9 @@ Slice::Gen::~Gen() } } -bool -Slice::Gen::operator!() const -{ - return !_out; -} - void Slice::Gen::generate(const UnitPtr& p) { - CsGenerator::validateMetaData(p); UnitVisitor unitVisitor(_out, _stream); diff --git a/cpp/src/slice2cs/Gen.h b/cpp/src/slice2cs/Gen.h index 265e1ab910d..dc9d655570e 100644 --- a/cpp/src/slice2cs/Gen.h +++ b/cpp/src/slice2cs/Gen.h @@ -47,7 +47,6 @@ class Gen : private ::IceUtil::noncopyable public: Gen(const std::string&, - const std::string&, const std::vector<std::string>&, const std::string&, bool, @@ -55,8 +54,6 @@ public: bool); ~Gen(); - bool operator!() const; // Returns true if there was a constructor error - void generate(const UnitPtr&); void generateTie(const UnitPtr&); void generateImpl(const UnitPtr&); diff --git a/cpp/src/slice2cs/Main.cpp b/cpp/src/slice2cs/Main.cpp index 2ed3177a683..abdc24c23db 100644 --- a/cpp/src/slice2cs/Main.cpp +++ b/cpp/src/slice2cs/Main.cpp @@ -11,6 +11,7 @@ #include <IceUtil/CtrlCHandler.h> #include <IceUtil/StaticMutex.h> #include <Slice/Preprocessor.h> +#include <Slice/FileTracker.h> #include <Gen.h> using namespace std; @@ -164,7 +165,10 @@ main(int argc, char* argv[]) if(depend) { Preprocessor icecpp(argv[0], *i, cppArgs); - icecpp.printMakefileDependencies(Preprocessor::CSharp, includePaths); + if(!icecpp.printMakefileDependencies(Preprocessor::CSharp, includePaths)) + { + return EXIT_FAILURE; + } } else { @@ -207,28 +211,35 @@ main(int argc, char* argv[]) } else { - Gen gen(argv[0], icecpp.getBaseName(), includePaths, output, impl, implTie, stream); - if(!gen) - { - p->destroy(); - return EXIT_FAILURE; - } - gen.generate(p); - if(tie) + try { - gen.generateTie(p); + Gen gen(icecpp.getBaseName(), includePaths, output, impl, implTie, stream); + gen.generate(p); + if(tie) + { + gen.generateTie(p); + } + if(impl) + { + gen.generateImpl(p); + } + if(implTie) + { + gen.generateImplTie(p); + } + if(checksum) + { + gen.generateChecksums(p); + } } - if(impl) + catch(const Slice::FileException& ex) { - gen.generateImpl(p); - } - if(implTie) - { - gen.generateImplTie(p); - } - if(checksum) - { - gen.generateChecksums(p); + // If a file could not be created, then + // cleanup any created files. + FileTracker::instance()->cleanup(); + p->destroy(); + cerr << argv[0] << ": " << ex.reason() << endl; + return EXIT_FAILURE; } } @@ -241,6 +252,7 @@ main(int argc, char* argv[]) if(_interrupted) { + FileTracker::instance()->cleanup(); return EXIT_FAILURE; } } diff --git a/cpp/src/slice2docbook/Gen.cpp b/cpp/src/slice2docbook/Gen.cpp index d40b9e1ee75..322ca9a1147 100644 --- a/cpp/src/slice2docbook/Gen.cpp +++ b/cpp/src/slice2docbook/Gen.cpp @@ -9,6 +9,7 @@ #include <IceUtil/DisableWarnings.h> #include <IceUtil/Functional.h> +#include <Slice/FileTracker.h> #include <Gen.h> #include <cstring> @@ -21,8 +22,7 @@ using namespace Slice; using namespace IceUtil; using namespace IceUtilInternal; -Slice::Gen::Gen(const string& name, const string& file, bool standAlone, bool chapter, - bool noIndex, bool sortFields) : +Slice::Gen::Gen(const string& file, bool standAlone, bool chapter, bool noIndex, bool sortFields) : _standAlone(standAlone), _noIndex(noIndex), _sortFields(sortFields) @@ -39,8 +39,9 @@ Slice::Gen::Gen(const string& name, const string& file, bool standAlone, bool ch O.open(file.c_str()); if(!O) { - cerr << name << ": can't open `" << file << "' for writing: " << strerror(errno) << endl; - return; + ostringstream os; + os << "cannot open `" << file << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } } @@ -48,12 +49,6 @@ Slice::Gen::~Gen() { } -bool -Slice::Gen::operator!() const -{ - return !O; -} - void Slice::Gen::generate(const UnitPtr& p) { diff --git a/cpp/src/slice2docbook/Gen.h b/cpp/src/slice2docbook/Gen.h index 55222938370..97cbe3e1274 100644 --- a/cpp/src/slice2docbook/Gen.h +++ b/cpp/src/slice2docbook/Gen.h @@ -21,11 +21,9 @@ class Gen : private ::IceUtil::noncopyable, public ParserVisitor { public: - Gen(const std::string&, const std::string&, bool, bool, bool, bool); + Gen(const std::string&, bool, bool, bool, bool); virtual ~Gen(); - bool operator!() const; // Returns true if there was a constructor error - void generate(const UnitPtr&); void closeOutput(); diff --git a/cpp/src/slice2docbook/Main.cpp b/cpp/src/slice2docbook/Main.cpp index 9e7add9b40c..25bd52137ac 100644 --- a/cpp/src/slice2docbook/Main.cpp +++ b/cpp/src/slice2docbook/Main.cpp @@ -12,6 +12,7 @@ #include <IceUtil/CtrlCHandler.h> #include <IceUtil/StaticMutex.h> #include <Slice/Preprocessor.h> +#include <Slice/FileTracker.h> #include <Gen.h> using namespace std; @@ -210,13 +211,20 @@ main(int argc, char* argv[]) if(status == EXIT_SUCCESS && !preprocess) { - Gen gen(argv[0], docbook, standAlone, chapter, noIndex, sortFields); - if(!gen) + try { + Gen gen(docbook, standAlone, chapter, noIndex, sortFields); + gen.generate(p); + } + catch(const Slice::FileException& ex) + { + // If a file could not be created, then + // cleanup any created files. + FileTracker::instance()->cleanup(); p->destroy(); + cerr << argv[0] << ": " << ex.reason() << endl; return EXIT_FAILURE; } - gen.generate(p); } p->destroy(); @@ -226,6 +234,7 @@ main(int argc, char* argv[]) if(_interrupted) { + FileTracker::instance()->cleanup(); return EXIT_FAILURE; } } diff --git a/cpp/src/slice2freeze/Main.cpp b/cpp/src/slice2freeze/Main.cpp index 16e95c109eb..84f98ac7c27 100644 --- a/cpp/src/slice2freeze/Main.cpp +++ b/cpp/src/slice2freeze/Main.cpp @@ -14,6 +14,7 @@ #include <Slice/Preprocessor.h> #include <Slice/Util.h> #include <Slice/CPlusPlusUtil.h> +#include <Slice/FileTracker.h> #include <IceUtil/OutputUtil.h> #include <IceUtil/StringUtil.h> #include <cstring> @@ -219,25 +220,25 @@ usage(const char* n) // Note: --case-sensitive is intentionally not shown here! } -bool -checkIdentifier(string n, string t, string s) +void +checkIdentifier(string t, string s) { if(s.empty() || (!isalpha(static_cast<unsigned char>(s[0])) && s[0] != '_')) { - cerr << n << ": `" << t << "' is not a valid type name" << endl; - return false; + ostringstream os; + os << t << "' is not a valid type name"; + throw os.str(); } for(unsigned int i = 1; i < s.size(); ++i) { if(!isalnum(static_cast<unsigned char>(s[i])) && s[i] != '_') { - cerr << n << ": `" << t << "' is not a valid type name" << endl; - return false; + ostringstream os; + os << t << "' is not a valid type name"; + throw os.str(); } } - - return true; } void @@ -924,9 +925,8 @@ writeDictWithIndicesC(const string& name, const string& absolute, const Dict& di } } - -bool -writeDict(const string& n, UnitPtr& u, const Dict& dict, Output& H, Output& C, const string& dllExport) +void +writeDict(const string& n, const UnitPtr& u, const Dict& dict, Output& H, Output& C, const string& dllExport) { string absolute = dict.name; if(absolute.find("::") == 0) @@ -941,32 +941,28 @@ writeDict(const string& n, UnitPtr& u, const Dict& dict, Output& H, Output& C, c string s = name.substr(0, pos); name.erase(0, pos + 2); - if(!checkIdentifier(n, absolute, s)) - { - return false; - } + checkIdentifier(absolute, s); scope.push_back(s); } - if(!checkIdentifier(n, absolute, name)) - { - return false; - } + checkIdentifier(absolute, name); TypeList keyTypes = u->lookupType(dict.key, false); if(keyTypes.empty()) { - cerr << n << ": `" << dict.key << "' is not a valid type" << endl; - return false; + ostringstream os; + os << "`" << dict.key << "' is not a valid type"; + throw os.str(); } TypePtr keyType = keyTypes.front(); TypeList valueTypes = u->lookupType(dict.value, false); if(valueTypes.empty()) { - cerr << n << ": `" << dict.value << "' is not a valid type" << endl; - return false; + ostringstream os; + os << "`" << dict.value << "' is not a valid type"; + throw os.str(); } TypePtr valueType = valueTypes.front(); @@ -1002,19 +998,21 @@ writeDict(const string& n, UnitPtr& u, const Dict& dict, Output& H, Output& C, c { if(dict.indices.size() > 1) { - cerr << n << ": bad index for dictionary `" << dict.name << "'" << endl; - return false; + ostringstream os; + os << "bad index for dictionary `" << dict.name << "'"; + throw os.str(); } bool containsSequence = false; if(!Dictionary::legalKeyType(valueType, containsSequence)) { - cerr << n << ": `" << dict.value << "' is not a valid index type" << endl; - return false; + ostringstream os; + os << "`" << dict.value << "' is not a valid index type"; + throw os.str(); } if(containsSequence) { - cerr << n << ": warning: use of sequences in dictionary keys has been deprecated" << endl; + cerr << n << ": warning: use of sequences in dictionary keys has been deprecated"; } @@ -1028,8 +1026,9 @@ writeDict(const string& n, UnitPtr& u, const Dict& dict, Output& H, Output& C, c if(builtInType == 0 || builtInType->kind() != Builtin::KindString) { - cerr << n << ": VALUE is a `" << dict.value << "', not a string" << endl; - return false; + ostringstream os; + os << "VALUE is a `" << dict.value << "', not a string"; + throw os.str(); } } IndexType iType; @@ -1052,8 +1051,9 @@ writeDict(const string& n, UnitPtr& u, const Dict& dict, Output& H, Output& C, c StructPtr structDecl = StructPtr::dynamicCast(valueType); if(structDecl == 0) { - cerr << n << ": `" << dict.value << "' is neither a class nor a struct." << endl; - return false; + ostringstream os; + os << "`" << dict.value << "' is neither a class nor a struct."; + throw os.str(); } dataMembers = structDecl->dataMembers(); } @@ -1072,9 +1072,10 @@ writeDict(const string& n, UnitPtr& u, const Dict& dict, Output& H, Output& C, c if(dataMember == 0) { - cerr << n << ": The value of `" << dict.name - << "' has no data member named `" << index.member << "'" << endl; - return false; + ostringstream os; + os << "The value of `" << dict.name + << "' has no data member named `" << index.member << "'"; + throw os.str(); } TypePtr dataMemberType = dataMember->type(); @@ -1082,12 +1083,13 @@ writeDict(const string& n, UnitPtr& u, const Dict& dict, Output& H, Output& C, c bool containsSequence = false; if(!Dictionary::legalKeyType(dataMemberType, containsSequence)) { - cerr << n << ": `" << index.member << "' cannot be used as an index" << endl; - return false; + ostringstream os; + os << "`" << index.member << "' cannot be used as an index"; + throw os.str(); } if(containsSequence) { - cerr << n << ": warning: use of sequences in dictionary keys has been deprecated" << endl; + cerr << n << ": warning: use of sequences in dictionary keys has been deprecated"; } @@ -1099,8 +1101,9 @@ writeDict(const string& n, UnitPtr& u, const Dict& dict, Output& H, Output& C, c BuiltinPtr memberType = BuiltinPtr::dynamicCast(dataMemberType); if(memberType == 0 || memberType->kind() != Builtin::KindString) { - cerr << n << ": `" << index.member << "' is not a string " << endl; - return false; + ostringstream os; + os << "`" << index.member << "' is not a string "; + throw os.str(); } } IndexType iType; @@ -1128,11 +1131,8 @@ writeDict(const string& n, UnitPtr& u, const Dict& dict, Output& H, Output& C, c writeDictWithIndicesC(name, absolute, dict, indexTypes, keyType, dict.keyMetaData, valueType, dict.valueMetaData, C); } - - return true; } - void writeIndexH(const string& memberTypeString, const string& name, Output& H, const string& dllExport) { @@ -1251,8 +1251,8 @@ writeIndexC(const TypePtr& type, const TypePtr& memberType, const string& member C << eb; } -bool -writeIndex(const string& n, UnitPtr& u, const Index& index, Output& H, Output& C, const string& dllExport) +void +writeIndex(const string& n, const UnitPtr& u, const Index& index, Output& H, Output& C, const string& dllExport) { string absolute = index.name; if(absolute.find("::") == 0) @@ -1267,32 +1267,28 @@ writeIndex(const string& n, UnitPtr& u, const Index& index, Output& H, Output& C string s = name.substr(0, pos); name.erase(0, pos + 2); - if(!checkIdentifier(n, absolute, s)) - { - return false; - } + checkIdentifier(absolute, s); scope.push_back(s); } - if(!checkIdentifier(n, absolute, name)) - { - return false; - } + checkIdentifier(absolute, name); TypeList types = u->lookupType(index.type, false); if(types.empty()) { - cerr << n << ": `" << index.type << "' is not a valid type" << endl; - return false; + ostringstream os; + os << "`" << index.type << "' is not a valid type"; + throw os.str(); } TypePtr type = types.front(); ClassDeclPtr classDecl = ClassDeclPtr::dynamicCast(type); if(classDecl == 0) { - cerr << n << ": `" << index.type << "' is not a class" << endl; - return false; + ostringstream os; + os << "`" << index.type << "' is not a class"; + throw os.str(); } DataMemberList dataMembers = classDecl->definition()->allDataMembers(); @@ -1312,8 +1308,9 @@ writeIndex(const string& n, UnitPtr& u, const Index& index, Output& H, Output& C if(dataMember == 0) { - cerr << n << ": `" << index.type << "' has no data member named `" << index.member << "'" << endl; - return false; + ostringstream os; + os << "`" << index.type << "' has no data member named `" << index.member << "'"; + throw os.str(); } if(index.caseSensitive == false) @@ -1324,8 +1321,9 @@ writeIndex(const string& n, UnitPtr& u, const Index& index, Output& H, Output& C BuiltinPtr memberType = BuiltinPtr::dynamicCast(dataMember->type()); if(memberType == 0 || memberType->kind() != Builtin::KindString) { - cerr << n << ": `" << index.member << "'is not a string " << endl; - return false; + ostringstream os; + os << "`" << index.member << "'is not a string"; + throw os.str(); } } @@ -1346,7 +1344,140 @@ writeIndex(const string& n, UnitPtr& u, const Index& index, Output& H, Output& C } writeIndexC(type, dataMember->type(), index.member, index.caseSensitive, absolute, name, C); - return true; +} + +void +gen(const string& name, const UnitPtr& u, const vector<string>& includePaths, const vector<string>& extraHeaders, + const vector<Dict>& dicts, const vector<Index>& indices, const string& include, const string& headerExtension, + const string& sourceExtension, string dllExport, const StringList& includes, const vector<string>& args, + const string& output) +{ + string fileH = args[0]; + fileH += "." + headerExtension; + string includeH = fileH; + string fileC = args[0]; + fileC += "." + sourceExtension; + + if(!output.empty()) + { + fileH = output + '/' + fileH; + fileC = output + '/' + fileC; + } + + u->mergeModules(); + u->sort(); + + IceUtilInternal::Output H; + H.open(fileH.c_str()); + if(!H) + { + ostringstream os; + os << "cannot open `" << fileH << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); + } + + FileTracker::instance()->addFile(fileH); + + printHeader(H); + printFreezeTypes(H, dicts, indices); + + IceUtilInternal::Output CPP; + CPP.open(fileC.c_str()); + if(!CPP) + { + ostringstream os; + os << "cannot open `" << fileC << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); + } + FileTracker::instance()->addFile(fileC); + + printHeader(CPP); + printFreezeTypes(CPP, dicts, indices); + + for(vector<string>::const_iterator i = extraHeaders.begin(); i != extraHeaders.end(); ++i) + { + string hdr = *i; + string guard; + string::size_type pos = hdr.rfind(','); + if(pos != string::npos) + { + hdr = i->substr(0, pos); + guard = i->substr(pos + 1); + } + if(!guard.empty()) + { + CPP << "\n#ifndef " << guard; + CPP << "\n#define " << guard; + } + CPP << "\n#include <"; + if(!include.empty()) + { + CPP << include << '/'; + } + CPP << hdr << '>'; + if(!guard.empty()) + { + CPP << "\n#endif"; + } + } + + string s = fileH; + transform(s.begin(), s.end(), s.begin(), ToIfdef()); + H << "\n#ifndef __" << s << "__"; + H << "\n#define __" << s << "__"; + H << '\n'; + + if(dicts.size() > 0) + { + H << "\n#include <Freeze/Map.h>"; + } + + if(indices.size() > 0) + { + H << "\n#include <Freeze/Index.h>"; + } + + { + for(StringList::const_iterator p = includes.begin(); p != includes.end(); ++p) + { + H << "\n#include <" << changeInclude(*p, includePaths) << "." + headerExtension + ">"; + } + } + + CPP << "\n#include <Ice/BasicStream.h>"; + CPP << "\n#include <"; + if(include.size()) + { + CPP << include << '/'; + } + CPP << includeH << '>'; + + printVersionCheck(H); + printVersionCheck(CPP); + + printDllExportStuff(H, dllExport); + if(dllExport.size()) + { + dllExport += " "; + } + + { + for(vector<Dict>::const_iterator p = dicts.begin(); p != dicts.end(); ++p) + { + writeDict(name, u, *p, H, CPP, dllExport); + } + + for(vector<Index>::const_iterator q = indices.begin(); q != indices.end(); ++q) + { + writeIndex(name, u, *q, H, CPP, dllExport); + } + } + + H << "\n\n#endif\n"; + CPP << '\n'; + + H.close(); + CPP.close(); } int @@ -1420,6 +1551,14 @@ main(int argc, char* argv[]) cppArgs.push_back("-I" + Preprocessor::normalizeIncludePath(*i)); } + // Convert include paths to full paths. + { + for(vector<string>::iterator p = includePaths.begin(); p != includePaths.end(); ++p) + { + *p = fullPath(*p); + } + } + bool preprocess= opts.isSet("E"); string include = opts.optArg("include-dir"); @@ -1775,17 +1914,6 @@ main(int argc, char* argv[]) return EXIT_FAILURE; } - string fileH = args[0]; - fileH += "." + headerExtension; - string includeH = fileH; - string fileC = args[0]; - fileC += "." + sourceExtension; - if(!output.empty()) - { - fileH = output + '/' + fileH; - fileC = output + '/' + fileC; - } - UnitPtr u = Unit::createUnit(true, false, ice, caseSensitive); StringList includes; @@ -1849,153 +1977,39 @@ main(int argc, char* argv[]) } } + if(status == EXIT_SUCCESS && !preprocess) { - u->mergeModules(); - u->sort(); - + try { - for(vector<string>::iterator p = includePaths.begin(); p != includePaths.end(); ++p) - { - *p = fullPath(*p); - } + gen(argv[0], u, includePaths, extraHeaders, dicts, indices, include, headerExtension, + sourceExtension, dllExport, includes, args, output); } - - IceUtilInternal::Output H; - H.open(fileH.c_str()); - if(!H) + catch(const string& ex) { - cerr << argv[0] << ": can't open `" << fileH << "' for writing: " << strerror(errno) << endl; + // If a file could not be created, then cleanup any + // created files. + FileTracker::instance()->cleanup(); u->destroy(); + cerr << argv[0] << ": " << ex << endl; return EXIT_FAILURE; } - printHeader(H); - printFreezeTypes(H, dicts, indices); - - IceUtilInternal::Output CPP; - CPP.open(fileC.c_str()); - if(!CPP) + catch(const Slice::FileException& ex) { - cerr << argv[0] << ": can't open `" << fileC << "' for writing: " << strerror(errno) << endl; + // If a file could not be created, then cleanup any + // created files. + FileTracker::instance()->cleanup(); u->destroy(); + cerr << argv[0] << ": " << ex.reason() << endl; return EXIT_FAILURE; } - printHeader(CPP); - printFreezeTypes(CPP, dicts, indices); - - for(vector<string>::const_iterator i = extraHeaders.begin(); i != extraHeaders.end(); ++i) - { - string hdr = *i; - string guard; - string::size_type pos = hdr.rfind(','); - if(pos != string::npos) - { - hdr = i->substr(0, pos); - guard = i->substr(pos + 1); - } - if(!guard.empty()) - { - CPP << "\n#ifndef " << guard; - CPP << "\n#define " << guard; - } - CPP << "\n#include <"; - if(!include.empty()) - { - CPP << include << '/'; - } - CPP << hdr << '>'; - if(!guard.empty()) - { - CPP << "\n#endif"; - } - } - - string s = fileH; - transform(s.begin(), s.end(), s.begin(), ToIfdef()); - H << "\n#ifndef __" << s << "__"; - H << "\n#define __" << s << "__"; - H << '\n'; - - if(dicts.size() > 0) - { - H << "\n#include <Freeze/Map.h>"; - } - - if(indices.size() > 0) - { - H << "\n#include <Freeze/Index.h>"; - } - - + catch(...) { - for(StringList::const_iterator p = includes.begin(); p != includes.end(); ++p) - { - H << "\n#include <" << changeInclude(*p, includePaths) << "." + headerExtension + ">"; - } - } - - CPP << "\n#include <Ice/BasicStream.h>"; - CPP << "\n#include <"; - if(include.size()) - { - CPP << include << '/'; - } - CPP << includeH << '>'; - - printVersionCheck(H); - printVersionCheck(CPP); - - printDllExportStuff(H, dllExport); - if(dllExport.size()) - { - dllExport += " "; - } - - { - for(vector<Dict>::const_iterator p = dicts.begin(); p != dicts.end(); ++p) - { - try - { - if(!writeDict(argv[0], u, *p, H, CPP, dllExport)) - { - u->destroy(); - return EXIT_FAILURE; - } - } - catch(...) - { - cerr << argv[0] << ": unknown exception" << endl; - u->destroy(); - return EXIT_FAILURE; - } - } - - - for(vector<Index>::const_iterator q = indices.begin(); q != indices.end(); ++q) - { - try - { - if(!writeIndex(argv[0], u, *q, H, CPP, dllExport)) - { - u->destroy(); - return EXIT_FAILURE; - } - } - catch(...) - { - cerr << argv[0] << ": unknown exception" << endl; - u->destroy(); - return EXIT_FAILURE; - } - } - + cerr << argv[0] << ": unknown exception" << endl; + FileTracker::instance()->cleanup(); + u->destroy(); + return EXIT_FAILURE; } - - H << "\n\n#endif\n"; - CPP << '\n'; - - H.close(); - CPP.close(); } u->destroy(); @@ -2005,10 +2019,10 @@ main(int argc, char* argv[]) if(_interrupted) { + FileTracker::instance()->cleanup(); return EXIT_FAILURE; } } - return status; } diff --git a/cpp/src/slice2freezej/Main.cpp b/cpp/src/slice2freezej/Main.cpp index 9bae291e172..2b89feb5cfc 100644 --- a/cpp/src/slice2freezej/Main.cpp +++ b/cpp/src/slice2freezej/Main.cpp @@ -12,6 +12,7 @@ #include <IceUtil/CtrlCHandler.h> #include <IceUtil/StaticMutex.h> #include <Slice/Preprocessor.h> +#include <Slice/FileTracker.h> #include <Slice/JavaUtil.h> #ifdef __BCPLUSPLUS__ @@ -73,15 +74,15 @@ public: FreezeGenerator(const string&, const string&); virtual ~FreezeGenerator(); - bool generate(UnitPtr&, const Dict&); + void generate(UnitPtr&, const Dict&); - bool generate(UnitPtr&, const Index&); + void generate(UnitPtr&, const Index&); private: string varToObject(const TypePtr&, const string&); string objectToVar(const TypePtr&, const string&); - string _prog; + const string _prog; }; FreezeGenerator::FreezeGenerator(const string& prog, const string& dir) @@ -204,7 +205,7 @@ FreezeGenerator::objectToVar(const TypePtr& type, const string& param) return result; } -bool +void FreezeGenerator::generate(UnitPtr& u, const Dict& dict) { static const char* builtinTable[] = @@ -236,16 +237,18 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) TypeList keyTypes = u->lookupType(dict.key, false); if(keyTypes.empty()) { - cerr << _prog << ": `" << dict.key << "' is not a valid type" << endl; - return false; + ostringstream os; + os << "`" << dict.key << "' is not a valid type" << endl; + throw os.str(); } TypePtr keyType = keyTypes.front(); TypeList valueTypes = u->lookupType(dict.value, false); if(valueTypes.empty()) { - cerr << _prog << ": `" << dict.value << "' is not a valid type" << endl; - return false; + ostringstream os; + os << "`" << dict.value << "' is not a valid type" << endl; + throw os.str(); } TypePtr valueType = valueTypes.front(); @@ -263,15 +266,17 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) { if(dict.indices.size() > 1) { - cerr << _prog << ": bad index for dictionary `" << dict.name << "'" << endl; - return false; + ostringstream os; + os << "bad index for dictionary `" << dict.name << "'" << endl; + throw os.str(); } bool containsSequence = false; if(!Dictionary::legalKeyType(valueType, containsSequence)) { - cerr << _prog << ": `" << dict.value << "' is not a valid index type" << endl; - return false; + ostringstream os; + os << "`" << dict.value << "' is not a valid index type" << endl; + throw os.str(); } if(containsSequence) { @@ -288,8 +293,9 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) if(builtInType == 0 || builtInType->kind() != Builtin::KindString) { - cerr << _prog << ": VALUE is a `" << dict.value << "', not a string " << endl; - return false; + ostringstream os; + os << "VALUE is a `" << dict.value << "', not a string " << endl; + throw os.str(); } } indexTypes.push_back(valueType); @@ -311,8 +317,9 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) StructPtr structDecl = StructPtr::dynamicCast(valueType); if(structDecl == 0) { - cerr << _prog << ": `" << dict.value << "' is neither a class nor a struct." << endl; - return false; + ostringstream os; + os << "`" << dict.value << "' is neither a class nor a struct." << endl; + throw os.str(); } dataMembers = structDecl->dataMembers(); } @@ -331,9 +338,10 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) if(dataMember == 0) { - cerr << _prog << ": The value of `" << dict.name - << "' has no data member named `" << index.member << "'" << endl; - return false; + ostringstream os; + os << "The value of `" << dict.name + << "' has no data member named `" << index.member << "'" << endl; + throw os.str(); } TypePtr dataMemberType = dataMember->type(); @@ -341,8 +349,9 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) bool containsSequence = false; if(!Dictionary::legalKeyType(dataMemberType, containsSequence)) { - cerr << _prog << ": `" << index.member << "' cannot be used as an index" << endl; - return false; + ostringstream os; + os << "`" << index.member << "' cannot be used as an index" << endl; + throw os.str(); } if(containsSequence) { @@ -357,8 +366,9 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) BuiltinPtr memberType = BuiltinPtr::dynamicCast(dataMemberType); if(memberType == 0 || memberType->kind() != Builtin::KindString) { - cerr << _prog << ": `" << index.member << "' is not a string " << endl; - return false; + ostringstream os; + os << "`" << index.member << "' is not a string " << endl; + throw os.str(); } } indexTypes.push_back(dataMemberType); @@ -934,13 +944,10 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) out << eb; - close(); - - return true; } -bool +void FreezeGenerator::generate(UnitPtr& u, const Index& index) { string name; @@ -957,16 +964,18 @@ FreezeGenerator::generate(UnitPtr& u, const Index& index) TypeList types = u->lookupType(index.type, false); if(types.empty()) { - cerr << _prog << ": `" << index.type << "' is not a valid type" << endl; - return false; + ostringstream os; + os << "`" << index.type << "' is not a valid type" << endl; + throw os.str(); } TypePtr type = types.front(); ClassDeclPtr classDecl = ClassDeclPtr::dynamicCast(type); if(classDecl == 0) { - cerr << _prog << ": `" << index.type << "' is not a class" << endl; - return false; + ostringstream os; + os << "`" << index.type << "' is not a class" << endl; + throw os.str(); } DataMemberList dataMembers = classDecl->definition()->allDataMembers(); @@ -986,8 +995,9 @@ FreezeGenerator::generate(UnitPtr& u, const Index& index) if(dataMember == 0) { - cerr << _prog << ": `" << index.type << "' has no data member named `" << index.member << "'" << endl; - return false; + ostringstream os; + os << "`" << index.type << "' has no data member named `" << index.member << "'" << endl; + throw os.str(); } if(index.caseSensitive == false) @@ -998,8 +1008,9 @@ FreezeGenerator::generate(UnitPtr& u, const Index& index) BuiltinPtr memberType = BuiltinPtr::dynamicCast(dataMember->type()); if(memberType == 0 || memberType->kind() != Builtin::KindString) { - cerr << _prog << ": `" << index.member << "'is not a string " << endl; - return false; + ostringstream os; + os << "`" << index.member << "'is not a string " << endl; + throw os.str(); } } @@ -1087,11 +1098,8 @@ FreezeGenerator::generate(UnitPtr& u, const Index& index) out << eb; close(); - - return true; } - void usage(const char* n) { @@ -1501,20 +1509,29 @@ main(int argc, char* argv[]) { try { - if(!gen.generate(u, *p)) - { - u->destroy(); - return EXIT_FAILURE; - } + gen.generate(u, *p); + } + catch(const string& ex) + { + // If a file could not be created, then cleanup any + // created files. + FileTracker::instance()->cleanup(); + u->destroy(); + cerr << argv[0] << ": " << ex << endl; + return EXIT_FAILURE; } catch(const Slice::FileException& ex) { + // If a file could not be created, then cleanup any + // created files. + FileTracker::instance()->cleanup(); u->destroy(); cerr << ex.reason() << endl; return EXIT_FAILURE; } catch(...) { + FileTracker::instance()->cleanup(); cerr << argv[0] << ": unknown exception" << endl; u->destroy(); return EXIT_FAILURE; @@ -1525,15 +1542,30 @@ main(int argc, char* argv[]) { try { - if(!gen.generate(u, *q)) - { - u->destroy(); - return EXIT_FAILURE; - } + gen.generate(u, *q); + } + catch(const string& ex) + { + // If a file could not be created, then cleanup any + // created files. + FileTracker::instance()->cleanup(); + u->destroy(); + cerr << argv[0] << ": " << ex << endl; + return EXIT_FAILURE; + } + catch(const Slice::FileException& ex) + { + // If a file could not be created, then cleanup any + // created files. + FileTracker::instance()->cleanup(); + u->destroy(); + cerr << argv[0] << ": " << ex.reason() << endl; + return EXIT_FAILURE; } catch(...) { cerr << argv[0] << ": unknown exception" << endl; + FileTracker::instance()->cleanup(); u->destroy(); return EXIT_FAILURE; } @@ -1548,6 +1580,7 @@ main(int argc, char* argv[]) if(_interrupted) { + FileTracker::instance()->cleanup(); return EXIT_FAILURE; } } diff --git a/cpp/src/slice2html/Gen.cpp b/cpp/src/slice2html/Gen.cpp index d1a56b6ed32..f02ef04b75f 100644 --- a/cpp/src/slice2html/Gen.cpp +++ b/cpp/src/slice2html/Gen.cpp @@ -7,8 +7,13 @@ // // ********************************************************************** +#if defined(_MSC_VER) && _MSC_VER >= 1400 +# define _CRT_SECURE_NO_DEPRECATE 1 // C4996 '<C function>' was declared deprecated +#endif + #include <IceUtil/DisableWarnings.h> #include <IceUtil/Functional.h> +#include <Slice/FileTracker.h> #include <Gen.h> #include <sys/types.h> @@ -1244,9 +1249,11 @@ Slice::GeneratorBase::openStream(const string& path) _out.open(path.c_str()); if(!_out.isOpen()) { - string err = "cannot open `" + path + "' for writing"; - throw err; + ostringstream os; + os << "cannot open file `" << path << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } + FileTracker::instance()->addFile(path); } void @@ -1447,18 +1454,28 @@ Slice::GeneratorBase::makeDir(const string& dir) int rc = stat(dir.c_str(), &st); if(rc == 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 - rc = mkdir(dir.c_str()); + rc = _mkdir(dir.c_str()); #else rc = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); #endif if(rc != 0) { - string err = "cannot create directory `" + dir + "'"; - throw err; + ostringstream os; + os << "cannot create directory `" << dir << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } + FileTracker::instance()->addDirectory(dir); } string @@ -1467,8 +1484,9 @@ Slice::GeneratorBase::readFile(const string& file) ifstream in(file.c_str()); if(!in) { - string err = "cannot open `" + file + "' for reading"; - throw err; + ostringstream os; + os << "cannot open file `" << file << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } ostringstream result; @@ -1540,8 +1558,9 @@ Slice::GeneratorBase::readFile(const string& file, string& part1, string& part2) ifstream in(file.c_str()); if(!in) { - string err = "cannot open `" + file + "' for reading"; - throw err; + ostringstream os; + os << "cannot open file `" << file << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } string line; diff --git a/cpp/src/slice2html/Main.cpp b/cpp/src/slice2html/Main.cpp index f1e864b140f..068287ed632 100644 --- a/cpp/src/slice2html/Main.cpp +++ b/cpp/src/slice2html/Main.cpp @@ -11,6 +11,7 @@ #include <IceUtil/CtrlCHandler.h> #include <IceUtil/StaticMutex.h> #include <Slice/Preprocessor.h> +#include <Slice/FileTracker.h> #include <Gen.h> #include <stdlib.h> @@ -238,13 +239,24 @@ main(int argc, char* argv[]) Slice::generate(p, output, header, footer, indexHeader, indexFooter, imageDir, logoURL, searchAction, indexCount, summaryCount); } + catch(const Slice::FileException& ex) + { + // If a file could not be created, then cleanup any + // created files. + FileTracker::instance()->cleanup(); + p->destroy(); + cerr << argv[0] << ": " << ex.reason() << endl; + return EXIT_FAILURE; + } catch(const string& err) { + FileTracker::instance()->cleanup(); cerr << argv[0] << ": " << err << endl; status = EXIT_FAILURE; } catch(const char* err) { + FileTracker::instance()->cleanup(); cerr << argv[0] << ": " << err << endl; status = EXIT_FAILURE; } @@ -257,6 +269,7 @@ main(int argc, char* argv[]) if(_interrupted) { + FileTracker::instance()->cleanup(); return EXIT_FAILURE; } } diff --git a/cpp/src/slice2java/Main.cpp b/cpp/src/slice2java/Main.cpp index b2fff573e39..bc555d403bb 100644 --- a/cpp/src/slice2java/Main.cpp +++ b/cpp/src/slice2java/Main.cpp @@ -11,6 +11,7 @@ #include <IceUtil/CtrlCHandler.h> #include <IceUtil/StaticMutex.h> #include <Slice/Preprocessor.h> +#include <Slice/FileTracker.h> #include <Gen.h> #ifdef __BCPLUSPLUS__ @@ -234,7 +235,7 @@ main(int argc, char* argv[]) p->destroy(); return EXIT_FAILURE; } - + if(parseStatus == EXIT_FAILURE) { status = EXIT_FAILURE; @@ -273,8 +274,11 @@ main(int argc, char* argv[]) } catch(const Slice::FileException& ex) { + // If a file could not be created, then + // cleanup any created files. + FileTracker::instance()->cleanup(); p->destroy(); - cerr << ex.reason() << endl; + cerr << argv[0] << ": " << ex.reason() << endl; return EXIT_FAILURE; } } @@ -287,6 +291,9 @@ main(int argc, char* argv[]) if(_interrupted) { + // If the translator was interrupted, then cleanup any + // created files. + FileTracker::instance()->cleanup(); return EXIT_FAILURE; } } @@ -294,7 +301,18 @@ main(int argc, char* argv[]) if(!checksumClass.empty()) { - Gen::writeChecksumClass(checksumClass, output, checksums, java2); + try + { + Gen::writeChecksumClass(checksumClass, output, checksums, java2); + } + catch(const Slice::FileException& ex) + { + // If a file could not be created, then + // cleanup any created files. + FileTracker::instance()->cleanup(); + cerr << argv[0] << ": " << ex.reason() << endl; + return EXIT_FAILURE; + } } return status; diff --git a/cpp/src/slice2py/Main.cpp b/cpp/src/slice2py/Main.cpp index 660914e715c..4b522bf9a98 100644 --- a/cpp/src/slice2py/Main.cpp +++ b/cpp/src/slice2py/Main.cpp @@ -14,6 +14,7 @@ #include <IceUtil/CtrlCHandler.h> #include <IceUtil/StaticMutex.h> #include <Slice/Preprocessor.h> +#include <Slice/FileTracker.h> #include <Slice/PythonUtil.h> #include <cstring> @@ -72,7 +73,7 @@ class PackageVisitor : public ParserVisitor { public: - PackageVisitor(const string&, const string&, const string&); + PackageVisitor(const string&, const string&); virtual bool visitModuleStart(const ModulePtr&); virtual void visitModuleEnd(const ModulePtr&); @@ -84,15 +85,14 @@ private: static const char* _moduleTag; static const char* _submoduleTag; - bool createDirectory(const string&); + void createDirectory(const string&); - bool addModule(const string&, const string&); - bool addSubmodule(const string&, const string&); + void addModule(const string&, const string&); + void addSubmodule(const string&, const string&); - bool readInit(const string&, StringList&, StringList&); - bool writeInit(const string&, const StringList&, const StringList&); + void readInit(const string&, StringList&, StringList&); + void writeInit(const string&, const StringList&, const StringList&); - string _name; string _module; StringList _pathStack; }; @@ -100,8 +100,8 @@ private: const char* PackageVisitor::_moduleTag = "# Modules:"; const char* PackageVisitor::_submoduleTag = "# Submodules:"; -PackageVisitor::PackageVisitor(const string& name, const string& module, const string& dir) : - _name(name), _module(module) +PackageVisitor::PackageVisitor(const string& module, const string& dir) : + _module(module) { if(dir.empty()) { @@ -138,27 +138,18 @@ PackageVisitor::visitModuleStart(const ModulePtr& p) } for(vector<string>::iterator q = v.begin(); q != v.end(); ++q) { - if(q != v.begin() && !addSubmodule(path, fixIdent(*q))) + if(q != v.begin()) { - return false; + addSubmodule(path, fixIdent(*q)); } path += "/" + *q; - if(!createDirectory(path)) - { - return false; - } + createDirectory(path); - if(!addModule(path, _module)) - { - return false; - } + addModule(path, _module); } - if(!addSubmodule(path, name)) - { - return false; - } + addSubmodule(path, name); } path += "/" + name; @@ -171,26 +162,20 @@ PackageVisitor::visitModuleStart(const ModulePtr& p) string parentPath = _pathStack.front(); _pathStack.push_front(path); - if(!createDirectory(path)) - { - return false; - } + createDirectory(path); // // If necessary, add this module to the set of imported modules in __init__.py. // - if(!addModule(path, _module)) - { - return false; - } + addModule(path, _module); // // If this is a submodule, then modify the parent's __init__.py to import us. // ModulePtr mod = ModulePtr::dynamicCast(p->container()); - if(mod && !addSubmodule(parentPath, name)) + if(mod) { - return false; + addSubmodule(parentPath, name); } return true; @@ -203,75 +188,72 @@ PackageVisitor::visitModuleEnd(const ModulePtr& p) _pathStack.pop_front(); } -bool +void PackageVisitor::createDirectory(const string& dir) { struct stat st; int result; result = stat(dir.c_str(), &st); - if(result != 0) + 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()); + result = _mkdir(dir.c_str()); #else - result = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); + result = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); #endif - if(result != 0) - { - cerr << _name << ": unable to create `" << dir << "': " << strerror(errno) << endl; - return false; - } + if(result != 0) + { + ostringstream os; + os << "cannot create directory `" << dir << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } - return true; + FileTracker::instance()->addDirectory(dir); } -bool +void PackageVisitor::addModule(const string& dir, const string& name) { // // Add a module to the set of imported modules in __init__.py. // StringList modules, submodules; - if(readInit(dir, modules, submodules)) + readInit(dir, modules, submodules); + StringList::iterator p = find(modules.begin(), modules.end(), name); + if(p == modules.end()) { - StringList::iterator p = find(modules.begin(), modules.end(), name); - if(p == modules.end()) - { - modules.push_back(name); - return writeInit(dir, modules, submodules); - } - - return true; + modules.push_back(name); + writeInit(dir, modules, submodules); } - - return false; } -bool +void PackageVisitor::addSubmodule(const string& dir, const string& name) { // // Add a submodule to the set of imported modules in __init__.py. // StringList modules, submodules; - if(readInit(dir, modules, submodules)) + readInit(dir, modules, submodules); + StringList::iterator p = find(submodules.begin(), submodules.end(), name); + if(p == submodules.end()) { - StringList::iterator p = find(submodules.begin(), submodules.end(), name); - if(p == submodules.end()) - { - submodules.push_back(name); - return writeInit(dir, modules, submodules); - } - - return true; + submodules.push_back(name); + writeInit(dir, modules, submodules); } - - return false; } -bool +void PackageVisitor::readInit(const string& dir, StringList& modules, StringList& submodules) { string initPath = dir + "/__init__.py"; @@ -282,8 +264,9 @@ PackageVisitor::readInit(const string& dir, StringList& modules, StringList& sub ifstream in(initPath.c_str()); if(!in) { - cerr << _name << ": unable to open `" << initPath << "': " << strerror(errno) << endl; - return false; + ostringstream os; + os << "cannot open file `" << initPath << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } ReadState state = PreModules; @@ -316,8 +299,9 @@ PackageVisitor::readInit(const string& dir, StringList& modules, StringList& sub if(s.size() < 8) { - cerr << _name << ": invalid line `" << s << "' in `" << initPath << "'" << endl; - return false; + ostringstream os; + os << "invalid line `" << s << "' in `" << initPath << "'"; + throw os.str(); } string name = s.substr(7); @@ -334,15 +318,14 @@ PackageVisitor::readInit(const string& dir, StringList& modules, StringList& sub if(state != InSubmodules) { - cerr << _name << ": invalid format in `" << initPath << "'" << endl; - return false; + ostringstream os; + os << "invalid format in `" << initPath << "'" << endl; + throw os.str(); } } - - return true; } -bool +void PackageVisitor::writeInit(const string& dir, const StringList& modules, const StringList& submodules) { string initPath = dir + "/__init__.py"; @@ -350,8 +333,11 @@ PackageVisitor::writeInit(const string& dir, const StringList& modules, const St ofstream os(initPath.c_str()); if(!os) { - return false; + ostringstream os; + os << "cannot open file `" << initPath << "': " << strerror(errno); + throw FileException(__FILE__, __LINE__, os.str()); } + FileTracker::instance()->addFile(initPath); StringList::const_iterator p; @@ -369,8 +355,6 @@ PackageVisitor::writeInit(const string& dir, const StringList& modules, const St { os << "import " << *p << endl; } - - return true; } void @@ -490,6 +474,7 @@ main(int argc, char* argv[]) IceUtil::CtrlCHandler ctrlCHandler; ctrlCHandler.setCallback(interruptedCallback); + for(i = args.begin(); i != args.end(); ++i) { Preprocessor icecpp(argv[0], *i, cppArgs); @@ -551,34 +536,52 @@ main(int argc, char* argv[]) file = output + '/' + file; } - IceUtilInternal::Output out; - out.open(file.c_str()); - if(!out) + 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); + out << "\n# Generated from file `" << base << ".ice'\n"; + + // + // Generate the Python mapping. + // + generate(u, all, checksum, includePaths, out); + + out.close(); + + // + // Create or update the Python package hierarchy. + // + if(!noPackage) + { + PackageVisitor visitor(prefix + base + "_ice", output); + u->visit(&visitor, false); + } + } + catch(const Slice::FileException& ex) { - cerr << argv[0] << ": can't open `" << file << "' for writing" << endl; + // If a file could not be created, then cleanup any + // created files. + FileTracker::instance()->cleanup(); u->destroy(); + cerr << argv[0] << ": " << ex.reason() << endl; return EXIT_FAILURE; } - - printHeader(out); - out << "\n# Generated from file `" << base << ".ice'\n"; - - // - // Generate the Python mapping. - // - generate(u, all, checksum, includePaths, out); - - out.close(); - - // - // Create or update the Python package hierarchy. - // - if(!noPackage) + catch(const string& err) { - PackageVisitor visitor(argv[0], prefix + base + "_ice", output); - u->visit(&visitor, false); + FileTracker::instance()->cleanup(); + cerr << argv[0] << ": " << err << endl; + status = EXIT_FAILURE; } - } u->destroy(); @@ -589,6 +592,7 @@ main(int argc, char* argv[]) if(_interrupted) { + FileTracker::instance()->cleanup(); return EXIT_FAILURE; } } diff --git a/cpp/src/slice2rb/Main.cpp b/cpp/src/slice2rb/Main.cpp index 0d6856a2123..092c16f8a35 100644 --- a/cpp/src/slice2rb/Main.cpp +++ b/cpp/src/slice2rb/Main.cpp @@ -12,6 +12,7 @@ #include <IceUtil/CtrlCHandler.h> #include <IceUtil/StaticMutex.h> #include <Slice/Preprocessor.h> +#include <Slice/FileTracker.h> #include <Slice/RubyUtil.h> #include <fstream> @@ -207,24 +208,37 @@ main(int argc, char* argv[]) file = output + '/' + file; } - IceUtilInternal::Output out; - out.open(file.c_str()); - if(!out) + try { - cerr << argv[0] << ": can't open `" << file << "' for writing" << endl; + 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); + out << "\n# Generated from file `" << base << ".ice'\n"; + + // + // 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(); + cerr << argv[0] << ": " << ex.reason() << endl; return EXIT_FAILURE; } - - printHeader(out); - out << "\n# Generated from file `" << base << ".ice'\n"; - - // - // Generate the Ruby mapping. - // - generate(u, all, checksum, includePaths, out); - - out.close(); } u->destroy(); @@ -235,6 +249,7 @@ main(int argc, char* argv[]) if(_interrupted) { + FileTracker::instance()->cleanup(); return EXIT_FAILURE; } } |