diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index 03fdb3fa0..1dc5197f3 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -93,7 +93,7 @@ void CMakeErrorHandler(const char* message, const char* title, bool&, void* clie int main(int argc, char** argv) { cmDocumentation doc; - if(cmDocumentation::Type ht = doc.CheckOptions(argc, argv)) + if(doc.CheckOptions(argc, argv)) { cmake hcm; std::vector commands; @@ -103,8 +103,7 @@ int main(int argc, char** argv) doc.SetDescriptionSection(cmDocumentationDescription); doc.SetOptionsSection(cmDocumentationOptions); doc.SetCommandsSection(&commands[0]); - doc.PrintDocumentation(ht, std::cout); - return 0; + return doc.PrintRequestedDocumentation(std::cout)? 0:1; } bool debug = false; diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 0e853d98c..390ab5b36 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -178,17 +178,69 @@ void cmDocumentation::PrintDocumentation(Type ht, std::ostream& os) } //---------------------------------------------------------------------------- -cmDocumentation::Type cmDocumentation::CheckOptions(int argc, char** argv) +bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os) +{ + bool result = true; + + // Loop over requested documentation types. + for(RequestedMapType::const_iterator i = this->RequestedMap.begin(); + i != this->RequestedMap.end(); ++i) + { + // If a file name was given, use it. Otherwise, default to the + // given stream. + std::ofstream* fout = 0; + std::ostream* s = &os; + if(i->second.length() > 0) + { +#ifdef _WIN32 + fout = new ofstream(i->second.c_str(), ios::out | ios::binary); +#else + fout = new ofstream(i->second.c_str(), ios::out); +#endif + if(fout) + { + s = fout; + } + else + { + result = false; + } + } + + // Print this documentation type to the stream. + this->PrintDocumentation(i->first, *s); + + // Check for error. + if(!*s) + { + result = false; + } + + // Close the file if we wrote one. + if(fout) + { + delete fout; + } + } + return result; +} + +//---------------------------------------------------------------------------- +bool cmDocumentation::CheckOptions(int argc, char** argv) { // Providing zero arguments gives usage information. if(argc == 1) { - return cmDocumentation::Usage; + this->RequestedMap[cmDocumentation::Usage] = ""; + return true; } // Search for supported help options. + bool result = false; for(int i=1; i < argc; ++i) { + // Check if this is a supported help option. + Type type = cmDocumentation::None; if((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0) || (strcmp(argv[i], "/?") == 0) || @@ -196,33 +248,48 @@ cmDocumentation::Type cmDocumentation::CheckOptions(int argc, char** argv) (strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "-H") == 0)) { - return cmDocumentation::Usage; + type = cmDocumentation::Usage; } - if(strcmp(argv[i], "--help-full") == 0) + else if(strcmp(argv[i], "--help-full") == 0) { - return cmDocumentation::Full; + type = cmDocumentation::Full; } - if(strcmp(argv[i], "--help-html") == 0) + else if(strcmp(argv[i], "--help-html") == 0) { - return cmDocumentation::HTML; + type = cmDocumentation::HTML; } - if(strcmp(argv[i], "--help-man") == 0) + else if(strcmp(argv[i], "--help-man") == 0) { - return cmDocumentation::Man; + type = cmDocumentation::Man; } - if(strcmp(argv[i], "--copyright") == 0) + else if(strcmp(argv[i], "--copyright") == 0) { - return cmDocumentation::Copyright; + type = cmDocumentation::Copyright; } - if((strcmp(argv[i], "--version") == 0) || - (strcmp(argv[i], "-version") == 0) || - (strcmp(argv[i], "-V") == 0) || - (strcmp(argv[i], "/V") == 0)) + else if((strcmp(argv[i], "--version") == 0) || + (strcmp(argv[i], "-version") == 0) || + (strcmp(argv[i], "-V") == 0) || + (strcmp(argv[i], "/V") == 0)) { - return cmDocumentation::Version; + type = cmDocumentation::Version; + } + if(type) + { + // This is a help option. See if there is a file name given. + result = true; + if((i+1 < argc) && (argv[i+1][0] != '-') && + (strcmp(argv[i+1], "/V") != 0) && (strcmp(argv[i+1], "/?") != 0)) + { + this->RequestedMap[type] = argv[i+1]; + i = i+1; + } + else + { + this->RequestedMap[type] = ""; + } } } - return cmDocumentation::None; + return result; } //---------------------------------------------------------------------------- diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index b5cf85c68..598b1d390 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -32,11 +32,19 @@ public: /** * Check command line arguments for documentation options. Returns - * the type of help to be provided. If non-zero, the result should - * be passed to PrintDocumentation to produce the desired - * documentation. + * true if documentation options are found, and false otherwise. + * When true is returned, PrintRequestedDocumentation should be + * called. */ - Type CheckOptions(int argc, char** argv); + bool CheckOptions(int argc, char** argv); + + /** + * Print help requested on the command line. Call after + * CheckOptions returns true. Returns true on success, and false + * otherwise. Failure can occur when output files specified on the + * command line cannot be written. + */ + bool PrintRequestedDocumentation(std::ostream& os); /** Print help of the given type. */ void PrintDocumentation(Type ht, std::ostream& os); @@ -134,6 +142,9 @@ private: Form CurrentForm; const char* TextIndent; int TextWidth; + + typedef std::map RequestedMapType; + RequestedMapType RequestedMap; }; #endif diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 0d3589465..784502a5c 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -93,7 +93,7 @@ int main(int ac, char** av) int do_cmake(int ac, char** av) { cmDocumentation doc; - if(cmDocumentation::Type ht = doc.CheckOptions(ac, av)) + if(doc.CheckOptions(ac, av)) { // Construct and print requested documentation. cmake hcm; @@ -107,8 +107,8 @@ int do_cmake(int ac, char** av) doc.SetGeneratorsSection(&generators[0]); doc.SetOptionsSection(cmDocumentationOptions); doc.SetCommandsSection(&commands[0]); - doc.PrintDocumentation(ht, std::cout); - + int result = doc.PrintRequestedDocumentation(std::cout)? 0:1; + // If we were run with no arguments, but a CMakeLists.txt file // exists, the user may have been trying to use the old behavior // of cmake to build a project in-source. Print a message @@ -121,7 +121,7 @@ int do_cmake(int ac, char** av) doc.Print(cmDocumentation::UsageForm, std::cerr); return 1; } - return 0; + return result; } bool wiz = false;