Skip to content

Commit ff585b8

Browse files
committed
Correction default output of \doxyconfig and adding options
- showing the used value of a confiruration option when not given (otherwise e.g. `\doxyconfig GENERATE_TREEVIEW` would show up as an empty value instead of `YES`). - adding options `full`, `help` and `all`.
1 parent 104c809 commit ff585b8

File tree

3 files changed

+179
-73
lines changed

3 files changed

+179
-73
lines changed

doc/commands.dox

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,8 @@ Structural indicators
889889

890890
\addindex \\fileinfo
891891
Shows (part) of the file name in which this command is placed.
892-
The `option` can be `name`, `extension`, `filename`, `directory` or, `full`,
893-
with
892+
The `option` can be `name`, `extension`, `filename`, `directory` or `full`
893+
with:
894894
- `name` the name of the file without extension
895895
- `extension` the extension of the file
896896
- `filename` the filename i.e. `name` plus `extension`
@@ -3682,12 +3682,18 @@ class Receiver
36823682
\ref cmdimage "\\image" command.
36833683

36843684
<hr>
3685-
\section cmddoxyconfig \\doxyconfig \<config_option\>
3685+
\section cmddoxyconfig \\doxyconfig['{'option'}'] [\<config_option\>]
36863686

36873687
\addindex \\doxyconfig
36883688
Displays the value of the configuration option `<config_option>` as used in Doxygen's
36893689
configuration file that is in use when this command is processed.
36903690

3691+
The `option` can be one of `full`, `help` or `all` with:
3692+
- `full` the name of the `config_option` (together with ` = `) is displayed along with the value
3693+
- `help` the help information of the `config_option` is displayed
3694+
- `all` the name and value (analogous to the format with `full`) s displayed for all possible
3695+
configuration options (so no the `config_option` should be given);
3696+
36913697
\par Example:
36923698
When creating this manual the following:
36933699
\verbatim

src/configimpl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class ConfigOption
7474
void addDependency(const char *dep) { m_dependency = dep; }
7575
void setEncoding(const QCString &e) { m_encoding = e; }
7676
void setUserComment(const QCString &u) { m_userComment += u; }
77+
QCString getDocumentation() const { return m_doc; }
7778

7879
protected:
7980
virtual void writeTemplate(TextStream &t,bool sl,bool upd) = 0;
@@ -229,6 +230,7 @@ class ConfigInt : public ConfigOption
229230
m_maxVal = maxVal;
230231
}
231232
QCString *valueStringRef() { return &m_valueString; }
233+
QCString getDefaultStr() { return QCString().setNum(m_value); }
232234
int *valueRef() { return &m_value; }
233235
int minVal() const { return m_minVal; }
234236
int maxVal() const { return m_maxVal; }
@@ -262,6 +264,7 @@ class ConfigBool : public ConfigOption
262264
m_defValue = defVal;
263265
}
264266
QCString *valueStringRef() { return &m_valueString; }
267+
QCString getDefaultStr() { return m_value ? "YES" : "NO"; }
265268
bool *valueRef() { return &m_value; }
266269
void convertStrToVal(Config::CompareMode compareMode) override;
267270
void substEnvVars() override;
@@ -610,6 +613,8 @@ class ConfigImpl
610613
static void config_term(const char *fmt, ...);
611614
static void config_warn(const char *fmt, ...);
612615

616+
ConfigOptionList *getOptions() {return &m_options;}
617+
613618
private:
614619
ConfigOptionList m_options;
615620
ConfigOptionList m_obsolete;

src/docnode.cpp

Lines changed: 165 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3358,99 +3358,194 @@ void DocPara::handleEmoji(char cmdChar,const QCString &cmdName)
33583358

33593359
void DocPara::handleDoxyConfig(char cmdChar,const QCString &cmdName)
33603360
{
3361-
// get the argument of the cite command.
3361+
QCString saveCmdName = cmdName;
33623362
Token tok=parser()->tokenizer.lex();
3363-
if (!tok.is(TokenRetval::TK_WHITESPACE))
3363+
bool allConfig = false;
3364+
bool fullConfig = false;
3365+
bool helpConfig = false;
3366+
if (tok.is(TokenRetval::TK_WORD) && parser()->context.token->name=="{")
33643367
{
3365-
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after '%c%s' command",
3366-
cmdChar,qPrint(cmdName));
3367-
return;
3368+
parser()->tokenizer.setStateOptions();
3369+
parser()->tokenizer.lex();
3370+
parser()->tokenizer.setStatePara();
3371+
StringVector optList=split(parser()->context.token->name.str(),",");
3372+
for (const auto &opt : optList)
3373+
{
3374+
if (opt.empty()) continue;
3375+
QCString locOpt(opt);
3376+
locOpt = locOpt.stripWhiteSpace().lower();
3377+
if (locOpt == "all")
3378+
{
3379+
allConfig = true;
3380+
}
3381+
else if (locOpt == "full")
3382+
{
3383+
fullConfig = true;
3384+
}
3385+
else if (locOpt == "help")
3386+
{
3387+
helpConfig = true;
3388+
}
3389+
else if (!locOpt.isEmpty())
3390+
{
3391+
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(), "Unknown option '%s' for '%c%s'",qPrint(opt),
3392+
cmdChar,qPrint(saveCmdName));
3393+
}
3394+
}
3395+
int nrOpt = 0;
3396+
if (allConfig) nrOpt++;
3397+
if (fullConfig) nrOpt++;
3398+
if (helpConfig) nrOpt++;
3399+
if (nrOpt > 1)
3400+
{
3401+
allConfig = false;
3402+
fullConfig = false;
3403+
helpConfig = false;
3404+
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(),
3405+
"More than one option specified for '%c%s', discarding all options",
3406+
cmdChar,qPrint(saveCmdName));
3407+
}
3408+
if (!allConfig)
3409+
{
3410+
tok=parser()->tokenizer.lex();
3411+
if (!tok.is(TokenRetval::TK_WHITESPACE))
3412+
{
3413+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after %c%s command",
3414+
cmdChar,qPrint(saveCmdName));
3415+
return;
3416+
}
3417+
}
33683418
}
3369-
parser()->tokenizer.setStateDoxyConfig();
3370-
tok=parser()->tokenizer.lex();
3371-
if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
3419+
else if (!tok.is(TokenRetval::TK_WHITESPACE))
33723420
{
3373-
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
3374-
"argument of command '%c%s'",cmdChar,qPrint(cmdName));
3421+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"expected whitespace after '%c%s' command",
3422+
cmdChar,qPrint(saveCmdName));
33753423
return;
33763424
}
3377-
else if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
3425+
if (!allConfig)
33783426
{
3379-
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of '%c%s'",
3380-
tok.to_string(),cmdChar,qPrint(cmdName));
3381-
return;
3427+
parser()->tokenizer.setStateDoxyConfig();
3428+
tok=parser()->tokenizer.lex();
3429+
if (tok.is_any_of(TokenRetval::TK_NONE,TokenRetval::TK_EOF))
3430+
{
3431+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected end of comment block while parsing the "
3432+
"argument of command '%c%s'",cmdChar,qPrint(saveCmdName));
3433+
return;
3434+
}
3435+
else if (!tok.is_any_of(TokenRetval::TK_WORD,TokenRetval::TK_LNKWORD))
3436+
{
3437+
warn_doc_error(parser()->context.fileName,parser()->tokenizer.getLineNr(),"unexpected token %s as the argument of '%c%s'",
3438+
tok.to_string(),cmdChar,qPrint(saveCmdName));
3439+
return;
3440+
}
33823441
}
3383-
ConfigOption * opt = ConfigImpl::instance()->get(parser()->context.token->name);
3384-
if (opt)
3442+
3443+
auto process = [&](const QCString &name)
33853444
{
3386-
QCString optionValue;
3387-
switch (opt->kind())
3445+
ConfigOption * opt = ConfigImpl::instance()->get(name);
3446+
if (opt)
33883447
{
3389-
case ConfigOption::O_Bool:
3390-
optionValue = *(static_cast<ConfigBool*>(opt)->valueStringRef());
3391-
break;
3392-
case ConfigOption::O_String:
3393-
optionValue = *(static_cast<ConfigString*>(opt)->valueRef());
3394-
break;
3395-
case ConfigOption::O_Enum:
3396-
optionValue = *(static_cast<ConfigEnum*>(opt)->valueRef());
3397-
break;
3398-
case ConfigOption::O_Int:
3399-
optionValue = *(static_cast<ConfigInt*>(opt)->valueStringRef());
3400-
break;
3401-
case ConfigOption::O_List:
3402-
{
3403-
StringVector *lst = static_cast<ConfigList*>(opt)->valueRef();
3404-
optionValue="";
3405-
if (!lst->empty())
3448+
QCString optionValue;
3449+
bool isSet = true;
3450+
switch (opt->kind())
3451+
{
3452+
case ConfigOption::O_Bool:
3453+
optionValue = *(static_cast<ConfigBool*>(opt)->valueStringRef());
3454+
if (optionValue.isEmpty()) optionValue = static_cast<ConfigBool*>(opt)->getDefaultStr();
3455+
break;
3456+
case ConfigOption::O_String:
3457+
optionValue = *(static_cast<ConfigString*>(opt)->valueRef());
3458+
break;
3459+
case ConfigOption::O_Enum:
3460+
optionValue = *(static_cast<ConfigEnum*>(opt)->valueRef());
3461+
break;
3462+
case ConfigOption::O_Int:
3463+
optionValue = *(static_cast<ConfigInt*>(opt)->valueStringRef());
3464+
if (optionValue.isEmpty()) optionValue = static_cast<ConfigInt*>(opt)->getDefaultStr();
3465+
break;
3466+
case ConfigOption::O_List:
34063467
{
3407-
std::string lstFormat = theTranslator->trWriteList(static_cast<int>(lst->size())).str();
3408-
static const reg::Ex marker(R"(@(\d+))");
3409-
reg::Iterator it(lstFormat,marker);
3410-
reg::Iterator end;
3411-
size_t index=0;
3412-
// now replace all markers with the real text
3413-
for ( ; it!=end ; ++it)
3468+
StringVector *lst = static_cast<ConfigList*>(opt)->valueRef();
3469+
optionValue="";
3470+
if (!lst->empty())
34143471
{
3415-
const auto &match = *it;
3416-
size_t newIndex = match.position();
3417-
size_t matchLen = match.length();
3418-
optionValue += lstFormat.substr(index,newIndex-index);
3419-
unsigned long entryIndex = std::stoul(match[1].str());
3420-
if (entryIndex<(unsigned long)lst->size())
3472+
std::string lstFormat = theTranslator->trWriteList(static_cast<int>(lst->size())).str();
3473+
static const reg::Ex marker(R"(@(\d+))");
3474+
reg::Iterator it(lstFormat,marker);
3475+
reg::Iterator end;
3476+
size_t index=0;
3477+
// now replace all markers with the real text
3478+
for ( ; it!=end ; ++it)
34213479
{
3422-
optionValue += lst->at(entryIndex);
3480+
const auto &match = *it;
3481+
size_t newIndex = match.position();
3482+
size_t matchLen = match.length();
3483+
optionValue += lstFormat.substr(index,newIndex-index);
3484+
unsigned long entryIndex = std::stoul(match[1].str());
3485+
if (entryIndex<(unsigned long)lst->size())
3486+
{
3487+
optionValue += lst->at(entryIndex);
3488+
}
3489+
index=newIndex+matchLen;
34233490
}
3424-
index=newIndex+matchLen;
3491+
optionValue+=lstFormat.substr(index);
34253492
}
3426-
optionValue+=lstFormat.substr(index);
34273493
}
3428-
}
3429-
break;
3430-
case ConfigOption::O_Obsolete:
3431-
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(), "Obsolete setting for '%c%s': '%s'",
3432-
cmdChar,qPrint(cmdName),qPrint(parser()->context.token->name));
3433-
break;
3434-
case ConfigOption::O_Disabled:
3435-
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(),
3436-
"Disabled setting (i.e. not supported in this doxygen executable) for '%c%s': '%s'",
3437-
cmdChar,qPrint(cmdName),qPrint(parser()->context.token->name));
3438-
break;
3439-
case ConfigOption::O_Info:
3440-
// nothing to show here
3441-
break;
3494+
break;
3495+
case ConfigOption::O_Obsolete:
3496+
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(), "Obsolete setting for '%c%s': '%s'",
3497+
cmdChar,qPrint(saveCmdName),qPrint(name));
3498+
isSet = false;
3499+
break;
3500+
case ConfigOption::O_Disabled:
3501+
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(),
3502+
"Disabled setting (i.e. not supported in this doxygen executable) for '%c%s': '%s'",
3503+
cmdChar,qPrint(saveCmdName),qPrint(name));
3504+
isSet = false;
3505+
break;
3506+
case ConfigOption::O_Info:
3507+
// nothing to show here
3508+
isSet = false;
3509+
break;
3510+
}
3511+
if (isSet && fullConfig)
3512+
{
3513+
children().append<DocWord>(parser(),thisVariant(),name + " = " + optionValue);
3514+
}
3515+
else if (isSet && allConfig)
3516+
{
3517+
children().append<DocWord>(parser(),thisVariant(),name + " = " + optionValue);
3518+
children().append<DocLineBreak>(parser(),thisVariant());
3519+
}
3520+
else if (isSet && helpConfig)
3521+
{
3522+
children().append<DocWord>(parser(),thisVariant(),opt->getDocumentation());
3523+
}
3524+
else if (!optionValue.isEmpty())
3525+
{
3526+
children().append<DocWord>(parser(),thisVariant(),optionValue);
3527+
}
34423528
}
3443-
if (!optionValue.isEmpty())
3529+
else if (!allConfig)
34443530
{
3445-
children().append<DocWord>(parser(),thisVariant(),optionValue);
3531+
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(), "Unknown option for '%c%s': '%s'",
3532+
cmdChar,qPrint(saveCmdName),qPrint(name));
3533+
children().append<DocWord>(parser(),thisVariant(),name);
3534+
}
3535+
};
3536+
3537+
if (allConfig)
3538+
{
3539+
for (const auto &option : *(ConfigImpl::instance()->getOptions()))
3540+
{
3541+
process(option->name());
34463542
}
34473543
}
34483544
else
34493545
{
3450-
warn(parser()->context.fileName,parser()->tokenizer.getLineNr(), "Unknown option for '%c%s': '%s'",
3451-
cmdChar,qPrint(cmdName),qPrint(parser()->context.token->name));
3452-
children().append<DocWord>(parser(),thisVariant(),parser()->context.token->name);
3546+
process(parser()->context.token->name);
34533547
}
3548+
34543549
parser()->tokenizer.setStatePara();
34553550
}
34563551

0 commit comments

Comments
 (0)