Skip to content

Commit 526775e

Browse files
authored
Merge pull request doxygen#12217 from albert-github/feature/bug_dw_compat
Compatibility code for reading obsolete settings in doxywizard
2 parents eb5e638 + b6748ff commit 526775e

1 file changed

Lines changed: 192 additions & 0 deletions

File tree

addon/doxywizard/config_doxyw.l

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,8 +703,88 @@ static void substEnvVarsInStrList(QStringList &sl)
703703

704704
//--------------------------------------------------------------------------
705705

706+
inline bool qisspace(char c)
707+
{
708+
return c==' ' || c=='\t' || c=='\n' || c=='\r';
709+
}
710+
711+
// Returns a quoted copy of this string, unless it is already quoted.
712+
// Note that trailing and leading whitespace is removed.
713+
QString quoted(QString &inpValue)
714+
{
715+
std::string rep = inpValue.toStdString();
716+
size_t start=0, sl=rep.size(), end=sl-1;
717+
while (start<sl && qisspace(rep[start])) start++; // skip over leading whitespace
718+
if (start==sl) return QString(); // only whitespace
719+
while (end>start && qisspace(rep[end])) end--; // skip over trailing whitespace
720+
bool needsQuotes=false;
721+
size_t i=start;
722+
if (i<end && rep[i]!='"') // stripped string has at least non-whitespace unquoted character
723+
{
724+
while (i<end && !needsQuotes) // check if the to be quoted part has at least one whitespace character
725+
{
726+
needsQuotes = rep[i] =='-';
727+
needsQuotes |= qisspace(rep[i++]);
728+
}
729+
}
730+
std::string result = rep.substr(start,1+end-start);
731+
if (needsQuotes)
732+
{
733+
result = "\"" + result + "\"";
734+
}
735+
return QString::fromUtf8(result.c_str());
736+
}
737+
738+
static void updateAttribute(InputString *attr, const char *key, QString &inpValue)
739+
{
740+
QString attrValue = attr->value().toString();
741+
std::string s = attrValue.toStdString();
742+
// look for key\s*=
743+
QRegularExpression re(QString::fromLatin1(key)+QString::fromLatin1(R"(\s*=)"));
744+
QRegularExpressionMatch match = re.match(attrValue);
745+
if (match.hasMatch()) // replace existing attribute
746+
{
747+
size_t len = s.length();
748+
size_t startPos = match.capturedStart()+match.capturedLength(); // position after =
749+
size_t pos = startPos;
750+
while (pos<len && qisspace(s[pos])) pos++;
751+
if (pos<len && s[pos]=='"') // quoted value, search for end quote, ignoring escaped quotes
752+
{
753+
char pc=s[pos];
754+
pos++; // skip over start quote
755+
while (pos<len && (s[pos]!='"' || (s[pos]=='"' && pc=='\\'))) pc=s[pos++];
756+
if (pos<len) pos++; // skip over end quote
757+
}
758+
else // unquoted value, search for attribute separator (space,comma, or semicolon)
759+
{
760+
while (pos<len && s[pos]!=',' && s[pos]!=';' && !qisspace(s[pos])) pos++;
761+
}
762+
QString value;
763+
if (inpValue.isEmpty())
764+
{
765+
value = attrValue.mid(startPos,pos-startPos);
766+
}
767+
else
768+
{
769+
value = inpValue;
770+
}
771+
// pos is now the position after the value, so replace the part between [start..pos) with the new value
772+
attrValue=attrValue.left(startPos)+quoted(value)+attrValue.mid(pos);
773+
}
774+
else // append new attribute
775+
{
776+
if (!inpValue.isEmpty())
777+
{
778+
if (!attrValue.isEmpty()) attrValue+=QString::fromLatin1(",");
779+
attrValue+=QString::fromLatin1(key)+QString::fromLatin1("=")+quoted(inpValue);
780+
}
781+
}
782+
attr->setValue(attrValue);
783+
}
784+
706785
static void upgradeConfig(const QHash<QString,Input*> &options)
707786
{
787+
// check for presence of obsolete CLASS_DIAGRAM option and correct CLASS_GRAPH if needed
708788
auto it1 = options.find(QString::fromLatin1("CLASS_DIAGRAMS"));
709789
auto it2 = options.find(QString::fromLatin1("HAVE_DOT"));
710790
auto it3 = options.find(QString::fromLatin1("CLASS_GRAPH"));
@@ -732,6 +812,118 @@ static void upgradeConfig(const QHash<QString,Input*> &options)
732812
}
733813
}
734814
}
815+
816+
// update TIMESTAMP based on HTML_TIMESTAMP and LATEX_TIMESTAMP
817+
auto HtmlTimestamp = options.find(QString::fromLatin1("HTML_TIMESTAMP"));
818+
auto timestamp = options.find(QString::fromLatin1("TIMESTAMP"));
819+
if (HtmlTimestamp!=options.end() && timestamp!=options.end())
820+
{
821+
if ((*HtmlTimestamp)->kind()==Input::Obsolete)
822+
{
823+
InputObsolete *htmlTimestamp_ = dynamic_cast<InputObsolete*>(*HtmlTimestamp);
824+
InputString *timestamp_ = dynamic_cast<InputString*>(*timestamp);
825+
if (htmlTimestamp_->orgKind()==Input::Bool)
826+
{
827+
const QVariant &htmlTimestampValue = htmlTimestamp_->value();
828+
bool isValid = false;
829+
bool bTimestamp = InputBool::convertToBool(htmlTimestampValue,isValid);
830+
if (isValid && bTimestamp)
831+
{
832+
config_warn("Changing TIMESTAMP option to YES because obsolete option HTML_TIMESTAMP was found and was set to YES.\n");
833+
timestamp_->setValue(QString::fromLatin1("YES"));
834+
}
835+
}
836+
}
837+
}
838+
839+
auto LatexTimestamp = options.find(QString::fromLatin1("LATEX_TIMESTAMP"));
840+
if (LatexTimestamp!=options.end() && timestamp!=options.end())
841+
{
842+
if ((*LatexTimestamp)->kind()==Input::Obsolete)
843+
{
844+
InputObsolete *latexTimestamp_ = dynamic_cast<InputObsolete*>(*LatexTimestamp);
845+
InputString *timestamp_ = dynamic_cast<InputString*>(*timestamp);
846+
if (latexTimestamp_->orgKind()==Input::Bool)
847+
{
848+
const QVariant &latexTimestampValue = latexTimestamp_->value();
849+
bool isValid = false;
850+
bool bTimestamp = InputBool::convertToBool(latexTimestampValue,isValid);
851+
if (isValid && bTimestamp)
852+
{
853+
config_warn("Changing TIMESTAMP option to YES because obsolete option LATEX_TIMESTAMP was found and was set to YES.\n");
854+
timestamp_->setValue(QString::fromLatin1("YES"));
855+
}
856+
}
857+
}
858+
}
859+
860+
auto fontName = options.find(QString::fromLatin1("DOT_FONTNAME"));
861+
auto fontSize = options.find(QString::fromLatin1("DOT_FONTSIZE"));
862+
QString fontNameValue;
863+
QString fontSizeValue;
864+
// correct DOT_FONTNAME if needed
865+
if (fontName!=options.end())
866+
{
867+
if ((*fontName)->kind()==Input::Obsolete)
868+
{
869+
InputObsolete *fontName_ = dynamic_cast<InputObsolete*>(*fontName);
870+
fontNameValue = fontName_->value().toString();
871+
if (fontNameValue == QString::fromLatin1("FreeSans") ||
872+
fontNameValue == QString::fromLatin1("FreeSans.ttf"))
873+
{
874+
config_warn("doxygen no longer ships with the FreeSans font.\n"
875+
" You may want to clear or change DOT_FONTNAME.\n"
876+
" Otherwise you run the risk that the wrong font is being used for dot generated graphs.\n");
877+
}
878+
}
879+
}
880+
881+
if (fontSize!=options.end())
882+
{
883+
if ((*fontSize)->kind()==Input::Obsolete)
884+
{
885+
InputObsolete *fontSize_ = dynamic_cast<InputObsolete*>(*fontSize);
886+
fontSizeValue = fontSize_->value().toString();
887+
}
888+
}
889+
890+
if (fontName!=options.end() || fontSize!=options.end())
891+
{
892+
auto commonAttrOpt = options.find(QString::fromLatin1("DOT_COMMON_ATTR"));
893+
auto edgeAttrOpt = options.find(QString::fromLatin1("DOT_EDGE_ATTR"));
894+
if ((*commonAttrOpt)->kind()==Input::String)
895+
{
896+
QString commonAttrValue;
897+
InputString *commonAttr_ = dynamic_cast<InputString*>(*commonAttrOpt);
898+
if ((*commonAttr_).stringMode()==InputString::StringFree)
899+
{
900+
if (fontName!=options.end())
901+
{
902+
updateAttribute(commonAttr_, "fontname", fontNameValue);
903+
}
904+
if (fontSize!=options.end())
905+
{
906+
updateAttribute(commonAttr_, "fontsize", fontSizeValue);
907+
}
908+
}
909+
}
910+
if ((*edgeAttrOpt)->kind()==Input::String)
911+
{
912+
QString edgeAttrValue;
913+
InputString *edgeAttr_ = dynamic_cast<InputString*>(*edgeAttrOpt);
914+
if ((*edgeAttr_).stringMode()==InputString::StringFree)
915+
{
916+
if (fontName!=options.end())
917+
{
918+
updateAttribute(edgeAttr_, "labelfontname", fontNameValue);
919+
}
920+
if (fontSize!=options.end())
921+
{
922+
updateAttribute(edgeAttr_, "labelfontsize", fontSizeValue);
923+
}
924+
}
925+
}
926+
}
735927
}
736928

737929
//--------------------------------------------------------------------------

0 commit comments

Comments
 (0)