argListHelp.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2018 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "argList.H"
29 #include "foamVersion.H"
30 #include "stringOps.H"
31 #include "IOmanip.H"
32 
33 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37 
38 // Convert api number (YYMM) -> 20YY. Eg, 1906 -> 2019
39 static inline int apiYear()
40 {
41  return 2000 + (foamVersion::api / 100);
42 }
43 
44 // manpage Footer
45 static inline void printManFooter()
46 {
47  Info<< ".SH \"SEE ALSO\"" << nl
48  << "Online documentation "
49  << "https://www.openfoam.com/documentation/" << nl
50  << ".SH COPYRIGHT" << nl
51  << "Copyright \\(co 2018-" << apiYear() << " OpenCFD Ltd." << nl;
52 }
53 
54 
55 // Regular option
56 static void printManOption(const word& optName)
57 {
58  Info<< ".TP\n\\fB\\-" << optName << "\\fR";
59 
60  // Option has arg?
61  const auto optIter = argList::validOptions.cfind(optName);
62 
63  if (optIter.found() && optIter().size())
64  {
65  Info<< " \\fI" << optIter().c_str() << "\\fR";
66  }
67  Info<< nl;
68 
69  // Option has usage information?
70 
71  const auto usageIter = argList::optionUsage.cfind(optName);
72  if (usageIter.found())
73  {
74  stringOps::writeWrapped(Info, *usageIter, argList::usageMax, 0, true);
75  }
76  else
77  {
78  Info<< nl;
79  }
80  if (argList::validParOptions.found(optName))
81  {
82  Info<< "\\fB[Parallel option]\\fR" << nl;
83  }
84 }
85 
86 
87 // Simple, hard-coded option
88 static inline void printManOption(const char* optName, const char* optUsage)
89 {
90  Info<< ".TP\n\\fB\\-" << optName << "\\fR" << nl
91  << optUsage << nl;
92 }
93 
94 
95 static void printOptionUsage
96 (
98  const string& str
99 )
100 {
101  if (str.empty())
102  {
103  Info<< nl;
104  return;
105  }
106 
107  // Indent the first line. Min 2 spaces between option and usage
108  if (start + 2 > argList::usageMin)
109  {
110  Info<< nl;
111  start = 0;
112  }
113  while (start < argList::usageMin)
114  {
115  Info<<' ';
116  ++start;
117  }
118 
120  (
121  Info,
122  str,
125  );
126 }
127 
128 
129 // Regular option
130 static void printOption(const word& optName)
131 {
132  Info<< " -" << optName;
133 
134  // Length includes leading ' -'
135  label len = optName.size() + 3;
136 
137  const auto optIter = argList::validOptions.cfind(optName);
138  if (optIter.found() && optIter().size())
139  {
140  // Length includes space between option/param and '<>'
141  len += optIter().size() + 3;
142  Info<< " <" << optIter().c_str() << '>';
143  }
144 
145  const auto usageIter = argList::optionUsage.cfind(optName);
146  if (usageIter.found())
147  {
148  printOptionUsage(len, usageIter());
149  }
150  else
151  {
152  Info<< nl;
153  }
154 }
155 
156 
157 // Simple, hard-coded option
158 static inline void printOption(const char* optName, const char* optUsage)
159 {
160  Info<< " -" << optName;
161  printOptionUsage(3 + strlen(optName), optUsage);
162 }
163 
164 } // End namespace Foam
165 
166 
167 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
168 
170 {
171  // .TH "<APPLICATION>" 1 "OpenFOAM-<version>" "source" "category"
172 
173  Info<< ".TH" << token::SPACE
174  // All uppercase (returns a Foam::string) and thus also quoted
175  << stringOps::upper(executable_) << token::SPACE
176  << 1 << token::SPACE
177  << token::DQUOTE << "OpenFOAM-v" << foamVersion::api << token::DQUOTE
178  << token::SPACE
179  << token::DQUOTE << "www.openfoam.com" << token::DQUOTE
180  << token::SPACE
181  << token::DQUOTE << "OpenFOAM Commands Manual" << token::DQUOTE
182  << nl;
183 
184 
185  // .SH NAME
186  // <application> \- part of OpenFOAM (The Open Source CFD Toolbox).
187  Info<< ".SH \"NAME\"" << nl
188  << executable_
189  << " \\- part of \\fBOpenFOAM\\fR (The Open Source CFD Toolbox)."
190  << nl;
191 
192 
193  // .SH SYNOPSIS
194  // .B command [OPTIONS] ...
195 
196  Info<< ".SH \"SYNOPSIS\"" << nl
197  << "\\fB" << executable_ << "\\fR [\\fIOPTIONS\\fR]";
198 
199  if (validArgs.size())
200  {
201  Info<< ' ';
202 
203  if (!argsMandatory_)
204  {
205  Info<< '[';
206  }
207 
208  label i = 0;
209  for (const std::string& argName : validArgs)
210  {
211  if (i++) Info<< ' ';
212  Info << "\\fI" << argName.c_str() << "\\fR";
213  }
214 
215  if (!argsMandatory_)
216  {
217  Info<< ']';
218  }
219  }
220  Info<< nl;
221 
222 
223  // .SH DESCRIPTION
224  {
225  Info<< ".SH \"DESCRIPTION\"" << nl;
226 
227  Info<< ".nf" << nl; // No fill lines
228 
229  if (notes.empty())
230  {
231  Info<< "No description available\n";
232  }
233  else
234  {
235  for (const std::string& note : notes)
236  {
237  if (note.empty())
238  {
239  Info<< nl;
240  }
241  else
242  {
243  stringOps::writeWrapped(Info, note, usageMax, 0, true);
244  }
245  }
246  }
247  Info<< ".fi" << nl; // Fill lines
248  }
249 
250 
251  // Arguments output
252  if (validArgs.size())
253  {
254  // .SH "ARGUMENTS"
255  Info<< ".SH \"ARGUMENTS\"" << nl;
256 
257  label argIndex = 0;
258  for (const std::string& argName : validArgs)
259  {
260  ++argIndex;
261 
262  Info<< ".TP\n\\fI" << argName.c_str() << "\\fR";
263  Info<< nl;
264 
265  // Arg has usage information?
266 
267  const auto usageIter = argList::argUsage.cfind(argIndex);
268  if (usageIter.found())
269  {
270  stringOps::writeWrapped(Info, *usageIter, usageMax, 0, true);
271  }
272  else
273  {
274  Info<< nl;
275  }
276  }
277  }
278 
279 
280  // .SH "OPTIONS"
281  Info<< ".SH \"OPTIONS\"" << nl;
282 
283  for (const word& optName : validOptions.sortedToc())
284  {
285  // Normal (non-advanced) options
286  if (!advancedOptions.found(optName))
287  {
288  printManOption(optName);
289  }
290  }
291 
292  // Standard documentation/help options
293 
294  printManOption("doc", "Display documentation in browser");
295  printManOption("help", "Display short help and exit");
296  printManOption("help-full", "Display full help and exit");
297 
298 
299  // .SS "ADVANCED OPTIONS"
300  Info<< ".SS \"ADVANCED OPTIONS\"" << nl;
301 
302  for (const word& optName : validOptions.sortedToc())
303  {
304  // Advanced options
305  if (advancedOptions.found(optName))
306  {
307  printManOption(optName);
308  }
309  }
310 
311  printManOption("doc-source", "Display source code in browser");
312 
313 
314  const bool hasCompat =
315  (
318  );
319 
320  if (hasCompat)
321  {
322  printManOption("help-compat", "Display compatibility options and exit");
323  }
324 
325  printManOption("help-man", "Display full help (manpage format) and exit");
326  printManOption("help-notes", "Display help notes (description) and exit");
327 
328  printManCompat();
329 
330  // Footer
331  printManFooter();
332 }
333 
334 
335 void Foam::argList::printUsage(bool full) const
336 {
337  Info<< "\nUsage: " << executable_ << " [OPTIONS]";
338 
339  if (validArgs.size())
340  {
341  Info<< ' ';
342 
343  if (!argsMandatory_)
344  {
345  Info<< '[';
346  }
347 
348  label i = 0;
349  for (const std::string& argName : validArgs)
350  {
351  if (i++) Info<< ' ';
352  Info<< '<' << argName.c_str() << '>';
353  }
354 
355  if (!argsMandatory_)
356  {
357  Info<< ']';
358  }
359  }
360  Info<< nl;
361 
362  // Arguments output
363  // Currently only if there is also usage information, but may wish to
364  // change this to remind developers to add some description.
365  if (validArgs.size() && argUsage.size())
366  {
367  Info<< "Arguments:\n";
368 
369  label argIndex = 0;
370  for (const std::string& argName : validArgs)
371  {
372  ++argIndex;
373 
374  Info<< " <" << argName.c_str() << '>';
375 
376  const auto usageIter = argList::argUsage.cfind(argIndex);
377  if (usageIter.found())
378  {
379  const label len = argName.size() + 4;
380 
381  printOptionUsage(len, usageIter());
382  }
383  else
384  {
385  Info<< nl;
386  }
387  }
388  }
389 
390  Info<< "Options:\n";
391 
392  for (const word& optName : validOptions.sortedToc())
393  {
394  // Suppress advanced options for regular -help.
395  if (full || !advancedOptions.found(optName))
396  {
397  printOption(optName);
398  }
399  }
400 
401 
402  // Place documentation/help options at the end
403 
404  printOption("doc", "Display documentation in browser");
405  if (full)
406  {
407  printOption("doc-source", "Display source code in browser");
408  }
409  printOption("help", "Display short help and exit");
410 
411  if
412  (
415  )
416  {
417  printOption("help-compat", "Display compatibility options and exit");
418  }
419 
420  if (full)
421  {
422  printOption("help-man", "Display full help (manpage format) and exit");
423  printOption("help-notes", "Display help notes (description) and exit");
424  }
425 
426  printOption("help-full", "Display full help and exit");
427 
428  printNotes();
429 
430  Info<< nl;
432  Info<< endl;
433 }
434 
435 
437 {
438  // Output notes with automatic text wrapping
439  if (!notes.empty())
440  {
441  Info<< nl;
442 
443  for (const std::string& note : notes)
444  {
445  if (note.empty())
446  {
447  Info<< nl;
448  }
449  else
450  {
451  stringOps::writeWrapped(Info, note, usageMax);
452  }
453  }
454  }
455 }
456 
457 
458 void Foam::argList::printManCompat() const
459 {
460  if
461  (
464  )
465  {
466  return;
467  }
468 
469 
470  // .SS "COMPATIBILITY OPTIONS"
471  Info<< ".SS \"COMPATIBILITY OPTIONS\"" << nl;
472 
473  for (const word& k : argList::validOptionsCompat.sortedToc())
474  {
475  const auto& iter = *argList::validOptionsCompat.cfind(k);
476 
477  const word& optName = iter.first;
478  const int until = abs(iter.second);
479 
480  Info<< ".TP\n\\fB\\-" << k
481  << "\\fR (now \\fB\\-" << optName << "\\fR)" << nl;
482 
483  if (until)
484  {
485  Info<< "The option was last used in " << until << "." << nl;
486  }
487  }
488 
489  for (const word& k : argList::ignoreOptionsCompat.sortedToc())
490  {
491  const auto& iter = *argList::ignoreOptionsCompat.cfind(k);
492 
493  const bool hasArg = iter.first;
494  const int until = abs(iter.second);
495 
496  Info<< ".TP\n\\fB\\-" << k << "\\fR";
497 
498  if (hasArg)
499  {
500  Info<< " \\fIarg\\fR";
501  }
502 
503  Info<< nl << "This option is ignored";
504 
505  if (until)
506  {
507  Info<< " after " << until << ".";
508  }
509  Info<< nl;
510  }
511 }
512 
513 
515 {
516  const label nopt
517  (
520  );
521 
522  Info<< nopt << " compatibility options for " << executable_ << nl;
523 
524  if (!nopt)
525  {
526  return;
527  }
528 
529  const int col1(32), col2(32);
530 
531  Info<< nl
532  << "|" << setf(ios_base::left) << setw(col1) << " Old option"
533  << "|" << setf(ios_base::left) << setw(col2) << " New option"
534  << "| Comment" << nl;
535 
536  Info<< setfill('-');
537  Info<< "|" << setf(ios_base::left) << setw(col1) << ""
538  << "|" << setf(ios_base::left) << setw(col2) << ""
539  << "|------------" << nl;
540 
542 
543  for (const word& k : argList::validOptionsCompat.sortedToc())
544  {
545  const auto& iter = *argList::validOptionsCompat.cfind(k);
546 
547  const word& optName = iter.first;
548  const int until = abs(iter.second);
549 
550  Info<< "| -" << setf(ios_base::left) << setw(col1-2) << k
551  << "| -" << setf(ios_base::left) << setw(col2-2) << optName
552  << "|";
553 
554  if (until)
555  {
556  Info<< " until " << until;
557  }
558  Info<< nl;
559  }
560 
561  for (const word& k : argList::ignoreOptionsCompat.sortedToc())
562  {
563  const auto& iter = *argList::ignoreOptionsCompat.cfind(k);
564 
565  const bool hasArg = iter.first;
566  const int until = abs(iter.second);
567 
568  Info<< "| -" << setf(ios_base::left) << setw(col1-2);
569 
570  if (hasArg)
571  {
572  Info<< (k + " <arg>").c_str();
573  }
574  else
575  {
576  Info<< k;
577  }
578 
579  Info<< "| ";
580  Info<< setf(ios_base::left) << setw(col2-1) << "ignored" << "|";
581  if (until)
582  {
583  Info<< " after " << until;
584  }
585  Info<< nl;
586  }
587 
588  Info<< setfill('-');
589  Info<< "|" << setf(ios_base::left) << setw(col1) << ""
590  << "|" << setf(ios_base::left) << setw(col2) << ""
591  << "|------------" << nl;
592 
594 }
595 
596 
597 // ************************************************************************* //
Foam::argList::validArgs
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:201
Foam::setf
Smanip< ios_base::fmtflags > setf(const ios_base::fmtflags flags)
Definition: IOmanip.H:169
Foam::argList::printMan
void printMan() const
Print usage as nroff-man format (Experimental)
Definition: argListHelp.C:169
Foam::argList::usageMin
static std::string::size_type usageMin
Min indentation when displaying usage (default: 20)
Definition: argList.H:230
Foam::apiYear
static int apiYear()
Definition: argListHelp.C:39
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::argList::usageMax
static std::string::size_type usageMax
Max screen width when displaying usage (default: 80)
Definition: argList.H:233
Foam::argList::validOptionsCompat
static HashTable< std::pair< word, int > > validOptionsCompat
A list of aliases for options.
Definition: argList.H:214
Foam::stringOps::writeWrapped
void writeWrapped(OSstream &os, const std::string &str, const std::string::size_type width, const std::string::size_type indent=0, const bool escape=false)
Output string with text wrapping.
Definition: stringOps.C:1240
Foam::argList::optionUsage
static HashTable< string > optionUsage
Short description for validOptions.
Definition: argList.H:224
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::argList::printCompat
void printCompat() const
Print option compatibility.
Definition: argListHelp.C:514
Foam::argList::validParOptions
static HashTable< string > validParOptions
A list of valid parallel options.
Definition: argList.H:210
Foam::argList::printNotes
void printNotes() const
Print notes (if any)
Definition: argListHelp.C:436
Foam::foamVersion::api
const int api
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::token::DQUOTE
Double quote.
Definition: token.H:129
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
argList.H
Foam::stringOps::upper
string upper(const std::string &str)
Return string transformed with std::toupper on each character.
Definition: stringOps.C:1219
IOmanip.H
Istream and Ostream manipulators taking arguments.
size_type
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:75
Foam::argList::validOptions
static HashTable< string > validOptions
A list of valid options.
Definition: argList.H:207
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::setw
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Foam::printOption
static void printOption(const word &optName)
Definition: argListHelp.C:130
found
bool found
Definition: TABSMDCalcMethod2.H:32
Foam::argList::advancedOptions
static HashSet< string > advancedOptions
The "advanced" options are shown with -help-full (not with –help)
Definition: argList.H:204
Foam::printOptionUsage
static void printOptionUsage(std::string::size_type start, const string &str)
Definition: argListHelp.C:96
Foam::HashTable::cfind
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
Definition: HashTableI.H:141
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::printManFooter
static void printManFooter()
Definition: argListHelp.C:45
Foam::setfill
Omanip< char > setfill(char fillch)
Definition: IOmanip.H:175
Foam::start
label ListType::const_reference const label start
Definition: ListOps.H:408
Foam::token::SPACE
Space [isspace].
Definition: token.H:112
k
label k
Boltzmann constant.
Definition: LISASMDCalcMethod2.H:41
Foam::foamVersion::printBuildInfo
void printBuildInfo(const bool full=true)
Print information about version, build, arch to Info.
Definition: foamVersion.C:46
Foam::argList::notes
static SLList< string > notes
General usage notes.
Definition: argList.H:227
Foam::HashTable::empty
bool empty() const noexcept
True if the hash table is empty.
Definition: HashTableI.H:59
Foam::argList::ignoreOptionsCompat
static HashTable< std::pair< bool, int > > ignoreOptionsCompat
A list of options to ignore.
Definition: argList.H:218
Foam::argList::argUsage
static HashTable< string, label, Hash< label > > argUsage
Short description for program arguments.
Definition: argList.H:221
Foam::printManOption
static void printManOption(const word &optName)
Definition: argListHelp.C:56
stringOps.H
Foam::argList::printUsage
void printUsage(bool full=true) const
Print usage.
Definition: argListHelp.C:335
foamVersion.H