mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
- restrict to text between "^[Oo]ptions:" and "-help-full" to avoid potential issues when more text is introduced in the usage output.
527 lines
12 KiB
C
527 lines
12 KiB
C
/*---------------------------------------------------------------------------*\
|
|
========= |
|
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
\\ / O peration |
|
|
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
|
|
\\/ M anipulation |
|
|
-------------------------------------------------------------------------------
|
|
License
|
|
This file is part of OpenFOAM.
|
|
|
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
#include "argList.H"
|
|
#include "foamVersion.H"
|
|
#include "stringOps.H"
|
|
#include "IOmanip.H"
|
|
|
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
|
|
|
namespace Foam
|
|
{
|
|
|
|
// manpage Footer
|
|
static inline void printManFooter()
|
|
{
|
|
Info<< ".SH \"SEE ALSO\"" << nl
|
|
<< "Online documentation "
|
|
<< "https://www.openfoam.com/documentation/" << nl
|
|
<< ".SH COPYRIGHT" << nl
|
|
<< "Copyright \\(co 2018 OpenCFD Ltd." << nl;
|
|
}
|
|
|
|
|
|
// Regular option
|
|
static void printManOption(const word& optName)
|
|
{
|
|
Info<< ".TP\n\\fB\\-" << optName << "\\fR";
|
|
|
|
// Option has arg?
|
|
const auto optIter = argList::validOptions.cfind(optName);
|
|
|
|
if (optIter.found() && optIter().size())
|
|
{
|
|
Info<< " \\fI" << optIter().c_str() << "\\fR";
|
|
}
|
|
Info<< nl;
|
|
|
|
// Option has usage information?
|
|
|
|
const auto usageIter = argList::optionUsage.cfind(optName);
|
|
if (usageIter.found())
|
|
{
|
|
stringOps::writeWrapped(Info, *usageIter, argList::usageMax, 0, true);
|
|
}
|
|
else
|
|
{
|
|
Info<< nl;
|
|
}
|
|
if (argList::validParOptions.found(optName))
|
|
{
|
|
Info<< "\\fB[Parallel option]\\fR" << nl;
|
|
}
|
|
}
|
|
|
|
|
|
// Simple, hard-coded option
|
|
static inline void printManOption(const char* optName, const char* optUsage)
|
|
{
|
|
Info<< ".TP\n\\fB\\-" << optName << "\\fR" << nl
|
|
<< optUsage << nl;
|
|
}
|
|
|
|
|
|
static void printOptionUsage
|
|
(
|
|
std::string::size_type start,
|
|
const string& str
|
|
)
|
|
{
|
|
if (str.empty())
|
|
{
|
|
Info<< nl;
|
|
return;
|
|
}
|
|
|
|
// Indent the first line. Min 2 spaces between option and usage
|
|
if (start + 2 > argList::usageMin)
|
|
{
|
|
Info<< nl;
|
|
start = 0;
|
|
}
|
|
while (start < argList::usageMin)
|
|
{
|
|
Info<<' ';
|
|
++start;
|
|
}
|
|
|
|
stringOps::writeWrapped
|
|
(
|
|
Info,
|
|
str,
|
|
(argList::usageMax - argList::usageMin),
|
|
argList::usageMin
|
|
);
|
|
}
|
|
|
|
|
|
// Regular option
|
|
static void printOption(const word& optName)
|
|
{
|
|
Info<< " -" << optName;
|
|
|
|
// Length includes leading ' -'
|
|
label len = optName.size() + 3;
|
|
|
|
const auto optIter = argList::validOptions.cfind(optName);
|
|
if (optIter.found() && optIter().size())
|
|
{
|
|
// Length includes space between option/param and '<>'
|
|
len += optIter().size() + 3;
|
|
Info<< " <" << optIter().c_str() << '>';
|
|
}
|
|
|
|
const auto usageIter = argList::optionUsage.cfind(optName);
|
|
if (usageIter.found())
|
|
{
|
|
printOptionUsage(len, usageIter());
|
|
}
|
|
else
|
|
{
|
|
Info<< nl;
|
|
}
|
|
}
|
|
|
|
|
|
// Simple, hard-coded option
|
|
static inline void printOption(const char* optName, const char* optUsage)
|
|
{
|
|
Info<< " -" << optName;
|
|
printOptionUsage(3 + strlen(optName), optUsage);
|
|
}
|
|
|
|
} // End namespace Foam
|
|
|
|
|
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
|
|
void Foam::argList::printMan() const
|
|
{
|
|
// .TH "<APPLICATION>" 1 "OpenFOAM-<version>" "source" "category"
|
|
|
|
Info<< ".TH" << token::SPACE
|
|
// All uppercase (returns a Foam::string) and thus also quoted
|
|
<< stringOps::upper(executable_) << token::SPACE
|
|
<< 1 << token::SPACE
|
|
<< token::DQUOTE << "OpenFOAM-v" << foamVersion::api << token::DQUOTE
|
|
<< token::SPACE
|
|
<< token::DQUOTE << "www.openfoam.com" << token::DQUOTE
|
|
<< token::SPACE
|
|
<< token::DQUOTE << "OpenFOAM Commands Manual" << token::DQUOTE
|
|
<< nl;
|
|
|
|
|
|
// .SH NAME
|
|
// <application> \- part of OpenFOAM (The Open Source CFD Toolbox).
|
|
Info<< ".SH \"NAME\"" << nl
|
|
<< executable_
|
|
<< " \\- part of \\fBOpenFOAM\\fR (The Open Source CFD Toolbox)."
|
|
<< nl;
|
|
|
|
|
|
// .SH SYNOPSIS
|
|
// .B command [OPTIONS] ...
|
|
|
|
Info<< ".SH \"SYNOPSIS\"" << nl
|
|
<< "\\fB" << executable_ << "\\fR [\\fIOPTIONS\\fR]";
|
|
|
|
if (validArgs.size())
|
|
{
|
|
Info<< ' ';
|
|
|
|
if (!argsMandatory_)
|
|
{
|
|
Info<< '[';
|
|
}
|
|
|
|
label i = 0;
|
|
for (const std::string& argName : validArgs)
|
|
{
|
|
if (i++) Info<< ' ';
|
|
Info << "\\fI" << argName.c_str() << "\\fR";
|
|
}
|
|
|
|
if (!argsMandatory_)
|
|
{
|
|
Info<< ']';
|
|
}
|
|
}
|
|
Info<< nl;
|
|
|
|
|
|
// .SH DESCRIPTION
|
|
{
|
|
Info<< ".SH \"DESCRIPTION\"" << nl;
|
|
|
|
Info<< ".nf" << nl; // No fill lines
|
|
|
|
if (notes.empty())
|
|
{
|
|
Info<< "No description available\n";
|
|
}
|
|
else
|
|
{
|
|
for (const std::string& note : notes)
|
|
{
|
|
if (note.empty())
|
|
{
|
|
Info<< nl;
|
|
}
|
|
else
|
|
{
|
|
stringOps::writeWrapped(Info, note, usageMax, 0, true);
|
|
}
|
|
}
|
|
}
|
|
Info<< ".fi" << nl; // Fill lines
|
|
}
|
|
|
|
|
|
// .SH "OPTIONS"
|
|
Info<< ".SH \"OPTIONS\"" << nl;
|
|
|
|
for (const word& optName : validOptions.sortedToc())
|
|
{
|
|
// Normal (non-advanced) options
|
|
if (!advancedOptions.found(optName))
|
|
{
|
|
printManOption(optName);
|
|
}
|
|
}
|
|
|
|
// Standard documentation/help options
|
|
|
|
printManOption("doc", "Display documentation in browser");
|
|
printManOption("doc-source", "Display source code in browser");
|
|
printManOption("help", "Display short help and exit");
|
|
printManOption("help-full", "Display full help and exit");
|
|
|
|
|
|
// .SS "ADVANCED OPTIONS"
|
|
Info<< ".SS \"ADVANCED OPTIONS\"" << nl;
|
|
|
|
for (const word& optName : validOptions.sortedToc())
|
|
{
|
|
// Advanced options
|
|
if (advancedOptions.found(optName))
|
|
{
|
|
printManOption(optName);
|
|
}
|
|
}
|
|
|
|
|
|
const bool hasCompat =
|
|
(
|
|
!argList::validOptionsCompat.empty()
|
|
|| !argList::ignoreOptionsCompat.empty()
|
|
);
|
|
|
|
if (hasCompat)
|
|
{
|
|
printManOption("help-compat", "Display compatibility options and exit");
|
|
}
|
|
|
|
printManOption("help-man", "Display full help (manpage format) and exit");
|
|
|
|
printManCompat();
|
|
|
|
// Footer
|
|
printManFooter();
|
|
}
|
|
|
|
|
|
void Foam::argList::printUsage(bool full) const
|
|
{
|
|
Info<< "\nUsage: " << executable_ << " [OPTIONS]";
|
|
|
|
if (validArgs.size())
|
|
{
|
|
Info<< ' ';
|
|
|
|
if (!argsMandatory_)
|
|
{
|
|
Info<< '[';
|
|
}
|
|
|
|
label i = 0;
|
|
for (const std::string& argName : validArgs)
|
|
{
|
|
if (i++) Info<< ' ';
|
|
Info<< '<' << argName.c_str() << '>';
|
|
}
|
|
|
|
if (!argsMandatory_)
|
|
{
|
|
Info<< ']';
|
|
}
|
|
}
|
|
Info<< nl;
|
|
|
|
Info<< "Options:\n";
|
|
|
|
for (const word& optName : validOptions.sortedToc())
|
|
{
|
|
// Suppress advanced options for regular -help.
|
|
if (full || !advancedOptions.found(optName))
|
|
{
|
|
printOption(optName);
|
|
}
|
|
}
|
|
|
|
|
|
// Place documentation/help options at the end
|
|
|
|
printOption("doc", "Display documentation in browser");
|
|
printOption("doc-source", "Display source code in browser");
|
|
printOption("help", "Display short help and exit");
|
|
|
|
if
|
|
(
|
|
argList::validOptionsCompat.size()
|
|
+ argList::ignoreOptionsCompat.size()
|
|
)
|
|
{
|
|
printOption("help-compat", "Display compatibility options and exit");
|
|
}
|
|
|
|
if (full)
|
|
{
|
|
printOption("help-man", "Display full help (manpage format) and exit");
|
|
}
|
|
|
|
printOption("help-full", "Display full help and exit");
|
|
|
|
printNotes();
|
|
|
|
Info<< nl;
|
|
foamVersion::printBuildInfo(true);
|
|
Info<< endl;
|
|
}
|
|
|
|
|
|
void Foam::argList::printNotes() const
|
|
{
|
|
// Output notes with automatic text wrapping
|
|
if (!notes.empty())
|
|
{
|
|
Info<< nl;
|
|
|
|
for (const std::string& note : notes)
|
|
{
|
|
if (note.empty())
|
|
{
|
|
Info<< nl;
|
|
}
|
|
else
|
|
{
|
|
stringOps::writeWrapped(Info, note, usageMax);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Foam::argList::printManCompat() const
|
|
{
|
|
if
|
|
(
|
|
argList::validOptionsCompat.empty()
|
|
&& argList::ignoreOptionsCompat.empty()
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
// .SS "COMPATIBILITY OPTIONS"
|
|
Info<< ".SS \"COMPATIBILITY OPTIONS\"" << nl;
|
|
|
|
for (const word& k : argList::validOptionsCompat.sortedToc())
|
|
{
|
|
const auto& iter = *argList::validOptionsCompat.cfind(k);
|
|
|
|
const word& optName = iter.first;
|
|
const int until = abs(iter.second);
|
|
|
|
Info<< ".TP\n\\fB\\-" << k
|
|
<< "\\fR (now \\fB\\-" << optName << "\\fR)" << nl;
|
|
|
|
if (until)
|
|
{
|
|
Info<< "The option was last used in " << until << "." << nl;
|
|
}
|
|
}
|
|
|
|
for (const word& k : argList::ignoreOptionsCompat.sortedToc())
|
|
{
|
|
const auto& iter = *argList::ignoreOptionsCompat.cfind(k);
|
|
|
|
const bool hasArg = iter.first;
|
|
const int until = abs(iter.second);
|
|
|
|
Info<< ".TP\n\\fB\\-" << k << "\\fR";
|
|
|
|
if (hasArg)
|
|
{
|
|
Info<< " \\fIarg\\fR";
|
|
}
|
|
|
|
Info<< nl << "This option is ignored";
|
|
|
|
if (until)
|
|
{
|
|
Info<< " after " << until << ".";
|
|
}
|
|
Info<< nl;
|
|
}
|
|
}
|
|
|
|
|
|
void Foam::argList::printCompat() const
|
|
{
|
|
const label nopt
|
|
(
|
|
argList::validOptionsCompat.size()
|
|
+ argList::ignoreOptionsCompat.size()
|
|
);
|
|
|
|
Info<< nopt << " compatibility options for " << executable_ << nl;
|
|
|
|
if (!nopt)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const int col1(32), col2(32);
|
|
|
|
Info<< nl
|
|
<< "|" << setf(ios_base::left) << setw(col1) << " Old option"
|
|
<< "|" << setf(ios_base::left) << setw(col2) << " New option"
|
|
<< "| Comment" << nl;
|
|
|
|
Info<< setfill('-');
|
|
Info<< "|" << setf(ios_base::left) << setw(col1) << ""
|
|
<< "|" << setf(ios_base::left) << setw(col2) << ""
|
|
<< "|------------" << nl;
|
|
|
|
Info<< setfill(token::SPACE);
|
|
|
|
for (const word& k : argList::validOptionsCompat.sortedToc())
|
|
{
|
|
const auto& iter = *argList::validOptionsCompat.cfind(k);
|
|
|
|
const word& optName = iter.first;
|
|
const int until = abs(iter.second);
|
|
|
|
Info<< "| -" << setf(ios_base::left) << setw(col1-2) << k
|
|
<< "| -" << setf(ios_base::left) << setw(col2-2) << optName
|
|
<< "|";
|
|
|
|
if (until)
|
|
{
|
|
Info<< " until " << until;
|
|
}
|
|
Info<< nl;
|
|
}
|
|
|
|
for (const word& k : argList::ignoreOptionsCompat.sortedToc())
|
|
{
|
|
const auto& iter = *argList::ignoreOptionsCompat.cfind(k);
|
|
|
|
const bool hasArg = iter.first;
|
|
const int until = abs(iter.second);
|
|
|
|
Info<< "| -" << setf(ios_base::left) << setw(col1-2);
|
|
|
|
if (hasArg)
|
|
{
|
|
Info<< (k + " <arg>").c_str();
|
|
}
|
|
else
|
|
{
|
|
Info<< k;
|
|
}
|
|
|
|
Info<< "| ";
|
|
Info<< setf(ios_base::left) << setw(col2-1) << "ignored" << "|";
|
|
if (until)
|
|
{
|
|
Info<< " after " << until;
|
|
}
|
|
Info<< nl;
|
|
}
|
|
|
|
Info<< setfill('-');
|
|
Info<< "|" << setf(ios_base::left) << setw(col1) << ""
|
|
<< "|" << setf(ios_base::left) << setw(col2) << ""
|
|
<< "|------------" << nl;
|
|
|
|
Info<< setfill(token::SPACE);
|
|
}
|
|
|
|
|
|
// ************************************************************************* //
|