diff options
Diffstat (limited to 'src/configimpl.l')
-rw-r--r-- | src/configimpl.l | 567 |
1 files changed, 273 insertions, 294 deletions
diff --git a/src/configimpl.l b/src/configimpl.l index d07e25c..9eda61d 100644 --- a/src/configimpl.l +++ b/src/configimpl.l @@ -1,10 +1,10 @@ /****************************************************************************** * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -29,11 +29,12 @@ #include <qfileinfo.h> #include <qdir.h> -#include <qtextstream.h> #include <qregexp.h> #include <qstack.h> #include <qglobal.h> + #include <thread> +#include <algorithm> #include "configimpl.h" #include "version.h" @@ -61,7 +62,7 @@ void config_err(const char *fmt, ...) va_list args; va_start(args, fmt); vfprintf(stderr, (QCString(error_str) + fmt).data(), args); - va_end(args); + va_end(args); } void config_term(const char *fmt, ...) { @@ -141,7 +142,7 @@ void ConfigOption::writeIntValue(FTextStream &t,int i) t << " " << i; } -void ConfigOption::writeStringValue(FTextStream &t,QCString &s) +void ConfigOption::writeStringValue(FTextStream &t,const QCString &s) { char c; bool needsEscaping=FALSE; @@ -151,10 +152,10 @@ void ConfigOption::writeStringValue(FTextStream &t,QCString &s) if (p) { t << " "; - while ((c=*p++)!=0 && !needsEscaping) + while ((c=*p++)!=0 && !needsEscaping) needsEscaping = (c==' ' || c=='\n' || c=='\t' || c=='"' || c=='#'); if (needsEscaping) - { + { t << "\""; p=se.data(); while (*p) @@ -172,19 +173,17 @@ void ConfigOption::writeStringValue(FTextStream &t,QCString &s) } } -void ConfigOption::writeStringList(FTextStream &t,QStrList &l) +void ConfigOption::writeStringList(FTextStream &t,const StringVector &l) { - const char *p = l.first(); bool first=TRUE; - while (p) + for (const auto &p : l) { - QCString s=p; + if (!first) t << " \\" << endl; + QCString s=p.c_str(); if (!first) t << " "; - first=FALSE; writeStringValue(t,s); - p = l.next(); - if (p) t << " \\" << endl; + first=FALSE; } } @@ -193,7 +192,7 @@ void ConfigOption::writeStringList(FTextStream &t,QStrList &l) ConfigImpl *ConfigImpl::m_instance = 0; -void ConfigInt::convertStrToVal() +void ConfigInt::convertStrToVal() { if (!m_valueString.isEmpty()) { @@ -216,7 +215,7 @@ void ConfigBool::convertStrToVal() QCString val = m_valueString.stripWhiteSpace().lower(); if (!val.isEmpty()) { - if (val=="yes" || val=="true" || val=="1" || val=="all") + if (val=="yes" || val=="true" || val=="1" || val=="all") { m_value=TRUE; } @@ -234,6 +233,11 @@ void ConfigBool::convertStrToVal() void ConfigEnum::convertStrToVal() { + if (m_value.isEmpty()) + { + m_value = m_defValue; + return; + } QCString val = m_value.stripWhiteSpace().lower(); const char *s=m_valueRange.first(); while (s) @@ -254,7 +258,7 @@ void ConfigEnum::convertStrToVal() QCString &ConfigImpl::getString(const char *fileName,int num,const char *name) const { ConfigOption *opt = m_dict->find(name); - if (opt==0) + if (opt==0) { config_term("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name); } @@ -265,10 +269,10 @@ QCString &ConfigImpl::getString(const char *fileName,int num,const char *name) c return *((ConfigString *)opt)->valueRef(); } -QStrList &ConfigImpl::getList(const char *fileName,int num,const char *name) const +StringVector &ConfigImpl::getList(const char *fileName,int num,const char *name) const { ConfigOption *opt = m_dict->find(name); - if (opt==0) + if (opt==0) { config_term("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name); } @@ -282,7 +286,7 @@ QStrList &ConfigImpl::getList(const char *fileName,int num,const char *name) con QCString &ConfigImpl::getEnum(const char *fileName,int num,const char *name) const { ConfigOption *opt = m_dict->find(name); - if (opt==0) + if (opt==0) { config_term("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name); } @@ -296,7 +300,7 @@ QCString &ConfigImpl::getEnum(const char *fileName,int num,const char *name) con int &ConfigImpl::getInt(const char *fileName,int num,const char *name) const { ConfigOption *opt = m_dict->find(name); - if (opt==0) + if (opt==0) { config_term("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name); } @@ -310,7 +314,7 @@ int &ConfigImpl::getInt(const char *fileName,int num,const char *name) const bool &ConfigImpl::getBool(const char *fileName,int num,const char *name) const { ConfigOption *opt = m_dict->find(name); - if (opt==0) + if (opt==0) { config_term("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name); } @@ -353,71 +357,33 @@ void ConfigList::writeTemplate(FTextStream &t,bool sl,bool) void ConfigList::compareDoxyfile(FTextStream &t) { - const char *p = m_value.first(); - const char *q = m_defaultValue.first(); - int defCnt = 0; - int valCnt = 0; - - // count non empty elements - while (p) - { - QCString s=p; - if (!s.stripWhiteSpace().isEmpty()) valCnt += 1; - p = m_value.next(); - } - - while (q) - { - QCString s=q; - if (!s.stripWhiteSpace().isEmpty()) defCnt += 1; - q = m_defaultValue.next(); - } + auto get_stripped = [](std::string s) { return QCString(s.c_str()).stripWhiteSpace(); }; + auto is_not_empty = [get_stripped](std::string s) { return !get_stripped(s).isEmpty(); }; + int defCnt = std::count_if( m_value.begin(), m_value.end(),is_not_empty); + int valCnt = std::count_if(m_defaultValue.begin(),m_defaultValue.end(),is_not_empty); if ( valCnt != defCnt) { writeTemplate(t,TRUE,TRUE); return; } - - // get first non empry element - q = m_defaultValue.first(); - p = m_value.first(); - QCString sp = p; - while (p && sp.stripWhiteSpace().isEmpty()) - { - p = m_value.next(); - sp = p; - } - QCString sq = q; - while (q && sq.stripWhiteSpace().isEmpty()) - { - q = m_value.next(); - sq = q; - } - while (p) + auto it1 = m_value.begin(); + auto it2 = m_defaultValue.begin(); + while (it1!=m_value.end() && it2!=m_defaultValue.end()) { - // skip empty elements - sp = p; - while (p && sp.stripWhiteSpace().isEmpty()) + // skip over empty values + while (it1!=m_value.end() && !is_not_empty(*it1)) { - p = m_value.next(); - sp = p; + ++it1; } - sq = q; - while (q && sq.stripWhiteSpace().isEmpty()) + if (it1!=m_value.end()) // non-empty value { - q = m_value.next(); - sq = q; - } - // be sure we have still an element (p and q have same number of 'filled' elements) - if (p) - { - if (sp.stripWhiteSpace() != sq.stripWhiteSpace()) + if (get_stripped(*it1) != get_stripped(*it2)) // not the default, write as difference { writeTemplate(t,TRUE,TRUE); return; } - p = m_value.next(); - q = m_defaultValue.next(); + ++it1; + ++it2; } } } @@ -539,7 +505,7 @@ struct ConfigFileState YY_BUFFER_STATE oldState; YY_BUFFER_STATE newState; QCString fileName; -}; +}; static const char *g_inputString; static int g_inputPosition; @@ -548,11 +514,11 @@ static QCString g_yyFileName; static QCString g_tmpString; static QCString *g_string=0; static bool *g_bool=0; -static QStrList *g_list=0; +static StringVector *g_list=0; static int g_lastState; static QCString g_elemStr; -static QStrList g_includePathList; -static QStack<ConfigFileState> g_includeStack; +static StringVector g_includePathList; +static QStack<ConfigFileState> g_includeStack; static int g_includeDepth; static bool g_configUpdate = FALSE; static QCString g_encoding; @@ -566,7 +532,7 @@ static ConfigImpl *g_config; static yy_size_t yyread(char *buf,yy_size_t max_size) { // no file included - if (g_includeStack.isEmpty()) + if (g_includeStack.isEmpty()) { yy_size_t c=0; if (g_inputString==0) return c; @@ -597,7 +563,7 @@ static QCString configStringRecode( int outputSize=inputSize*4+1; QCString output(outputSize); void *cd = portable_iconv_open(outputEncoding,inputEncoding); - if (cd==(void *)(-1)) + if (cd==(void *)(-1)) { config_term("Error: unsupported character conversion: '%s'->'%s'\n", inputEncoding.data(),outputEncoding.data()); @@ -641,7 +607,7 @@ static FILE *tryPath(const char *path,const char *fileName) return 0; } -static void substEnvVarsInStrList(QStrList &sl); +static void substEnvVarsInStrList(StringVector &sl); static void substEnvVarsInString(QCString &s); static FILE *findFile(const char *fileName) @@ -655,13 +621,11 @@ static FILE *findFile(const char *fileName) return tryPath(NULL, fileName); } substEnvVarsInStrList(g_includePathList); - char *s=g_includePathList.first(); - while (s) // try each of the include paths + for (const auto &s : g_includePathList) { - FILE *f = tryPath(s,fileName); + FILE *f = tryPath(s.c_str(),fileName); if (f) return f; - s=g_includePathList.next(); - } + } // try cwd if g_includePathList fails return tryPath(".",fileName); } @@ -671,7 +635,7 @@ static void readIncludeFile(const char *incName) if (g_includeDepth==MAX_INCLUDE_DEPTH) { config_term("maximum include depth (%d) reached, %s is not included. Aborting...\n", MAX_INCLUDE_DEPTH,incName); - } + } QCString inc = incName; substEnvVarsInString(inc); @@ -692,7 +656,7 @@ static void readIncludeFile(const char *incName) msg("@INCLUDE = %s: parsing...\n",inc.data()); #endif - // store the state of the old file + // store the state of the old file ConfigFileState *fs=new ConfigFileState; fs->oldState=YY_CURRENT_BUFFER; fs->lineNr=g_yyLineNr; @@ -705,7 +669,7 @@ static void readIncludeFile(const char *incName) fs->newState=YY_CURRENT_BUFFER; g_yyFileName=inc; g_includeDepth++; - } + } else { config_term("@INCLUDE = %s: not found!\n",inc.data()); @@ -740,12 +704,12 @@ static void readIncludeFile(const char *incName) <Start,GetString,GetStrList,GetStrList1,GetBool,SkipInvalid>"##".*"\n" { g_config->appendUserComment(yytext);g_yyLineNr++;} <Start,GetString,GetStrList,GetStrList1,GetBool,SkipInvalid>"#" { BEGIN(SkipComment); } <Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"=" { QCString cmd=yytext; - cmd=cmd.left(cmd.length()-1).stripWhiteSpace(); + cmd=cmd.left(cmd.length()-1).stripWhiteSpace(); ConfigOption *option = g_config->get(cmd); if (option==0) // oops not known { config_warn("ignoring unsupported tag '%s' at line %d, file %s\n", - cmd.data(),g_yyLineNr,g_yyFileName.data()); + cmd.data(),g_yyLineNr,g_yyFileName.data()); BEGIN(SkipInvalid); } else // known tag @@ -801,7 +765,7 @@ static void readIncludeFile(const char *incName) { config_warn("Tag '%s' at line %d of file '%s' has become obsolete.\n" " To avoid this warning please remove this line from your configuration " - "file or upgrade it using \"doxygen -u\"\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); + "file or upgrade it using \"doxygen -u\"\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); } BEGIN(SkipInvalid); break; @@ -815,7 +779,7 @@ static void readIncludeFile(const char *incName) { config_warn("Tag '%s' at line %d of file '%s' belongs to an option that was not enabled at compile time.\n" " To avoid this warning please remove this line from your configuration " - "file or upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); + "file or upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); } BEGIN(SkipInvalid); break; @@ -823,12 +787,12 @@ static void readIncludeFile(const char *incName) } } <Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"+=" { QCString cmd=yytext; - cmd=cmd.left(cmd.length()-2).stripWhiteSpace(); + cmd=cmd.left(cmd.length()-2).stripWhiteSpace(); ConfigOption *option = g_config->get(cmd); if (option==0) // oops not known { config_warn("ignoring unsupported tag '%s' at line %d, file %s\n", - cmd.data(),g_yyLineNr,g_yyFileName.data()); + cmd.data(),g_yyLineNr,g_yyFileName.data()); BEGIN(SkipInvalid); } else // known tag @@ -857,19 +821,19 @@ static void readIncludeFile(const char *incName) case ConfigOption::O_Int: case ConfigOption::O_Bool: config_warn("operator += not supported for '%s'. Ignoring line at line %d, file %s\n", - yytext,g_yyLineNr,g_yyFileName.data()); + yytext,g_yyLineNr,g_yyFileName.data()); BEGIN(SkipInvalid); break; case ConfigOption::O_Obsolete: config_warn("Tag '%s' at line %d of file %s has become obsolete.\n" "To avoid this warning please update your configuration " - "file using \"doxygen -u\"\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); + "file using \"doxygen -u\"\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); BEGIN(SkipInvalid); break; case ConfigOption::O_Disabled: config_warn("Tag '%s' at line %d of file %s belongs to an option that was not enabled at compile time.\n" "To avoid this warning please remove this line from your configuration " - "file, upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); + "file, upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),g_yyLineNr,g_yyFileName.data()); BEGIN(SkipInvalid); break; } @@ -878,8 +842,8 @@ static void readIncludeFile(const char *incName) <Start>"@INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); g_list=&g_includePathList; g_list->clear(); g_elemStr=""; } /* include a g_config file */ <Start>"@INCLUDE"[ \t]*"=" { BEGIN(Include);} -<Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") { - readIncludeFile(configStringRecode(yytext,g_encoding,"UTF-8")); +<Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") { + readIncludeFile(configStringRecode(yytext,g_encoding,"UTF-8")); BEGIN(Start); } <<EOF>> { @@ -907,19 +871,19 @@ static void readIncludeFile(const char *incName) <Start>[a-z_A-Z0-9]+ { config_warn("ignoring unknown tag '%s' at line %d, file %s\n",yytext,g_yyLineNr,g_yyFileName.data()); } <GetString,GetBool,SkipInvalid>\n { g_yyLineNr++; BEGIN(Start); } <GetStrList,GetStrList1>\n { - g_yyLineNr++; + g_yyLineNr++; if (!g_elemStr.isEmpty()) { //printf("elemStr1='%s'\n",g_elemStr.data()); - g_list->append(g_elemStr); + g_list->push_back(g_elemStr.data()); } - BEGIN(Start); + BEGIN(Start); } <GetStrList1>[ \t]+ { if (!g_elemStr.isEmpty()) { //printf("elemStr2='%s'\n",g_elemStr.data()); - g_list->append(g_elemStr); + g_list->push_back(g_elemStr.data()); } g_elemStr.resize(0); } @@ -927,18 +891,18 @@ static void readIncludeFile(const char *incName) if (!g_elemStr.isEmpty()) { //printf("elemStr2='%s'\n",g_elemStr.data()); - g_list->append(g_elemStr); + g_list->push_back(g_elemStr.data()); } g_elemStr.resize(0); } -<GetString>[^ \"\t\r\n]+ { (*g_string)+=configStringRecode(yytext,g_encoding,"UTF-8"); +<GetString>[^ \"\t\r\n]+ { (*g_string)+=configStringRecode(yytext,g_encoding,"UTF-8"); checkEncoding(); } <GetString,GetStrList,GetStrList1,SkipInvalid>"\"" { g_lastState=YY_START; - BEGIN(GetQuotedString); - g_tmpString.resize(0); + BEGIN(GetQuotedString); + g_tmpString.resize(0); } -<GetQuotedString>"\""|"\n" { +<GetQuotedString>"\""|"\n" { // we add a bogus space to signal that the string was quoted. This space will be stripped later on. g_tmpString+=" "; //printf("Quoted String = '%s'\n",g_tmpString.data()); @@ -962,16 +926,16 @@ static void readIncludeFile(const char *incName) g_tmpString+='"'; } <GetQuotedString>. { g_tmpString+=*yytext; } -<GetBool>[a-zA-Z]+ { - QCString bs=yytext; +<GetBool>[a-zA-Z]+ { + QCString bs=yytext; bs=bs.upper(); if (bs=="YES" || bs=="1") *g_bool=TRUE; else if (bs=="NO" || bs=="0") *g_bool=FALSE; - else + else { - *g_bool=FALSE; + *g_bool=FALSE; config_warn("Invalid value '%s' for " "boolean tag in line %d, file %s; use YES or NO\n", bs.data(),g_yyLineNr,g_yyFileName.data()); @@ -986,7 +950,7 @@ static void readIncludeFile(const char *incName) <SkipComment>\n { g_yyLineNr++; BEGIN(Start); } <SkipComment>\\[ \r\t]*\n { g_yyLineNr++; BEGIN(Start); } <*>\\[ \r\t]*\n { g_yyLineNr++; } -<*>. +<*>. <*>\n { g_yyLineNr++ ; } %% @@ -999,7 +963,7 @@ void ConfigImpl::writeTemplate(FTextStream &t,bool sl,bool upd) /* print first lines of user comment that were at the beginning of the file, might have special meaning for editors */ if (m_startComment) { - t << takeStartComment() << endl; + t << takeStartComment() << endl; } t << "# Doxyfile " << getDoxygenVersion() << endl << endl; if (!sl) @@ -1073,12 +1037,12 @@ static void substEnvVarsInString(QCString &s) //printf("substEnvVarInString(%s) end\n",s.data()); } -static void substEnvVarsInStrList(QStrList &sl) +static void substEnvVarsInStrList(StringVector &sl) { - char *s = sl.first(); - while (s) + StringVector results; + for (const auto &s : sl) { - QCString result(s); + QCString result = s.c_str(); // an argument with quotes will have an extra space at the end, so wasQuoted will be TRUE. bool wasQuoted = (result.find(' ')!=-1) || (result.find('\t')!=-1); // here we strip the quote again @@ -1088,8 +1052,8 @@ static void substEnvVarsInStrList(QStrList &sl) if (!wasQuoted) /* as a result of the expansion, a single string may have expanded into a list, which we'll - add to sl. If the original string already - contained multiple elements no further + add to sl. If the original string already + contained multiple elements no further splitting is done to allow quoted items with spaces! */ { int l=result.length(); @@ -1100,7 +1064,7 @@ static void substEnvVarsInStrList(QStrList &sl) { char c=0; // skip until start of new word - while (i<l && ((c=result.at(i))==' ' || c=='\t')) i++; + while (i<l && ((c=result.at(i))==' ' || c=='\t')) i++; p=i; // p marks the start index of the word // skip until end of a word while (i<l && ((c=result.at(i))!=' ' && c!='\t' && c!='"')) i++; @@ -1114,11 +1078,9 @@ static void substEnvVarsInStrList(QStrList &sl) c=result.at(i); if (c=='"') // end quote { - // replace the string in the list and go to the next item. - sl.insert(sl.at(),result.mid(p,i-p)); // insert new item before current item. - sl.next(); // current item is now the old item + results.push_back(result.mid(p,i-p).data()); p=i+1; - break; + break; } else if (c=='\\') // skip escaped stuff { @@ -1128,33 +1090,22 @@ static void substEnvVarsInStrList(QStrList &sl) } else if (c==' ' || c=='\t') // separator { - // replace the string in the list and go to the next item. - sl.insert(sl.at(),result.mid(p,i-p)); // insert new item before current item. - sl.next(); // current item is now the old item + if (i>p) results.push_back(result.mid(p,i-p).data()); p=i+1; } } } if (p!=l) // add the leftover as a string { - // replace the string in the list and go to the next item. - sl.insert(sl.at(),result.right(l-p)); // insert new item before current item. - sl.next(); // current item is now the old item + results.push_back(result.right(l-p).data()); } } else // just goto the next element in the list { - sl.insert(sl.at(),result); - sl.next(); + if (!result.isEmpty()) results.push_back(result.data()); } - // remove the old unexpanded string from the list - int i=sl.at(); - sl.remove(); // current item index changes if the last element is removed. - if (sl.at()==i) // not last item - s = sl.current(); - else // just removed last item - s = 0; } + sl = results; } void ConfigString::substEnvVars() @@ -1221,7 +1172,7 @@ void ConfigImpl::init() void ConfigImpl::create() { - if (m_initialized) return; + if (m_initialized) return; m_initialized = TRUE; addConfigOptions(this); } @@ -1244,7 +1195,7 @@ static QCString configFileToString(const char *name) while ((size=f.readBlock(contents.rawData()+totalSize,bSize))==bSize) { totalSize+=bSize; - contents.resize(totalSize+bSize); + contents.resize(totalSize+bSize); } totalSize+=size+2; contents.resize(totalSize); @@ -1269,7 +1220,7 @@ static QCString configFileToString(const char *name) QCString contents(fsize+2); f.readBlock(contents.rawData(),fsize); f.close(); - if (fsize==0 || contents[fsize-1]=='\n') + if (fsize==0 || contents[fsize-1]=='\n') contents[fsize]='\0'; else contents[fsize]='\n'; // to help the scanner @@ -1277,7 +1228,7 @@ static QCString configFileToString(const char *name) return contents; } } - if (!fileOpened) + if (!fileOpened) { config_term("cannot open file '%s' for reading\n",name); } @@ -1308,59 +1259,42 @@ bool ConfigImpl::parse(const char *fn,bool update) int retval; g_encoding = "UTF-8"; printlex(yy_flex_debug, TRUE, __FILE__, fn); - retval = parseString(fn,configFileToString(fn), update); + retval = parseString(fn,configFileToString(fn), update); printlex(yy_flex_debug, FALSE, __FILE__, fn); return retval; } //---------------------------------------------------------------------- -static void cleanUpPaths(QStrList &str) +static void cleanUpPaths(StringVector &str) { - char *sfp = str.first(); - while (sfp) + for (size_t i=0;i<str.size();i++) { - char *p = sfp; - if (p) - { - char c; - while ((c=*p)) - { - if (c=='\\') *p='/'; - p++; - } - } - QCString path = sfp; - if ((path.at(0)!='/' && (path.length()<=2 || path.at(1)!=':')) || - path.at(path.length()-1)!='/' - ) + std::string path = str[i]; + std::replace(path.begin(),path.end(),'\\','/'); + if ((path[0]!='/' && (path.size()<=2 || path[1]!=':')) || path[path.size()-1]!='/') { - QFileInfo fi(path); + QFileInfo fi(path.c_str()); if (fi.exists() && fi.isDir()) { - int i = str.at(); - QCString path_str = fi.absFilePath().utf8(); - if (path_str[path_str.length()-1]!='/') path_str+='/'; - str.remove(); - if (str.at()==i) // did not remove last item - str.insert(i,path_str); - else - str.append(path_str); + path = fi.absFilePath().utf8().data(); + if (path[path.size()-1]!='/') path+='/'; } } - sfp = str.next(); + str[i]=path; } } -static void checkFileName(QCString &s,const char *optionName) +static bool checkFileName(const QCString &s,const char *optionName) { QCString val = s.stripWhiteSpace().lower(); if ((val=="yes" || val=="true" || val=="1" || val=="all") || (val=="no" || val=="false" || val=="0" || val=="none")) { err("file name expected for option %s, got %s instead. Ignoring...\n",optionName,s.data()); - s=""; // note the use of &s above: this will change the option value! + return false; } + return true; } #include "config.h" @@ -1370,12 +1304,11 @@ void Config::init() ConfigImpl::instance()->init(); } -static void checkList(QStrList &list,const char *name, bool equalRequired,bool valueRequired) +static void checkList(const StringVector &list,const char *name, bool equalRequired,bool valueRequired) { - const char *s=list.first(); - while (s) + for (const auto &s: list) { - QCString item=s; + QCString item=s.c_str(); item=item.stripWhiteSpace(); int i=item.find('='); if (i==-1 && equalRequired) @@ -1398,7 +1331,6 @@ static void checkList(QStrList &list,const char *name, bool equalRequired,bool v } } } - s=list.next(); } } @@ -1406,17 +1338,18 @@ void Config::checkAndCorrect() { ConfigValues::instance().init(); - QCString &warnFormat = Config_getString(WARN_FORMAT); + //------------------------ + // check WARN_FORMAT + QCString warnFormat = Config_getString(WARN_FORMAT); if (warnFormat.stripWhiteSpace().isEmpty()) { - warnFormat="$file:$line $text"; + Config_updateString(WARN_FORMAT,"$file:$line $text"); } else { if (warnFormat.find("$file")==-1) { warn_uncond("warning format does not contain a $file tag!\n"); - } if (warnFormat.find("$line")==-1) { @@ -1428,15 +1361,17 @@ void Config::checkAndCorrect() } } - QCString &manExtension = Config_getString(MAN_EXTENSION); - + //------------------------ // set default man page extension if non is given by the user + QCString manExtension = Config_getString(MAN_EXTENSION); if (manExtension.isEmpty()) { - manExtension=".3"; + Config_updateString(MAN_EXTENSION,".3"); } - QCString &paperType = Config_getEnum(PAPER_TYPE); + //------------------------ + // check and correct PAPER_TYPE + QCString paperType = Config_getEnum(PAPER_TYPE); paperType=paperType.lower().stripWhiteSpace(); if (paperType.isEmpty() || paperType=="a4wide") { @@ -1448,42 +1383,53 @@ void Config::checkAndCorrect() err("Unknown page type specified\n"); paperType="a4"; } + Config_updateEnum(PAPER_TYPE,paperType); - QCString &outputLanguage=Config_getEnum(OUTPUT_LANGUAGE); + //------------------------ + // check & correct OUTPUT_LANGUAGE + QCString outputLanguage=Config_getEnum(OUTPUT_LANGUAGE); outputLanguage=outputLanguage.stripWhiteSpace(); if (outputLanguage.isEmpty()) { outputLanguage = "English"; } + Config_updateEnum(OUTPUT_LANGUAGE,outputLanguage); - QCString &htmlFileExtension=Config_getString(HTML_FILE_EXTENSION); + //------------------------ + // check & correct HTML_FILE_EXTENSION + QCString htmlFileExtension=Config_getString(HTML_FILE_EXTENSION); htmlFileExtension=htmlFileExtension.stripWhiteSpace(); if (htmlFileExtension.isEmpty()) { htmlFileExtension = ".html"; } + Config_updateString(HTML_FILE_EXTENSION,htmlFileExtension); - // expand the relative stripFromPath values - QStrList &stripFromPath = Config_getList(STRIP_FROM_PATH); - char *sfp = stripFromPath.first(); - if (sfp==0) // by default use the current path + //------------------------ + // check & correct STRIP_FROM_PATH + StringVector stripFromPath = Config_getList(STRIP_FROM_PATH); + if (stripFromPath.empty()) // by default use the current path { QString p = QDir::currentDirPath(); if (p.at(p.length()-1)!='/') p.append('/'); - stripFromPath.append(p.utf8()); + stripFromPath.push_back(p.utf8().data()); } else { cleanUpPaths(stripFromPath); } + Config_updateList(STRIP_FROM_PATH,stripFromPath); - // expand the relative stripFromPath values - QStrList &stripFromIncPath = Config_getList(STRIP_FROM_INC_PATH); + //------------------------ + // check & correct STRIP_FROM_INC_PATH + StringVector stripFromIncPath = Config_getList(STRIP_FROM_INC_PATH); cleanUpPaths(stripFromIncPath); + Config_updateList(STRIP_FROM_INC_PATH,stripFromIncPath); + //------------------------ // Test to see if HTML header is valid - QCString &headerFile = Config_getString(HTML_HEADER); + QCString headerFile = Config_getString(HTML_HEADER); if (!headerFile.isEmpty()) { QFileInfo fi(headerFile); @@ -1493,8 +1439,10 @@ void Config::checkAndCorrect() "does not exist\n",headerFile.data()); } } + + //------------------------ // Test to see if HTML footer is valid - QCString &footerFile = Config_getString(HTML_FOOTER); + QCString footerFile = Config_getString(HTML_FOOTER); if (!footerFile.isEmpty()) { QFileInfo fi(footerFile); @@ -1505,29 +1453,31 @@ void Config::checkAndCorrect() } } + //------------------------ // Test to see if MathJax code file is valid if (Config_getBool(USE_MATHJAX)) { - QCString &MathJaxCodefile = Config_getString(MATHJAX_CODEFILE); - if (!MathJaxCodefile.isEmpty()) + QCString mathJaxCodefile = Config_getString(MATHJAX_CODEFILE); + if (!mathJaxCodefile.isEmpty()) { - QFileInfo fi(MathJaxCodefile); + QFileInfo fi(mathJaxCodefile); if (!fi.exists()) { config_term("tag MATHJAX_CODEFILE file '%s' " - "does not exist\n",MathJaxCodefile.data()); + "does not exist\n",mathJaxCodefile.data()); } } - QCString &path = Config_getString(MATHJAX_RELPATH); + QCString path = Config_getString(MATHJAX_RELPATH); if (!path.isEmpty() && path.at(path.length()-1)!='/') { path+="/"; } - + Config_updateString(MATHJAX_RELPATH,path); } + //------------------------ // Test to see if LaTeX header is valid - QCString &latexHeaderFile = Config_getString(LATEX_HEADER); + QCString latexHeaderFile = Config_getString(LATEX_HEADER); if (!latexHeaderFile.isEmpty()) { QFileInfo fi(latexHeaderFile); @@ -1537,8 +1487,10 @@ void Config::checkAndCorrect() "does not exist\n",latexHeaderFile.data()); } } + + //------------------------ // Test to see if LaTeX footer is valid - QCString &latexFooterFile = Config_getString(LATEX_FOOTER); + QCString latexFooterFile = Config_getString(LATEX_FOOTER); if (!latexFooterFile.isEmpty()) { QFileInfo fi(latexFooterFile); @@ -1549,25 +1501,24 @@ void Config::checkAndCorrect() } } + //------------------------ // check include path - QStrList &includePath = Config_getList(INCLUDE_PATH); - char *s=includePath.first(); - while (s) + const StringVector &includePath = Config_getList(INCLUDE_PATH); + for (const auto &s : includePath) { - QFileInfo fi(s); + QFileInfo fi(s.c_str()); if (!fi.exists()) warn_uncond("tag INCLUDE_PATH: include path '%s' " - "does not exist\n",s); - s=includePath.next(); + "does not exist\n",s.c_str()); } + //------------------------ // check PREDEFINED if (Config_getBool(ENABLE_PREPROCESSING)) { - QStrList &predefList = Config_getList(PREDEFINED); - s=predefList.first(); - while (s) + const StringVector &predefList = Config_getList(PREDEFINED); + for (const auto &s : predefList) { - QCString predef=s; + QCString predef=s.c_str(); predef=predef.stripWhiteSpace(); int i_equals=predef.find('='); int i_obrace=predef.find('('); @@ -1575,79 +1526,85 @@ void Config::checkAndCorrect() { err("Illegal PREDEFINED format '%s', no define name specified\n",predef.data()); } - s=predefList.next(); } } + //------------------------ // check ALIASES - QStrList &aliasList = Config_getList(ALIASES); - s=aliasList.first(); - while (s) + const StringVector &aliasList = Config_getList(ALIASES); + for (const auto &s : aliasList) { QRegExp re1("[a-z_A-Z][a-z_A-Z0-9]*[ \t]*="); // alias without argument QRegExp re2("[a-z_A-Z][a-z_A-Z0-9]*{[0-9]+}[ \t]*="); // alias with argument - QCString alias=s; + QCString alias=s.c_str(); alias=alias.stripWhiteSpace(); if (alias.find(re1)!=0 && alias.find(re2)!=0) { err("Illegal ALIASES format '%s'. Use \"name=value\" or \"name{n}=value\", where n is the number of arguments\n", alias.data()); } - s=aliasList.next(); } + //------------------------ // check EXTENSION_MAPPING checkList(Config_getList(EXTENSION_MAPPING),"EXTENSION_MAPPING",TRUE,TRUE); + //------------------------ // check FILTER_PATTERNS checkList(Config_getList(FILTER_PATTERNS),"FILTER_PATTERNS",TRUE,TRUE); + //------------------------ // check FILTER_SOURCE_PATTERNS checkList(Config_getList(FILTER_SOURCE_PATTERNS),"FILTER_SOURCE_PATTERNS",FALSE,FALSE); + //------------------------ // check TAGFILES checkList(Config_getList(TAGFILES),"TAGFILES",FALSE,TRUE); + //------------------------ // check EXTRA_SEARCH_MAPPINGS if (Config_getBool(SEARCHENGINE) && Config_getBool(GENERATE_HTML)) { checkList(Config_getList(EXTRA_SEARCH_MAPPINGS),"EXTRA_SEARCH_MAPPING",TRUE,TRUE); } + //------------------------ // check if GENERATE_TREEVIEW and GENERATE_HTMLHELP are both enabled if (Config_getBool(GENERATE_TREEVIEW) && Config_getBool(GENERATE_HTMLHELP)) { err("When enabling GENERATE_HTMLHELP the tree view (GENERATE_TREEVIEW) should be disabled. I'll do it for you.\n"); - Config_getBool(GENERATE_TREEVIEW)=FALSE; + Config_updateBool(GENERATE_TREEVIEW,FALSE); } + + //------------------------ + // check if SEARCHENGINE and GENERATE_HTMLHELP are both enabled if (Config_getBool(SEARCHENGINE) && Config_getBool(GENERATE_HTMLHELP)) { err("When enabling GENERATE_HTMLHELP the search engine (SEARCHENGINE) should be disabled. I'll do it for you.\n"); - Config_getBool(SEARCHENGINE)=FALSE; + Config_updateBool(SEARCHENGINE,FALSE); } + //------------------------ // check if SEPARATE_MEMBER_PAGES and INLINE_GROUPED_CLASSES are both enabled if (Config_getBool(SEPARATE_MEMBER_PAGES) && Config_getBool(INLINE_GROUPED_CLASSES)) { err("When enabling INLINE_GROUPED_CLASSES the SEPARATE_MEMBER_PAGES option should be disabled. I'll do it for you.\n"); - Config_getBool(SEPARATE_MEMBER_PAGES)=FALSE; + Config_updateBool(SEPARATE_MEMBER_PAGES,FALSE); } - // check dot image format - QCString &dotImageFormat=Config_getEnum(DOT_IMAGE_FORMAT); + //------------------------ + // check and correct DOT_IMAGE_FORMAT + QCString dotImageFormat=Config_getEnum(DOT_IMAGE_FORMAT); dotImageFormat=dotImageFormat.stripWhiteSpace(); if (dotImageFormat.isEmpty()) { dotImageFormat = "png"; } - //else if (dotImageFormat!="gif" && dotImageFormat!="png" && dotImageFormat!="jpg") - //{ - // err("Invalid value for DOT_IMAGE_FORMAT: '%s'. Using the default.\n",dotImageFormat.data()); - // dotImageFormat = "png"; - //} + Config_updateEnum(DOT_IMAGE_FORMAT,dotImageFormat); + //------------------------ // correct DOT_FONTNAME if needed - QCString &dotFontName=Config_getString(DOT_FONTNAME); + QCString dotFontName=Config_getString(DOT_FONTNAME); if (dotFontName=="FreeSans" || dotFontName=="FreeSans.ttf") { warn_uncond("doxygen no longer ships with the FreeSans font.\n" @@ -1658,9 +1615,11 @@ void Config::checkAndCorrect() { dotFontName = "Helvetica"; } + Config_updateString(DOT_FONTNAME,dotFontName); + //------------------------ // clip dotFontSize against the maximum bounds - int &dotFontSize = Config_getInt(DOT_FONTSIZE); + int dotFontSize = Config_getInt(DOT_FONTSIZE); if (dotFontSize<4) { dotFontSize=4; @@ -1669,9 +1628,11 @@ void Config::checkAndCorrect() { dotFontSize=24; } + Config_updateInt(DOT_FONTSIZE,dotFontSize); + //------------------------ // clip number of threads - int &dotNumThreads = Config_getInt(DOT_NUM_THREADS); + int dotNumThreads = Config_getInt(DOT_NUM_THREADS); if (dotNumThreads>32) { dotNumThreads=32; @@ -1680,9 +1641,11 @@ void Config::checkAndCorrect() { dotNumThreads=QMAX(2,std::thread::hardware_concurrency()+1); } + Config_updateInt(DOT_NUM_THREADS,dotNumThreads); + //------------------------ // check dot path - QCString &dotPath = Config_getString(DOT_PATH); + QCString dotPath = Config_getString(DOT_PATH); if (!dotPath.isEmpty()) { QFileInfo fi(dotPath); @@ -1712,9 +1675,11 @@ void Config::checkAndCorrect() { dotPath=""; } + Config_updateString(DOT_PATH,dotPath); + //------------------------ // check plantuml path - QCString &plantumlJarPath = Config_getString(PLANTUML_JAR_PATH); + QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH); if (!plantumlJarPath.isEmpty()) { QFileInfo pu(plantumlJarPath); @@ -1743,9 +1708,11 @@ void Config::checkAndCorrect() plantumlJarPath=""; } } + Config_updateString(PLANTUML_JAR_PATH,plantumlJarPath); + //------------------------ // check dia path - QCString &diaPath = Config_getString(DIA_PATH); + QCString diaPath = Config_getString(DIA_PATH); if (!diaPath.isEmpty()) { QFileInfo dp(diaPath+"/dia"+Portable::commandExtension()); @@ -1767,52 +1734,52 @@ void Config::checkAndCorrect() { diaPath=""; } + Config_updateString(DIA_PATH,diaPath); - // check input - QStrList &inputSources=Config_getList(INPUT); - if (inputSources.count()==0) + //------------------------ + // check INPUT + StringVector inputSources=Config_getList(INPUT); + if (inputSources.empty()) { // use current dir as the default - inputSources.append(QDir::currentDirPath().utf8()); + inputSources.push_back(QDir::currentDirPath().utf8().data()); } else { - s=inputSources.first(); - while (s) + for (const auto &s : inputSources) { - QFileInfo fi(s); + QFileInfo fi(s.c_str()); if (!fi.exists()) { - warn_uncond("tag INPUT: input source '%s' does not exist\n",s); + warn_uncond("tag INPUT: input source '%s' does not exist\n",s.c_str()); } - s=inputSources.next(); } } + Config_updateList(INPUT,inputSources); + //------------------------ // add default file patterns if needed - QStrList &filePatternList = Config_getList(FILE_PATTERNS); - if (filePatternList.isEmpty()) + StringVector filePatternList = Config_getList(FILE_PATTERNS); + if (filePatternList.empty()) { ConfigOption * opt = ConfigImpl::instance()->get("FILE_PATTERNS"); if (opt->kind()==ConfigOption::O_List) { - QStrList l = ((ConfigList*)opt)->getDefault(); - const char *p = l.first(); - while (p) - { - filePatternList.append(p); - p = l.next(); - } + filePatternList = ((ConfigList*)opt)->getDefault(); } } + Config_updateList(FILE_PATTERNS,filePatternList); + //------------------------ // add default pattern if needed - QStrList &examplePatternList = Config_getList(EXAMPLE_PATTERNS); - if (examplePatternList.isEmpty()) + StringVector examplePatternList = Config_getList(EXAMPLE_PATTERNS); + if (examplePatternList.empty()) { - examplePatternList.append("*"); + examplePatternList.push_back("*"); + Config_updateList(EXAMPLE_PATTERNS,examplePatternList); } + //------------------------ // if no output format is enabled, warn the user if (!Config_getBool(GENERATE_HTML) && !Config_getBool(GENERATE_LATEX) && @@ -1829,6 +1796,7 @@ void Config::checkAndCorrect() warn_uncond("No output formats selected! Set at least one of the main GENERATE_* options to YES.\n"); } + //------------------------ // check HTMLHELP creation requirements if (!Config_getBool(GENERATE_HTML) && Config_getBool(GENERATE_HTMLHELP)) @@ -1836,36 +1804,40 @@ void Config::checkAndCorrect() warn_uncond("GENERATE_HTMLHELP=YES requires GENERATE_HTML=YES.\n"); } + //------------------------ // check QHP creation requirements if (Config_getBool(GENERATE_QHP)) { if (Config_getString(QHP_NAMESPACE).isEmpty()) { err("GENERATE_QHP=YES requires QHP_NAMESPACE to be set. Using 'org.doxygen.doc' as default!.\n"); - Config_getString(QHP_NAMESPACE)="org.doxygen.doc"; + Config_updateString(QHP_NAMESPACE,"org.doxygen.doc"); } if (Config_getString(QHP_VIRTUAL_FOLDER).isEmpty()) { err("GENERATE_QHP=YES requires QHP_VIRTUAL_FOLDER to be set. Using 'doc' as default!\n"); - Config_getString(QHP_VIRTUAL_FOLDER)="doc"; + Config_updateString(QHP_VIRTUAL_FOLDER,"doc"); } } + //------------------------ if (Config_getBool(OPTIMIZE_OUTPUT_JAVA) && Config_getBool(INLINE_INFO)) { // don't show inline info for Java output, since Java has no inline // concept. - Config_getBool(INLINE_INFO)=FALSE; + Config_updateBool(INLINE_INFO,FALSE); } - int &depth = Config_getInt(MAX_DOT_GRAPH_DEPTH); + //------------------------ + int depth = Config_getInt(MAX_DOT_GRAPH_DEPTH); if (depth==0) { - depth=1000; + Config_updateInt(MAX_DOT_GRAPH_DEPTH,1000); } - int &hue = Config_getInt(HTML_COLORSTYLE_HUE); + //------------------------ + int hue = Config_getInt(HTML_COLORSTYLE_HUE); if (hue<0) { hue=0; @@ -1874,8 +1846,10 @@ void Config::checkAndCorrect() { hue=hue%360; } + Config_updateInt(HTML_COLORSTYLE_HUE,hue); - int &sat = Config_getInt(HTML_COLORSTYLE_SAT); + //------------------------ + int sat = Config_getInt(HTML_COLORSTYLE_SAT); if (sat<0) { sat=0; @@ -1884,7 +1858,11 @@ void Config::checkAndCorrect() { sat=255; } - int &gamma = Config_getInt(HTML_COLORSTYLE_GAMMA); + Config_updateInt(HTML_COLORSTYLE_SAT,sat); + + + //------------------------ + int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA); if (gamma<40) { gamma=40; @@ -1893,32 +1871,30 @@ void Config::checkAndCorrect() { gamma=240; } + Config_updateInt(HTML_COLORSTYLE_GAMMA,gamma); + //------------------------ QCString mathJaxFormat = Config_getEnum(MATHJAX_FORMAT); if (!mathJaxFormat.isEmpty() && mathJaxFormat!="HTML-CSS" && mathJaxFormat!="NativeMML" && mathJaxFormat!="SVG") { err("Unsupported value for MATHJAX_FORMAT: Should be one of HTML-CSS, NativeMML, or SVG\n"); - Config_getEnum(MATHJAX_FORMAT)="HTML-CSS"; + Config_updateEnum(MATHJAX_FORMAT,"HTML-CSS"); } + //------------------------ // add default words if needed - QStrList &annotationFromBrief = Config_getList(ABBREVIATE_BRIEF); - if (annotationFromBrief.isEmpty()) - { - annotationFromBrief.append("The $name class"); - annotationFromBrief.append("The $name widget"); - annotationFromBrief.append("The $name file"); - annotationFromBrief.append("is"); - annotationFromBrief.append("provides"); - annotationFromBrief.append("specifies"); - annotationFromBrief.append("contains"); - annotationFromBrief.append("represents"); - annotationFromBrief.append("a"); - annotationFromBrief.append("an"); - annotationFromBrief.append("the"); + const StringVector &annotationFromBrief = Config_getList(ABBREVIATE_BRIEF); + if (annotationFromBrief.empty()) + { + Config_updateList(ABBREVIATE_BRIEF, + { "The $name class", "The $name widget", + "The $name file", "is", "provides", "specifies", + "contains", "represents", "a", "an", "the" + }); } + //------------------------ // some default settings for vhdl if (Config_getBool(OPTIMIZE_OUTPUT_VHDL) && (Config_getBool(INLINE_INHERITED_MEMB) || @@ -1948,15 +1924,18 @@ void Config::checkAndCorrect() "%s%s%s%s%s%s",s1,s2,s3,s4,s5,s6 ); - Config_getBool(INLINE_INHERITED_MEMB) = FALSE; - Config_getBool(INHERIT_DOCS) = FALSE; - Config_getBool(HIDE_SCOPE_NAMES) = TRUE; - Config_getBool(EXTRACT_PRIVATE) = TRUE; - Config_getBool(ENABLE_PREPROCESSING) = FALSE; - Config_getBool(EXTRACT_PACKAGE) = TRUE; + Config_updateBool(INLINE_INHERITED_MEMB, FALSE); + Config_updateBool(INHERIT_DOCS, FALSE); + Config_updateBool(HIDE_SCOPE_NAMES, TRUE); + Config_updateBool(EXTRACT_PRIVATE, TRUE); + Config_updateBool(ENABLE_PREPROCESSING, FALSE); + Config_updateBool(EXTRACT_PACKAGE, TRUE); } - checkFileName(Config_getString(GENERATE_TAGFILE),"GENERATE_TAGFILE"); + if (!checkFileName(Config_getString(GENERATE_TAGFILE),"GENERATE_TAGFILE")) + { + Config_updateString(GENERATE_TAGFILE,""); + } #if 0 // TODO: this breaks test 25; SOURCEBROWSER = NO and SOURCE_TOOLTIPS = YES. // So this and other regressions should be analysed and fixed before this can be enabled @@ -2011,10 +1990,10 @@ void Config::postProcess(bool clearHeaderAndFooter, bool compare) // refers to the files that we are supposed to parse. if (clearHeaderAndFooter) { - Config_getString(HTML_HEADER)=""; - Config_getString(HTML_FOOTER)=""; - Config_getString(LATEX_HEADER)=""; - Config_getString(LATEX_FOOTER)=""; + Config_updateString(HTML_HEADER ,""); + Config_updateString(HTML_FOOTER ,""); + Config_updateString(LATEX_HEADER,""); + Config_updateString(LATEX_FOOTER,""); } } |