// ********************************************************************** // // Copyright (c) 2004 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 #include #include using namespace std; using namespace Ice; using namespace IcePatch2; namespace IcePatch2 { class Client : public Application { public: void usage(); virtual int run(int, char*[]); private: void usage(const std::string&); }; }; class TextPatcherFeedback : public PatcherFeedback { public: virtual bool noFileSummary(const string& reason) { cout << "Cannot load file summary:\n" << reason << endl; string answer; do { cout << "Do a thorough patch? (yes/no)" << endl; cin >> answer; transform(answer.begin(), answer.end(), answer.begin(), ::tolower); if(answer == "no") { return false; } } while(answer != "yes"); return true; } virtual bool fileListStart() { _lastProgress = "0%"; cout << "Getting list of files to patch: " << _lastProgress << flush; return true; } virtual bool fileListProgress(Int percent) { for(unsigned int i = 0; i < _lastProgress.size(); ++i) { cout << '\b'; } ostringstream s; s << percent << '%'; _lastProgress = s.str(); cout << _lastProgress << flush; return true; } virtual bool fileListEnd() { cout << endl; return true; } virtual bool patchStart(const string& path, Long size, Long totalProgress, Long totalSize) { ostringstream s; s << "0/" << size << " (" << totalProgress << '/' << totalSize << ')'; _lastProgress = s.str(); cout << getBasename(path) << ' ' << _lastProgress << flush; return true; } virtual bool patchProgress(Long progress, Long size, Long totalProgress, Long totalSize) { for(unsigned int i = 0; i < _lastProgress.size(); ++i) { cout << '\b'; } ostringstream s; s << progress << '/' << size << " (" << totalProgress << '/' << totalSize << ')'; _lastProgress = s.str(); cout << _lastProgress << flush; return true; } virtual bool patchEnd() { cout << endl; return true; } private: string _lastProgress; }; int IcePatch2::Client::run(int argc, char* argv[]) { PropertiesPtr properties = communicator()->getProperties(); for(int i = 1; i < argc; ++i) { if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { usage(argv[0]); return EXIT_FAILURE; } else if(strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) { cout << ICE_STRING_VERSION << endl; return EXIT_FAILURE; } else if(strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--thorough") == 0) { properties->setProperty("IcePatch2.Thorough", "1"); } else if(strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--dry") == 0) { properties->setProperty("IcePatch2.DryRun", "1"); } else if(argv[i][0] == '-') { cerr << argv[0] << ": unknown option `" << argv[i] << "'" << endl; usage(argv[0]); return EXIT_FAILURE; } else { if(properties->getProperty("IcePatch2.Directory").empty()) { properties->setProperty("IcePatch2.Directory", argv[i]); } else { cerr << argv[0] << ": too many arguments" << endl; usage(argv[0]); return EXIT_FAILURE; } } } try { PatcherFeedbackPtr feedback = new TextPatcherFeedback; PatcherPtr patcher = new Patcher(communicator(), feedback); patcher->patch(); } catch(const string& ex) { cerr << argv[0] << ": " << ex << endl; return EXIT_FAILURE; } return EXIT_SUCCESS; } void IcePatch2::Client::usage(const string& appName) { string options = "Options:\n" "-h, --help Show this message.\n" "-v, --version Display the Ice version.\n" "-t, --thorough Recalculate all checksums.\n" "-d, --dry Don't update, do a dry run only."; cerr << "Usage: " << appName << " [options] [DIR]" << endl; cerr << options << endl; } int main(int argc, char* argv[]) { Client app; return app.main(argc, argv); }