| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450 |
- /*=========================================================================
- 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"
- #include "cmVersion.h"
- #include <cmsys/Directory.hxx>
- //----------------------------------------------------------------------------
- static const cmDocumentationEntry cmDocumentationStandardOptions[] =
- {
- {"--copyright [file]", "Print the CMake copyright and exit.",
- "If a file is specified, the copyright is written into it."},
- {"--help", "Print usage information and exit.",
- "Usage describes the basic command line interface and its options."},
- {"--help-full [file]", "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. If a file is "
- "specified, the help is written into it."},
- {"--help-html [file]", "Print full help in HTML format.",
- "This option is used by CMake authors to help produce web pages. "
- "If a file is specified, the help is written into it."},
- {"--help-man [file]", "Print a UNIX man page and exit.",
- "This option is used by the cmake build to generate the UNIX man page. "
- "If a file is specified, the help is written into it."},
- {"--version [file]", "Show program name/version banner and exit.",
- "If a file is specified, the version is written into it."},
- {0,0,0}
- };
- //----------------------------------------------------------------------------
- static const cmDocumentationEntry cmDocumentationCommandsHeader[] =
- {
- {0,
- "The following commands are available in CMakeLists.txt code:", 0},
- {0,0,0}
- };
- //----------------------------------------------------------------------------
- static const cmDocumentationEntry cmDocumentationPropertiesHeader[] =
- {
- {0,
- "The following properties are available in CMakeLists.txt code:", 0},
- {0,0,0}
- };
- //----------------------------------------------------------------------------
- static const cmDocumentationEntry cmDocumentationModulesHeader[] =
- {
- {0,
- "The following modules are provided with CMake. "
- "They can be used with INCLUDE(ModuleName).", 0},
- {0,0,0}
- };
- //----------------------------------------------------------------------------
- static const cmDocumentationEntry cmDocumentationGeneratorsHeader[] =
- {
- {0,
- "The following generators are available on this platform:", 0},
- {0,0,0}
- };
- //----------------------------------------------------------------------------
- static const cmDocumentationEntry cmDocumentationStandardSeeAlso[] =
- {
- {0,
- "The following resources are available to get help using CMake:", 0},
- {"Home Page",
- "http://www.cmake.org",
- "The primary starting point for learning about CMake."},
- {"Frequently Asked Questions",
- "http://www.cmake.org/Wiki/CMake_FAQ",
- "A Wiki is provided containing answers to frequently asked questions. "},
- {"Online Documentation",
- "http://www.cmake.org/HTML/Documentation.html",
- "Links to available documentation may be found on this web page."},
- {"Mailing List",
- "http://www.cmake.org/HTML/MailingLists.html",
- "For help and discussion about using cmake, a mailing list is provided at "
- "[email protected]. "
- "The list is member-post-only but one may sign up on the CMake web page. "
- "Please first read the full documentation at "
- "http://www.cmake.org before posting questions to the list."},
- {0,
- "Summary of helpful links:\n"
- " Home: http://www.cmake.org\n"
- " Docs: http://www.cmake.org/HTML/Documentation.html\n"
- " Mail: http://www.cmake.org/HTML/MailingLists.html\n"
- " FAQ: http://www.cmake.org/Wiki/CMake_FAQ\n"
- , 0},
- {0,0,0}
- };
- //----------------------------------------------------------------------------
- const cmDocumentationEntry cmDocumentationAuthor[] =
- {
- {0,
- "This manual page was generated by the \"--help-man\" option.", 0},
- {0,0,0}
- };
- //----------------------------------------------------------------------------
- const cmDocumentationEntry cmDocumentationCopyright[] =
- {
- {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:", 0},
- {"",
- "Redistributions of source code must retain the above copyright notice, "
- "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.",
- 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.", 0},
- {"",
- "Modified source versions must be plainly marked as such, and must "
- "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 "
- "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.", 0},
- {0, 0, 0}
- };
- //----------------------------------------------------------------------------
- cmDocumentation::cmDocumentation()
- :NameSection ("Name", "NAME")
- ,UsageSection ("Usage", "SYNOPSIS")
- ,DescriptionSection ("", "DESCRIPTION")
- ,OptionsSection ("Command-Line Options", "OPTIONS")
- ,CommandsSection ("Listfile Commands", "COMMANDS")
- ,CompatCommandsSection("Compatibility Listfile Commands",
- "COMPATIBILITY COMMANDS")
- ,ModulesSection ("Standard CMake Modules", "MODULES")
- ,PropertiesSection ("Standard Properties", "PROPERTIES")
- ,GeneratorsSection ("Generators", "GENERATORS")
- ,SeeAlsoSection ("See Also", "SEE ALSO")
- ,CopyrightSection ("Copyright", "COPYRIGHT")
- ,AuthorSection ("Author", "AUTHOR")
- {
- this->CurrentForm = TextForm;
- this->TextIndent = "";
- this->TextWidth = 77;
- }
- //----------------------------------------------------------------------------
- cmDocumentation::~cmDocumentation()
- {
- for(std::vector< char* >::iterator i = this->ModuleStrings.begin();
- i != this->ModuleStrings.end(); ++i)
- {
- delete [] *i;
- }
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::PrintCopyright(std::ostream& os)
- {
- for(const cmDocumentationEntry* op = cmDocumentationCopyright;
- op->brief; ++op)
- {
- if(op->name)
- {
- os << " * ";
- this->TextIndent = " ";
- this->PrintColumn(os, op->brief);
- }
- else
- {
- this->TextIndent = "";
- this->PrintColumn(os, op->brief);
- }
- os << "\n";
- }
- return true;
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::PrintVersion(std::ostream& os)
- {
- os << this->GetNameString() << " version "
- << cmVersion::GetCMakeVersion() << "\n";
- return true;
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::AddSection(const char* name,
- const cmDocumentationEntry* d)
- {
- this->Names.push_back(name);
- this->Sections.push_back(d);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::AddSection(const cmSection& section)
- {
- if (!section.IsEmpty())
- {
- this->Names.push_back(section.GetName(this->CurrentForm));
- this->Sections.push_back(section.GetEntries());
- }
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::ClearSections()
- {
- this->Names.erase(this->Names.begin(), this->Names.end());
- this->Sections.erase(this->Sections.begin(), this->Sections.end());
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os)
- {
- if(ht != cmDocumentation::HTML && ht != cmDocumentation::Man)
- {
- this->PrintVersion(os);
- }
- switch (ht)
- {
- case cmDocumentation::Full:
- case cmDocumentation::Single:
- case cmDocumentation::SingleModule:
- case cmDocumentation::SingleProperty:
- case cmDocumentation::List:
- case cmDocumentation::ModuleList:
- case cmDocumentation::PropertyList:
- this->CurrentForm = TextForm;
- break;
- case cmDocumentation::HTML: this->CurrentForm = HTMLForm; break;
- case cmDocumentation::Man: this->CurrentForm = ManForm; break;
- case cmDocumentation::Usage:
- case cmDocumentation::Copyright:
- case cmDocumentation::Version:
- this->CurrentForm = UsageForm;
- break;
- case cmDocumentation::None:
- break;
- }
- switch (ht)
- {
- case cmDocumentation::Usage:
- return this->PrintDocumentationUsage(os);
- case cmDocumentation::Single:
- return this->PrintDocumentationSingle(os);
- case cmDocumentation::SingleModule:
- return this->PrintDocumentationSingleModule(os);
- case cmDocumentation::SingleProperty:
- return this->PrintDocumentationSingleProperty(os);
- case cmDocumentation::List: return this->PrintDocumentationList(os);
- case cmDocumentation::ModuleList: return this->PrintModuleList(os);
- case cmDocumentation::PropertyList: return this->PrintPropertyList(os);
- case cmDocumentation::Full:
- case cmDocumentation::HTML:
- case cmDocumentation::Man: return this->PrintDocumentationFull(os);
- case cmDocumentation::Copyright: return this->PrintCopyright(os);
- case cmDocumentation::Version: return true;
- default: return false;
- }
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::CreateModulesSection()
- {
- std::string cmakeModules = this->CMakeRoot;
- cmakeModules += "/Modules";
- cmsys::Directory dir;
- dir.Load(cmakeModules.c_str());
- if (dir.GetNumberOfFiles() > 0)
- {
- this->ModulesSection.Append(cmDocumentationModulesHeader[0]);
- for(unsigned int i = 0; i < dir.GetNumberOfFiles(); ++i)
- {
- std::string fname = dir.GetFile(i);
- if(fname.length() > 6)
- {
- if(fname.substr(fname.length()-6, 6) == ".cmake")
- {
- std::string moduleName = fname.substr(0, fname.length()-6);
- std::string path = cmakeModules;
- path += "/";
- path += fname;
- this->CreateSingleModule(path.c_str(), moduleName.c_str());
- }
- }
- }
- cmDocumentationEntry e = { 0, 0, 0 };
- this->ModulesSection.Append(e);
- }
- return true;
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::CreateSingleModule(const char* fname,
- const char* moduleName)
- {
- std::ifstream fin(fname);
- if(!fin)
- {
- std::cerr << "Internal error: can not open module." << fname << std::endl;
- return false;
- }
- std::string line;
- std::string text;
- std::string brief;
- brief = " ";
- bool newParagraph = true;
- while ( fin && cmSystemTools::GetLineFromStream(fin, line) )
- {
- if(line.size() && line[0] == '#')
- {
- // blank line
- if(line.size() <= 2)
- {
- text += "\n";
- newParagraph = true;
- }
- else if(line[2] == '-')
- {
- brief = line.c_str()+4;
- }
- else
- {
- // two spaces
- if(line[1] == ' ' && line[2] == ' ')
- {
- if(!newParagraph)
- {
- text += "\n";
- newParagraph = true;
- }
- // Skip #, and leave space for preformatted
- text += line.c_str()+1;
- text += "\n";
- }
- else if(line[1] == ' ')
- {
- if(!newParagraph)
- {
- text += " ";
- }
- newParagraph = false;
- // skip # and space
- text += line.c_str()+2;
- }
- else
- {
- if(!newParagraph)
- {
- text += " ";
- }
- newParagraph = false;
- // skip #
- text += line.c_str()+1;
- }
- }
- }
- else
- {
- if(text.length() < 2 && brief.length() == 1)
- {
- return false;
- }
- char* pname = strcpy(new char[strlen(moduleName)+1], moduleName);
- char* ptext = strcpy(new char[text.length()+1], text.c_str());
- this->ModuleStrings.push_back(pname);
- this->ModuleStrings.push_back(ptext);
- char* pbrief = strcpy(new char[brief.length()+1], brief.c_str());
- this->ModuleStrings.push_back(pbrief);
- cmDocumentationEntry e = { pname, pbrief, ptext };
- this->ModulesSection.Append(e);
- return true;
- }
- }
- return true;
- }
- //----------------------------------------------------------------------------
- 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)
- {
- // Special case for printing help for a single command.
- if(i->first == cmDocumentation::Usage && i->second.length() > 0 &&
- !this->CommandsSection.IsEmpty())
- {
- // Check if the argument to the usage request was a command.
- for(cmDocumentationEntry* entry = this->CommandsSection.GetEntries();
- entry->brief; ++entry)
- {
- if(entry->name && (strcmp(entry->name, i->second.c_str()) == 0))
- {
- this->PrintDocumentationCommand(os, entry);
- return true;
- }
- }
-
- // Argument was not a command. Complain.
- os << "Help argument \"" << i->second.c_str()
- << "\" is not a CMake command. "
- << "Use --help-command-list to see all commands.\n";
- return false;
- }
-
- // 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)
- {
- fout = new std::ofstream(i->second.c_str(), std::ios::out);
- if(fout)
- {
- s = fout;
- }
- else
- {
- result = false;
- }
- }
-
- // Print this documentation type to the stream.
- if(!this->PrintDocumentation(i->first, *s) || !*s)
- {
- result = false;
- }
-
- // Close the file if we wrote one.
- if(fout)
- {
- delete fout;
- }
- }
- return result;
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::CheckOptions(int argc, const char* const* argv)
- {
- // Providing zero arguments gives usage information.
- if(argc == 1)
- {
- 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) ||
- (strcmp(argv[i], "-usage") == 0) ||
- (strcmp(argv[i], "-h") == 0) ||
- (strcmp(argv[i], "-H") == 0))
- {
- type = cmDocumentation::Usage;
- }
- else if(strcmp(argv[i], "--help-full") == 0)
- {
- type = cmDocumentation::Full;
- }
- else if(strcmp(argv[i], "--help-html") == 0)
- {
- type = cmDocumentation::HTML;
- }
- else if(strcmp(argv[i], "--help-man") == 0)
- {
- type = cmDocumentation::Man;
- }
- else if(strcmp(argv[i], "--help-command") == 0)
- {
- type = cmDocumentation::Single;
- if((i+1 < argc) && !this->IsOption(argv[i+1]))
- {
- this->SingleCommand = argv[i+1];
- this->SingleCommand = cmSystemTools::UpperCase(this->SingleCommand);
- i = i+1;
- }
- }
- else if(strcmp(argv[i], "--help-module") == 0)
- {
- type = cmDocumentation::SingleModule;
- if((i+1 < argc) && !this->IsOption(argv[i+1]))
- {
- this->SingleModuleName = argv[i+1];
- i = i+1;
- }
- }
- else if(strcmp(argv[i], "--help-property") == 0)
- {
- type = cmDocumentation::SingleProperty;
- if((i+1 < argc) && !this->IsOption(argv[i+1]))
- {
- this->SinglePropertyName = argv[i+1];
- i = i+1;
- }
- }
- else if(strcmp(argv[i], "--help-command-list") == 0)
- {
- type = cmDocumentation::List;
- }
- else if(strcmp(argv[i], "--help-module-list") == 0)
- {
- type = cmDocumentation::ModuleList;
- }
- else if(strcmp(argv[i], "--help-property-list") == 0)
- {
- type = cmDocumentation::PropertyList;
- }
- else if(strcmp(argv[i], "--copyright") == 0)
- {
- type = cmDocumentation::Copyright;
- }
- else if((strcmp(argv[i], "--version") == 0) ||
- (strcmp(argv[i], "-version") == 0) ||
- (strcmp(argv[i], "/V") == 0))
- {
- type = cmDocumentation::Version;
- }
- if(type)
- {
- // This is a help option. See if there is a file name given.
- result = true;
- if((i+1 < argc) && !this->IsOption(argv[i+1]))
- {
- this->RequestedMap[type] = argv[i+1];
- i = i+1;
- }
- else
- {
- this->RequestedMap[type] = "";
- }
- }
- }
- return result;
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::Print(Form f, std::ostream& os)
- {
- this->CurrentForm = f;
- Print(os);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::Print(std::ostream& os)
- {
- for(unsigned int i=0; i < this->Sections.size(); ++i)
- {
- this->PrintSection(os, this->Sections[i], this->Names[i]);
- }
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::SetName(const char* name)
- {
- this->NameString = name?name:"";
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::SetNameSection(const cmDocumentationEntry* section)
- {
- this->NameSection.Set(0, section, 0);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::SetUsageSection(const cmDocumentationEntry* section)
- {
- this->UsageSection.Set(0, section, 0);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation
- ::SetDescriptionSection(const cmDocumentationEntry* section)
- {
- this->DescriptionSection.Set(0, section, 0);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::SetOptionsSection(const cmDocumentationEntry* section)
- {
- this->OptionsSection.Set(0, section, cmDocumentationStandardOptions);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::SetCommandsSection(const cmDocumentationEntry* section)
- {
- this->CommandsSection.Set(cmDocumentationCommandsHeader, section, 0);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation
- ::SetPropertiesSection(const cmDocumentationEntry* section)
- {
- this->PropertiesSection.Set(cmDocumentationPropertiesHeader, section, 0);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation
- ::SetGeneratorsSection(const cmDocumentationEntry* section)
- {
- this->GeneratorsSection.Set(cmDocumentationGeneratorsHeader, section, 0);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::SetSeeAlsoList(const cmDocumentationEntry* also)
- {
- this->SeeAlsoSection.Clear();
- this->SeeAlsoString = ".B ";
- for(const cmDocumentationEntry* i = also; i->brief; ++i)
- {
- this->SeeAlsoString += i->brief;
- this->SeeAlsoString += (i+1)->brief? "(1), ":"(1)";
- }
- cmDocumentationEntry e = {0, 0, 0};
- e.brief = this->SeeAlsoString.c_str();
- this->SeeAlsoSection.Append(e);
- for(const cmDocumentationEntry* i = cmDocumentationStandardSeeAlso;
- i->brief; ++i)
- {
- this->SeeAlsoSection.Append(*i);
- }
- e.brief = 0;
- this->SeeAlsoSection.Append(e);
- }
- //----------------------------------------------------------------------------
- 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::PrintSectionText(std::ostream& os,
- const cmDocumentationEntry* section,
- const char* name)
- {
- if(name)
- {
- os <<
- "---------------------------------------"
- "---------------------------------------\n";
- os << name << "\n\n";
- }
- if(!section) { return; }
- for(const cmDocumentationEntry* op = section; op->brief; ++op)
- {
- 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)
- {
- os << "<ul>\n";
- for(;op->name;++op)
- {
- os << " <li>\n";
- 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>\n ";
- this->PrintFormatted(os, op->full);
- }
- os << "\n";
- os << " </li>\n";
- }
- os << "</ul>\n";
- }
- else
- {
- this->PrintFormatted(os, op->brief);
- os << "\n";
- ++op;
- }
- }
- }
- //----------------------------------------------------------------------------
- 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;
- this->TextIndent = " ";
- int align = static_cast<int>(strlen(this->TextIndent))-4;
- for(int i = static_cast<int>(strlen(op->name)); i < align; ++i)
- {
- os << " ";
- }
- if ( strlen(op->name) > strlen(this->TextIndent)-4 )
- {
- os << "\n";
- os.write(this->TextIndent, strlen(this->TextIndent)-2);
- }
- os << "= ";
- this->PrintColumn(os, op->brief);
- os << "\n";
- }
- else
- {
- os << "\n";
- this->TextIndent = "";
- this->PrintFormatted(os, op->brief);
- }
- }
- os << "\n";
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::PrintFormatted(std::ostream& os, const char* text)
- {
- 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::PrintPreformatted(std::ostream& os, const char* text)
- {
- switch (this->CurrentForm)
- {
- 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;
- }
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::PrintParagraph(std::ostream& os, const char* text)
- {
- 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
- ::PrintPreformattedText(std::ostream& os, const char* text)
- {
- bool newline = true;
- for(const char* ptr = text; *ptr; ++ptr)
- {
- if(newline)
- {
- os << this->TextIndent;
- newline = false;
- }
- os << *ptr;
- if(*ptr == '\n')
- {
- newline = true;
- }
- }
- os << "\n";
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::PrintParagraphText(std::ostream& os, const char* text)
- {
- 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::PrintParagraphHTML(std::ostream& os, const char* text)
- {
- os << "<p>";
- this->PrintHTMLEscapes(os, text);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::PrintPreformattedMan(std::ostream& os, const char* text)
- {
- std::string man_text = text;
- cmSystemTools::ReplaceString(man_text, "\\", "\\\\");
- os << man_text << "\n";
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::PrintParagraphMan(std::ostream& os, const char* text)
- {
- std::string man_text = text;
- cmSystemTools::ReplaceString(man_text, "\\", "\\\\");
- os << man_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;
- int width = this->TextWidth - static_cast<int>(strlen(this->TextIndent));
-
- // Loop until the end of the text.
- 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 << (firstLine?"":this->TextIndent);
- }
-
- // 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;
- firstLine = 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";
- firstLine = false;
- if(r > l)
- {
- os << this->TextIndent;
- os.write(l, static_cast<long>(r-l));
- column = static_cast<long>(r-l);
- newSentence = (*(r-1) == '.');
- }
- else
- {
- column = 0;
- }
- }
-
- // Move to beginning of next word. Skip over whitespace.
- l = r;
- while(*l && (*l == ' ')) { ++l; }
- }
- }
- //----------------------------------------------------------------------------
- static bool cmDocumentationIsHyperlinkChar(char c)
- {
- // This is not a complete list but works for CMake documentation.
- return ((c >= 'A' && c <= 'Z') ||
- (c >= 'a' && c <= 'z') ||
- (c >= '0' && c <= '9') ||
- c == '-' || c == '.' || c == '/' || c == '~' || c == '@' ||
- c == ':' || c == '_' || c == '&' || c == '?' || c == '=');
- }
- //----------------------------------------------------------------------------
- static void cmDocumentationPrintHTMLChar(std::ostream& os, char c)
- {
- // Use an escape sequence if necessary.
- static cmDocumentationEntry escapes[] =
- {
- {"<", "<", 0},
- {">", ">", 0},
- {"&", "&", 0},
- {"\n", "<br>", 0},
- {0,0,0}
- };
- for(const cmDocumentationEntry* op = escapes; op->name; ++op)
- {
- if(op->name[0] == c)
- {
- os << op->brief;
- return;
- }
- }
- // No escape sequence is needed.
- os << c;
- }
- //----------------------------------------------------------------------------
- const char* cmDocumentationPrintHTMLLink(std::ostream& os, const char* begin)
- {
- // Look for the end of the link.
- const char* end = begin;
- while(cmDocumentationIsHyperlinkChar(*end))
- {
- ++end;
- }
- // Print the hyperlink itself.
- os << "<a href=\"";
- for(const char* c = begin; c != end; ++c)
- {
- cmDocumentationPrintHTMLChar(os, *c);
- }
- os << "\">";
- // The name of the hyperlink is the text itself.
- for(const char* c = begin; c != end; ++c)
- {
- cmDocumentationPrintHTMLChar(os, *c);
- }
- os << "</a>";
- // Return the position at which to continue scanning the input
- // string.
- return end;
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::PrintHTMLEscapes(std::ostream& os, const char* text)
- {
- // Hyperlink prefixes.
- static const char* hyperlinks[] = {"http://", "ftp://", "mailto:", 0};
- // Print each character.
- for(const char* p = text; *p;)
- {
- // Handle hyperlinks specially to make them active.
- bool found_hyperlink = false;
- for(const char** h = hyperlinks; !found_hyperlink && *h; ++h)
- {
- if(strncmp(p, *h, strlen(*h)) == 0)
- {
- p = cmDocumentationPrintHTMLLink(os, p);
- found_hyperlink = true;
- }
- }
- // Print other characters normally.
- if(!found_hyperlink)
- {
- cmDocumentationPrintHTMLChar(os, *p++);
- }
- }
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::PrintDocumentationSingle(std::ostream& os)
- {
- if(this->CommandsSection.IsEmpty())
- {
- os << "Internal error: commands list is empty." << std::endl;
- return false;
- }
- if(this->SingleCommand.length() == 0)
- {
- os << "Argument --help-command needs a command name.\n";
- return false;
- }
- for(cmDocumentationEntry* entry = this->CommandsSection.GetEntries();
- entry->brief; ++entry)
- {
- if(entry->name && this->SingleCommand == entry->name)
- {
- this->PrintDocumentationCommand(os, entry);
- return true;
- }
- }
- // Argument was not a command. Complain.
- os << "Argument \"" << this->SingleCommand.c_str()
- << "\" to --help-command is not a CMake command. "
- << "Use --help-command-list to see all commands.\n";
- return false;
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::PrintDocumentationSingleModule(std::ostream& os)
- {
- if(this->SingleModuleName.length() == 0)
- {
- os << "Argument --help-module needs a module name.\n";
- return false;
- }
- std::string cmakeModules = this->CMakeRoot;
- cmakeModules += "/Modules/";
- cmakeModules += this->SingleModuleName;
- cmakeModules += ".cmake";
- if(cmSystemTools::FileExists(cmakeModules.c_str())
- && this->CreateSingleModule(cmakeModules.c_str(),
- this->SingleModuleName.c_str()))
- {
- this->PrintDocumentationCommand(os, this->ModulesSection.GetEntries());
- os << "\n Defined in: ";
- os << cmakeModules << "\n";
- return true;
- }
- // Argument was not a module. Complain.
- os << "Argument \"" << this->SingleModuleName.c_str()
- << "\" to --help-module is not a CMake module.";
- return false;
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::PrintDocumentationSingleProperty(std::ostream& os)
- {
- if(this->PropertiesSection.IsEmpty())
- {
- os << "Internal error: properties list is empty." << std::endl;
- return false;
- }
- if(this->SinglePropertyName.length() == 0)
- {
- os << "Argument --help-property needs a property name.\n";
- return false;
- }
- for(cmDocumentationEntry* entry = this->PropertiesSection.GetEntries();
- entry->brief; ++entry)
- {
- if(entry->name && this->SinglePropertyName == entry->name)
- {
- this->PrintDocumentationCommand(os, entry);
- return true;
- }
- }
- // Argument was not a command. Complain.
- os << "Argument \"" << this->SinglePropertyName.c_str()
- << "\" to --help-property is not a CMake property. "
- << "Use --help-property-list to see all properties.\n";
- return false;
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::PrintDocumentationList(std::ostream& os)
- {
- if(this->CommandsSection.IsEmpty())
- {
- os << "Internal error: commands list is empty." << std::endl;
- return false;
- }
- for(cmDocumentationEntry* entry = this->CommandsSection.GetEntries();
- entry->brief; ++entry)
- {
- if(entry->name)
- {
- os << entry->name << std::endl;
- }
- }
- return true;
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::PrintPropertyList(std::ostream& os)
- {
- if(this->PropertiesSection.IsEmpty())
- {
- os << "Internal error: properties list is empty." << std::endl;
- return false;
- }
- for(cmDocumentationEntry* entry = this->PropertiesSection.GetEntries();
- entry->brief; ++entry)
- {
- if(entry->name)
- {
- os << entry->name << std::endl;
- }
- }
- return true;
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::PrintModuleList(std::ostream& os)
- {
- this->CreateModulesSection();
- if(this->ModulesSection.IsEmpty())
- {
- os << "Internal error: modules list is empty." << std::endl;
- return false;
- }
- for(cmDocumentationEntry* entry = this->ModulesSection.GetEntries();
- entry->brief; ++entry)
- {
- if(entry->name)
- {
- os << entry->name << std::endl;
- }
- }
- return true;
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::PrintDocumentationUsage(std::ostream& os)
- {
- this->CreateUsageDocumentation();
- this->Print(os);
- return true;
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::PrintDocumentationFull(std::ostream& os)
- {
- this->CreateFullDocumentation();
- this->PrintHeader(GetNameString(), os);
- this->Print(os);
- this->PrintFooter(os);
- return true;
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::PrintHeader(const char* name, std::ostream& os)
- {
- switch(this->CurrentForm)
- {
- case HTMLForm:
- os << "<html><body>\n";
- break;
- case ManForm:
- os << ".TH " << name << " 1 \""
- << cmSystemTools::GetCurrentDateTime("%B %d, %Y").c_str()
- << "\" \"" << this->GetNameString()
- << " " << cmVersion::GetCMakeVersion()
- << "\"\n";
- break;
- case TextForm:
- case UsageForm:
- break;
- }
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::PrintFooter(std::ostream& os)
- {
- switch(this->CurrentForm)
- {
- case HTMLForm:
- os << "</body></html>\n";
- break;
- case ManForm:
- case TextForm:
- case UsageForm:
- break;
- }
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::PrintDocumentationCommand(std::ostream& os,
- cmDocumentationEntry* entry)
- {
- cmDocumentationEntry singleCommandSection[3] =
- {
- {entry->name, entry->brief, entry->full},
- {0,0,0}
- };
- this->ClearSections();
- this->AddSection(0, &singleCommandSection[0]);
- this->Print(os);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::CreateUsageDocumentation()
- {
- this->ClearSections();
- this->AddSection(this->UsageSection);
- this->AddSection(this->OptionsSection);
- this->AddSection(this->GeneratorsSection);
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::CreateFullDocumentation()
- {
- this->ClearSections();
- this->CreateModulesSection();
- this->AddSection(this->NameSection);
- this->AddSection(this->UsageSection);
- this->AddSection(this->DescriptionSection);
- this->AddSection(this->OptionsSection);
- this->AddSection(this->GeneratorsSection);
- this->AddSection(this->CommandsSection);
- this->AddSection(this->ModulesSection);
- this->AddSection(this->PropertiesSection);
- this->AddSection(this->CopyrightSection.GetName(this->CurrentForm),
- cmDocumentationCopyright);
- if(this->CurrentForm == ManForm)
- {
- this->AddSection(this->SeeAlsoSection);
- this->AddSection(this->AuthorSection.GetName(ManForm),
- cmDocumentationAuthor);
- }
- else
- {
- this->AddSection(this->SeeAlsoSection.GetName(TextForm),
- cmDocumentationStandardSeeAlso);
- }
- }
- //----------------------------------------------------------------------------
- void cmDocumentation::cmSection::Set(const cmDocumentationEntry* header,
- const cmDocumentationEntry* section,
- const cmDocumentationEntry* footer)
- {
- this->Entries.erase(this->Entries.begin(), this->Entries.end());
- if(header)
- {
- for(const cmDocumentationEntry* op = header; op->brief; ++op)
- {
- this->Entries.push_back(*op);
- }
- }
- if(section)
- {
- for(const cmDocumentationEntry* op = section; op->brief; ++op)
- {
- this->Entries.push_back(*op);
- }
- }
- if(footer)
- {
- for(const cmDocumentationEntry* op = footer; op->brief; ++op)
- {
- this->Entries.push_back(*op);
- }
- }
- cmDocumentationEntry empty = {0,0,0};
- this->Entries.push_back(empty);
- }
- //----------------------------------------------------------------------------
- const char* cmDocumentation::GetNameString() const
- {
- if(this->NameString.length() > 0)
- {
- return this->NameString.c_str();
- }
- else
- {
- return "CMake";
- }
- }
- //----------------------------------------------------------------------------
- bool cmDocumentation::IsOption(const char* arg) const
- {
- return ((arg[0] == '-') || (strcmp(arg, "/V") == 0) ||
- (strcmp(arg, "/?") == 0));
- }
|