summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2003-02-19 01:42:02 (GMT)
committerBrad King <brad.king@kitware.com>2003-02-19 01:42:02 (GMT)
commit5e18bec8f76a811e48d2c31a954d0de44e8c5c11 (patch)
tree7c9f61e2a5d552f3ce69c2dd80618edc2cdf0af2 /Source
parentba56262ae21686670b26935d3a89cabc6f4d8a1f (diff)
downloadCMake-5e18bec8f76a811e48d2c31a954d0de44e8c5c11.zip
CMake-5e18bec8f76a811e48d2c31a954d0de44e8c5c11.tar.gz
CMake-5e18bec8f76a811e48d2c31a954d0de44e8c5c11.tar.bz2
ENH: Re-implemented document generation class to be more organized and more robust.
Diffstat (limited to 'Source')
-rw-r--r--Source/CursesDialog/ccmake.cxx19
-rw-r--r--Source/cmDocumentation.cxx789
-rw-r--r--Source/cmDocumentation.h132
-rw-r--r--Source/cmakemain.cxx18
4 files changed, 590 insertions, 368 deletions
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 47ae7ee..a9386a2 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -30,8 +30,8 @@
//----------------------------------------------------------------------------
static const cmDocumentationEntry cmDocumentationName[] =
{
- {"ccmake",
- "- Curses Interface for CMake.", 0},
+ {0,
+ " ccmake - Curses Interface for CMake.", 0},
{0,0,0}
};
@@ -39,7 +39,7 @@ static const cmDocumentationEntry cmDocumentationName[] =
static const cmDocumentationEntry cmDocumentationUsage[] =
{
{0,
- "ccmake <path-to-source>", 0},
+ " ccmake <path-to-source>", 0},
{0,0,0}
};
@@ -88,10 +88,15 @@ int main(int argc, char** argv)
cmDocumentation doc;
if(cmDocumentation::Type ht = doc.CheckOptions(argc, argv))
{
- doc.SetName(cmDocumentationName);
- doc.SetUsage(cmDocumentationUsage);
- doc.SetDescription(cmDocumentationDescription);
- doc.Print(ht, std::cout);
+ cmake hcm;
+ std::vector<cmDocumentationEntry> commands;
+ hcm.GetCommandDocumentation(commands);
+ doc.SetNameSection(cmDocumentationName);
+ doc.SetUsageSection(cmDocumentationUsage);
+ doc.SetDescriptionSection(cmDocumentationDescription);
+ doc.SetOptionsSection(0);
+ doc.SetCommandsSection(&commands[0]);
+ doc.PrintDocumentation(ht, std::cout);
return 0;
}
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
index 8ea414e..1e2e695 100644
--- a/Source/cmDocumentation.cxx
+++ b/Source/cmDocumentation.cxx
@@ -49,37 +49,45 @@ const cmDocumentationEntry cmDocumentationMailingList[] =
{
{0,
"For help and discussion about using cmake, a mailing list is provided "
- "at cmake@www.cmake.org. Please first read the full documentation at "
+ "at cmake@www.cmake.org. Please first read the full documentation at "
"http://www.cmake.org before posting questions to the list.", 0},
{0,0,0}
};
//----------------------------------------------------------------------------
+const cmDocumentationEntry cmDocumentationAuthor[] =
+{
+ {0,
+ "This manual page was generated by \"cmake --help-man\".", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
const cmDocumentationEntry cmDocumentationCopyright[] =
{
{0,
- "Copyright (c) 2002 Kitware, Inc., Insight Consortium.\n"
- "All rights reserved.\n", 0},
+ "Copyright (c) 2002 Kitware, Inc., Insight Consortium. "
+ "All rights reserved.", 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},
- {" * ",
+ "met:", 0},
+ {"",
"Redistributions of source code must retain the above copyright notice, "
- "this list of conditions and the following disclaimer.\n", 0},
- {" * ",
+ "this list of conditions and the following disclaimer.", 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",
+ "documentation and/or other materials provided with the distribution.",
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},
- {" * ",
+ "specific prior written permission.", 0},
+ {"",
"Modified source versions must be plainly marked as such, and must "
- "not be misrepresented as being the original software.\n", 0},
+ "not be misrepresented as being the original software.", 0},
{0,
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "
"``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "
@@ -91,124 +99,218 @@ const cmDocumentationEntry cmDocumentationCopyright[] =
"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},
+ "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", 0},
{0, 0, 0}
};
//----------------------------------------------------------------------------
cmDocumentation::cmDocumentation()
{
- this->SetCommands(0);
- this->Description = 0;
- this->Name = 0;
- this->UsageHelp = 0;
- this->SetOptions(0);
+ this->CurrentForm = TextForm;
+ this->TextIndent = "";
+ this->TextWidth = 77;
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintManSection(std::ostream& os,
- const cmDocumentationEntry* section,
- const char* name)
+void cmDocumentation::PrintCopyright(std::ostream& os)
{
- if(!section) { return; }
- os << ".SH " << name << "\n";
- for(const cmDocumentationEntry* op = section; op->brief; ++op)
+ os << "CMake version " CMake_VERSION_STRING "\n";
+ for(const cmDocumentationEntry* op = cmDocumentationCopyright;
+ op->brief; ++op)
{
if(op->name)
{
- os << ".TP\n"
- << ".B " << op->name << "\n"
- << op->brief << "\n\n";
- if(op->full)
- {
- this->PrintFull(os, op->full, 0, 0);
- }
+ os << " * ";
+ this->TextIndent = " ";
+ this->PrintColumn(os, op->brief);
}
else
{
- os << ".PP\n"
- << op->brief << "\n";
+ this->TextIndent = "";
+ this->PrintColumn(os, op->brief);
}
- }
+ os << "\n";
+ }
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintHelpSection(std::ostream& os,
- const cmDocumentationEntry* section)
+void cmDocumentation::PrintVersion(std::ostream& os)
{
- if(!section) { return; }
- for(const cmDocumentationEntry* op = section; op->brief; ++op)
+ os << "CMake version " CMake_VERSION_STRING "\n";
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::AddSection(const char* name,
+ const cmDocumentationEntry* d)
+{
+ this->Names.push_back(name);
+ this->Sections.push_back(d);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::ClearSections()
+{
+ this->Names.erase(this->Names.begin(), this->Names.end());
+ this->Sections.erase(this->Sections.begin(), this->Sections.end());
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrintDocumentation(Type ht, std::ostream& os)
+{
+ switch (ht)
{
- if(op->name)
- {
- os << " " << op->name << "\n"
- << " ";
- this->PrintColumn(os, 70, " ", op->brief);
- if(op->full)
- {
- os << "\n"
- << "\n"
- << " ";
- this->PrintColumn(os, 70, " ", op->full);
- }
- os << "\n";
- }
- else
- {
- this->PrintColumn(os, 77, "", op->brief);
- os << "\n";
- }
- os << "\n";
- }
+ case cmDocumentation::Usage: this->PrintDocumentationUsage(os); break;
+ case cmDocumentation::Full: this->PrintDocumentationFull(os); break;
+ case cmDocumentation::HTML: this->PrintDocumentationHTML(os); break;
+ case cmDocumentation::Man: this->PrintDocumentationMan(os); break;
+ case cmDocumentation::Copyright: this->PrintCopyright(os); break;
+ case cmDocumentation::Version: this->PrintVersion(os); break;
+ default: break;
+ }
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintHTMLEscapes(std::ostream& os, const char* text)
+cmDocumentation::Type cmDocumentation::CheckOptions(int argc, char** argv)
{
- static cmDocumentationEntry escapes[] =
- {
- {"<", "&lt;", 0},
- {">", "&gt;", 0},
- {"&", "&amp;", 0},
- {"\n", "<br>", 0},
- {0,0,0}
- };
- for(const char* p = text; *p; ++p)
+ for(int i=1; i < argc; ++i)
{
- bool found = false;
- for(const cmDocumentationEntry* op = escapes; !found && op->name; ++op)
+ if((strcmp(argv[i], "-help") == 0) ||
+ (strcmp(argv[i], "--help") == 0) ||
+ (strcmp(argv[i], "/?") == 0) ||
+ (strcmp(argv[i], "-usage") == 0) ||
+ (strcmp(argv[i], "-h") == 0) ||
+ (strcmp(argv[i], "-H") == 0))
{
- if(op->name[0] == *p)
- {
- os << op->brief;
- found = true;
- }
+ return cmDocumentation::Usage;
}
- if(!found)
+ if(strcmp(argv[i], "--help-full") == 0)
{
- os << *p;
+ return cmDocumentation::Full;
+ }
+ if(strcmp(argv[i], "--help-html") == 0)
+ {
+ return cmDocumentation::HTML;
+ }
+ if(strcmp(argv[i], "--help-man") == 0)
+ {
+ return cmDocumentation::Man;
+ }
+ if(strcmp(argv[i], "--copyright") == 0)
+ {
+ return cmDocumentation::Copyright;
+ }
+ if((strcmp(argv[i], "--version") == 0) ||
+ (strcmp(argv[i], "-version") == 0) ||
+ (strcmp(argv[i], "-V") == 0) ||
+ (strcmp(argv[i], "/V") == 0))
+ {
+ return cmDocumentation::Version;
}
}
+ return cmDocumentation::None;
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintHTMLPreformatted(std::ostream& os, const char* text)
+void cmDocumentation::Print(Form f, std::ostream& os)
{
- os << "<pre>";
- cmDocumentation::PrintHTMLEscapes(os, text);
- os << "</pre>";
+ this->CurrentForm = f;
+ for(int i=0; i < this->Sections.size(); ++i)
+ {
+ this->PrintSection(os, this->Sections[i], this->Names[i]);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetNameSection(const cmDocumentationEntry* section)
+{
+ this->SetSection(0, section, 0, this->NameSection);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetUsageSection(const cmDocumentationEntry* section)
+{
+ this->SetSection(0, section, 0, this->UsageSection);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetDescriptionSection(const cmDocumentationEntry* section)
+{
+ this->SetSection(0, section, 0, this->DescriptionSection);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetOptionsSection(const cmDocumentationEntry* section)
+{
+ this->SetSection(0, section, cmDocumentationStandardOptions,
+ this->OptionsSection);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetCommandsSection(const cmDocumentationEntry* section)
+{
+ this->SetSection(cmDocumentationCommandsHeader, section, 0,
+ this->CommandsSection);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrintSection(std::ostream& os,
+ const cmDocumentationEntry* section,
+ const char* name)
+{
+ switch (this->CurrentForm)
+ {
+ case TextForm: this->PrintSectionText(os, section, name); break;
+ case HTMLForm: this->PrintSectionHTML(os, section, name); break;
+ case ManForm: this->PrintSectionMan(os, section, name); break;
+ case UsageForm: this->PrintSectionUsage(os, section, name); break;
+ }
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintHelpHTMLSection(std::ostream& os,
- const cmDocumentationEntry* section,
- const char* header)
+void cmDocumentation::PrintSectionText(std::ostream& os,
+ const cmDocumentationEntry* section,
+ const char* name)
{
+ if(name)
+ {
+ os << name << "\n\n";
+ }
if(!section) { return; }
- if(header)
+ for(const cmDocumentationEntry* op = section; op->brief; ++op)
{
- os << "<h2>" << header << "</h2>\n";
+ if(op->name)
+ {
+ if(op->name[0])
+ {
+ os << " " << op->name << "\n";
+ }
+ this->TextIndent = " ";
+ this->PrintFormatted(os, op->brief);
+ if(op->full)
+ {
+ os << "\n";
+ this->PrintFormatted(os, op->full);
+ }
+ }
+ else
+ {
+ this->TextIndent = "";
+ this->PrintFormatted(os, op->brief);
+ }
+ os << "\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrintSectionHTML(std::ostream& os,
+ const cmDocumentationEntry* section,
+ const char* name)
+{
+ if(name)
+ {
+ os << "<h2>" << name << "</h2>\n";
}
+ if(!section) { return; }
for(const cmDocumentationEntry* op = section; op->brief;)
{
if(op->name)
@@ -217,16 +319,17 @@ void cmDocumentation::PrintHelpHTMLSection(std::ostream& os,
for(;op->name;++op)
{
os << " <li>\n";
- os << " <b><code>";
- this->PrintHTMLEscapes(os, op->name);
- os << "</code></b>: ";
+ if(op->name[0])
+ {
+ os << " <b><code>";
+ this->PrintHTMLEscapes(os, op->name);
+ os << "</code></b>: ";
+ }
this->PrintHTMLEscapes(os, op->brief);
if(op->full)
{
- os << "<br>";
- this->PrintFull(os, op->full,
- &cmDocumentation::PrintHTMLPreformatted,
- &cmDocumentation::PrintHTMLEscapes);
+ os << "<br>\n ";
+ this->PrintFormatted(os, op->full);
}
os << "\n";
os << " </li>\n";
@@ -235,7 +338,7 @@ void cmDocumentation::PrintHelpHTMLSection(std::ostream& os,
}
else
{
- this->PrintHTMLEscapes(os, op->brief);
+ this->PrintFormatted(os, op->brief);
os << "\n";
++op;
}
@@ -243,136 +346,202 @@ void cmDocumentation::PrintHelpHTMLSection(std::ostream& os,
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintUsageSection(std::ostream& os,
- const cmDocumentationEntry* section)
+void cmDocumentation::PrintSectionMan(std::ostream& os,
+ const cmDocumentationEntry* section,
+ const char* name)
{
+ if(name)
+ {
+ os << ".SH " << name << "\n";
+ }
+ if(!section) { return; }
+ for(const cmDocumentationEntry* op = section; op->brief; ++op)
+ {
+ if(op->name)
+ {
+ os << ".TP\n"
+ << ".B " << (op->name[0]?op->name:"*") << "\n";
+ this->PrintFormatted(os, op->brief);
+ this->PrintFormatted(os, op->full);
+ }
+ else
+ {
+ os << ".PP\n";
+ this->PrintFormatted(os, op->brief);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrintSectionUsage(std::ostream& os,
+ const cmDocumentationEntry* section,
+ const char* name)
+{
+ if(name)
+ {
+ os << name << "\n";
+ }
if(!section) { return; }
for(const cmDocumentationEntry* op = section; op->brief; ++op)
{
if(op->name)
{
os << " " << op->name;
- for(int i = static_cast<int>(strlen(op->name)); i < 25; ++i)
+ this->TextIndent = " ";
+ int align = static_cast<int>(strlen(this->TextIndent))-4;
+ for(int i = static_cast<int>(strlen(op->name)); i < align; ++i)
{
os << " ";
}
- os << "= " << op->brief << "\n";
+ os << "= ";
+ this->PrintColumn(os, op->brief);
+ os << "\n";
}
else
{
os << "\n";
- this->PrintColumn(os, 74, "", op->brief);
+ this->TextIndent = "";
+ this->PrintFormatted(os, op->brief);
os << "\n";
}
- }
-}
-
-//----------------------------------------------------------------------------
-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)
+void cmDocumentation::PrintFormatted(std::ostream& os, const char* text)
{
- 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[0]);
+ if(!text)
+ {
+ return;
+ }
+ const char* ptr = text;
+ while(*ptr)
+ {
+ // Any ptrs starting in a space are treated as preformatted text.
+ std::string preformatted;
+ while(*ptr == ' ')
+ {
+ for(char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr)
+ {
+ preformatted.append(1, ch);
+ }
+ if(*ptr)
+ {
+ ++ptr;
+ preformatted.append(1, '\n');
+ }
+ }
+ if(preformatted.length())
+ {
+ this->PrintPreformatted(os, preformatted.c_str());
+ }
+
+ // Other ptrs are treated as paragraphs.
+ std::string paragraph;
+ for(char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr)
+ {
+ paragraph.append(1, ch);
+ }
+ if(*ptr)
+ {
+ ++ptr;
+ paragraph.append(1, '\n');
+ }
+ if(paragraph.length())
+ {
+ this->PrintParagraph(os, paragraph.c_str());
+ }
+ }
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintHelpHTML(std::ostream& os)
+void cmDocumentation::PrintPreformatted(std::ostream& os, const char* text)
{
- os << "<html>\n"
- << "<body>\n";
- os << "<h2>Using CMake</h2>\n";
- if(this->UsageHelp)
+ switch (this->CurrentForm)
{
- os << "<blockquote><code>\n";
- this->PrintHelpHTMLSection(os, this->UsageHelp, 0);
- os << "</code></blockquote>\n";
+ case TextForm: this->PrintPreformattedText(os, text); break;
+ case HTMLForm: this->PrintPreformattedHTML(os, text); break;
+ case ManForm: this->PrintPreformattedMan(os, text); break;
+ case UsageForm: this->PrintPreformattedText(os, text); break;
}
- this->PrintHelpHTMLSection(os, this->Description, 0);
- this->PrintHelpHTMLSection(os, &this->Options[0], "Command-line Options");
- this->PrintHelpHTMLSection(os, &this->Commands[0], "Listfile Commands");
- //this->PrintHelpHTMLSection(os, cmDocumentationCopyright, "Copyright");
- //this->PrintHelpHTMLSection(os, cmDocumentationMailingList, "Mailing List");
- os << "</body>\n"
- << "</html>\n";
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintManPage(std::ostream& os)
+void cmDocumentation::PrintParagraph(std::ostream& os, const char* text)
{
- 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[0], "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 --help-man\".\n";
+ switch (this->CurrentForm)
+ {
+ case TextForm: this->PrintParagraphText(os, text); break;
+ case HTMLForm: this->PrintParagraphHTML(os, text); break;
+ case ManForm: this->PrintParagraphMan(os, text); break;
+ case UsageForm: this->PrintParagraphText(os, text); break;
+ }
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintCopyright(std::ostream& os)
+void cmDocumentation::PrintPreformattedText(std::ostream& os, const char* text)
{
- os << "CMake version " CMake_VERSION_STRING "\n";
- for(const cmDocumentationEntry* op = cmDocumentationCopyright;
- op->brief; ++op)
+ bool newline = true;
+ for(const char* ptr = text; *ptr; ++ptr)
{
- if(op->name)
+ if(newline)
{
- os << " * ";
- this->PrintColumn(os, 74, " ", op->brief);
+ os << this->TextIndent;
+ newline = false;
}
- else
+ os << *ptr;
+ if(*ptr == '\n')
{
- this->PrintColumn(os, 77, "", op->brief);
+ newline = true;
}
- os << "\n";
}
+ os << "\n";
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintVersion(std::ostream& os)
+void cmDocumentation::PrintParagraphText(std::ostream& os, const char* text)
{
- os << "CMake version " CMake_VERSION_STRING "\n";
+ os << this->TextIndent;
+ this->PrintColumn(os, text);
+ os << "\n";
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrintPreformattedHTML(std::ostream& os, const char* text)
+{
+ os << "<pre>";
+ this->PrintHTMLEscapes(os, text);
+ os << "</pre>\n ";
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintColumn(std::ostream& os, int width,
- const char* indent, const char* text)
+void cmDocumentation::PrintParagraphHTML(std::ostream& os, const char* text)
{
- // Print text arranged in a column of fixed witdh indented by the
- // "indent" text.
+ os << "<p>";
+ this->PrintHTMLEscapes(os, text);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrintPreformattedMan(std::ostream& os, const char* text)
+{
+ os << text << "\n";
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrintParagraphMan(std::ostream& os, const char* text)
+{
+ os << text << "\n\n";
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrintColumn(std::ostream& os, const char* text)
+{
+ // Print text arranged in an indented column of fixed witdh.
const char* l = text;
int column = 0;
bool newSentence = false;
bool firstLine = true;
- bool lastHadBlanks = false;
-
- // Count leading blanks in the text.
- int blanks = 0;
- for(const char* b = l; *b == ' '; ++b) { ++blanks; }
+ int width = this->TextWidth - strlen(this->TextIndent);
// Loop until the end of the text.
while(*l)
@@ -404,38 +573,9 @@ void cmDocumentation::PrintColumn(std::ostream& os, int width,
}
else
{
- // If we are switching from a line that has leading blanks
- // to a line that does not, or vice versa, add an extra
- // newline.
- if(blanks)
- {
- if(!lastHadBlanks && !firstLine)
- {
- os << "\n";
- }
- lastHadBlanks = true;
- }
- else
- {
- if(lastHadBlanks && !firstLine)
- {
- os << "\n";
- }
- lastHadBlanks = false;
- }
-
// First word on line. Print indentation unless this is the
// first line.
- os << (firstLine?"":indent);
-
- // Further indent by leading blanks from the text on this
- // line.
- for(int i = 0; i < blanks; ++i)
- {
- os << " ";
- ++column;
- }
- blanks = 0;
+ os << (firstLine?"":this->TextIndent);
}
// Print the word.
@@ -450,9 +590,6 @@ void cmDocumentation::PrintColumn(std::ostream& os, int width,
++r;
column = 0;
firstLine = false;
-
- // Count leading blanks in the text.
- for(const char* b = r; *b == ' '; ++b) { ++blanks; }
}
else
{
@@ -467,7 +604,7 @@ void cmDocumentation::PrintColumn(std::ostream& os, int width,
firstLine = false;
if(r > l)
{
- os << indent;
+ os << this->TextIndent;
os.write(l, static_cast<long>(r-l));
column = static_cast<long>(r-l);
newSentence = (*(r-1) == '.');
@@ -481,156 +618,170 @@ void cmDocumentation::PrintColumn(std::ostream& os, int width,
}
//----------------------------------------------------------------------------
-void cmDocumentation::PrintFull(std::ostream& os, const char* text,
- void (*pPreform)(std::ostream&, const char*),
- void (*pNormal)(std::ostream&, const char*))
+void cmDocumentation::PrintHTMLEscapes(std::ostream& os, const char* text)
{
- const char* line = text;
- while(*line)
+ static cmDocumentationEntry escapes[] =
+ {
+ {"<", "&lt;", 0},
+ {">", "&gt;", 0},
+ {"&", "&amp;", 0},
+ {"\n", "<br>", 0},
+ {0,0,0}
+ };
+ for(const char* p = text; *p; ++p)
{
- // Any lines starting in a space are treated as preformatted text.
- std::string preformatted;
- while(*line == ' ')
- {
- for(char ch = *line; ch && ch != '\n'; ++line, ch = *line)
- {
- preformatted.append(1, ch);
- }
- if(*line)
- {
- ++line;
- preformatted.append(1, '\n');
- }
- }
- if(preformatted.length())
+ bool found = false;
+ for(const cmDocumentationEntry* op = escapes; !found && op->name; ++op)
{
- if(pPreform)
- {
- pPreform(os, preformatted.c_str());
- }
- else
+ if(op->name[0] == *p)
{
- os << preformatted << "\n";
+ os << op->brief;
+ found = true;
}
}
-
- // Other lines are treated as normal text.
- std::string normal;
- for(char ch = *line; ch && ch != '\n'; ++line, ch = *line)
- {
- normal.append(1, ch);
- }
- if(*line)
- {
- ++line;
- normal.append(1, '\n');
- }
- if(normal.length())
+ if(!found)
{
- if(pNormal)
- {
- pNormal(os, normal.c_str());
- }
- else
- {
- os << normal << "\n";
- }
+ os << *p;
}
}
}
//----------------------------------------------------------------------------
-void cmDocumentation::Print(Type ht, std::ostream& os)
+void cmDocumentation::PrintDocumentationUsage(std::ostream& os)
{
- switch (ht)
+ this->CreateUsageDocumentation();
+ this->Print(UsageForm, os);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrintDocumentationFull(std::ostream& os)
+{
+ this->CreateFullDocumentation();
+ this->Print(TextForm, os);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrintDocumentationHTML(std::ostream& os)
+{
+ this->CreateFullDocumentation();
+ os << "<html><body>\n";
+ this->Print(HTMLForm, os);
+ os << "</body></html>\n";
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrintDocumentationMan(std::ostream& os)
+{
+ this->CreateManDocumentation();
+ os << ".TH CMake 1 \""
+ << cmSystemTools::GetCurrentDateTime("%B %d, %Y").c_str()
+ << "\" \"CMake " CMake_VERSION_STRING "\"\n";
+ this->Print(ManForm, os);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::CreateUsageDocumentation()
+{
+ this->ClearSections();
+ if(!this->NameSection.empty())
{
- 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;
+ this->AddSection("Name", &this->NameSection[0]);
+ }
+ if(!this->UsageSection.empty())
+ {
+ this->AddSection("Usage", &this->UsageSection[0]);
+ }
+ if(!this->OptionsSection.empty())
+ {
+ this->AddSection("Command-Line Options", &this->OptionsSection[0]);
}
}
//----------------------------------------------------------------------------
-cmDocumentation::Type cmDocumentation::CheckOptions(int argc, char** argv)
+void cmDocumentation::CreateFullDocumentation()
{
- for(int i=1; i < argc; ++i)
+ this->ClearSections();
+ if(!this->NameSection.empty())
{
- if((strcmp(argv[i], "-help") == 0) ||
- (strcmp(argv[i], "--help") == 0) ||
- (strcmp(argv[i], "/?") == 0) ||
- (strcmp(argv[i], "-usage") == 0) ||
- (strcmp(argv[i], "-h") == 0) ||
- (strcmp(argv[i], "-H") == 0))
- {
- return cmDocumentation::Usage;
- }
- if(strcmp(argv[i], "--help-full") == 0)
- {
- return cmDocumentation::Help;
- }
- if(strcmp(argv[i], "--help-html") == 0)
- {
- return cmDocumentation::HelpHTML;
- }
- if(strcmp(argv[i], "--help-man") == 0)
- {
- return cmDocumentation::Man;
- }
- if(strcmp(argv[i], "--copyright") == 0)
- {
- return cmDocumentation::Copyright;
- }
- if((strcmp(argv[i], "--version") == 0) ||
- (strcmp(argv[i], "-version") == 0) ||
- (strcmp(argv[i], "-V") == 0) ||
- (strcmp(argv[i], "/V") == 0))
- {
- return cmDocumentation::Version;
- }
+ this->AddSection("Name", &this->NameSection[0]);
}
- return cmDocumentation::None;
+ if(!this->UsageSection.empty())
+ {
+ this->AddSection("Usage", &this->UsageSection[0]);
+ }
+ if(!this->DescriptionSection.empty())
+ {
+ this->AddSection(0, &this->DescriptionSection[0]);
+ }
+ if(!this->OptionsSection.empty())
+ {
+ this->AddSection("Command-Line Options", &this->OptionsSection[0]);
+ }
+ if(!this->CommandsSection.empty())
+ {
+ this->AddSection("Listfile Commands", &this->CommandsSection[0]);
+ }
+ this->AddSection("Copyright", cmDocumentationCopyright);
+ this->AddSection("Mailing List", cmDocumentationMailingList);
}
//----------------------------------------------------------------------------
-void cmDocumentation::SetOptions(const cmDocumentationEntry* d)
+void cmDocumentation::CreateManDocumentation()
{
- this->Options.erase(this->Options.begin(), this->Options.end());
- if(d)
+ this->ClearSections();
+ if(!this->NameSection.empty())
{
- for(const cmDocumentationEntry* op = d; op->brief; ++op)
- {
- this->Options.push_back(*op);
- }
+ this->AddSection("NAME", &this->NameSection[0]);
}
- for(const cmDocumentationEntry* op = cmDocumentationStandardOptions;
- op->brief; ++op)
+ if(!this->UsageSection.empty())
{
- this->Options.push_back(*op);
+ this->AddSection("SYNOPSIS", &this->UsageSection[0]);
}
- cmDocumentationEntry empty = {0,0,0};
- this->Options.push_back(empty);
+ if(!this->DescriptionSection.empty())
+ {
+ this->AddSection("DESCRIPTION", &this->DescriptionSection[0]);
+ }
+ if(!this->OptionsSection.empty())
+ {
+ this->AddSection("OPTIONS", &this->OptionsSection[0]);
+ }
+ if(!this->CommandsSection.empty())
+ {
+ this->AddSection("COMMANDS", &this->CommandsSection[0]);
+ }
+ this->AddSection("COPYRIGHT", cmDocumentationCopyright);
+ this->AddSection("MAILING LIST", cmDocumentationMailingList);
+ this->AddSection("AUTHOR", cmDocumentationAuthor);
}
//----------------------------------------------------------------------------
-void cmDocumentation::SetCommands(const cmDocumentationEntry* d)
+void cmDocumentation::SetSection(const cmDocumentationEntry* header,
+ const cmDocumentationEntry* section,
+ const cmDocumentationEntry* footer,
+ std::vector<cmDocumentationEntry>& vec)
{
- this->Commands.erase(this->Commands.begin(), this->Commands.end());
- for(const cmDocumentationEntry* op = cmDocumentationCommandsHeader;
- op->brief; ++op)
+ vec.erase(vec.begin(), vec.end());
+ if(header)
{
- this->Commands.push_back(*op);
+ for(const cmDocumentationEntry* op = header; op->brief; ++op)
+ {
+ vec.push_back(*op);
+ }
+ }
+ if(section)
+ {
+ for(const cmDocumentationEntry* op = section; op->brief; ++op)
+ {
+ vec.push_back(*op);
+ }
}
- if(d)
+ if(footer)
{
- for(const cmDocumentationEntry* op = d; op->brief; ++op)
+ for(const cmDocumentationEntry* op = footer; op->brief; ++op)
{
- this->Commands.push_back(*op);
+ vec.push_back(*op);
}
}
cmDocumentationEntry empty = {0,0,0};
- this->Commands.push_back(empty);
+ vec.push_back(empty);
}
diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h
index fc87ce0..5e507a0 100644
--- a/Source/cmDocumentation.h
+++ b/Source/cmDocumentation.h
@@ -25,45 +25,111 @@ class cmDocumentation
public:
cmDocumentation();
- enum Type { None, Usage, Help, HelpHTML, Man, Copyright, Version };
+ // High-level interface for standard documents:
- void Print(Type ht, std::ostream& os);
- void PrintUsage(std::ostream& os);
- void PrintHelp(std::ostream& os);
- void PrintHelpHTML(std::ostream& os);
- void PrintManPage(std::ostream& os);
- void PrintCopyright(std::ostream& os);
- void PrintVersion(std::ostream& os);
-
- void SetCommands(const cmDocumentationEntry* d);
- void SetDescription(const cmDocumentationEntry* d) {this->Description = d;}
- void SetName(const cmDocumentationEntry* d) {this->Name = d;}
- void SetOptions(const cmDocumentationEntry* d);
- void SetUsage(const cmDocumentationEntry* d) {this->UsageHelp = d;}
+ /** Types of help provided. */
+ enum Type { None, Usage, Full, HTML, Man, Copyright, Version };
+ /**
+ * 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.
+ */
Type CheckOptions(int argc, char** argv);
+
+ /** Print help of the given type. */
+ void PrintDocumentation(Type ht, std::ostream& os);
+
+ /** Set the program name for standard document generation. */
+ void SetNameSection(const cmDocumentationEntry*);
+
+ /** Set the program usage for standard document generation. */
+ void SetUsageSection(const cmDocumentationEntry*);
+
+ /** Set the program description for standard document generation. */
+ void SetDescriptionSection(const cmDocumentationEntry*);
+
+ /** Set the program options for standard document generation. */
+ void SetOptionsSection(const cmDocumentationEntry*);
+
+ /** Set the listfile commands for standard document generation. */
+ void SetCommandsSection(const cmDocumentationEntry*);
+
+ // Low-level interface for custom documents:
+
+ /** Forms of documentation output. */
+ enum Form { TextForm, HTMLForm, ManForm, UsageForm };
+
+ /**
+ * Print documentation in the given form. All previously added
+ * sections will be generated.
+ */
+ void Print(Form f, std::ostream& os);
+
+ /**
+ * Add a section of documentation. The cmDocumentationEntry pointer
+ * should point at an array terminated by an all zero ({0,0,0})
+ * entry. This can be used to generate custom help documents.
+ */
+ void AddSection(const char* name, const cmDocumentationEntry* d);
+
+ /** Clear all previously added sections of help. */
+ void ClearSections();
private:
- void PrintColumn(std::ostream& os, int width,
- const char* indent, const char* text);
- void PrintManSection(std::ostream& os, const cmDocumentationEntry* section,
+ void PrintSection(std::ostream& os,
+ const cmDocumentationEntry* section,
+ const char* name);
+ void PrintSectionText(std::ostream& os,
+ const cmDocumentationEntry* section,
+ const char* name);
+ void PrintSectionHTML(std::ostream& os,
+ const cmDocumentationEntry* section,
+ const char* name);
+ void PrintSectionMan(std::ostream& os, const cmDocumentationEntry* section,
const char* name);
- void PrintHelpSection(std::ostream& os, const cmDocumentationEntry* section);
- static void PrintHTMLEscapes(std::ostream& os, const char* text);
- static void PrintHTMLPreformatted(std::ostream& os, const char* text);
- void PrintFull(std::ostream& os, const char* text,
- void (*pPreform)(std::ostream&, const char*),
- void (*pNormal)(std::ostream&, const char*));
- void PrintHelpHTMLSection(std::ostream& os,
- const cmDocumentationEntry* section,
- const char* header);
- void PrintUsageSection(std::ostream& os,
- const cmDocumentationEntry* section);
+ void PrintSectionUsage(std::ostream& os,
+ const cmDocumentationEntry* section,
+ const char* name);
+ void PrintFormatted(std::ostream& os, const char* text);
+ void PrintPreformatted(std::ostream& os, const char* text);
+ void PrintPreformattedText(std::ostream& os, const char* text);
+ void PrintPreformattedHTML(std::ostream& os, const char* text);
+ void PrintPreformattedMan(std::ostream& os, const char* text);
+ void PrintParagraph(std::ostream& os, const char* text);
+ void PrintParagraphText(std::ostream& os, const char* text);
+ void PrintParagraphHTML(std::ostream& os, const char* text);
+ void PrintParagraphMan(std::ostream& os, const char* text);
+ void PrintColumn(std::ostream& os, const char* text);
+ void PrintHTMLEscapes(std::ostream& os, const char* text);
+
+ void PrintCopyright(std::ostream& os);
+ void PrintVersion(std::ostream& os);
+ void PrintDocumentationUsage(std::ostream& os);
+ void PrintDocumentationFull(std::ostream& os);
+ void PrintDocumentationHTML(std::ostream& os);
+ void PrintDocumentationMan(std::ostream& os);
+
+ void CreateUsageDocumentation();
+ void CreateFullDocumentation();
+ void CreateManDocumentation();
+
+ void SetSection(const cmDocumentationEntry* header,
+ const cmDocumentationEntry* section,
+ const cmDocumentationEntry* footer,
+ std::vector<cmDocumentationEntry>&);
+
+ std::vector<cmDocumentationEntry> NameSection;
+ std::vector<cmDocumentationEntry> UsageSection;
+ std::vector<cmDocumentationEntry> DescriptionSection;
+ std::vector<cmDocumentationEntry> OptionsSection;
+ std::vector<cmDocumentationEntry> CommandsSection;
- std::vector<cmDocumentationEntry> Commands;
- const cmDocumentationEntry* Description;
- const cmDocumentationEntry* Name;
- std::vector<cmDocumentationEntry> Options;
- const cmDocumentationEntry* UsageHelp;
+ std::vector< const char* > Names;
+ std::vector< const cmDocumentationEntry* > Sections;
+ Form CurrentForm;
+ const char* TextIndent;
+ int TextWidth;
};
#endif
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index b86dc07..6a0dc1f 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -24,8 +24,8 @@
//----------------------------------------------------------------------------
static const cmDocumentationEntry cmDocumentationName[] =
{
- {"cmake",
- "- Cross-Platform Makefile Generator.", 0},
+ {0,
+ " cmake - Cross-Platform Makefile Generator.", 0},
{0,0,0}
};
@@ -33,7 +33,7 @@ static const cmDocumentationEntry cmDocumentationName[] =
static const cmDocumentationEntry cmDocumentationUsage[] =
{
{0,
- "cmake [options] <path-to-source>", 0},
+ " cmake [options] <path-to-source>", 0},
{0,0,0}
};
@@ -74,12 +74,12 @@ int do_cmake(int ac, char** av)
cmake hcm;
std::vector<cmDocumentationEntry> commands;
hcm.GetCommandDocumentation(commands);
- doc.SetName(cmDocumentationName);
- doc.SetUsage(cmDocumentationUsage);
- doc.SetDescription(cmDocumentationDescription);
- doc.SetOptions(cmDocumentationOptions);
- doc.SetCommands(&commands[0]);
- doc.Print(ht, std::cout);
+ doc.SetNameSection(cmDocumentationName);
+ doc.SetUsageSection(cmDocumentationUsage);
+ doc.SetDescriptionSection(cmDocumentationDescription);
+ doc.SetOptionsSection(cmDocumentationOptions);
+ doc.SetCommandsSection(&commands[0]);
+ doc.PrintDocumentation(ht, std::cout);
return 0;
}