diff options
Diffstat (limited to 'addon/doxywizard/config_doxyw.l')
-rw-r--r-- | addon/doxywizard/config_doxyw.l | 227 |
1 files changed, 163 insertions, 64 deletions
diff --git a/addon/doxywizard/config_doxyw.l b/addon/doxywizard/config_doxyw.l index 4018af7..71d48c9 100644 --- a/addon/doxywizard/config_doxyw.l +++ b/addon/doxywizard/config_doxyw.l @@ -3,8 +3,8 @@ * Copyright (C) 1997-2019 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. * @@ -24,6 +24,7 @@ #include "config.h" #include "input.h" #include "inputstring.h" +#include "doxywizard.h" #include <QString> #include <QVariant> @@ -53,14 +54,14 @@ struct ConfigFileState YY_BUFFER_STATE oldState; YY_BUFFER_STATE newState; QString fileName; -}; +}; static const QHash<QString,Input*> *g_options; static FILE *g_file; static QString g_yyFileName; static QString g_includeName; static QVariant g_includePathList; -static QStack<ConfigFileState*> g_includeStack; +static QStack<ConfigFileState*> g_includeStack; static int g_includeDepth; static QVariant *g_arg; static Input *g_curOption=0; @@ -69,6 +70,8 @@ static QTextCodec *g_codec = QTextCodec::codecForName("UT static QString g_codecName = QString::fromLatin1("UTF-8"); static int g_lastState; static QByteArray g_tmpString; +static QString g_cmd; +static int g_part; static const char *stateToString(int state); @@ -77,14 +80,14 @@ static const char *stateToString(int state); #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); -static int yyread(char *buf,int maxSize) +static yy_size_t yyread(char *buf,yy_size_t maxSize) { // no file included - if (g_includeStack.isEmpty()) + if (g_includeStack.isEmpty()) { return fread(buf,1,maxSize,g_file); - } - else + } + else { return fread(buf,1,maxSize,g_includeStack.top()->file); } @@ -96,19 +99,39 @@ static QString error_str = QString::fromLatin1("error: "); void config_err(const char *fmt, ...) { QString msg = error_str; + msg.append(QString::fromLatin1(fmt)); va_list args; va_start(args, fmt); - vfprintf(stderr, qPrintable(msg), args); + if (DoxygenWizard::debugFlag) + { + char debugOut[1000]; // this size should be sufficient + vsnprintf(debugOut, 1000,qPrintable(msg), args); + MainWindow::instance().outputLogText(QString::fromLatin1(debugOut)); + } + else + { + vfprintf(stderr, qPrintable(msg), args); + } va_end(args); } void config_warn(const char *fmt, ...) { QString msg = warning_str; + msg.append(QString::fromLatin1(fmt)); va_list args; va_start(args, fmt); - vfprintf(stderr, qPrintable(msg), args); + if (DoxygenWizard::debugFlag) + { + char debugOut[1000]; + vsnprintf(debugOut, 1000,qPrintable(msg), args); + MainWindow::instance().outputLogText(QString::fromLatin1(debugOut)); + } + else + { + vfprintf(stderr, qPrintable(msg), args); + } va_end(args); } @@ -138,7 +161,7 @@ static FILE *tryPath(const QString &path,const QString &fileName) FILE *f = fopen(absName.toLocal8Bit(),"r"); if (f==NULL) config_err("could not open file %s for reading\n",qPrintable(absName)); - else + else return f; } return NULL; @@ -154,7 +177,7 @@ static FILE *findFile(const QString &fileName) // relative path, try with include paths in the list QStringList sl = g_includePathList.toStringList(); substEnvVarsInStrList(sl); - foreach (QString s, sl) + foreach (QString s, sl) { FILE *f = tryPath(s,fileName); if (f) return f; @@ -165,18 +188,18 @@ static FILE *findFile(const QString &fileName) static void readIncludeFile(const QString &incName) { - if (g_includeDepth==MAX_INCLUDE_DEPTH) + if (g_includeDepth==MAX_INCLUDE_DEPTH) { config_err("maximum include depth (%d) reached, %s is not included. Aborting...\n", MAX_INCLUDE_DEPTH,qPrintable(incName)); exit(1); - } + } QString inc = incName; substEnvVarsInString(inc); inc = inc.trimmed(); uint incLen = inc.length(); - if (inc.at(0)==QChar::fromLatin1('"') && + if (inc.at(0)==QChar::fromLatin1('"') && inc.at(incLen-1)==QChar::fromLatin1('"')) // strip quotes { inc=inc.mid(1,incLen-2); @@ -191,7 +214,7 @@ static void readIncludeFile(const QString &incName) msg("@INCLUDE = %s: parsing...\n",qPrintable(inc)); #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->fileName=g_yyFileName; @@ -203,7 +226,7 @@ static void readIncludeFile(const QString &incName) fs->newState=YY_CURRENT_BUFFER; g_yyFileName=inc; g_includeDepth++; - } + } else { config_err("@INCLUDE = %s: not found!\n",qPrintable(inc)); @@ -225,20 +248,20 @@ static void readIncludeFile(const QString &incName) %x GetEnum %x GetStrList %x GetQuotedString -%x GetEnvVar %x Include %% <*>\0x0d <Start,GetString,GetEnum,GetStrList,SkipInvalid>"#" { BEGIN(SkipComment); } -<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"=" { QString cmd = g_codec->toUnicode(yytext); - cmd=cmd.left(cmd.length()-1).trimmed(); - g_curOption = g_options->value(cmd); +<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"=" { g_cmd = g_codec->toUnicode(yytext); + g_part = 0; + g_cmd=g_cmd.left(g_cmd.length()-1).trimmed(); + g_curOption = g_options->value(g_cmd); if (g_curOption==0) // oops not known { config_warn("ignoring unsupported tag '%s' at line %d, file %s\n", - qPrintable(cmd),yylineno,qPrintable(g_yyFileName)); + qPrintable(g_cmd),yylineno,qPrintable(g_yyFileName)); BEGIN(SkipInvalid); } else // known tag @@ -271,20 +294,20 @@ static void readIncludeFile(const QString &incName) case Input::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", qPrintable(cmd), - yylineno,qPrintable(g_yyFileName)); + "file using \"doxygen -u\"\n", qPrintable(g_cmd), + yylineno,qPrintable(g_yyFileName)); BEGIN(SkipInvalid); break; } } } -<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"+=" { QString cmd=g_codec->toUnicode(yytext); - cmd=cmd.left(cmd.length()-2).trimmed(); - g_curOption = g_options->value(cmd); +<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"+=" { g_cmd=g_codec->toUnicode(yytext); + g_cmd=g_cmd.left(g_cmd.length()-2).trimmed(); + g_curOption = g_options->value(g_cmd); if (g_curOption==0) // oops not known { config_warn("ignoring unsupported tag '%s' at line %d, file %s\n", - yytext,yylineno,qPrintable(g_yyFileName)); + yytext,yylineno,qPrintable(g_yyFileName)); BEGIN(SkipInvalid); } else // known tag @@ -299,15 +322,15 @@ static void readIncludeFile(const QString &incName) case Input::String: case Input::Int: case Input::Bool: - config_warn("operator += not supported for '%s'. Ignoring line at line %d, file %s\n", - yytext,yylineno,qPrintable(g_yyFileName)); + config_warn("operator += not supported for '%s'. Ignoring line %d, file %s\n", + qPrintable(g_cmd),yylineno,qPrintable(g_yyFileName)); BEGIN(SkipInvalid); break; case Input::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", - qPrintable(cmd),yylineno,qPrintable(g_yyFileName)); + "file using \"doxygen -u\"\n", + qPrintable(g_cmd),yylineno,qPrintable(g_yyFileName)); BEGIN(SkipInvalid); break; } @@ -316,8 +339,8 @@ static void readIncludeFile(const QString &incName) <Start>"@INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); g_arg=&g_includePathList; *g_arg = QStringList(); g_elemStr=QString(); } /* include a config file */ <Start>"@INCLUDE"[ \t]*"=" { BEGIN(Include);} -<Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") { - readIncludeFile(g_codec->toUnicode(yytext)); +<Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") { + readIncludeFile(g_codec->toUnicode(yytext)); BEGIN(Start); } <<EOF>> { @@ -336,20 +359,20 @@ static void readIncludeFile(const QString &incName) yy_switch_to_buffer( fs->oldState ); yy_delete_buffer( oldBuf ); g_yyFileName=fs->fileName; - delete fs; + delete fs; g_includeDepth--; } } <Start>[a-z_A-Z0-9]+ { config_warn("ignoring unknown tag '%s' at line %d, file %s\n",yytext,yylineno,qPrintable(g_yyFileName)); } <GetString,GetEnum,SkipInvalid>\n { BEGIN(Start); } -<GetStrList>\n { +<GetStrList>\n { if (!g_elemStr.isEmpty()) { //printf("elemStr1='%s'\n",qPrintable(elemStr)); *g_arg = QVariant(g_arg->toStringList() << g_elemStr); } - BEGIN(Start); + BEGIN(Start); } <GetStrList>[ \t]+ { if (!g_elemStr.isEmpty()) @@ -360,30 +383,94 @@ static void readIncludeFile(const QString &incName) g_elemStr = QString(); } <GetString>[^ \"\t\r\n]+ { - *g_arg = QVariant(g_codec->toUnicode(yytext)); - checkEncoding(); + if (g_part == 1) // multiple unquoted parts, reset to default + { + config_warn("Invalid value for '%s' tag in line %d, file %s\n" + "Value should not contain unquoted whitespace, " + "using the default\n", + qPrintable(g_cmd),yylineno,qPrintable(g_yyFileName)); + *g_arg=QVariant(g_codec->toUnicode("")); + } + else if (g_part > 1) // multiple unquoted parts, reset to default + { + *g_arg=QVariant(g_codec->toUnicode("")); + } + else + { + *g_arg = QVariant(g_codec->toUnicode(yytext)); + checkEncoding(); + } + g_part++; } <GetEnum>[^ \"\t\r\n]+ { InputString *cur = dynamic_cast<InputString *>(g_curOption); - *g_arg = cur->checkEnumVal(g_codec->toUnicode(yytext)); + if (g_part == 1) // multiple unquoted parts, reset to default + { + config_warn("Invalid value for '%s' tag in line %d, file %s\n" + "Value should not contain unquoted whitespace, " + "using the default\n", + qPrintable(g_cmd),yylineno,qPrintable(g_yyFileName)); + *g_arg=QVariant(g_codec->toUnicode("")); + } + else if (g_part > 1) // multiple unquoted parts, reset to default + { + *g_arg=QVariant(g_codec->toUnicode("")); + } + else + { + *g_arg = cur->checkEnumVal(g_codec->toUnicode(yytext)); + } + g_part++; } <GetString,GetEnum,GetStrList,SkipInvalid>"\"" { g_lastState=YY_START; - BEGIN(GetQuotedString); + BEGIN(GetQuotedString); g_tmpString=""; } -<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",qPrintable(tmpString)); if (g_lastState==GetString) { - *g_arg = g_codec->toUnicode(g_tmpString); - checkEncoding(); + if (g_part == 1) // multiple unquoted parts, reset to default + { + config_warn("Invalid value for '%s' tag in line %d, file %s\n" + "Value should not contain unquoted whitespace, " + "using the default\n", + qPrintable(g_cmd),yylineno,qPrintable(g_yyFileName)); + *g_arg=g_codec->toUnicode(""); + } + else if (g_part > 1) // multiple unquoted parts, reset to default + { + *g_arg=g_codec->toUnicode(""); + } + else + { + *g_arg = g_codec->toUnicode(g_tmpString); + checkEncoding(); + } + g_part++; } else if (g_lastState==GetEnum) { - InputString *cur = dynamic_cast<InputString *>(g_curOption); - *g_arg = cur->checkEnumVal(g_codec->toUnicode(g_tmpString)); + if (g_part == 1) // multiple unquoted parts, reset to default + { + config_warn("Invalid value for '%s' tag in line %d, file %s\n" + "Value should not contain unquoted whitespace, " + "using the default\n", + qPrintable(g_cmd),yylineno,qPrintable(g_yyFileName)); + *g_arg=g_codec->toUnicode(""); + } + else if (g_part > 1) // multiple unquoted parts, reset to default + { + *g_arg=g_codec->toUnicode(""); + } + else + { + InputString *cur = dynamic_cast<InputString *>(g_curOption); + *g_arg = cur->checkEnumVal(g_codec->toUnicode(g_tmpString)); + } + g_part++; } else { @@ -396,6 +483,9 @@ static void readIncludeFile(const QString &incName) } BEGIN(g_lastState); } +<GetQuotedString>("\\\\"|"@\\"|"\\@"|"@@") { + g_tmpString+=yytext; + } <GetQuotedString>"\\\"" { g_tmpString+='"'; } @@ -442,7 +532,7 @@ static void substEnvVarsInStrList(QStringList &sl) foreach (QString result, sl) { // an argument with quotes will have an extra space at the end, so wasQuoted will be TRUE. - bool wasQuoted = (result.indexOf(QChar::fromLatin1(' '))!=-1) || + bool wasQuoted = (result.indexOf(QChar::fromLatin1(' '))!=-1) || (result.indexOf(QChar::fromLatin1('\t'))!=-1); // here we strip the quote again substEnvVarsInString(result); @@ -452,7 +542,7 @@ static void substEnvVarsInStrList(QStringList &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 + contained multiple elements no further splitting is done to allow quoted items with spaces! */ { int l=result.length(); @@ -463,11 +553,11 @@ static void substEnvVarsInStrList(QStringList &sl) { QChar c=0; // skip until start of new word - while (i<l && ((c=result.at(i))==QChar::fromLatin1(' ') || c==QChar::fromLatin1('\t'))) i++; + while (i<l && ((c=result.at(i))==QChar::fromLatin1(' ') || c==QChar::fromLatin1('\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))!=QChar::fromLatin1(' ') && - c!=QChar::fromLatin1('\t') && + while (i<l && ((c=result.at(i))!=QChar::fromLatin1(' ') && + c!=QChar::fromLatin1('\t') && c!=QChar::fromLatin1('"'))) i++; if (i<l) // not at the end of the string { @@ -481,7 +571,7 @@ static void substEnvVarsInStrList(QStringList &sl) { out += result.mid(p,i-p); p=i+1; - break; + break; } else if (c==QChar::fromLatin1('\\')) // skip escaped stuff { @@ -516,13 +606,18 @@ bool parseConfig( const QHash<QString,Input *> &options ) { + yylineno = 1; + if (DoxygenWizard::debugFlag) + { + MainWindow::instance().outputLogStart(); + } QHashIterator<QString, Input*> i(options); g_file = fopen(fileName.toLocal8Bit(),"r"); if (g_file==NULL) return false; // reset all values i.toFront(); - while (i.hasNext()) + while (i.hasNext()) { i.next(); if (i.value()) @@ -542,7 +637,7 @@ bool parseConfig( // update the values in the UI i.toFront(); - while (i.hasNext()) + while (i.hasNext()) { i.next(); if (i.value()) @@ -554,8 +649,12 @@ bool parseConfig( { printf("Invalid option: %s\n",qPrintable(i.key())); } - } + } fclose(g_file); + if (DoxygenWizard::debugFlag) + { + MainWindow::instance().outputLogFinish(); + } return true; } @@ -572,29 +671,29 @@ void writeStringValue(QTextStream &t,QTextCodec *codec,const QString &s) { if (*p != QChar::fromLatin1('"')) { - while (!(c=*p++).isNull() && !needsEscaping) + while (!(c=*p++).isNull() && !needsEscaping) { - needsEscaping = (c==QChar::fromLatin1(' ') || - c==QChar::fromLatin1('\n') || - c==QChar::fromLatin1('\t') || + needsEscaping = (c==QChar::fromLatin1(' ') || + c==QChar::fromLatin1('\n') || + c==QChar::fromLatin1('\t') || c==QChar::fromLatin1('"')); } p=s.data(); - while (!(c=*p++).isNull() && !needsHashEscaping) + while (!(c=*p++).isNull() && !needsHashEscaping) { needsHashEscaping = (c==QChar::fromLatin1('#')); } } if (needsHashEscaping || needsEscaping) - { + { t << "\""; } if (needsEscaping) - { + { p=s.data(); while (!p->isNull()) { - if (*p ==QChar::fromLatin1(' ') && + if (*p ==QChar::fromLatin1(' ') && *(p+1)==QChar::fromLatin1('\0')) break; // skip inserted space at the end if (*p ==QChar::fromLatin1('"')) t << "\\"; // escape quotes t << *p++; @@ -605,7 +704,7 @@ void writeStringValue(QTextStream &t,QTextCodec *codec,const QString &s) t << s; } if (needsHashEscaping || needsEscaping) - { + { t << "\""; } } |