diff options
author | Brad King <brad.king@kitware.com> | 2003-02-14 15:53:37 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2003-02-14 15:53:37 (GMT) |
commit | 1f55680332c133fddce4a0b85cfb7ee1a20cff75 (patch) | |
tree | 7cc80032918bf19095fe31fb7d52b29e6c1d64e8 /Source/cmDocumentation.cxx | |
parent | d9a74e1b1e18156be224697383b571ad9af4336c (diff) | |
download | CMake-1f55680332c133fddce4a0b85cfb7ee1a20cff75.zip CMake-1f55680332c133fddce4a0b85cfb7ee1a20cff75.tar.gz CMake-1f55680332c133fddce4a0b85cfb7ee1a20cff75.tar.bz2 |
ENH: Added cmDocumentation class to generate various forms of documentation. Each executable will be able to generate its own documentation.
Diffstat (limited to 'Source/cmDocumentation.cxx')
-rw-r--r-- | Source/cmDocumentation.cxx | 478 |
1 files changed, 478 insertions, 0 deletions
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx new file mode 100644 index 0000000..2532c16 --- /dev/null +++ b/Source/cmDocumentation.cxx @@ -0,0 +1,478 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmDocumentation.h" + +#include "cmSystemTools.h" + +//---------------------------------------------------------------------------- +static const cmDocumentationEntry cmDocumentationStandardOptions[] = +{ + {"--copyright", "Print the CMake copyright and exit.", 0}, + {"--usage", "Print usage information and exit.", + "Usage describes the basic command line interface and its options."}, + {"--help", "Print full help and exit.", + "Full help displays most of the documentation provided by the UNIX " + "man page. It is provided for use on non-UNIX platforms, but is " + "also convenient if the man page is not installed."}, + {"--help-html", "Print full help in HTML format.", + "This option is used by CMake authors to help produce web pages."}, + {"--man", "Print a UNIX man page and exit.", + "This option is used by CMake authors to generate the UNIX man page."}, + {"--version", "Show program name/version banner and exit.", 0}, + {0,0,0} +}; + +//---------------------------------------------------------------------------- +const cmDocumentationEntry cmDocumentationCopyright[] = +{ + {0, + "Copyright (c) 2002 Kitware, Inc., Insight Consortium.\n" + "All rights reserved.\n", 0}, + {0, + "Redistribution and use in source and binary forms, with or without " + "modification, are permitted provided that the following conditions are " + "met:\n", 0}, + {" * ", + "Redistributions of source code must retain the above copyright notice, " + "this list of conditions and the following disclaimer.\n", 0}, + {" * ", + "Redistributions in binary form must reproduce the above copyright " + "notice, this list of conditions and the following disclaimer in the " + "documentation and/or other materials provided with the distribution.\n", + 0}, + {" * ", + "The names of Kitware, Inc., the Insight Consortium, or the names of " + "any consortium members, or of any contributors, may not be used to " + "endorse or promote products derived from this software without " + "specific prior written permission.\n", 0}, + {" * ", + "Modified source versions must be plainly marked as such, and must " + "not be misrepresented as being the original software.\n", 0}, + {0, + "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS " + "``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT " + "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR " + "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR " + "CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, " + "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, " + "PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR " + "PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF " + "LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING " + "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS " + "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n", 0}, + {0, 0, 0} +}; + +//---------------------------------------------------------------------------- +cmDocumentation::cmDocumentation() +{ + this->Commands = 0; + this->Description = 0; + this->Name = 0; + this->UsageHelp = 0; + this->SetOptions(0); +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintManSection(std::ostream& os, + const cmDocumentationEntry* section, + const char* name) +{ + if(!section) { return; } + os << ".SH " << name << "\n"; + for(const cmDocumentationEntry* op = section; op->brief; ++op) + { + if(op->name) + { + os << ".TP\n" + << ".B " << op->name << "\n" + << op->brief << "\n"; + if(op->full) { os << op->full << "\n"; } + } + else + { + os << ".PP\n" + << op->brief << "\n"; + } + } +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintHelpSection(std::ostream& os, + const cmDocumentationEntry* section) +{ + if(!section) { return; } + for(const cmDocumentationEntry* op = section; op->brief; ++op) + { + if(op->name) + { + os << " " << op->name << "\n" + << " "; + this->PrintColumn(os, 70, " ", op->brief); + if(op->full) + { + os << "\n" + << " "; + this->PrintColumn(os, 70, " ", op->full); + } + os << "\n"; + } + else + { + this->PrintColumn(os, 77, "", op->brief); + os << "\n"; + } + os << "\n"; + } +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintHTMLEscapes(std::ostream& os, const char* text) +{ + static cmDocumentationEntry escapes[] = + { + {"<", "<", 0}, + {">", ">", 0}, + {"&", "&", 0}, + {0,0,0} + }; + for(const char* p = text; *p; ++p) + { + bool found = false; + for(const cmDocumentationEntry* op = escapes; !found && op->name; ++op) + { + if(op->name[0] == *p) + { + os << op->brief; + found = true; + } + } + if(!found) + { + os << *p; + } + } +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintHelpHTMLSection(std::ostream& os, + const cmDocumentationEntry* section, + const char* header) +{ + if(!section) { return; } + if(header) + { + os << "<h2>" << header << "</h2>\n"; + } + for(const cmDocumentationEntry* op = section; op->brief;) + { + if(op->name) + { + os << "<ul>\n"; + for(;op->name;++op) + { + os << " <li>\n"; + os << " <b><code>"; + this->PrintHTMLEscapes(os, op->name); + os << "</code></b>: "; + this->PrintHTMLEscapes(os, op->brief); + if(op->full) + { + os << " "; + this->PrintHTMLEscapes(os, op->full); + } + os << "\n"; + os << " </li>\n"; + } + os << "</ul>\n"; + } + else + { + this->PrintHTMLEscapes(os, op->brief); + os << "\n"; + ++op; + } + } +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintUsageSection(std::ostream& os, + const cmDocumentationEntry* section) +{ + if(!section) { return; } + std::ios::fmtflags flags = os.flags(); + os.setf(flags | std::ios::left); + for(const cmDocumentationEntry* op = section; op->brief; ++op) + { + if(op->name) + { + os << " "; + os.width(25); + os << op->name << "= " << op->brief << "\n"; + } + else + { + os << "\n"; + this->PrintColumn(os, 74, "", op->brief); + os << "\n"; + } + } + os.setf(flags); +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintUsage(std::ostream& os) +{ + os << "Usage:\n"; + this->PrintUsageSection(os, this->UsageHelp); + this->PrintUsageSection(os, &this->Options[0]); +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintHelp(std::ostream& os) +{ + os << "Usage:\n"; + os << "\n"; + this->PrintHelpSection(os, this->UsageHelp); + this->PrintHelpSection(os, this->Description); + os << "--------------------------------------------------------------------------\n"; + this->PrintHelpSection(os, &this->Options[0]); + os << "--------------------------------------------------------------------------\n"; + this->PrintHelpSection(os, this->Commands); +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintHelpHTML(std::ostream& os) +{ + os << "<html>\n" + << "<body>\n"; + os << "<h2>Using CMake</h2>\n"; + if(this->UsageHelp) + { + os << "<blockquote><code>\n"; + this->PrintHelpHTMLSection(os, this->UsageHelp, 0); + os << "</code></blockquote>\n"; + } + this->PrintHelpHTMLSection(os, this->Description, 0); + this->PrintHelpHTMLSection(os, &this->Options[0], "Command-line Options"); + this->PrintHelpHTMLSection(os, this->Commands, "CMakeLists.txt Commands"); + os << "</body>\n" + << "</html>\n"; +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintManPage(std::ostream& os) +{ + os << ".TH CMake 1 \"" + << cmSystemTools::GetCurrentDateTime("%B %d, %Y").c_str() + << "\" \"CMake " CMake_VERSION_STRING "\"\n"; + this->PrintManSection(os, this->Name, "NAME"); + this->PrintManSection(os, this->UsageHelp, "SYNOPSIS"); + this->PrintManSection(os, this->Description, "DESCRIPTION"); + this->PrintManSection(os, &this->Options[0], "OPTIONS"); + this->PrintManSection(os, this->Commands, "COMMANDS"); + this->PrintManSection(os, cmDocumentationCopyright, "COPYRIGHT"); + os << ".SH MAILING LIST\n"; + os << "For help and discussion about using cmake, a mailing list is\n" + << "provided at\n" + << ".B cmake@www.cmake.org.\n" + << "Please first read the full documentation at\n" + << ".B http://www.cmake.org\n" + << "before posting questions to the list.\n"; + os << ".SH AUTHOR\n" + << "This manual page was generated by \"cmake --man\".\n"; +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintCopyright(std::ostream& os) +{ + os << "CMake version " CMake_VERSION_STRING "\n"; + for(const cmDocumentationEntry* op = cmDocumentationCopyright; + op->brief; ++op) + { + if(op->name) + { + os << " * "; + this->PrintColumn(os, 74, " ", op->brief); + } + else + { + this->PrintColumn(os, 77, "", op->brief); + } + os << "\n"; + } +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintVersion(std::ostream& os) +{ + os << "CMake version " CMake_VERSION_STRING "\n"; +} + +//---------------------------------------------------------------------------- +void cmDocumentation::PrintColumn(std::ostream& os, int width, + const char* indent, const char* text) +{ + // Print text arranged in a column of fixed witdh indented by the + // "indent" text. + const char* l = text; + int column = 0; + bool newSentence = false; + bool first = true; + while(*l) + { + // Parse the next word. + const char* r = l; + while(*r && (*r != '\n') && (*r != ' ')) { ++r; } + + // Does it fit on this line? + if(r-l < (width-column-(newSentence?1:0))) + { + // Word fits on this line. + if(r > l) + { + if(column) + { + // Not first word on line. Separate from the previous word + // by a space, or two if this is a new sentence. + if(newSentence) + { + os << " "; + column += 2; + } + else + { + os << " "; + column += 1; + } + } + else + { + // First word on line. Print indentation unless this is the + // first line. + os << (first?"":indent); + } + + // Print the word. + os.write(l, static_cast<long>(r-l)); + newSentence = (*(r-1) == '.'); + } + + if(*r == '\n') + { + // Text provided a newline. Start a new line. + os << "\n"; + ++r; + column = 0; + first = false; + } + else + { + // No provided newline. Continue this line. + column += static_cast<long>(r-l); + } + } + else + { + // Word does not fit on this line. Start a new line. + os << "\n"; + first = false; + if(r > l) + { + os << indent; + os.write(l, static_cast<long>(r-l)); + column = static_cast<long>(r-l); + newSentence = (*(r-1) == '.'); + } + } + + // Move to beginning of next word. Skip over whitespace. + l = r; + while(*l && (*l == ' ')) { ++l; } + } +} + +//---------------------------------------------------------------------------- +void cmDocumentation::Print(Type ht, std::ostream& os) +{ + switch (ht) + { + case cmDocumentation::Usage: this->PrintUsage(os); break; + case cmDocumentation::Help: this->PrintHelp(os); break; + case cmDocumentation::HelpHTML: this->PrintHelpHTML(os); break; + case cmDocumentation::Man: this->PrintManPage(os); break; + case cmDocumentation::Copyright: this->PrintCopyright(os); break; + case cmDocumentation::Version: this->PrintVersion(os); break; + default: break; + } +} + +//---------------------------------------------------------------------------- +cmDocumentation::Type cmDocumentation::CheckOptions(int argc, char** argv) +{ + for(int i=1; i < argc; ++i) + { + if((strcmp(argv[i], "/?") == 0) || + (strcmp(argv[i], "-usage") == 0) || + (strcmp(argv[i], "--usage") == 0)) + { + return cmDocumentation::Usage; + } + if((strcmp(argv[i], "-help") == 0) || + (strcmp(argv[i], "--help") == 0)) + { + return cmDocumentation::Help; + } + if(strcmp(argv[i], "--help-html") == 0) + { + return cmDocumentation::HelpHTML; + } + if(strcmp(argv[i], "--man") == 0) + { + return cmDocumentation::Man; + } + if(strcmp(argv[i], "--copyright") == 0) + { + return cmDocumentation::Copyright; + } + if(strcmp(argv[i], "--version") == 0) + { + return cmDocumentation::Version; + } + } + return cmDocumentation::None; +} + +//---------------------------------------------------------------------------- +void cmDocumentation::SetOptions(const cmDocumentationEntry* d) +{ + this->Options.erase(this->Options.begin(), this->Options.end()); + if(d) + { + for(const cmDocumentationEntry* op = d; op->brief; ++op) + { + this->Options.push_back(*op); + } + } + for(const cmDocumentationEntry* op = cmDocumentationStandardOptions; + op->brief; ++op) + { + this->Options.push_back(*op); + } + cmDocumentationEntry empty = {0,0,0}; + this->Options.push_back(empty); +} |