Skip to main content

The configimpl.l File Reference

Included Headers

#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <ctype.h> #include <stdarg.h> #include <errno.h> #include <thread> #include <algorithm> #include <iostream> #include <iomanip> #include <cstdint> #include "config.h" #include "regex.h" #include "configimpl.h" #include "version.h" #include "portable.h" #include "language.h" #include "configoptions.h" #include "fileinfo.h" #include "dir.h" #include "textstream.h" #include "dotattributes.h" #include "debug.h" #include "doxygen_lex.h" #include "configimpl.l.h"

Classes Index

structConfigFileState

Functions Index

static const char *stateToString (int state)
static QCStringconfigStringRecode (const QCString &str, const QCString &fromEncoding, const QCString &toEncoding)
static boolcontainsEnvVar (QCString &str)
static QCStringconvertToComment (const QCString &s, const QCString &u)
static boolconvertStringToBool (const QCString &str, bool &isValid)
static const char *getLexerFILE ()
static intyyread (char *buf, int max_size)
static voidcheckEncoding ()
static QCStringstripComment (const QCString &s)
static voidprocessStoreRepl (QCString &storeReplStr)
static voidprocessString ()
static voidprocessList ()
static FILE *tryPath (const QCString &path, const QCString &fileName)
static voidsubstEnvVarsInStrList (StringVector &sl)
static voidsubstEnvVarsInString (QCString &s)
static FILE *findFile (const QCString &fileName)
static voidreadIncludeFile (const QCString &incName)
intyylex (void)
static QCStringconfigFileToString (const QCString &name)
static voidcleanUpPaths (StringVector &str)
static boolcheckFileName (const QCString &s, const char *optionName)
static voidcheckList (const StringVector &list, const char *name, bool equalRequired, bool valueRequired)
static voidadjustBoolSetting (const char *depOption, const char *optionName, bool expectedValue)
static voidadjustStringSetting (const char *depOption, const char *optionName, const QCString &expectedValue)
static voidadjustColorStyleSetting (const char *depOption)
static voidupdateAttribute (DotAttributes &attr, QCString name, ConfigObsolete *value)

Variables Index

static const char *warning_str = "warning: "
static const char *error_str = "error: "
static const char *g_inputString = nullptr
static intg_inputPosition = 0
static intg_yyLineNr = 1
static QCStringg_yyFileName
static QCStringg_cmd
static QCString *g_string = nullptr
static StringVector *g_list = nullptr
static QCStringg_listStr
static StringVectorg_includePathList
static std::vector< std::unique_ptr< ConfigFileState > >g_includeStack
static boolg_configUpdate = FALSE
static QCStringg_encoding
static ConfigImpl *g_config = nullptr
static Config::CompareModeg_compareMode = Config::CompareMode::Full
static QCStringg_localStoreRepl
static const reg::ExreEnvVar(R"(\$\((\a[\w.-]*)\))")
static const reg::ExreEnvVarExt(R"(\$\((\a[\w.-]*\(\a[\w.-]*\))\))")
static const reg::ExreEnvVarCMake(R"(@\a\w*@)")
static const reg::ExreEnvVar1CMake(R"(\${\a\w*})")

Macro Definitions Index

#defineYY_NO_INPUT   1
#defineYY_NO_UNISTD_H   1
#defineSHOW_INCLUDES   0
#defineMAX_INCLUDE_DEPTH   10
#defineYY_NEVER_INTERACTIVE   1
#defineunput_string(yytext, yyleng)   do { for (int i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); } while(0)
#defineYY_INPUT(buf, result, max_size)   result=yyread(buf,max_size);
#defineLEX_NO_REENTRANT

Functions

adjustBoolSetting()

void adjustBoolSetting (const char * depOption, const char * optionName, bool expectedValue)
static

Definition at line 1697 of file configimpl.l.

1697static void adjustBoolSetting(const char *depOption, const char *optionName,bool expectedValue)
1698{
1699 // lookup option by name
1700 const ConfigValues::Info *option = ConfigValues::instance().get(optionName);
1701 if (option && option->type==ConfigValues::Info::Bool) // safety check
1702 {
1703 if (ConfigValues::instance().*(option->value.b)!=expectedValue) // current value differs from expectation
1704 {
1705 err("When enabling {} the {} option should be {}. I'll adjust it for you.\n",depOption,optionName,expectedValue? "enabled" : "disabled");
1706 ConfigValues::instance().*(option->value.b)=expectedValue; // adjust option
1707 }
1708 }
1709}

Reference err.

Referenced by Config::checkAndCorrect.

adjustColorStyleSetting()

void adjustColorStyleSetting (const char * depOption)
static

Definition at line 1725 of file configimpl.l.

1725static void adjustColorStyleSetting(const char *depOption)
1726{
1727 auto updateColorStyle = [&depOption](HTML_COLORSTYLE_t curStyle,HTML_COLORSTYLE_t newStyle)
1728 {
1729 err("When enabling '{}' the 'HTML_COLORSTYLE' option should be either 'LIGHT' or 'DARK' but has value '{}'. I'll adjust it for you to '{}'.\n",
1730 depOption,
1731 HTML_COLORSTYLE_enum2str(curStyle),
1732 HTML_COLORSTYLE_enum2str(newStyle));
1733 Config_updateEnum(HTML_COLORSTYLE,newStyle);
1734 };
1735 auto colorStyle = Config_getEnum(HTML_COLORSTYLE);
1736 switch (colorStyle)
1737 {
1738 case HTML_COLORSTYLE_t::LIGHT:
1739 case HTML_COLORSTYLE_t::DARK:
1740 // no adjustment needed
1741 break;
1742 case HTML_COLORSTYLE_t::AUTO_LIGHT:
1743 case HTML_COLORSTYLE_t::TOGGLE:
1744 updateColorStyle(colorStyle,HTML_COLORSTYLE_t::LIGHT);
1745 break;
1746 case HTML_COLORSTYLE_t::AUTO_DARK:
1747 updateColorStyle(colorStyle,HTML_COLORSTYLE_t::DARK);
1748 break;
1749 }
1750}

References Config_getEnum, Config_updateEnum and err.

Referenced by Config::checkAndCorrect.

adjustStringSetting()

void adjustStringSetting (const char * depOption, const char * optionName, const QCString & expectedValue)
static

Definition at line 1711 of file configimpl.l.

1711static void adjustStringSetting(const char *depOption, const char *optionName,const QCString &expectedValue)
1712{
1713 // lookup option by name
1714 const ConfigValues::Info *option = ConfigValues::instance().get(optionName);
1715 if (option && option->type==ConfigValues::Info::String) // safety check
1716 {
1717 if (ConfigValues::instance().*(option->value.s)!=expectedValue) // current value differs from expectation
1718 {
1719 err("When enabling {} the {} option should have value '{}'. I'll adjust it for you.\n",depOption,optionName,expectedValue);
1720 ConfigValues::instance().*(option->value.s)=expectedValue; // adjust option
1721 }
1722 }
1723}

Reference err.

Referenced by Config::checkAndCorrect.

checkEncoding()

void checkEncoding ()
static

Definition at line 726 of file configimpl.l.

726static void checkEncoding()
727{
728 ConfigString *option = dynamic_cast<ConfigString*>(g_config->get("DOXYFILE_ENCODING"));
729 g_encoding = *option->valueRef();
730}

References g_config, g_encoding and ConfigString::valueRef.

Referenced by processString.

checkFileName()

bool checkFileName (const QCString & s, const char * optionName)
static

Definition at line 1649 of file configimpl.l.

1649static bool checkFileName(const QCString &s,const char *optionName)
1650{
1651 QCString val = s.stripWhiteSpace().lower();
1652 if ((val=="yes" || val=="true" || val=="1" || val=="all") ||
1653 (val=="no" || val=="false" || val=="0" || val=="none"))
1654 {
1655 err("file name expected for option {}, got {} instead. Ignoring...\n",optionName,s);
1656 return false;
1657 }
1658 return true;
1659}

References err, QCString::lower and QCString::stripWhiteSpace.

Referenced by Config::checkAndCorrect.

checkList()

void checkList (const StringVector & list, const char * name, bool equalRequired, bool valueRequired)
static

Definition at line 1667 of file configimpl.l.

1667static void checkList(const StringVector &list,const char *name, bool equalRequired,bool valueRequired)
1668{
1669 for (const auto &s: list)
1670 {
1671 QCString item=s.c_str();
1672 item=item.stripWhiteSpace();
1673 int i=item.find('=');
1674 if (i==-1 && equalRequired)
1675 {
1676 err("Illegal format for option {}, no equal sign ('=') specified for item '{}'\n",name,item);
1677 }
1678 if (i!=-1)
1679 {
1680 QCString myName=item.left(i).stripWhiteSpace();
1681 if (myName.isEmpty())
1682 {
1683 err("Illegal format for option {}, no name specified for item '{}'\n",name,item);
1684 }
1685 else if (valueRequired)
1686 {
1687 QCString myValue=item.right(item.length()-i-1).stripWhiteSpace();
1688 if (myValue.isEmpty())
1689 {
1690 err("Illegal format for option {}, no value specified for item '{}'\n",name,item);
1691 }
1692 }
1693 }
1694 }
1695}

References err, QCString::find, QCString::isEmpty, QCString::left, QCString::length, QCString::right and QCString::stripWhiteSpace.

Referenced by Config::checkAndCorrect.

cleanUpPaths()

void cleanUpPaths (StringVector & str)
static

Definition at line 1630 of file configimpl.l.

1630static void cleanUpPaths(StringVector &str)
1631{
1632 for (size_t i=0;i<str.size();i++)
1633 {
1634 std::string path = str[i];
1635 std::replace(path.begin(),path.end(),'\\','/');
1636 if ((path[0]!='/' && (path.size()<=2 || path[1]!=':')) || path[path.size()-1]!='/')
1637 {
1638 FileInfo fi(path);
1639 if (fi.exists() && fi.isDir())
1640 {
1641 path = fi.absFilePath();
1642 if (path[path.size()-1]!='/') path+='/';
1643 }
1644 }
1645 str[i]=path;
1646 }
1647}

References FileInfo::absFilePath, FileInfo::exists and FileInfo::isDir.

Referenced by Config::checkAndCorrect.

configFileToString()

QCString configFileToString (const QCString & name)
static

Definition at line 1569 of file configimpl.l.

1570{
1571 if (name.isEmpty()) return QCString();
1572
1573 auto stream2string = [](std::istream &in) -> std::string
1574 {
1575 std::string ret;
1576 char buffer[4096];
1577 while (in.read(buffer, sizeof(buffer))) ret.append(buffer, sizeof(buffer));
1578 ret.append(buffer, static_cast<uint32_t>(in.gcount()));
1579 if (!ret.empty() && ret[ret.length()-1]!='\n') ret+='\n'; // to help the scanner
1580 return ret;
1581 };
1582
1583 if (name=="-") // read from stdin
1584 {
1585 // read contents from stdin into contents string
1586 return stream2string(std::cin);
1587 }
1588 else // read from file
1589 {
1590 std::ifstream f = Portable::openInputStream(name);
1591 if (!f.is_open())
1592 {
1593 ConfigImpl::config_term("file '{}' not found or could not be opened\n",name);
1594 return "";
1595 }
1596 return stream2string(f);
1597 }
1598}

References ConfigImpl::config_term, QCString::isEmpty and Portable::openInputStream.

Referenced by ConfigImpl::parse.

configStringRecode()

QCString configStringRecode (const QCString & str, const QCString & fromEncoding, const QCString & toEncoding)
static

Definition at line 690 of file configimpl.l.

691 const QCString &str,
692 const QCString &inputEncoding,
693 const QCString &outputEncoding)
694{
695 if (inputEncoding.isEmpty() || outputEncoding.isEmpty() || inputEncoding==outputEncoding) return str;
696 size_t inputSize=str.length();
697 size_t outputSize=inputSize*4;
698 QCString output(outputSize, QCString::ExplicitSize);
699 void *cd = portable_iconv_open(outputEncoding.data(),inputEncoding.data());
700 if (cd==reinterpret_cast<void *>(-1))
701 {
702 ConfigImpl::config_term("Error: unsupported character conversion: '{}'->'{}'\n"
703 "Check the 'DOXYFILE_ENCODING' setting in the config file!\n",
704 inputEncoding,outputEncoding);
705 }
706 size_t iLeft=inputSize;
707 size_t oLeft=outputSize;
708 const char *inputPtr = str.data();
709 char *outputPtr = output.rawData();
710 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
711 {
712 outputSize-=oLeft;
713 output.resize(outputSize);
714 output.at(outputSize)='\0';
715 //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf));
716 }
717 else
718 {
719 ConfigImpl::config_term("Error: failed to translate characters from {} to {}: {}\n",
720 inputEncoding,outputEncoding,strerror(errno));
721 }
723 return output;
724}

References QCString::at, ConfigImpl::config_term, QCString::data, QCString::ExplicitSize, QCString::isEmpty, QCString::length, portable_iconv, portable_iconv_close, portable_iconv_open, QCString::rawData and QCString::resize.

Referenced by processList, processStoreRepl, processString and ConfigOption::writeStringValue.

containsEnvVar()

bool containsEnvVar (QCString & str)
static

convertStringToBool()

bool convertStringToBool (const QCString & str, bool & isValid)
static

Definition at line 217 of file configimpl.l.

217static bool convertStringToBool(const QCString &str,bool &isValid)
218{
219 isValid=false;
220 QCString val = str.stripWhiteSpace().lower();
221 if (!val.isEmpty())
222 {
223 if (val=="yes" || val=="true" || val=="1" || val=="all")
224 {
225 isValid=true;
226 return true;
227 }
228 else if (val=="no" || val=="false" || val=="0" || val=="none")
229 {
230 isValid=true;
231 return false;
232 }
233 }
234 return false;
235}

References QCString::isEmpty, QCString::lower and QCString::stripWhiteSpace.

Referenced by ConfigBool::convertStrToVal and Config::updateObsolete.

convertToComment()

QCString convertToComment (const QCString & s, const QCString & u)
static

Definition at line 88 of file configimpl.l.

88static QCString convertToComment(const QCString &s, const QCString &u)
89{
90 //printf("convertToComment(%s)=%s\n",qPrint(s),qPrint(u));
91 QCString result;
92 if (!s.isEmpty())
93 {
95 const char *p=tmp.data();
96 char c = 0;
97 if (p)
98 {
99 result+="#";
100 if (*p && *p!='\n')
101 {
102 result+=" ";
103 }
104 while ((c=*p++))
105 {
106 if (c=='\n')
107 {
108 result+="\n#";
109 if (*p && *p!='\n')
110 {
111 result+=" ";
112 }
113 }
114 else result+=c;
115 }
116 result+='\n';
117 }
118 }
119 if (!u.isEmpty())
120 {
121 if (!result.isEmpty()) result+='\n';
122 result+= u;
123 }
124 return result;
125}

References QCString::data, QCString::isEmpty and QCString::stripWhiteSpace.

Referenced by ConfigBool::writeTemplate, ConfigEnum::writeTemplate, ConfigImpl::writeTemplate, ConfigInt::writeTemplate, ConfigList::writeTemplate and ConfigString::writeTemplate.

findFile()

FILE * findFile (const QCString & fileName)
static

Definition at line 937 of file configimpl.l.

937static FILE *findFile(const QCString &fileName)
938{
939 if (fileName.isEmpty())
940 {
941 return 0;
942 }
943 if (Portable::isAbsolutePath(fileName))
944 {
945 return tryPath(QCString(), fileName);
946 }
948 for (const auto &s : g_includePathList)
949 {
950 FILE *f = tryPath(s.c_str(),fileName);
951 if (f) return f;
952 }
953 // try cwd if g_includePathList fails
954 return tryPath(".",fileName);
955}

References g_includePathList, Portable::isAbsolutePath, QCString::isEmpty, substEnvVarsInStrList and tryPath.

Referenced by readIncludeFile and readIncludeFile.

getLexerFILE()

const char * getLexerFILE ()
inline static

Definition at line 664 of file configimpl.l.

664static inline const char *getLexerFILE() {return __FILE__;}

processList()

void processList ()
static

Definition at line 828 of file configimpl.l.

828static void processList()
829{
830 bool allowCommaAsSeparator = g_cmd!="PREDEFINED";
831
832 QCString s = stripComment(g_listStr.stripWhiteSpace());
833 size_t l = s.length();
834
835 QCString elemStr;
836 bool wasQuote=false;
837
838 // helper to push elemStr to the list and clear it
839 auto addElem = [&elemStr,&wasQuote]()
840 {
841 if (!elemStr.isEmpty())
842 {
843 QCString e = configStringRecode(elemStr,g_encoding,"UTF-8");
844 //printf("Processed list element '%s'\n",qPrint(e));
845 if (wasQuote) e = "\""+e+"\"";
846 wasQuote = false;
847 g_list->push_back(e.str());
848 elemStr="";
849 }
850 };
851
852 bool needsSeparator=false;
853 bool insideQuote=false;
854 bool warned=false;
855 for (size_t i=0;i<l;i++)
856 {
857 char c = s.at(i);
858 if (!needsSeparator && c=='\\') // escaped character
859 {
860 if (i<l-1 && s.at(i+1)=='"') // unescape the quote character
861 {
862 elemStr+='"';
863 }
864 else // keep other escaped characters in escaped form
865 {
866 elemStr+=c;
867 if (i<l-1)
868 {
869 elemStr+=s.at(i+1);
870 }
871 }
872 i++; // skip over the escaped character
873 }
874 else if (!needsSeparator && c=='"') // quote character
875 {
876 if (!insideQuote)
877 {
878 insideQuote=true;
879 wasQuote=true;
880 }
881 else // this quote ends an element
882 {
883 insideQuote=false;
884 needsSeparator=true;
885 }
886 }
887 else if (!insideQuote && ((c==',' && allowCommaAsSeparator) || isspace(c))) // separator
888 {
889 needsSeparator=false;
890 addElem();
891 }
892 else // normal content character
893 {
894 if (needsSeparator)
895 {
896 if (!warned)
897 {
898 ConfigImpl::config_warn("Invalid value for '{}' tag at line {}, file {}: Values in list '{}' are not properly space {}separated\n",
899 g_cmd,g_yyLineNr,g_yyFileName,g_listStr.stripWhiteSpace(),allowCommaAsSeparator?"or comma ":"");
900 warned=true;
901 }
902 needsSeparator=false;
903 i--; // try the character again as part of a new element
904 addElem();
905 }
906 else
907 {
908 elemStr+=c;
909 }
910 }
911 }
912 // add last part
913 addElem();
914 if (insideQuote)
915 {
916 ConfigImpl::config_warn("Invalid value for '{}' tag at line {}, file {}: Values in list '{}' are not properly quoted\n",
917 g_cmd,g_yyLineNr,g_yyFileName,g_listStr.stripWhiteSpace());
918 }
919}

References QCString::at, ConfigImpl::config_warn, configStringRecode, g_cmd, g_encoding, g_list, g_listStr, g_yyFileName, g_yyLineNr, QCString::isEmpty, QCString::length, QCString::str and stripComment.

processStoreRepl()

void processStoreRepl (QCString & storeReplStr)
static

Definition at line 760 of file configimpl.l.

760static void processStoreRepl(QCString &storeReplStr)
761{
762 // strip leading and trailing whitespace
763 QCString s = stripComment(storeReplStr.stripWhiteSpace());
764 // recode the string
765 storeReplStr=configStringRecode(s,g_encoding,"UTF-8");
766}

References configStringRecode, g_encoding, stripComment and QCString::stripWhiteSpace.

processString()

void processString ()
static

Definition at line 768 of file configimpl.l.

768static void processString()
769{
770 // strip leading and trailing whitespace
771 QCString s = stripComment(g_string->stripWhiteSpace());
772 size_t l = s.length();
773
774 // remove surrounding quotes if present (and not escaped)
775 if (l>=2 && s.at(0)=='"' && s.at(l-1)=='"' && // remove quotes
776 (s.at(l-2)!='\\' || (s.at(l-2)=='\\' && s.at(l-3)=='\\')))
777 {
778 s=s.mid(1,s.length()-2);
779 l=s.length();
780 }
781
782 // check for invalid and/or escaped quotes
783 bool warned=false;
784 QCString result;
785 for (size_t i=0;i<l;i++)
786 {
787 char c = s.at(i);
788 if (c=='\\') // escaped character
789 {
790 if (i<l-1 && s.at(i+1)=='"') // unescape the quote character
791 {
792 result+='"';
793 }
794 else // keep other escaped characters in escaped form
795 {
796 result+=c;
797 if (i<l-1)
798 {
799 result+=s.at(i+1);
800 }
801 }
802 i++; // skip over the escaped character
803 }
804 else if (c=='"') // unescaped quote
805 {
806 if (!warned)
807 {
808 ConfigImpl::config_warn("Invalid value for '{}' tag at line {}, file {}: Value '{}' is not properly quoted\n",
809 g_cmd,g_yyLineNr,g_yyFileName,g_string->stripWhiteSpace());
810 }
811 warned=true;
812 }
813 else // normal character
814 {
815 result+=c;
816 }
817 }
818
819 // recode the string
820 *g_string=configStringRecode(result,g_encoding,"UTF-8");
821
822 // update encoding
824
825 //printf("Processed string '%s'\n",qPrint(g_string));
826}

References QCString::at, checkEncoding, ConfigImpl::config_warn, configStringRecode, g_cmd, g_encoding, g_string, g_yyFileName, g_yyLineNr, QCString::length, QCString::mid and stripComment.

readIncludeFile()

void readIncludeFile (const QCString & incName)
static

Definition at line 957 of file configimpl.l.

957static void readIncludeFile(const QCString &incName)
958{
960 ConfigImpl::config_term("maximum include depth ({:d}) reached, {} is not included. Aborting...\n",
961 MAX_INCLUDE_DEPTH,incName);
962 }
963
964 QCString inc = incName;
966 inc = inc.stripWhiteSpace();
967 size_t incLen = inc.length();
968 if (incLen>0 && inc.at(0)=='"' && inc.at(incLen-1)=='"') // strip quotes
969 {
970 inc=inc.mid(1,incLen-2);
971 }
972
973 FILE *f;
974
975 if ((f=findFile(inc))) // see if the include file can be found
976 {
977 // For debugging
978#if SHOW_INCLUDES
979 for (size_t i=0;i<g_includeStack.size();i++) msg(" ");
980 msg("@INCLUDE = {}: parsing...\n",inc);
981#endif
982
983 // store the state of the old file
985 fs->oldState=YY_CURRENT_BUFFER;
988 fs->filePtr=f;
989 // push the state on the stack
990 g_includeStack.push_back(std::unique_ptr<ConfigFileState>(fs));
991 // set the scanner to the include file
992 yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
993 fs->newState=YY_CURRENT_BUFFER;
994 g_yyFileName=inc;
995 }
996 else
997 {
998 ConfigImpl::config_term("@INCLUDE = {}: not found!\n",inc);
999 }
1000}

References QCString::at, ConfigImpl::config_term, ConfigFileState::fileName, ConfigFileState::filePtr, findFile, g_includeStack, g_yyFileName, g_yyLineNr, QCString::length, ConfigFileState::lineNr, MAX_INCLUDE_DEPTH, QCString::mid, msg, ConfigFileState::newState, ConfigFileState::oldState, QCString::stripWhiteSpace, substEnvVarsInString and YY_BUF_SIZE.

stateToString()

const char * stateToString (int state)
static

Definition at line 54 of file configimpl.l.

stripComment()

QCString stripComment (const QCString & s)
static

Definition at line 732 of file configimpl.l.

733{
734 // check if there is a comment at the end of the string
735 bool insideQuote=false;
736 size_t l = s.length();
737 for (size_t i=0;i<l;i++)
738 {
739 char c = s.at(i);
740 if (c=='\\') // skip over escaped characters
741 {
742 i++;
743 }
744 else if (c=='"') // toggle inside/outside quotation
745 {
746 insideQuote=!insideQuote;
747 }
748 else if (!insideQuote && c=='#') // found start of a comment
749 {
750 if (i<l-1 && s.at(i+1)=='#') // ## -> user comment
751 {
752 g_config->appendUserComment(s.mid(i)+"\n");
753 }
754 return s.left(i).stripWhiteSpace();
755 }
756 }
757 return s;
758}

References QCString::at, g_config, QCString::left, QCString::length, QCString::mid and QCString::stripWhiteSpace.

Referenced by processList, processStoreRepl and processString.

substEnvVarsInString()

void substEnvVarsInString (QCString & s)
static

Definition at line 1400 of file configimpl.l.

1401{
1402 if (str.isEmpty()) return;
1403 auto replace = [](const std::string &s, const reg::Ex &re) -> std::string
1404 {
1405 reg::Iterator it(s,re);
1407 std::string result;
1408 size_t p = 0;
1409 for (; it!=end ; ++it)
1410 {
1411 const auto &match = *it;
1412 size_t i = match.position();
1413 size_t l = match.length();
1414 result+=s.substr(p,i-p);
1415 std::string matchContents = match[1].str();
1416 QCString env=Portable::getenv(matchContents.c_str()); // get content of $(..) match
1417 substEnvVarsInString(env); // recursively expand variables if needed.
1418 result+=env.str();
1419 p=i+l;
1420 }
1421 result+=s.substr(p);
1422 return result;
1423 };
1424
1425 str = QCString(replace(replace(str.str(),reEnvVar),reEnvVarExt)).stripWhiteSpace();
1426}

References end, Portable::getenv, QCString::isEmpty, reEnvVar, reEnvVarExt, QCString::str, QCString::stripWhiteSpace and substEnvVarsInString.

Referenced by readIncludeFile, ConfigBool::substEnvVars, ConfigEnum::substEnvVars, ConfigInt::substEnvVars, ConfigString::substEnvVars, substEnvVarsInString and substEnvVarsInStrList.

substEnvVarsInStrList()

void substEnvVarsInStrList (StringVector & sl)
static

Definition at line 1428 of file configimpl.l.

1429{
1430 StringVector results;
1431 for (const auto &s : sl)
1432 {
1433 QCString result = s.c_str();
1434 bool wasQuoted = ((result.at(0)=='"') && (result.at(result.length()-1)=='"'));
1435 if (wasQuoted)
1436 {
1437 result = result.mid(1,result.length()-2);
1438 }
1439 else
1440 {
1441 wasQuoted = (result.find(' ')!=-1) || (result.find('\t')!=-1) || (result.find('"')!=-1);
1442 }
1443 // here we strip the quote again
1444 substEnvVarsInString(result);
1445
1446 //printf("Result %s was quoted=%d\n",qPrint(result),wasQuoted);
1447
1448 if (!wasQuoted) /* as a result of the expansion, a single string
1449 may have expanded into a list, which we'll
1450 add to sl. If the original string already
1451 contained multiple elements no further
1452 splitting is done to allow quoted items with spaces! */
1453 {
1454 int l = static_cast<int>(result.length());
1455 int p = 0;
1456 // skip spaces
1457 // search for a "word"
1458 for (int i=0;i<l;i++)
1459 {
1460 char c=0;
1461 // skip until start of new word
1462 while (i<l && ((c=result.at(i))==' ' || c=='\t')) i++;
1463 p=i; // p marks the start index of the word
1464 // skip until end of a word
1465 while (i<l && ((c=result.at(i))!=' ' && c!='\t' && c!='"')) i++;
1466 if (i<l) // not at the end of the string
1467 {
1468 if (c=='"') // word within quotes
1469 {
1470 p=i+1;
1471 for (i++;i<l;i++)
1472 {
1473 c=result.at(i);
1474 if (c=='"') // end quote
1475 {
1476 results.push_back(result.mid(p,i-p).str());
1477 p=i+1;
1478 break;
1479 }
1480 else if (c=='\\') // skip escaped stuff
1481 {
1482 i++;
1483 }
1484 }
1485 }
1486 else if (c==' ' || c=='\t') // separator
1487 {
1488 if (i>p) results.push_back(result.mid(p,i-p).str());
1489 p=i+1;
1490 }
1491 }
1492 }
1493 if (p!=l) // add the leftover as a string
1494 {
1495 results.push_back(result.right(l-p).str());
1496 }
1497 }
1498 else // just goto the next element in the list
1499 {
1500 if (!result.isEmpty()) results.push_back(result.str());
1501 }
1502 }
1503 sl = results;
1504}

References QCString::at, QCString::find, QCString::isEmpty, QCString::length, QCString::mid, QCString::right, QCString::str and substEnvVarsInString.

Referenced by findFile and ConfigList::substEnvVars.

tryPath()

FILE * tryPath (const QCString & path, const QCString & fileName)
static

Definition at line 921 of file configimpl.l.

921static FILE *tryPath(const QCString &path,const QCString &fileName)
922{
923 QCString absName=(!path.isEmpty() ? path+"/"+fileName : fileName);
924 FileInfo fi(absName.str());
925 if (fi.exists() && fi.isFile())
926 {
927 FILE *f=Portable::fopen(absName,"r");
928 if (!f) ConfigImpl::config_err("could not open file {} for reading\n",absName);
929 return f;
930 }
931 return 0;
932}

References ConfigImpl::config_err, FileInfo::exists, Portable::fopen, QCString::isEmpty, FileInfo::isFile and QCString::str.

Referenced by findFile.

updateAttribute()

void updateAttribute (DotAttributes & attr, QCString name, ConfigObsolete * value)
static

Definition at line 2238 of file configimpl.l.

2238static void updateAttribute(DotAttributes& attr, QCString name, ConfigObsolete* value)
2239{
2240 attr.updateValue(name,*value->valueStringRef());
2241}

References DotAttributes::updateValue and ConfigObsolete::valueStringRef.

Referenced by Config::updateObsolete.

yylex()

int yylex (void)

Definition at line 1017 of file configimpl.l.

1018
1019<*>\0x0d
1020
1021 /*-------------- Comments ---------------*/
1022
1023<Start>"##".*"\n" {
1024 g_config->appendUserComment(yytext);
1025 g_yyLineNr++;
1026 }
1027<Start>"#".*"\n" { /* normal comment */
1028 g_yyLineNr++;
1029 }
1030
1031 /*-------------- TAG start ---------------*/
1032
1033<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"=" { g_cmd=yytext;
1034 g_cmd=g_cmd.left(g_cmd.length()-1).stripWhiteSpace();
1035 ConfigOption *option = g_config->get(g_cmd);
1036 if (option==0) // oops not known
1037 {
1038 ConfigImpl::config_warn("ignoring unsupported tag '{}' at line {}, file {}\n",
1040 BEGIN(SkipInvalid);
1041 }
1042 else // known tag
1043 {
1044 option->setUserComment(g_config->takeUserComment());
1045 option->setEncoding(g_encoding);
1046 switch(option->kind())
1047 {
1049 // shouldn't get here!
1050 BEGIN(SkipInvalid);
1051 break;
1053 g_list = dynamic_cast<ConfigList *>(option)->valueRef();
1054 g_list->clear();
1055 g_listStr="";
1056 BEGIN(GetStrList);
1057 break;
1059 g_string = dynamic_cast<ConfigEnum *>(option)->valueRef();
1060 g_string->clear();
1061 BEGIN(GetString);
1062 break;
1064 g_string = dynamic_cast<ConfigString *>(option)->valueRef();
1065 g_string->clear();
1066 BEGIN(GetString);
1067 break;
1069 g_string = dynamic_cast<ConfigInt *>(option)->valueStringRef();
1070 g_string->clear();
1071 BEGIN(GetString);
1072 break;
1074 g_string = dynamic_cast<ConfigBool *>(option)->valueStringRef();
1075 g_string->clear();
1076 BEGIN(GetString);
1077 break;
1079 if (g_configUpdate)
1080 {
1081 ConfigImpl::config_warn("Tag '{}' at line {} of file '{}' has become obsolete.\n"
1082 " This tag has been removed.\n", g_cmd,g_yyLineNr,g_yyFileName);
1083 }
1084 else
1085 {
1086 ConfigImpl::config_warn("Tag '{}' at line {} of file '{}' has become obsolete.\n"
1087 " To avoid this warning please remove this line from your configuration "
1088 "file or upgrade it using \"doxygen -u\"\n", g_cmd,g_yyLineNr,g_yyFileName);
1089 }
1090 dynamic_cast<ConfigObsolete*>(option)->markAsPresent();
1091 if (dynamic_cast<ConfigObsolete*>(option)->orgType()==ConfigOption::O_List)
1092 {
1093 g_list = dynamic_cast<ConfigObsolete*>(option)->valueListRef();
1094 g_list->clear();
1095 g_listStr="";
1096 BEGIN(GetStrList);
1097 }
1098 else
1099 {
1100 g_string = dynamic_cast<ConfigObsolete*>(option)->valueStringRef();
1101 g_string->clear();
1102 BEGIN(GetString);
1103 }
1104 break;
1106 if (g_configUpdate)
1107 {
1108 ConfigImpl::config_warn("Tag '{}' at line {} of file '{}' belongs to an option that was not enabled at compile time.\n"
1109 " This tag has been removed.\n", g_cmd,g_yyLineNr,g_yyFileName);
1110 }
1111 else
1112 {
1113 ConfigImpl::config_warn("Tag '{}' at line {} of file '{}' belongs to an option that was not enabled at compile time.\n"
1114 " To avoid this warning please remove this line from your configuration "
1115 "file or upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", g_cmd,g_yyLineNr,g_yyFileName);
1116 }
1117 BEGIN(SkipInvalid);
1118 break;
1119 }
1120 }
1121 }
1122<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"+=" { g_cmd=yytext;
1123 g_cmd=g_cmd.left(g_cmd.length()-2).stripWhiteSpace();
1124 ConfigOption *option = g_config->get(g_cmd);
1125 if (option==0) // oops not known
1126 {
1127 ConfigImpl::config_warn("ignoring unsupported tag '{}' at line {}, file {}\n",
1129 BEGIN(SkipInvalid);
1130 }
1131 else // known tag
1132 {
1133 option->setUserComment(g_config->takeUserComment());
1134 switch(option->kind())
1135 {
1137 // shouldn't get here!
1138 BEGIN(SkipInvalid);
1139 break;
1141 g_list = dynamic_cast<ConfigList *>(option)->valueRef();
1142 g_listStr="";
1143 BEGIN(GetStrList);
1144 break;
1149 ConfigImpl::config_warn("operator += not supported for '{}'. Ignoring line at line {}, file {}\n",
1150 yytext,g_yyLineNr,g_yyFileName);
1151 BEGIN(SkipInvalid);
1152 break;
1154 ConfigImpl::config_warn("Tag '{}' at line {} of file {} has become obsolete.\n"
1155 "To avoid this warning please update your configuration "
1156 "file using \"doxygen -u\"\n", g_cmd,g_yyLineNr,g_yyFileName);
1157 if (dynamic_cast<ConfigObsolete*>(option)->orgType()==ConfigOption::O_List)
1158 {
1159 g_list = dynamic_cast<ConfigObsolete*>(option)->valueListRef();
1160 g_listStr="";
1161 BEGIN(GetStrList);
1162 }
1163 else
1164 {
1165 BEGIN(SkipInvalid);
1166 }
1167 break;
1169 ConfigImpl::config_warn("Tag '{}' at line {} of file {} belongs to an option that was not enabled at compile time.\n"
1170 "To avoid this warning please remove this line from your configuration "
1171 "file, upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n",
1173 BEGIN(SkipInvalid);
1174 break;
1175 }
1176 }
1177 }
1178
1179 /*-------------- INCLUDE* ---------------*/
1180
1181<Start>"@INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); g_list=&g_includePathList; g_list->clear(); g_listStr=""; }
1182 /* include a g_config file */
1183<Start>"@INCLUDE"[ \t]*"=" { BEGIN(Include);}
1184<Start>"$("{REGEX_a}({REGEX_w}|[.-])*")" | // e.g. $(HOME)
1185<Start>"$("{REGEX_a}({REGEX_w}|[.-])*"("{REGEX_a}({REGEX_w}|[.-])*"))" { // e.g. $(PROGRAMFILES(X86))
1186 g_localStoreRepl = yytext;
1188 {
1189 BEGIN(StoreRepl);
1190 }
1191 else
1192 {
1195 }
1196 }
1197<Start>"@"{REGEX_a}{REGEX_w}*"@" {
1199 {
1200 g_localStoreRepl = yytext;
1201 BEGIN(StoreRepl);
1202 }
1203 else
1204 {
1205 ConfigImpl::config_warn("ignoring unknown '{}' at line {}, file {}\n",
1206 yytext,g_yyLineNr,g_yyFileName);
1207 }
1208 }
1209<Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") {
1211 BEGIN(Start);
1212 }
1213<<EOF>> {
1214 //printf("End of include file\n");
1215 //printf("Include stack depth=%d\n",g_includeStack.count());
1216 if (g_includeStack.empty())
1217 {
1218 //printf("Terminating scanner!\n");
1219 yyterminate();
1220 }
1221 else
1222 {
1223 auto &fs=g_includeStack.back();
1224 fclose(fs->filePtr);
1225 YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
1226 yy_switch_to_buffer( fs->oldState );
1227 yy_delete_buffer( oldBuf );
1228 g_yyLineNr=fs->lineNr;
1229 g_yyFileName=fs->fileName;
1230 g_includeStack.pop_back();
1231 }
1232 }
1233
1234<Start>[a-z_A-Z0-9]+ { ConfigImpl::config_warn("ignoring unknown tag '{}' at line {}, file {}\n",yytext,g_yyLineNr,g_yyFileName); }
1235 /*-------------- GetString ---------------*/
1236
1237<StoreRepl>\n {
1238 g_localStoreRepl += yytext;
1240 g_config->appendStoreRepl(g_localStoreRepl + "\n");
1241 g_localStoreRepl.clear();
1242 g_yyLineNr++; // end of string
1243 BEGIN(Start);
1244 }
1245<StoreRepl>\\[ \r\t]*\n { g_yyLineNr++; // line continuation
1246 g_localStoreRepl += yytext;
1247 }
1248<StoreRepl>"\\" { // escape character
1249 g_localStoreRepl += yytext;
1250 }
1251<StoreRepl>[^\n\\]+ { // string part without escape characters
1252 g_localStoreRepl += yytext;
1253 }
1254 /*-------------- GetString ---------------*/
1255
1256<GetString>\n { processString();
1257 g_yyLineNr++; // end of string
1258 BEGIN(Start);
1259 }
1260<GetString>\\[ \r\t]*\n { g_yyLineNr++; // line continuation
1261 *g_string+=' ';
1262 }
1263<GetString>"\\" { // escape character
1264 *g_string+=yytext;
1265 }
1266<GetString>[^\n\\]+ { // string part without escape characters
1267 *g_string+=yytext;
1268 }
1269
1270 /*-------------- GetStrList --------------*/
1271
1272<GetStrList>\n { processList();
1273 g_yyLineNr++; // end of list
1274 BEGIN(Start);
1275 }
1276<GetStrList>\\[ \r\t]*\n { g_yyLineNr++; // line continuation
1277 g_listStr+=' ';
1278 }
1279<GetStrList>"\\" { // escape character
1280 g_listStr+=yytext;
1281 }
1282<GetStrList>[^\n\\]+ { // string part without escape characters
1283 g_listStr+=yytext;
1284 }
1285
1286 /*-------------- SkipInvalid --------------*/
1287
1288<SkipInvalid>\n { g_yyLineNr++; // end of list
1289 BEGIN(Start);
1290 }
1291<SkipInvalid>\\[ \r\t]*\n { g_yyLineNr++; // line continuation
1292 }
1293<SkipInvalid>"\\" { // escape character
1294 }
1295<SkipInvalid>[^\n\\]+ { // string part without escape characters
1296 }
1297
1298 /*-------------- fall through -------------*/
1299
1300<*>\\[ \r\t]*\n { g_yyLineNr++; }
1301<*>[ \t\r]
1302<*>\n { g_yyLineNr++ ; }
1303<*>. { ConfigImpl::config_warn("ignoring unknown character '{:c}' at line {}, file {}\n",yytext[0],g_yyLineNr,g_yyFileName); }
1304
1305%%

Referenced by convertCppComments.

yyread()

int yyread (char * buf, int max_size)
static

Definition at line 668 of file configimpl.l.

668static int yyread(char *buf,int max_size)
669{
670 // no file included
671 if (g_includeStack.empty())
672 {
673 int c=0;
674 if (g_inputString==0) return c;
675 while( c < max_size && g_inputString[g_inputPosition] )
676 {
678 c++; buf++;
679 }
680 return c;
681 }
682 else
683 {
684 //assert(g_includeStack.current()->newState==YY_CURRENT_BUFFER);
685 return static_cast<int>(fread(buf,1,max_size,g_includeStack.back()->filePtr));
686 }
687}

References g_includeStack, g_inputPosition and g_inputString.

Variables

error_str

const char* error_str = "error: "
static

Definition at line 57 of file configimpl.l.

57static const char *error_str = "error: ";

Referenced by ConfigImpl::config_err_ and ConfigImpl::config_term_.

g_cmd

QCString g_cmd
static

Definition at line 645 of file configimpl.l.

Referenced by processList and processString.

g_compareMode

Config::CompareMode g_compareMode = Config::CompareMode::Full
static

Definition at line 654 of file configimpl.l.

Referenced by Config::parse.

g_config

ConfigImpl* g_config = nullptr
static

Definition at line 653 of file configimpl.l.

653static ConfigImpl *g_config = nullptr;

Referenced by checkEncoding, Config::parse, ConfigImpl::parseString and stripComment.

g_configUpdate

bool g_configUpdate = FALSE
static

Definition at line 651 of file configimpl.l.

651static bool g_configUpdate = FALSE;

Referenced by ConfigImpl::parseString.

g_encoding

QCString g_encoding
static

Definition at line 652 of file configimpl.l.

Referenced by checkEncoding, ConfigImpl::parse, processList, processStoreRepl and processString.

g_includePathList

StringVector g_includePathList
static

Definition at line 649 of file configimpl.l.

Referenced by findFile.

g_includeStack

std::vector< std::unique_ptr<ConfigFileState> > g_includeStack
static

Definition at line 650 of file configimpl.l.

650static std::vector< std::unique_ptr<ConfigFileState> > g_includeStack;

Referenced by ConfigImpl::parseString, readIncludeFile and yyread.

g_inputPosition

int g_inputPosition = 0
static

Definition at line 642 of file configimpl.l.

642static int g_inputPosition = 0;

Referenced by ConfigImpl::parseString and yyread.

g_inputString

const char* g_inputString = nullptr
static

Definition at line 641 of file configimpl.l.

641static const char *g_inputString = nullptr;

Referenced by ConfigImpl::parseString and yyread.

g_list

StringVector* g_list = nullptr
static

Definition at line 647 of file configimpl.l.

647static StringVector *g_list = nullptr;

Referenced by processList.

g_listStr

QCString g_listStr
static

Definition at line 648 of file configimpl.l.

Referenced by processList.

g_localStoreRepl

QCString g_localStoreRepl
static

Definition at line 655 of file configimpl.l.

g_string

QCString* g_string = nullptr
static

Definition at line 646 of file configimpl.l.

646static QCString *g_string = nullptr;

Referenced by processString.

g_yyFileName

QCString g_yyFileName
static

Definition at line 644 of file configimpl.l.

Referenced by ConfigImpl::parseString, processList, processString and readIncludeFile.

g_yyLineNr

int g_yyLineNr = 1
static

Definition at line 643 of file configimpl.l.

643static int g_yyLineNr = 1;

Referenced by ConfigImpl::parseString, processList, processString and readIncludeFile.

reEnvVar

const reg::Ex reEnvVar(R"(\$\((\a[\w.-]*)\))")
static

Definition at line 1388 of file configimpl.l.

Referenced by containsEnvVar and substEnvVarsInString.

reEnvVar1CMake

const reg::Ex reEnvVar1CMake(R"(\${\a\w*})")
static

Definition at line 1391 of file configimpl.l.

Referenced by containsEnvVar.

reEnvVarCMake

const reg::Ex reEnvVarCMake(R"(@\a\w*@)")
static

Definition at line 1390 of file configimpl.l.

Referenced by containsEnvVar.

reEnvVarExt

const reg::Ex reEnvVarExt(R"(\$\((\a[\w.-]*\(\a[\w.-]*\))\))")
static

Definition at line 1389 of file configimpl.l.

Referenced by containsEnvVar and substEnvVarsInString.

warning_str

const char* warning_str = "warning: "
static

Definition at line 56 of file configimpl.l.

56static const char *warning_str = "warning: ";

Referenced by ConfigImpl::config_warn_.

Macro Definitions

LEX_NO_REENTRANT

#define LEX_NO_REENTRANT

Definition at line 665 of file configimpl.l.

665#define LEX_NO_REENTRANT

MAX_INCLUDE_DEPTH

#define MAX_INCLUDE_DEPTH   10

Definition at line 83 of file configimpl.l.

83#define MAX_INCLUDE_DEPTH 10

Referenced by readIncludeFile.

SHOW_INCLUDES

#define SHOW_INCLUDES   0

Definition at line 52 of file configimpl.l.

52#define SHOW_INCLUDES 0

unput_string

#define unput_string(yytext, yyleng)   do { for (int i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); } while(0)

Definition at line 657 of file configimpl.l.

657#define unput_string(yytext,yyleng) do { for (int i=(int)yyleng-1;i>=0;i--) unput(yytext[i]); } while(0)

YY_INPUT

#define YY_INPUT(buf, result, max_size)   result=yyread(buf,max_size);

Definition at line 661 of file configimpl.l.

661#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);

YY_NEVER_INTERACTIVE

#define YY_NEVER_INTERACTIVE   1

Definition at line 84 of file configimpl.l.

84#define YY_NEVER_INTERACTIVE 1

YY_NO_INPUT

#define YY_NO_INPUT   1

Definition at line 48 of file configimpl.l.

48#define YY_NO_INPUT 1

YY_NO_UNISTD_H

#define YY_NO_UNISTD_H   1

Definition at line 49 of file configimpl.l.

49#define YY_NO_UNISTD_H 1

Generated via doxygen2docusaurus by Doxygen 1.14.0.