cmDocumentation.cxx 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmDocumentation.h"
  11. #include "cmSystemTools.h"
  12. #include "cmVersion.h"
  13. #include <cmsys/Directory.hxx>
  14. #include <cmsys/Glob.hxx>
  15. #include <algorithm>
  16. //----------------------------------------------------------------------------
  17. static const char *cmDocumentationStandardOptions[][3] =
  18. {
  19. {"--copyright [file]", "Print the CMake copyright and exit.",
  20. "If a file is specified, the copyright is written into it."},
  21. {"--help,-help,-usage,-h,-H,/?", "Print usage information and exit.",
  22. "Usage describes the basic command line interface and its options."},
  23. {"--help-full [file]", "Print full help and exit.",
  24. "Full help displays most of the documentation provided by the UNIX "
  25. "man page. It is provided for use on non-UNIX platforms, but is "
  26. "also convenient if the man page is not installed. If a file is "
  27. "specified, the help is written into it."},
  28. {"--help-html [file]", "Print full help in HTML format.",
  29. "This option is used by CMake authors to help produce web pages. "
  30. "If a file is specified, the help is written into it."},
  31. {"--help-man [file]", "Print full help as a UNIX man page and exit.",
  32. "This option is used by the cmake build to generate the UNIX man page. "
  33. "If a file is specified, the help is written into it."},
  34. {"--version,-version,/V [file]",
  35. "Show program name/version banner and exit.",
  36. "If a file is specified, the version is written into it."},
  37. {0,0,0}
  38. };
  39. //----------------------------------------------------------------------------
  40. static const char *cmModulesDocumentationDescription[][3] =
  41. {
  42. {0,
  43. " CMake Modules - Modules coming with CMake, the Cross-Platform Makefile "
  44. "Generator.", 0},
  45. // CMAKE_DOCUMENTATION_OVERVIEW,
  46. {0,
  47. "This is the documentation for the modules and scripts coming with CMake. "
  48. "Using these modules you can check the computer system for "
  49. "installed software packages, features of the compiler and the "
  50. "existence of headers to name just a few.", 0},
  51. {0,0,0}
  52. };
  53. //----------------------------------------------------------------------------
  54. static const char *cmCustomModulesDocumentationDescription[][3] =
  55. {
  56. {0,
  57. " Custom CMake Modules - Additional Modules for CMake.", 0},
  58. // CMAKE_DOCUMENTATION_OVERVIEW,
  59. {0,
  60. "This is the documentation for additional modules and scripts for CMake. "
  61. "Using these modules you can check the computer system for "
  62. "installed software packages, features of the compiler and the "
  63. "existence of headers to name just a few.", 0},
  64. {0,0,0}
  65. };
  66. //----------------------------------------------------------------------------
  67. static const char *cmPropertiesDocumentationDescription[][3] =
  68. {
  69. {0,
  70. " CMake Properties - Properties supported by CMake, "
  71. "the Cross-Platform Makefile Generator.", 0},
  72. // CMAKE_DOCUMENTATION_OVERVIEW,
  73. {0,
  74. "This is the documentation for the properties supported by CMake. "
  75. "Properties can have different scopes. They can either be assigned to a "
  76. "source file, a directory, a target or globally to CMake. By modifying the "
  77. "values of properties the behaviour of the build system can be customized.",
  78. 0},
  79. {0,0,0}
  80. };
  81. //----------------------------------------------------------------------------
  82. static const char *cmCompatCommandsDocumentationDescription[][3] =
  83. {
  84. {0,
  85. " CMake Compatibility Listfile Commands - "
  86. "Obsolete commands supported by CMake for compatibility.", 0},
  87. // CMAKE_DOCUMENTATION_OVERVIEW,
  88. {0,
  89. "This is the documentation for now obsolete listfile commands from previous "
  90. "CMake versions, which are still supported for compatibility reasons. You "
  91. "should instead use the newer, faster and shinier new commands. ;-)", 0},
  92. {0,0,0}
  93. };
  94. //----------------------------------------------------------------------------
  95. static const char *cmDocumentationModulesHeader[][3] =
  96. {
  97. {0,
  98. "The following modules are provided with CMake. "
  99. "They can be used with INCLUDE(ModuleName).", 0},
  100. {0,0,0}
  101. };
  102. //----------------------------------------------------------------------------
  103. static const char *cmDocumentationCustomModulesHeader[][3] =
  104. {
  105. {0,
  106. "The following modules are also available for CMake. "
  107. "They can be used with INCLUDE(ModuleName).", 0},
  108. {0,0,0}
  109. };
  110. //----------------------------------------------------------------------------
  111. static const char *cmDocumentationGeneratorsHeader[][3] =
  112. {
  113. {0,
  114. "The following generators are available on this platform:", 0},
  115. {0,0,0}
  116. };
  117. //----------------------------------------------------------------------------
  118. static const char *cmDocumentationStandardSeeAlso[][3] =
  119. {
  120. {0,
  121. "The following resources are available to get help using CMake:", 0},
  122. {"Home Page",
  123. "http://www.cmake.org",
  124. "The primary starting point for learning about CMake."},
  125. {"Frequently Asked Questions",
  126. "http://www.cmake.org/Wiki/CMake_FAQ",
  127. "A Wiki is provided containing answers to frequently asked questions. "},
  128. {"Online Documentation",
  129. "http://www.cmake.org/HTML/Documentation.html",
  130. "Links to available documentation may be found on this web page."},
  131. {"Mailing List",
  132. "http://www.cmake.org/HTML/MailingLists.html",
  133. "For help and discussion about using cmake, a mailing list is provided at "
  134. "[email protected]. "
  135. "The list is member-post-only but one may sign up on the CMake web page. "
  136. "Please first read the full documentation at "
  137. "http://www.cmake.org before posting questions to the list."},
  138. {0,0,0}
  139. };
  140. //----------------------------------------------------------------------------
  141. static const char *cmDocumentationCopyright[][3] =
  142. {
  143. {0,
  144. "Copyright 2000-2012 Kitware, Inc., Insight Software Consortium. "
  145. "All rights reserved.", 0},
  146. {0,
  147. "Redistribution and use in source and binary forms, with or without "
  148. "modification, are permitted provided that the following conditions are "
  149. "met:", 0},
  150. {"",
  151. "Redistributions of source code must retain the above copyright notice, "
  152. "this list of conditions and the following disclaimer.", 0},
  153. {"",
  154. "Redistributions in binary form must reproduce the above copyright "
  155. "notice, this list of conditions and the following disclaimer in the "
  156. "documentation and/or other materials provided with the distribution.",
  157. 0},
  158. {"",
  159. "Neither the names of Kitware, Inc., the Insight Software Consortium, "
  160. "nor the names of their contributors may be used to endorse or promote "
  161. "products derived from this software without specific prior written "
  162. "permission.", 0},
  163. {0,
  164. "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "
  165. "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "
  166. "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR "
  167. "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT "
  168. "HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, "
  169. "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT "
  170. "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, "
  171. "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY "
  172. "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT "
  173. "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE "
  174. "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
  175. 0},
  176. {0, 0, 0}
  177. };
  178. //----------------------------------------------------------------------------
  179. #define DOCUMENT_INTRO(type, default_name, desc) \
  180. static char const *cmDocumentation##type##Intro[2] = { default_name, desc };
  181. #define GET_DOCUMENT_INTRO(type) cmDocumentation##type##Intro
  182. DOCUMENT_INTRO(Modules, "cmakemodules",
  183. "Reference of available CMake modules.");
  184. DOCUMENT_INTRO(CustomModules, "cmakecustommodules",
  185. "Reference of available CMake custom modules.");
  186. DOCUMENT_INTRO(Policies, "cmakepolicies",
  187. "Reference of CMake policies.");
  188. DOCUMENT_INTRO(Properties, "cmakeprops",
  189. "Reference of CMake properties.");
  190. DOCUMENT_INTRO(Variables, "cmakevars",
  191. "Reference of CMake variables.");
  192. DOCUMENT_INTRO(Commands, "cmakecommands",
  193. "Reference of available CMake commands.");
  194. DOCUMENT_INTRO(CompatCommands, "cmakecompat",
  195. "Reference of CMake compatibility commands.");
  196. //----------------------------------------------------------------------------
  197. cmDocumentation::cmDocumentation()
  198. :CurrentFormatter(0)
  199. {
  200. this->SetForm(TextForm, 0);
  201. this->addCommonStandardDocSections();
  202. this->ShowGenerators = true;
  203. }
  204. //----------------------------------------------------------------------------
  205. cmDocumentation::~cmDocumentation()
  206. {
  207. for(std::vector< char* >::iterator i = this->ModuleStrings.begin();
  208. i != this->ModuleStrings.end(); ++i)
  209. {
  210. delete [] *i;
  211. }
  212. for(std::map<std::string,cmDocumentationSection *>::iterator i =
  213. this->AllSections.begin();
  214. i != this->AllSections.end(); ++i)
  215. {
  216. delete i->second;
  217. }
  218. }
  219. //----------------------------------------------------------------------------
  220. bool cmDocumentation::PrintCopyright(std::ostream& os)
  221. {
  222. cmDocumentationSection *sec = this->AllSections["Copyright"];
  223. const std::vector<cmDocumentationEntry> &entries = sec->GetEntries();
  224. for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
  225. op != entries.end(); ++op)
  226. {
  227. if(op->Name.size())
  228. {
  229. os << " * ";
  230. this->TextFormatter.SetIndent(" ");
  231. this->TextFormatter.PrintColumn(os, op->Brief.c_str());
  232. }
  233. else
  234. {
  235. this->TextFormatter.SetIndent("");
  236. this->TextFormatter.PrintColumn(os, op->Brief.c_str());
  237. }
  238. os << "\n";
  239. }
  240. return true;
  241. }
  242. //----------------------------------------------------------------------------
  243. bool cmDocumentation::PrintVersion(std::ostream& os)
  244. {
  245. os << this->GetNameString() << " version "
  246. << cmVersion::GetCMakeVersion() << "\n";
  247. return true;
  248. }
  249. //----------------------------------------------------------------------------
  250. void cmDocumentation::AddSectionToPrint(const char *section)
  251. {
  252. if (this->AllSections.find(section) != this->AllSections.end())
  253. {
  254. this->PrintSections.push_back(this->AllSections[section]);
  255. }
  256. }
  257. //----------------------------------------------------------------------------
  258. void cmDocumentation::ClearSections()
  259. {
  260. this->PrintSections.erase(this->PrintSections.begin(),
  261. this->PrintSections.end());
  262. this->ModulesFound.clear();
  263. }
  264. //----------------------------------------------------------------------------
  265. void cmDocumentation::AddDocumentIntroToPrint(const char* intro[2])
  266. {
  267. const char* docname = this->GetDocName(false);
  268. if(intro && docname)
  269. {
  270. cmDocumentationSection* section;
  271. std::string desc("");
  272. desc += docname;
  273. desc += " - ";
  274. desc += intro[1];
  275. section = new cmDocumentationSection("Introduction", "NAME");
  276. section->Append(0, desc.c_str(), 0);
  277. this->PrintSections.push_back(section);
  278. }
  279. }
  280. //----------------------------------------------------------------------------
  281. bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os,
  282. const char* docname)
  283. {
  284. // Handle Document Name. docname==0 disables intro.
  285. this->SetDocName("");
  286. if (docname)
  287. {
  288. if (*docname)
  289. this->SetDocName(docname);
  290. else // empty string was given. select default if possible
  291. this->SetDocName(this->GetDefaultDocName(ht));
  292. }
  293. switch (ht)
  294. {
  295. case cmDocumentation::Usage:
  296. return this->PrintDocumentationUsage(os);
  297. case cmDocumentation::Single:
  298. return this->PrintDocumentationSingle(os);
  299. case cmDocumentation::SingleModule:
  300. return this->PrintDocumentationSingleModule(os);
  301. case cmDocumentation::SinglePolicy:
  302. return this->PrintDocumentationSinglePolicy(os);
  303. case cmDocumentation::SingleProperty:
  304. return this->PrintDocumentationSingleProperty(os);
  305. case cmDocumentation::SingleVariable:
  306. return this->PrintDocumentationSingleVariable(os);
  307. case cmDocumentation::List:
  308. this->PrintDocumentationList(os,"Commands");
  309. this->PrintDocumentationList(os,"Compatibility Commands");
  310. return true;
  311. case cmDocumentation::ModuleList:
  312. // find the modules first, print the custom module docs only if
  313. // any custom modules have been found actually, Alex
  314. this->CreateCustomModulesSection();
  315. this->CreateModulesSection();
  316. if (this->AllSections.find("Custom CMake Modules")
  317. != this->AllSections.end())
  318. {
  319. this->PrintDocumentationList(os,"Custom CMake Modules");
  320. }
  321. this->PrintDocumentationList(os,"Modules");
  322. return true;
  323. case cmDocumentation::PropertyList:
  324. this->PrintDocumentationList(os,"Properties Description");
  325. for (std::vector<std::string>::iterator i =
  326. this->PropertySections.begin();
  327. i != this->PropertySections.end(); ++i)
  328. {
  329. this->PrintDocumentationList(os,i->c_str());
  330. }
  331. return true;
  332. case cmDocumentation::VariableList:
  333. for (std::vector<std::string>::iterator i =
  334. this->VariableSections.begin();
  335. i != this->VariableSections.end(); ++i)
  336. {
  337. this->PrintDocumentationList(os,i->c_str());
  338. }
  339. return true;
  340. case cmDocumentation::PolicyList:
  341. this->PrintDocumentationList(os,"Policies");
  342. return true;
  343. case cmDocumentation::Full:
  344. return this->PrintDocumentationFull(os);
  345. case cmDocumentation::Modules:
  346. return this->PrintDocumentationModules(os);
  347. case cmDocumentation::CustomModules:
  348. return this->PrintDocumentationCustomModules(os);
  349. case cmDocumentation::Policies:
  350. return this->PrintDocumentationPolicies(os);
  351. case cmDocumentation::Properties:
  352. return this->PrintDocumentationProperties(os);
  353. case cmDocumentation::Variables:
  354. return this->PrintDocumentationVariables(os);
  355. case cmDocumentation::Commands:
  356. return this->PrintDocumentationCurrentCommands(os);
  357. case cmDocumentation::CompatCommands:
  358. return this->PrintDocumentationCompatCommands(os);
  359. case cmDocumentation::Copyright:
  360. return this->PrintCopyright(os);
  361. case cmDocumentation::Version:
  362. return this->PrintVersion(os);
  363. default: return false;
  364. }
  365. }
  366. //----------------------------------------------------------------------------
  367. bool cmDocumentation::CreateModulesSection()
  368. {
  369. cmDocumentationSection *sec =
  370. new cmDocumentationSection("Standard CMake Modules", "MODULES");
  371. this->AllSections["Modules"] = sec;
  372. std::string cmakeModules = this->CMakeRoot;
  373. cmakeModules += "/Modules";
  374. cmsys::Directory dir;
  375. dir.Load(cmakeModules.c_str());
  376. if (dir.GetNumberOfFiles() > 0)
  377. {
  378. sec->Append(cmDocumentationModulesHeader[0]);
  379. sec->Append(cmModulesDocumentationDescription);
  380. this->CreateModuleDocsForDir(dir, *this->AllSections["Modules"]);
  381. }
  382. return true;
  383. }
  384. //----------------------------------------------------------------------------
  385. bool cmDocumentation::CreateCustomModulesSection()
  386. {
  387. bool sectionHasHeader = false;
  388. std::vector<std::string> dirs;
  389. cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
  390. for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
  391. dirIt != dirs.end();
  392. ++dirIt)
  393. {
  394. cmsys::Directory dir;
  395. dir.Load(dirIt->c_str());
  396. if (dir.GetNumberOfFiles() > 0)
  397. {
  398. if (!sectionHasHeader)
  399. {
  400. cmDocumentationSection *sec =
  401. new cmDocumentationSection("Custom CMake Modules","CUSTOM MODULES");
  402. this->AllSections["Custom CMake Modules"] = sec;
  403. sec->Append(cmDocumentationCustomModulesHeader[0]);
  404. sec->Append(cmCustomModulesDocumentationDescription);
  405. sectionHasHeader = true;
  406. }
  407. this->CreateModuleDocsForDir
  408. (dir, *this->AllSections["Custom CMake Modules"]);
  409. }
  410. }
  411. return true;
  412. }
  413. //----------------------------------------------------------------------------
  414. void cmDocumentation
  415. ::CreateModuleDocsForDir(cmsys::Directory& dir,
  416. cmDocumentationSection &moduleSection)
  417. {
  418. // sort the files alphabetically, so the docs for one module are easier
  419. // to find than if they are in random order
  420. std::vector<std::string> sortedFiles;
  421. for(unsigned int i = 0; i < dir.GetNumberOfFiles(); ++i)
  422. {
  423. sortedFiles.push_back(dir.GetFile(i));
  424. }
  425. std::sort(sortedFiles.begin(), sortedFiles.end());
  426. for(std::vector<std::string>::const_iterator fname = sortedFiles.begin();
  427. fname!=sortedFiles.end(); ++fname)
  428. {
  429. if(fname->length() > 6)
  430. {
  431. if(fname->substr(fname->length()-6, 6) == ".cmake")
  432. {
  433. std::string moduleName = fname->substr(0, fname->length()-6);
  434. // this check is to avoid creating documentation for the modules with
  435. // the same name in multiple directories of CMAKE_MODULE_PATH
  436. if (this->ModulesFound.find(moduleName) == this->ModulesFound.end())
  437. {
  438. this->ModulesFound.insert(moduleName);
  439. std::string path = dir.GetPath();
  440. path += "/";
  441. path += (*fname);
  442. this->CreateSingleModule(path.c_str(), moduleName.c_str(),
  443. moduleSection);
  444. }
  445. }
  446. }
  447. }
  448. }
  449. //----------------------------------------------------------------------------
  450. bool cmDocumentation::CreateSingleModule(const char* fname,
  451. const char* moduleName,
  452. cmDocumentationSection &moduleSection)
  453. {
  454. std::ifstream fin(fname);
  455. if(!fin)
  456. {
  457. std::cerr << "Internal error: can not open module." << fname << std::endl;
  458. return false;
  459. }
  460. std::string line;
  461. std::string text;
  462. std::string brief;
  463. brief = " ";
  464. bool newParagraph = true;
  465. while ( fin && cmSystemTools::GetLineFromStream(fin, line) )
  466. {
  467. if(line.size() && line[0] == '#')
  468. {
  469. // blank line
  470. if(line.size() <= 2)
  471. {
  472. text += "\n";
  473. newParagraph = true;
  474. }
  475. else if(line[2] == '-')
  476. {
  477. brief = line.c_str()+4;
  478. }
  479. else
  480. {
  481. // two spaces
  482. if(line[1] == ' ' && line[2] == ' ')
  483. {
  484. if(!newParagraph)
  485. {
  486. text += "\n";
  487. newParagraph = true;
  488. }
  489. // Skip #, and leave space for preformatted
  490. text += line.c_str()+1;
  491. text += "\n";
  492. }
  493. else if(line[1] == ' ')
  494. {
  495. if(!newParagraph)
  496. {
  497. text += " ";
  498. }
  499. newParagraph = false;
  500. // skip # and space
  501. text += line.c_str()+2;
  502. }
  503. else
  504. {
  505. if(!newParagraph)
  506. {
  507. text += " ";
  508. }
  509. newParagraph = false;
  510. // skip #
  511. text += line.c_str()+1;
  512. }
  513. }
  514. }
  515. else
  516. {
  517. break;
  518. }
  519. }
  520. if(text.length() < 2 && brief.length() == 1)
  521. {
  522. return false;
  523. }
  524. char* pname = strcpy(new char[strlen(moduleName)+1], moduleName);
  525. char* ptext = strcpy(new char[text.length()+1], text.c_str());
  526. this->ModuleStrings.push_back(pname);
  527. this->ModuleStrings.push_back(ptext);
  528. char* pbrief = strcpy(new char[brief.length()+1], brief.c_str());
  529. this->ModuleStrings.push_back(pbrief);
  530. moduleSection.Append(pname, pbrief, ptext);
  531. return true;
  532. }
  533. //----------------------------------------------------------------------------
  534. bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
  535. {
  536. bool result = true;
  537. // Loop over requested documentation types.
  538. for(std::vector<RequestedHelpItem>::const_iterator
  539. i = this->RequestedHelpItems.begin();
  540. i != this->RequestedHelpItems.end();
  541. ++i)
  542. {
  543. this->SetForm(i->HelpForm, i->ManSection);
  544. this->CurrentArgument = i->Argument;
  545. // If a file name was given, use it. Otherwise, default to the
  546. // given stream.
  547. std::ofstream* fout = 0;
  548. std::ostream* s = &os;
  549. std::string docname("");
  550. if(i->Filename.length() > 0)
  551. {
  552. fout = new std::ofstream(i->Filename.c_str(), std::ios::out);
  553. if(fout)
  554. {
  555. s = fout;
  556. }
  557. else
  558. {
  559. result = false;
  560. }
  561. if(i->Filename != "-")
  562. {
  563. docname = cmSystemTools::GetFilenameWithoutLastExtension(i->Filename);
  564. }
  565. }
  566. // Print this documentation type to the stream.
  567. if(!this->PrintDocumentation(i->HelpType, *s, docname.c_str()) || !*s)
  568. {
  569. result = false;
  570. }
  571. // Close the file if we wrote one.
  572. if(fout)
  573. {
  574. delete fout;
  575. }
  576. }
  577. return result;
  578. }
  579. #define GET_OPT_ARGUMENT(target) \
  580. if((i+1 < argc) && !this->IsOption(argv[i+1])) \
  581. { \
  582. target = argv[i+1]; \
  583. i = i+1; \
  584. };
  585. cmDocumentation::Form cmDocumentation::GetFormFromFilename(
  586. const std::string& filename,
  587. int* manSection)
  588. {
  589. std::string ext = cmSystemTools::GetFilenameLastExtension(filename);
  590. ext = cmSystemTools::UpperCase(ext);
  591. if ((ext == ".HTM") || (ext == ".HTML"))
  592. {
  593. return cmDocumentation::HTMLForm;
  594. }
  595. if (ext == ".DOCBOOK")
  596. {
  597. return cmDocumentation::DocbookForm;
  598. }
  599. // ".1" to ".9" should be manpages
  600. if ((ext.length()==2) && (ext[1] >='1') && (ext[1]<='9'))
  601. {
  602. if (manSection)
  603. {
  604. *manSection = ext[1] - '0';
  605. }
  606. return cmDocumentation::ManForm;
  607. }
  608. return cmDocumentation::TextForm;
  609. }
  610. //----------------------------------------------------------------------------
  611. void cmDocumentation::addCommonStandardDocSections()
  612. {
  613. cmDocumentationSection *sec;
  614. sec = new cmDocumentationSection("Author","AUTHOR");
  615. sec->Append(cmDocumentationEntry
  616. (0,
  617. "This manual page was generated by the \"--help-man\" option.",
  618. 0));
  619. this->AllSections["Author"] = sec;
  620. sec = new cmDocumentationSection("Copyright","COPYRIGHT");
  621. sec->Append(cmDocumentationCopyright);
  622. this->AllSections["Copyright"] = sec;
  623. sec = new cmDocumentationSection("See Also","SEE ALSO");
  624. sec->Append(cmDocumentationStandardSeeAlso);
  625. this->AllSections["Standard See Also"] = sec;
  626. sec = new cmDocumentationSection("Options","OPTIONS");
  627. sec->Append(cmDocumentationStandardOptions);
  628. this->AllSections["Options"] = sec;
  629. sec = new cmDocumentationSection("Compatibility Commands",
  630. "COMPATIBILITY COMMANDS");
  631. sec->Append(cmCompatCommandsDocumentationDescription);
  632. this->AllSections["Compatibility Commands"] = sec;
  633. }
  634. //----------------------------------------------------------------------------
  635. void cmDocumentation::addCMakeStandardDocSections()
  636. {
  637. cmDocumentationSection *sec;
  638. sec = new cmDocumentationSection("Properties","PROPERTIES");
  639. sec->Append(cmPropertiesDocumentationDescription);
  640. this->AllSections["Properties Description"] = sec;
  641. sec = new cmDocumentationSection("Generators","GENERATORS");
  642. sec->Append(cmDocumentationGeneratorsHeader);
  643. this->AllSections["Generators"] = sec;
  644. this->PropertySections.push_back("Properties of Global Scope");
  645. this->PropertySections.push_back("Properties on Directories");
  646. this->PropertySections.push_back("Properties on Targets");
  647. this->PropertySections.push_back("Properties on Tests");
  648. this->PropertySections.push_back("Properties on Source Files");
  649. this->PropertySections.push_back("Properties on Cache Entries");
  650. this->VariableSections.push_back("Variables that Provide Information");
  651. this->VariableSections.push_back("Variables That Change Behavior");
  652. this->VariableSections.push_back("Variables That Describe the System");
  653. this->VariableSections.push_back("Variables that Control the Build");
  654. this->VariableSections.push_back("Variables for Languages");
  655. }
  656. //----------------------------------------------------------------------------
  657. void cmDocumentation::addCTestStandardDocSections()
  658. {
  659. // This is currently done for backward compatibility reason
  660. // We may suppress some of these.
  661. addCMakeStandardDocSections();
  662. }
  663. //----------------------------------------------------------------------------
  664. void cmDocumentation::addCPackStandardDocSections()
  665. {
  666. cmDocumentationSection *sec;
  667. sec = new cmDocumentationSection("Generators","GENERATORS");
  668. sec->Append(cmDocumentationGeneratorsHeader);
  669. this->AllSections["Generators"] = sec;
  670. this->VariableSections.push_back(
  671. "Variables common to all CPack generators");
  672. }
  673. void cmDocumentation::addAutomaticVariableSections(const std::string& section)
  674. {
  675. std::vector<std::string>::iterator it;
  676. it = std::find(this->VariableSections.begin(),
  677. this->VariableSections.end(),
  678. section);
  679. /* if the section does not exist then add it */
  680. if (it==this->VariableSections.end())
  681. {
  682. this->VariableSections.push_back(section);
  683. }
  684. }
  685. //----------------------------------------------------------------------------
  686. bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
  687. const char* exitOpt)
  688. {
  689. // Providing zero arguments gives usage information.
  690. if(argc == 1)
  691. {
  692. RequestedHelpItem help;
  693. help.HelpType = cmDocumentation::Usage;
  694. help.HelpForm = cmDocumentation::UsageForm;
  695. this->RequestedHelpItems.push_back(help);
  696. return true;
  697. }
  698. // Search for supported help options.
  699. bool result = false;
  700. for(int i=1; i < argc; ++i)
  701. {
  702. if(exitOpt && strcmp(argv[i], exitOpt) == 0)
  703. {
  704. return result;
  705. }
  706. RequestedHelpItem help;
  707. // Check if this is a supported help option.
  708. if((strcmp(argv[i], "-help") == 0) ||
  709. (strcmp(argv[i], "--help") == 0) ||
  710. (strcmp(argv[i], "/?") == 0) ||
  711. (strcmp(argv[i], "-usage") == 0) ||
  712. (strcmp(argv[i], "-h") == 0) ||
  713. (strcmp(argv[i], "-H") == 0))
  714. {
  715. help.HelpType = cmDocumentation::Usage;
  716. help.HelpForm = cmDocumentation::UsageForm;
  717. GET_OPT_ARGUMENT(help.Argument);
  718. help.Argument = cmSystemTools::LowerCase(help.Argument);
  719. // special case for single command
  720. if (!help.Argument.empty())
  721. {
  722. help.HelpType = cmDocumentation::Single;
  723. }
  724. }
  725. else if(strcmp(argv[i], "--help-properties") == 0)
  726. {
  727. help.HelpType = cmDocumentation::Properties;
  728. GET_OPT_ARGUMENT(help.Filename);
  729. help.HelpForm = this->GetFormFromFilename(help.Filename,
  730. &help.ManSection);
  731. }
  732. else if(strcmp(argv[i], "--help-policies") == 0)
  733. {
  734. help.HelpType = cmDocumentation::Policies;
  735. GET_OPT_ARGUMENT(help.Filename);
  736. help.HelpForm = this->GetFormFromFilename(help.Filename,
  737. &help.ManSection);
  738. }
  739. else if(strcmp(argv[i], "--help-variables") == 0)
  740. {
  741. help.HelpType = cmDocumentation::Variables;
  742. GET_OPT_ARGUMENT(help.Filename);
  743. help.HelpForm = this->GetFormFromFilename(help.Filename,
  744. &help.ManSection);
  745. }
  746. else if(strcmp(argv[i], "--help-modules") == 0)
  747. {
  748. help.HelpType = cmDocumentation::Modules;
  749. GET_OPT_ARGUMENT(help.Filename);
  750. help.HelpForm = this->GetFormFromFilename(help.Filename,
  751. &help.ManSection);
  752. }
  753. else if(strcmp(argv[i], "--help-custom-modules") == 0)
  754. {
  755. help.HelpType = cmDocumentation::CustomModules;
  756. GET_OPT_ARGUMENT(help.Filename);
  757. help.HelpForm = this->GetFormFromFilename(help.Filename,
  758. &help.ManSection);
  759. }
  760. else if(strcmp(argv[i], "--help-commands") == 0)
  761. {
  762. help.HelpType = cmDocumentation::Commands;
  763. GET_OPT_ARGUMENT(help.Filename);
  764. help.HelpForm = this->GetFormFromFilename(help.Filename,
  765. &help.ManSection);
  766. }
  767. else if(strcmp(argv[i], "--help-compatcommands") == 0)
  768. {
  769. help.HelpType = cmDocumentation::CompatCommands;
  770. GET_OPT_ARGUMENT(help.Filename);
  771. help.HelpForm = this->GetFormFromFilename(help.Filename,
  772. &help.ManSection);
  773. }
  774. else if(strcmp(argv[i], "--help-full") == 0)
  775. {
  776. help.HelpType = cmDocumentation::Full;
  777. GET_OPT_ARGUMENT(help.Filename);
  778. help.HelpForm = this->GetFormFromFilename(help.Filename,
  779. &help.ManSection);
  780. }
  781. else if(strcmp(argv[i], "--help-html") == 0)
  782. {
  783. help.HelpType = cmDocumentation::Full;
  784. GET_OPT_ARGUMENT(help.Filename);
  785. help.HelpForm = cmDocumentation::HTMLForm;
  786. }
  787. else if(strcmp(argv[i], "--help-man") == 0)
  788. {
  789. help.HelpType = cmDocumentation::Full;
  790. GET_OPT_ARGUMENT(help.Filename);
  791. help.HelpForm = cmDocumentation::ManForm;
  792. help.ManSection = 1;
  793. }
  794. else if(strcmp(argv[i], "--help-command") == 0)
  795. {
  796. help.HelpType = cmDocumentation::Single;
  797. GET_OPT_ARGUMENT(help.Argument);
  798. GET_OPT_ARGUMENT(help.Filename);
  799. help.Argument = cmSystemTools::LowerCase(help.Argument);
  800. help.HelpForm = this->GetFormFromFilename(help.Filename,
  801. &help.ManSection);
  802. }
  803. else if(strcmp(argv[i], "--help-module") == 0)
  804. {
  805. help.HelpType = cmDocumentation::SingleModule;
  806. GET_OPT_ARGUMENT(help.Argument);
  807. GET_OPT_ARGUMENT(help.Filename);
  808. help.HelpForm = this->GetFormFromFilename(help.Filename,
  809. &help.ManSection);
  810. }
  811. else if(strcmp(argv[i], "--help-property") == 0)
  812. {
  813. help.HelpType = cmDocumentation::SingleProperty;
  814. GET_OPT_ARGUMENT(help.Argument);
  815. GET_OPT_ARGUMENT(help.Filename);
  816. help.HelpForm = this->GetFormFromFilename(help.Filename,
  817. &help.ManSection);
  818. }
  819. else if(strcmp(argv[i], "--help-policy") == 0)
  820. {
  821. help.HelpType = cmDocumentation::SinglePolicy;
  822. GET_OPT_ARGUMENT(help.Argument);
  823. GET_OPT_ARGUMENT(help.Filename);
  824. help.HelpForm = this->GetFormFromFilename(help.Filename,
  825. &help.ManSection);
  826. }
  827. else if(strcmp(argv[i], "--help-variable") == 0)
  828. {
  829. help.HelpType = cmDocumentation::SingleVariable;
  830. GET_OPT_ARGUMENT(help.Argument);
  831. GET_OPT_ARGUMENT(help.Filename);
  832. help.HelpForm = this->GetFormFromFilename(help.Filename,
  833. &help.ManSection);
  834. }
  835. else if(strcmp(argv[i], "--help-command-list") == 0)
  836. {
  837. help.HelpType = cmDocumentation::List;
  838. GET_OPT_ARGUMENT(help.Filename);
  839. help.HelpForm = cmDocumentation::TextForm;
  840. }
  841. else if(strcmp(argv[i], "--help-module-list") == 0)
  842. {
  843. help.HelpType = cmDocumentation::ModuleList;
  844. GET_OPT_ARGUMENT(help.Filename);
  845. help.HelpForm = cmDocumentation::TextForm;
  846. }
  847. else if(strcmp(argv[i], "--help-property-list") == 0)
  848. {
  849. help.HelpType = cmDocumentation::PropertyList;
  850. GET_OPT_ARGUMENT(help.Filename);
  851. help.HelpForm = cmDocumentation::TextForm;
  852. }
  853. else if(strcmp(argv[i], "--help-variable-list") == 0)
  854. {
  855. help.HelpType = cmDocumentation::VariableList;
  856. GET_OPT_ARGUMENT(help.Filename);
  857. help.HelpForm = cmDocumentation::TextForm;
  858. }
  859. else if(strcmp(argv[i], "--help-policy-list") == 0)
  860. {
  861. help.HelpType = cmDocumentation::PolicyList;
  862. GET_OPT_ARGUMENT(help.Filename);
  863. help.HelpForm = cmDocumentation::TextForm;
  864. }
  865. else if(strcmp(argv[i], "--copyright") == 0)
  866. {
  867. help.HelpType = cmDocumentation::Copyright;
  868. GET_OPT_ARGUMENT(help.Filename);
  869. help.HelpForm = cmDocumentation::UsageForm;
  870. }
  871. else if((strcmp(argv[i], "--version") == 0) ||
  872. (strcmp(argv[i], "-version") == 0) ||
  873. (strcmp(argv[i], "/V") == 0))
  874. {
  875. help.HelpType = cmDocumentation::Version;
  876. GET_OPT_ARGUMENT(help.Filename);
  877. help.HelpForm = cmDocumentation::UsageForm;
  878. }
  879. if(help.HelpType != None)
  880. {
  881. // This is a help option. See if there is a file name given.
  882. result = true;
  883. this->RequestedHelpItems.push_back(help);
  884. }
  885. }
  886. return result;
  887. }
  888. //----------------------------------------------------------------------------
  889. void cmDocumentation::Print(Form f, int manSection, std::ostream& os)
  890. {
  891. this->SetForm(f, manSection);
  892. this->Print(os);
  893. }
  894. //----------------------------------------------------------------------------
  895. void cmDocumentation::Print(std::ostream& os)
  896. {
  897. // if the formatter supports it, print a master index for
  898. // all sections
  899. this->CurrentFormatter->PrintIndex(os, this->PrintSections);
  900. for(unsigned int i=0; i < this->PrintSections.size(); ++i)
  901. {
  902. std::string name = this->PrintSections[i]->
  903. GetName((this->CurrentFormatter->GetForm()));
  904. this->CurrentFormatter->PrintSection(os,*this->PrintSections[i],
  905. name.c_str());
  906. }
  907. }
  908. //----------------------------------------------------------------------------
  909. void cmDocumentation::SetName(const char* name)
  910. {
  911. this->NameString = name?name:"";
  912. }
  913. //----------------------------------------------------------------------------
  914. void cmDocumentation::SetDocName(const char *docname)
  915. {
  916. this->DocName = docname?docname:"";
  917. }
  918. //----------------------------------------------------------------------------
  919. void cmDocumentation::SetSection(const char *name,
  920. cmDocumentationSection *section)
  921. {
  922. if (this->AllSections.find(name) != this->AllSections.end())
  923. {
  924. delete this->AllSections[name];
  925. }
  926. this->AllSections[name] = section;
  927. }
  928. //----------------------------------------------------------------------------
  929. void cmDocumentation::SetSection(const char *name,
  930. std::vector<cmDocumentationEntry> &docs)
  931. {
  932. cmDocumentationSection *sec =
  933. new cmDocumentationSection(name,
  934. cmSystemTools::UpperCase(name).c_str());
  935. sec->Append(docs);
  936. this->SetSection(name,sec);
  937. }
  938. //----------------------------------------------------------------------------
  939. void cmDocumentation::SetSection(const char *name,
  940. const char *docs[][3])
  941. {
  942. cmDocumentationSection *sec =
  943. new cmDocumentationSection(name,
  944. cmSystemTools::UpperCase(name).c_str());
  945. sec->Append(docs);
  946. this->SetSection(name,sec);
  947. }
  948. //----------------------------------------------------------------------------
  949. void cmDocumentation
  950. ::SetSections(std::map<std::string,cmDocumentationSection *> &sections)
  951. {
  952. for (std::map<std::string,cmDocumentationSection *>::const_iterator
  953. it = sections.begin(); it != sections.end(); ++it)
  954. {
  955. this->SetSection(it->first.c_str(),it->second);
  956. }
  957. }
  958. //----------------------------------------------------------------------------
  959. void cmDocumentation::PrependSection(const char *name,
  960. const char *docs[][3])
  961. {
  962. cmDocumentationSection *sec = 0;
  963. if (this->AllSections.find(name) == this->AllSections.end())
  964. {
  965. sec = new cmDocumentationSection
  966. (name, cmSystemTools::UpperCase(name).c_str());
  967. this->SetSection(name,sec);
  968. }
  969. else
  970. {
  971. sec = this->AllSections[name];
  972. }
  973. sec->Prepend(docs);
  974. }
  975. //----------------------------------------------------------------------------
  976. void cmDocumentation::PrependSection(const char *name,
  977. std::vector<cmDocumentationEntry> &docs)
  978. {
  979. cmDocumentationSection *sec = 0;
  980. if (this->AllSections.find(name) == this->AllSections.end())
  981. {
  982. sec = new cmDocumentationSection
  983. (name, cmSystemTools::UpperCase(name).c_str());
  984. this->SetSection(name,sec);
  985. }
  986. else
  987. {
  988. sec = this->AllSections[name];
  989. }
  990. sec->Prepend(docs);
  991. }
  992. //----------------------------------------------------------------------------
  993. void cmDocumentation::AppendSection(const char *name,
  994. const char *docs[][3])
  995. {
  996. cmDocumentationSection *sec = 0;
  997. if (this->AllSections.find(name) == this->AllSections.end())
  998. {
  999. sec = new cmDocumentationSection
  1000. (name, cmSystemTools::UpperCase(name).c_str());
  1001. this->SetSection(name,sec);
  1002. }
  1003. else
  1004. {
  1005. sec = this->AllSections[name];
  1006. }
  1007. sec->Append(docs);
  1008. }
  1009. //----------------------------------------------------------------------------
  1010. void cmDocumentation::AppendSection(const char *name,
  1011. std::vector<cmDocumentationEntry> &docs)
  1012. {
  1013. cmDocumentationSection *sec = 0;
  1014. if (this->AllSections.find(name) == this->AllSections.end())
  1015. {
  1016. sec = new cmDocumentationSection
  1017. (name, cmSystemTools::UpperCase(name).c_str());
  1018. this->SetSection(name,sec);
  1019. }
  1020. else
  1021. {
  1022. sec = this->AllSections[name];
  1023. }
  1024. sec->Append(docs);
  1025. }
  1026. //----------------------------------------------------------------------------
  1027. void cmDocumentation::AppendSection(const char *name,
  1028. cmDocumentationEntry &docs)
  1029. {
  1030. std::vector<cmDocumentationEntry> docsVec;
  1031. docsVec.push_back(docs);
  1032. this->AppendSection(name,docsVec);
  1033. }
  1034. //----------------------------------------------------------------------------
  1035. void cmDocumentation::PrependSection(const char *name,
  1036. cmDocumentationEntry &docs)
  1037. {
  1038. std::vector<cmDocumentationEntry> docsVec;
  1039. docsVec.push_back(docs);
  1040. this->PrependSection(name,docsVec);
  1041. }
  1042. //----------------------------------------------------------------------------
  1043. void cmDocumentation::SetSeeAlsoList(const char *data[][3])
  1044. {
  1045. cmDocumentationSection *sec =
  1046. new cmDocumentationSection("See Also", "SEE ALSO");
  1047. this->AllSections["See Also"] = sec;
  1048. this->SeeAlsoString = ".B ";
  1049. int i = 0;
  1050. while(data[i][1])
  1051. {
  1052. this->SeeAlsoString += data[i][1];
  1053. this->SeeAlsoString += data[i+1][1]? "(1), ":"(1)";
  1054. ++i;
  1055. }
  1056. sec->Append(0,this->SeeAlsoString.c_str(),0);
  1057. sec->Append(cmDocumentationStandardSeeAlso);
  1058. }
  1059. //----------------------------------------------------------------------------
  1060. bool cmDocumentation::PrintDocumentationGeneric(std::ostream& os,
  1061. const char *section)
  1062. {
  1063. if(this->AllSections.find(section) == this->AllSections.end())
  1064. {
  1065. os << "Internal error: " << section << " list is empty." << std::endl;
  1066. return false;
  1067. }
  1068. if(this->CurrentArgument.length() == 0)
  1069. {
  1070. os << "Required argument missing.\n";
  1071. return false;
  1072. }
  1073. const std::vector<cmDocumentationEntry> &entries =
  1074. this->AllSections[section]->GetEntries();
  1075. for(std::vector<cmDocumentationEntry>::const_iterator ei =
  1076. entries.begin();
  1077. ei != entries.end(); ++ei)
  1078. {
  1079. if(this->CurrentArgument == ei->Name)
  1080. {
  1081. this->PrintDocumentationCommand(os, *ei);
  1082. return true;
  1083. }
  1084. }
  1085. return false;
  1086. }
  1087. //----------------------------------------------------------------------------
  1088. bool cmDocumentation::PrintDocumentationSingle(std::ostream& os)
  1089. {
  1090. if (this->PrintDocumentationGeneric(os,"Commands"))
  1091. {
  1092. return true;
  1093. }
  1094. if (this->PrintDocumentationGeneric(os,"Compatibility Commands"))
  1095. {
  1096. return true;
  1097. }
  1098. // Argument was not a command. Complain.
  1099. os << "Argument \"" << this->CurrentArgument.c_str()
  1100. << "\" to --help-command is not a CMake command. "
  1101. << "Use --help-command-list to see all commands.\n";
  1102. return false;
  1103. }
  1104. //----------------------------------------------------------------------------
  1105. bool cmDocumentation::PrintDocumentationSingleModule(std::ostream& os)
  1106. {
  1107. if(this->CurrentArgument.length() == 0)
  1108. {
  1109. os << "Argument --help-module needs a module name.\n";
  1110. return false;
  1111. }
  1112. std::string moduleName;
  1113. // find the module
  1114. std::vector<std::string> dirs;
  1115. cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
  1116. for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
  1117. dirIt != dirs.end();
  1118. ++dirIt)
  1119. {
  1120. moduleName = *dirIt;
  1121. moduleName += "/";
  1122. moduleName += this->CurrentArgument;
  1123. moduleName += ".cmake";
  1124. if(cmSystemTools::FileExists(moduleName.c_str()))
  1125. {
  1126. break;
  1127. }
  1128. moduleName = "";
  1129. }
  1130. if (moduleName.empty())
  1131. {
  1132. moduleName = this->CMakeRoot;
  1133. moduleName += "/Modules/";
  1134. moduleName += this->CurrentArgument;
  1135. moduleName += ".cmake";
  1136. if(!cmSystemTools::FileExists(moduleName.c_str()))
  1137. {
  1138. moduleName = "";
  1139. }
  1140. }
  1141. if(!moduleName.empty())
  1142. {
  1143. cmDocumentationSection *sec =
  1144. new cmDocumentationSection("Standard CMake Modules", "MODULES");
  1145. this->AllSections["Modules"] = sec;
  1146. if (this->CreateSingleModule(moduleName.c_str(),
  1147. this->CurrentArgument.c_str(),
  1148. *this->AllSections["Modules"]))
  1149. {
  1150. if(this->AllSections["Modules"]->GetEntries().size())
  1151. {
  1152. this->PrintDocumentationCommand
  1153. (os, this->AllSections["Modules"]->GetEntries()[0]);
  1154. os << "\n Defined in: ";
  1155. os << moduleName << "\n";
  1156. return true;
  1157. }
  1158. else
  1159. {
  1160. return false;
  1161. }
  1162. }
  1163. }
  1164. // Argument was not a module. Complain.
  1165. os << "Argument \"" << this->CurrentArgument.c_str()
  1166. << "\" to --help-module is not a CMake module.\n";
  1167. return false;
  1168. }
  1169. //----------------------------------------------------------------------------
  1170. bool cmDocumentation::PrintDocumentationSingleProperty(std::ostream& os)
  1171. {
  1172. bool done = false;
  1173. for (std::vector<std::string>::iterator i =
  1174. this->PropertySections.begin();
  1175. !done && i != this->PropertySections.end(); ++i)
  1176. {
  1177. done = this->PrintDocumentationGeneric(os,i->c_str());
  1178. }
  1179. if (done)
  1180. {
  1181. return true;
  1182. }
  1183. // Argument was not a command. Complain.
  1184. os << "Argument \"" << this->CurrentArgument.c_str()
  1185. << "\" to --help-property is not a CMake property. "
  1186. << "Use --help-property-list to see all properties.\n";
  1187. return false;
  1188. }
  1189. //----------------------------------------------------------------------------
  1190. bool cmDocumentation::PrintDocumentationSinglePolicy(std::ostream& os)
  1191. {
  1192. if (this->PrintDocumentationGeneric(os,"Policies"))
  1193. {
  1194. return true;
  1195. }
  1196. // Argument was not a policy. Complain.
  1197. os << "Argument \"" << this->CurrentArgument.c_str()
  1198. << "\" to --help-policy is not a CMake policy.\n";
  1199. return false;
  1200. }
  1201. //----------------------------------------------------------------------------
  1202. bool cmDocumentation::PrintDocumentationSingleVariable(std::ostream& os)
  1203. {
  1204. bool done = false;
  1205. for (std::vector<std::string>::iterator i =
  1206. this->VariableSections.begin();
  1207. !done && i != this->VariableSections.end(); ++i)
  1208. {
  1209. done = this->PrintDocumentationGeneric(os,i->c_str());
  1210. }
  1211. if (done)
  1212. {
  1213. return true;
  1214. }
  1215. // Argument was not a variable. Complain.
  1216. os << "Argument \"" << this->CurrentArgument.c_str()
  1217. << "\" to --help-variable is not a defined variable. "
  1218. << "Use --help-variable-list to see all defined variables.\n";
  1219. return false;
  1220. }
  1221. //----------------------------------------------------------------------------
  1222. bool cmDocumentation::PrintDocumentationList(std::ostream& os,
  1223. const char *section)
  1224. {
  1225. if(this->AllSections.find(section) == this->AllSections.end())
  1226. {
  1227. os << "Internal error: " << section << " list is empty." << std::endl;
  1228. return false;
  1229. }
  1230. const std::vector<cmDocumentationEntry> &entries =
  1231. this->AllSections[section]->GetEntries();
  1232. for(std::vector<cmDocumentationEntry>::const_iterator ei =
  1233. entries.begin();
  1234. ei != entries.end(); ++ei)
  1235. {
  1236. if(ei->Name.size())
  1237. {
  1238. os << ei->Name << std::endl;
  1239. }
  1240. }
  1241. return true;
  1242. }
  1243. //----------------------------------------------------------------------------
  1244. bool cmDocumentation::PrintDocumentationUsage(std::ostream& os)
  1245. {
  1246. this->ClearSections();
  1247. this->AddSectionToPrint("Usage");
  1248. this->AddSectionToPrint("Options");
  1249. if(this->ShowGenerators)
  1250. {
  1251. this->AddSectionToPrint("Generators");
  1252. }
  1253. this->Print(os);
  1254. return true;
  1255. }
  1256. //----------------------------------------------------------------------------
  1257. bool cmDocumentation::PrintDocumentationFull(std::ostream& os)
  1258. {
  1259. this->CreateFullDocumentation();
  1260. this->CurrentFormatter->PrintHeader(GetNameString(), GetNameString(), os);
  1261. this->Print(os);
  1262. this->CurrentFormatter->PrintFooter(os);
  1263. return true;
  1264. }
  1265. //----------------------------------------------------------------------------
  1266. bool cmDocumentation::PrintDocumentationModules(std::ostream& os)
  1267. {
  1268. this->ClearSections();
  1269. this->CreateModulesSection();
  1270. this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Modules));
  1271. this->AddSectionToPrint("Description");
  1272. this->AddSectionToPrint("Modules");
  1273. this->AddSectionToPrint("Copyright");
  1274. this->AddSectionToPrint("See Also");
  1275. this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  1276. this->Print(os);
  1277. this->CurrentFormatter->PrintFooter(os);
  1278. return true;
  1279. }
  1280. //----------------------------------------------------------------------------
  1281. bool cmDocumentation::PrintDocumentationCustomModules(std::ostream& os)
  1282. {
  1283. this->ClearSections();
  1284. this->CreateCustomModulesSection();
  1285. this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(CustomModules));
  1286. this->AddSectionToPrint("Description");
  1287. this->AddSectionToPrint("Custom CMake Modules");
  1288. // the custom modules are most probably not under Kitware's copyright, Alex
  1289. // this->AddSectionToPrint("Copyright");
  1290. this->AddSectionToPrint("See Also");
  1291. this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  1292. this->Print(os);
  1293. this->CurrentFormatter->PrintFooter(os);
  1294. return true;
  1295. }
  1296. //----------------------------------------------------------------------------
  1297. bool cmDocumentation::PrintDocumentationPolicies(std::ostream& os)
  1298. {
  1299. this->ClearSections();
  1300. this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Policies));
  1301. this->AddSectionToPrint("Description");
  1302. this->AddSectionToPrint("Policies");
  1303. this->AddSectionToPrint("Copyright");
  1304. this->AddSectionToPrint("See Also");
  1305. this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  1306. this->Print(os);
  1307. this->CurrentFormatter->PrintFooter(os);
  1308. return true;
  1309. }
  1310. //----------------------------------------------------------------------------
  1311. bool cmDocumentation::PrintDocumentationProperties(std::ostream& os)
  1312. {
  1313. this->ClearSections();
  1314. this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Properties));
  1315. this->AddSectionToPrint("Properties Description");
  1316. for (std::vector<std::string>::iterator i =
  1317. this->PropertySections.begin();
  1318. i != this->PropertySections.end(); ++i)
  1319. {
  1320. this->AddSectionToPrint(i->c_str());
  1321. }
  1322. this->AddSectionToPrint("Copyright");
  1323. this->AddSectionToPrint("Standard See Also");
  1324. this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  1325. this->Print(os);
  1326. this->CurrentFormatter->PrintFooter(os);
  1327. return true;
  1328. }
  1329. //----------------------------------------------------------------------------
  1330. bool cmDocumentation::PrintDocumentationVariables(std::ostream& os)
  1331. {
  1332. this->ClearSections();
  1333. this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Variables));
  1334. for (std::vector<std::string>::iterator i =
  1335. this->VariableSections.begin();
  1336. i != this->VariableSections.end(); ++i)
  1337. {
  1338. this->AddSectionToPrint(i->c_str());
  1339. }
  1340. this->AddSectionToPrint("Copyright");
  1341. this->AddSectionToPrint("Standard See Also");
  1342. this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  1343. this->Print(os);
  1344. this->CurrentFormatter->PrintFooter(os);
  1345. return true;
  1346. }
  1347. //----------------------------------------------------------------------------
  1348. bool cmDocumentation::PrintDocumentationCurrentCommands(std::ostream& os)
  1349. {
  1350. this->ClearSections();
  1351. this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Commands));
  1352. this->AddSectionToPrint("Commands");
  1353. this->AddSectionToPrint("Copyright");
  1354. this->AddSectionToPrint("Standard See Also");
  1355. this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  1356. this->Print(os);
  1357. this->CurrentFormatter->PrintFooter(os);
  1358. return true;
  1359. }
  1360. //----------------------------------------------------------------------------
  1361. bool cmDocumentation::PrintDocumentationCompatCommands(std::ostream& os)
  1362. {
  1363. this->ClearSections();
  1364. this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(CompatCommands));
  1365. this->AddSectionToPrint("Compatibility Commands Description");
  1366. this->AddSectionToPrint("Compatibility Commands");
  1367. this->AddSectionToPrint("Copyright");
  1368. this->AddSectionToPrint("Standard See Also");
  1369. this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
  1370. this->Print(os);
  1371. this->CurrentFormatter->PrintFooter(os);
  1372. return true;
  1373. }
  1374. //----------------------------------------------------------------------------
  1375. void cmDocumentation
  1376. ::PrintDocumentationCommand(std::ostream& os,
  1377. const cmDocumentationEntry &entry)
  1378. {
  1379. // the string "SingleItem" will be used in a few places to detect the case
  1380. // that only the documentation for a single item is printed
  1381. cmDocumentationSection *sec = new cmDocumentationSection("SingleItem","");
  1382. sec->Append(entry);
  1383. this->AllSections["temp"] = sec;
  1384. this->ClearSections();
  1385. this->AddSectionToPrint("temp");
  1386. this->Print(os);
  1387. this->AllSections.erase("temp");
  1388. delete sec;
  1389. }
  1390. //----------------------------------------------------------------------------
  1391. void cmDocumentation::CreateFullDocumentation()
  1392. {
  1393. this->ClearSections();
  1394. this->CreateCustomModulesSection();
  1395. this->CreateModulesSection();
  1396. std::set<std::string> emitted;
  1397. this->AddSectionToPrint("Name");
  1398. emitted.insert("Name");
  1399. this->AddSectionToPrint("Usage");
  1400. emitted.insert("Usage");
  1401. this->AddSectionToPrint("Description");
  1402. emitted.insert("Description");
  1403. this->AddSectionToPrint("Options");
  1404. emitted.insert("Options");
  1405. this->AddSectionToPrint("Generators");
  1406. emitted.insert("Generators");
  1407. this->AddSectionToPrint("Commands");
  1408. emitted.insert("Commands");
  1409. this->AddSectionToPrint("Properties Description");
  1410. emitted.insert("Properties Description");
  1411. for (std::vector<std::string>::iterator i =
  1412. this->PropertySections.begin();
  1413. i != this->PropertySections.end(); ++i)
  1414. {
  1415. this->AddSectionToPrint(i->c_str());
  1416. emitted.insert(i->c_str());
  1417. }
  1418. emitted.insert("Copyright");
  1419. emitted.insert("See Also");
  1420. emitted.insert("Standard See Also");
  1421. emitted.insert("Author");
  1422. // add any sections not yet written out, or to be written out
  1423. for (std::map<std::string, cmDocumentationSection*>::iterator i =
  1424. this->AllSections.begin();
  1425. i != this->AllSections.end(); ++i)
  1426. {
  1427. if (emitted.find(i->first) == emitted.end())
  1428. {
  1429. this->AddSectionToPrint(i->first.c_str());
  1430. }
  1431. }
  1432. this->AddSectionToPrint("Copyright");
  1433. if(this->CurrentFormatter->GetForm() == ManForm)
  1434. {
  1435. this->AddSectionToPrint("See Also");
  1436. this->AddSectionToPrint("Author");
  1437. }
  1438. else
  1439. {
  1440. this->AddSectionToPrint("Standard See Also");
  1441. }
  1442. }
  1443. //----------------------------------------------------------------------------
  1444. void cmDocumentation::SetForm(Form f, int manSection)
  1445. {
  1446. switch(f)
  1447. {
  1448. case HTMLForm:
  1449. this->CurrentFormatter = &this->HTMLFormatter;
  1450. break;
  1451. case DocbookForm:
  1452. this->CurrentFormatter = &this->DocbookFormatter;
  1453. break;
  1454. case ManForm:
  1455. this->ManFormatter.SetManSection(manSection);
  1456. this->CurrentFormatter = &this->ManFormatter;
  1457. break;
  1458. case TextForm:
  1459. this->CurrentFormatter = &this->TextFormatter;
  1460. break;
  1461. case UsageForm:
  1462. this->CurrentFormatter = & this->UsageFormatter;
  1463. break;
  1464. }
  1465. }
  1466. //----------------------------------------------------------------------------
  1467. const char* cmDocumentation::GetNameString() const
  1468. {
  1469. if(this->NameString.length() > 0)
  1470. {
  1471. return this->NameString.c_str();
  1472. }
  1473. else
  1474. {
  1475. return "CMake";
  1476. }
  1477. }
  1478. //----------------------------------------------------------------------------
  1479. const char* cmDocumentation::GetDocName(bool fallbackToNameString) const
  1480. {
  1481. if (this->DocName.length() > 0)
  1482. {
  1483. return this->DocName.c_str();
  1484. }
  1485. else if (fallbackToNameString)
  1486. {
  1487. return this->GetNameString();
  1488. }
  1489. else
  1490. return 0;
  1491. }
  1492. //----------------------------------------------------------------------------
  1493. #define CASE_DEFAULT_DOCNAME(doctype) \
  1494. case cmDocumentation::doctype : \
  1495. return GET_DOCUMENT_INTRO(doctype)[0];
  1496. const char* cmDocumentation::GetDefaultDocName(Type ht) const
  1497. {
  1498. switch (ht)
  1499. {
  1500. CASE_DEFAULT_DOCNAME(Modules)
  1501. CASE_DEFAULT_DOCNAME(CustomModules)
  1502. CASE_DEFAULT_DOCNAME(Policies)
  1503. CASE_DEFAULT_DOCNAME(Properties)
  1504. CASE_DEFAULT_DOCNAME(Variables)
  1505. CASE_DEFAULT_DOCNAME(Commands)
  1506. CASE_DEFAULT_DOCNAME(CompatCommands)
  1507. default: break;
  1508. }
  1509. return 0;
  1510. }
  1511. //----------------------------------------------------------------------------
  1512. bool cmDocumentation::IsOption(const char* arg) const
  1513. {
  1514. return ((arg[0] == '-') || (strcmp(arg, "/V") == 0) ||
  1515. (strcmp(arg, "/?") == 0));
  1516. }