diff options
Diffstat (limited to 'trunk/src/pre.l')
-rw-r--r-- | trunk/src/pre.l | 3051 |
1 files changed, 0 insertions, 3051 deletions
diff --git a/trunk/src/pre.l b/trunk/src/pre.l deleted file mode 100644 index d0acd41..0000000 --- a/trunk/src/pre.l +++ /dev/null @@ -1,3051 +0,0 @@ -/****************************************************************************** - * - * - * - * Copyright (C) 1997-2012 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 - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ - -%{ - -/* - * includes - */ - -#include <stdio.h> -#include <assert.h> -#include <ctype.h> -#include <errno.h> - -#include "qtbc.h" -#include <qarray.h> -#include <qstack.h> -#include <qfile.h> -#include <qstrlist.h> -#include <qdict.h> -#include <qregexp.h> -#include <qfileinfo.h> -#include <qdir.h> - -#include "pre.h" -#include "constexp.h" -#include "define.h" -#include "doxygen.h" -#include "message.h" -#include "util.h" -#include "defargs.h" -#include "debug.h" -#include "bufstr.h" -#include "portable.h" -#include "bufstr.h" -#include "arguments.h" -#include "entry.h" - -#define YY_NEVER_INTERACTIVE 1 - - -struct FileState -{ - FileState(int size) : fileBuf(size), - oldFileBuf(0), oldFileBufPos(0) {} - int lineNr; - BufStr fileBuf; - BufStr *oldFileBuf; - int oldFileBufPos; - YY_BUFFER_STATE bufState; - QCString fileName; -}; - -/** @brief Singleton that manages the defines available while - * proprocessing files. - */ -class DefineManager -{ - /** Local class used to hold the defines for a single file */ - class DefinesPerFile - { - public: - /** Creates an empty container for defines */ - DefinesPerFile() : m_defines(257), m_includedFiles(17) - { - m_defines.setAutoDelete(TRUE); - } - /** Destroys the object */ - virtual ~DefinesPerFile() - { - } - /** Adds a define in the context of a file. Will replace - * an existing define with the same name (redefinition) - * @param def The Define object to add. - */ - void addDefine(Define *def) - { - Define *d = m_defines.find(def->name); - if (d!=0) // redefine - { - m_defines.remove(d->name); - } - m_defines.insert(def->name,def); - } - /** Adds an include file for this file - * @param fileName The name of the include file - */ - void addInclude(const char *fileName) - { - m_includedFiles.insert(fileName,(void*)0x8); - } - void collectDefines(DefineDict *dict,QDict<void> &includeStack); - private: - DefineDict m_defines; - QDict<void> m_includedFiles; - }; - - public: - friend class DefinesPerFile; - /** Returns a reference to the singleton */ - static DefineManager &instance() - { - if (theInstance==0) theInstance = new DefineManager; - return *theInstance; - } - /** Deletes the singleton */ - static void deleteInstance() - { - delete theInstance; - theInstance = 0; - } - /** Starts a context in which defines are collected. - * Called at the start of a new file that is preprocessed. - * @param fileName the name of the file to process. - */ - void startContext(const char *fileName) - { - //printf("DefineManager::startContext()\n"); - m_contextDefines.clear(); - if (fileName==0) return; - DefinesPerFile *dpf = m_fileMap.find(fileName); - if (dpf==0) - { - //printf("New file!\n"); - dpf = new DefinesPerFile; - m_fileMap.insert(fileName,dpf); - } - } - /** Ends the context started with startContext() freeing any - * defines collected within in this context. - */ - void endContext() - { - //printf("DefineManager::endContext()\n"); - m_contextDefines.clear(); - } - /** Add an included file to the current context. - * If the file has been pre-processed already, all defines are added - * to the context. - * @param fileName The name of the include file to add to the context. - */ - void addFileToContext(const char *fileName) - { - if (fileName==0) return; - //printf("DefineManager::addFileToContext(%s)\n",fileName); - DefinesPerFile *dpf = m_fileMap.find(fileName); - if (dpf==0) - { - //printf("New file!\n"); - dpf = new DefinesPerFile; - m_fileMap.insert(fileName,dpf); - } - else - { - //printf("existing file!\n"); - QDict<void> includeStack(17); - dpf->collectDefines(&m_contextDefines,includeStack); - } - } - - /** Add a define to the manager object. - * @param fileName The file in which the define was found - * @param def The Define object to add. - */ - void addDefine(const char *fileName,Define *def) - { - if (fileName==0) return; - //printf("DefineManager::addDefine(%s,%s)\n",fileName,def->name.data()); - Define *d = m_contextDefines.find(def->name); - if (d!=0) // redefine - { - m_contextDefines.remove(d->name); - } - m_contextDefines.insert(def->name,def); - - DefinesPerFile *dpf = m_fileMap.find(fileName); - if (dpf==0) - { - dpf = new DefinesPerFile; - } - dpf->addDefine(def); - } - - /** Add an include relation to the manager object. - * @param fromFileName file name in which the include was found. - * @param toFileName file name that is included. - */ - void addInclude(const char *fromFileName,const char *toFileName) - { - //printf("DefineManager::addInclude(%s,%s)\n",fromFileName,toFileName); - if (fromFileName==0 || toFileName==0) return; - DefinesPerFile *dpf = m_fileMap.find(fromFileName); - if (dpf==0) - { - dpf = new DefinesPerFile; - } - dpf->addInclude(toFileName); - } - /** Returns a Define object given its name or 0 if the Define does - * not exist. - */ - Define *isDefined(const char *name) const - { - return m_contextDefines.find(name); - } - /** Returns a reference to the defines found in the current context. */ - const DefineDict &defineContext() const - { - return m_contextDefines; - } - private: - static DefineManager *theInstance; - - /** Helper function to collect all define for a given file */ - void collectDefinesForFile(const char *fileName,DefineDict *dict) - { - if (fileName==0) return; - DefinesPerFile *dpf = m_fileMap.find(fileName); - if (dpf) - { - QDict<void> includeStack(17); - dpf->collectDefines(dict,includeStack); - } - } - - /** Helper function to return the DefinesPerFile object for a given file name. */ - DefinesPerFile *find(const char *fileName) const - { - if (fileName==0) return 0; - return m_fileMap.find(fileName); - } - - /** Creates a new DefineManager object */ - DefineManager() : m_fileMap(1009), m_contextDefines(1009) - { - m_fileMap.setAutoDelete(TRUE); - } - - /** Destroys the object */ - virtual ~DefineManager() - { - } - - QDict<DefinesPerFile> m_fileMap; - DefineDict m_contextDefines; -}; - -/** Singleton instance */ -DefineManager *DefineManager::theInstance = 0; - -/** Collects all defines for a file and all files that the file includes. - * This function will recursively call itself for each file. - * @param dict The dictionary to fill with the defines. A redefine will - * replace a previous definition. - * @param includeStack The stack of includes, used to stop recursion in - * case there is a cyclic include dependency. - */ -void DefineManager::DefinesPerFile::collectDefines( - DefineDict *dict,QDict<void> &includeStack) -{ - //printf("DefinesPerFile::collectDefines #defines=%d\n",m_defines.count()); - { - QDictIterator<void> di(m_includedFiles); - for (di.toFirst();(di.current());++di) - { - QCString incFile = di.currentKey(); - DefinesPerFile *dpf = DefineManager::instance().find(incFile); - if (dpf && includeStack.find(incFile)==0) - { - //printf(" processing include %s\n",incFile.data()); - includeStack.insert(incFile,(void*)0x8); - dpf->collectDefines(dict,includeStack); - } - } - } - { - QDictIterator<Define> di(m_defines); - Define *def; - for (di.toFirst();(def=di.current());++di) - { - Define *d = dict->find(def->name); - if (d!=0) // redefine - { - dict->remove(d->name); - } - dict->insert(def->name,def); - //printf(" adding define %s\n",def->name.data()); - } - } -} - -/* ----------------------------------------------------------------- - * - * scanner's state - */ - -static int g_yyLineNr = 1; -static QCString g_yyFileName; -static FileDef *g_yyFileDef; -static FileDef *g_inputFileDef; -static int g_ifcount = 0; -static QStrList *g_pathList = 0; -static QStack<FileState> g_includeStack; -static QDict<int> *g_argDict; -static int g_defArgs = -1; -static QCString g_defName; -static QCString g_defText; -static QCString g_defLitText; -static QCString g_defArgsStr; -static QCString g_defExtraSpacing; -static bool g_defVarArgs; -static int g_level; -static int g_lastCContext; -static int g_lastCPPContext; -static QArray<int> g_levelGuard; -static BufStr *g_inputBuf; -static int g_inputBufPos; -static BufStr *g_outputBuf; -static int g_roundCount; -static bool g_quoteArg; -static DefineDict *g_expandedDict; -static int g_findDefArgContext; -static bool g_expectGuard; -static QCString g_guardName; -static QCString g_lastGuardName; -static QCString g_incName; -static QCString g_guardExpr; -static int g_curlyCount; -static bool g_nospaces; // add extra spaces during macro expansion - -static bool g_macroExpansion; // from the configuration -static bool g_expandOnlyPredef; // from the configuration -static int g_commentCount; -static bool g_insideComment; -static bool g_isImported; -static QCString g_blockName; -static int g_condCtx; -static bool g_skip; -static QStack<bool> g_condStack; -static bool g_insideCS; // C# has simpler preprocessor -static bool g_isSource; - -static bool g_lexInit = FALSE; - -//DefineDict* getGlobalDefineDict() -//{ -// return g_globalDefineDict; -//} - -static void setFileName(const char *name) -{ - bool ambig; - QFileInfo fi(name); - g_yyFileName=convertToQCString(fi.absFilePath()); - g_yyFileDef=findFileDef(Doxygen::inputNameDict,g_yyFileName,ambig); - if (g_yyFileDef==0) // if this is not an input file check if it is an - // include file - { - g_yyFileDef=findFileDef(Doxygen::includeNameDict,g_yyFileName,ambig); - } - //printf("setFileName(%s) g_yyFileName=%s g_yyFileDef=%p\n", - // name,g_yyFileName.data(),g_yyFileDef); - if (g_yyFileDef && g_yyFileDef->isReference()) g_yyFileDef=0; - g_insideCS = getLanguageFromFileName(g_yyFileName)==SrcLangExt_CSharp; - g_isSource = guessSection(g_yyFileName); -} - -static void incrLevel() -{ - g_level++; - g_levelGuard.resize(g_level); - g_levelGuard[g_level-1]=FALSE; - //printf("%s line %d: incrLevel %d\n",g_yyFileName.data(),g_yyLineNr,g_level); -} - -static void decrLevel() -{ - //printf("%s line %d: decrLevel %d\n",g_yyFileName.data(),g_yyLineNr,g_level); - if (g_level > 0) - { - g_level--; - g_levelGuard.resize(g_level); - } - else - { - warn(g_yyFileName,g_yyLineNr,"warning: More #endif's than #if's found.\n"); - } -} - -static bool otherCaseDone() -{ - if (g_level==0) - { - warn(g_yyFileName,g_yyLineNr,"warning: Found an #else without a preceding #if.\n"); - return TRUE; - } - else - { - return g_levelGuard[g_level-1]; - } -} - -static void setCaseDone(bool value) -{ - g_levelGuard[g_level-1]=value; -} - -#if 0 -static bool macroIsAccessible(Define *def) -{ - //printf("macroIsAccessible(%s) input=%s def=%s\n", - // def->name.data(),g_inputFileDef?g_inputFileDef->name().data():"<none>", - // def->fileDef ? def->fileDef->name().data() : "<none>"); - if (def && def->isPredefined) // predefined macro -> globally accessible - { - //printf("%s: predefined macro %s\n",g_inputFileDef->name().data(),def->name.data()); - return TRUE; - } - if (def && def->fileDef==g_inputFileDef) - { - //printf("%s: macro %s defined in this file at line %d now at %d\n", - // g_inputFileDef->name().data(),def->name.data(),def->lineNr,g_yyLineNr); - return def->lineNr<=g_yyLineNr; - } - if (g_inputFileDef && def && def->fileDef) // check if g_inputFileDef actually includes def->fileDef - { - QDict<FileDef> includedFiles(257); - bool b = g_inputFileDef->includes(def->fileDef,&includedFiles); - //printf("%s: Checking for accessibility of define '%s' (defined in %s): result=%d\n", - // g_inputFileDef->name().data(),def->name.data(),def->fileDef->name().data(),b); - return b; - } - if (g_inputFileDef && def && !def->fileName.isEmpty()) - { - bool b = g_inputFileDef->includesByName(def->fileName); - //printf("%s: Checking for accessibility of define '%s' (defined in %s): result=%d\n", - // g_inputFileDef->name().data(),def->name.data(),def->fileName.data(),b); - return b; - } - //printf("not accessible!\n"); - return FALSE; -} - -static Define *isDefined(const char *name) -{ - Define *def=0; - if (name) - { - def=g_globalDefineDict->find(name); - if (def && def->undef) def=0; - if (def && !macroIsAccessible(def)) def=0; - } - //printf("isDefined(%s)=%p\n",name,def); - return def; -} -#endif - - -static QDict<void> g_allIncludes(10009); - -static FileState *checkAndOpenFile(const QCString &fileName,bool &alreadyIncluded) -{ - alreadyIncluded = FALSE; - FileState *fs = 0; - //printf("checkAndOpenFile(%s)\n",fileName.data()); - QFileInfo fi(fileName); - if (fi.exists() && fi.isFile()) - { - static QStrList &exclPatterns = Config_getList("EXCLUDE_PATTERNS"); - if (patternMatch(fi,&exclPatterns)) return 0; - - QCString absName = convertToQCString(fi.absFilePath()); - - // global guard - if (g_curlyCount==0) // not #include inside { ... } - { - if (g_allIncludes.find(absName)!=0) - { - alreadyIncluded = TRUE; - //printf(" already included 1\n"); - return 0; // already done - } - g_allIncludes.insert(absName,(void *)0x8); - } - // check include stack for absName - - QStack<FileState> tmpStack; - g_includeStack.setAutoDelete(FALSE); - while ((fs=g_includeStack.pop())) - { - if (fs->fileName==absName) alreadyIncluded=TRUE; - tmpStack.push(fs); - } - while ((fs=tmpStack.pop())) - { - g_includeStack.push(fs); - } - g_includeStack.setAutoDelete(TRUE); - - if (alreadyIncluded) - { - //printf(" already included 2\n"); - return 0; - } - //printf("#include %s\n",absName.data()); - - fs = new FileState(fi.size()+4096); - alreadyIncluded = FALSE; - if (!readInputFile(absName,fs->fileBuf)) - { // error - //printf(" error reading\n"); - delete fs; - fs=0; - } - else - { - fs->oldFileBuf = g_inputBuf; - fs->oldFileBufPos = g_inputBufPos; - } - } - return fs; -} - -static FileState *findFile(const char *fileName,bool localInclude,bool &alreadyIncluded) -{ - //printf("** findFile(%s,%d) g_yyFileName=%s\n",fileName,localInclude,g_yyFileName.data()); - if (localInclude && !g_yyFileName.isEmpty()) - { - QFileInfo fi(g_yyFileName); - if (fi.exists()) - { - QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+fileName; - FileState *fs = checkAndOpenFile(absName,alreadyIncluded); - if (fs) - { - setFileName(absName); - g_yyLineNr=1; - return fs; - } - else if (alreadyIncluded) - { - return 0; - } - } - } - if (g_pathList==0) - { - return 0; - } - char *s=g_pathList->first(); - while (s) - { - QCString absName = (QCString)s+"/"+fileName; - //printf(" Looking for %s in %s\n",fileName,s); - FileState *fs = checkAndOpenFile(absName,alreadyIncluded); - if (fs) - { - setFileName(absName); - g_yyLineNr=1; - //printf(" -> found it\n"); - return fs; - } - else if (alreadyIncluded) - { - return 0; - } - - s=g_pathList->next(); - } - return 0; -} - -static QCString extractTrailingComment(const char *s) -{ - if (s==0) return ""; - int i=strlen(s)-1; - while (i>=0) - { - char c=s[i]; - switch (c) - { - case '/': - { - i--; - if (i>=0 && s[i]=='*') // end of a comment block - { - i--; - while (i>0 && !(s[i-1]=='/' && s[i]=='*')) i--; - if (i==0) - { - i++; - } - // only /*!< or /**< are treated as a comment for the macro name, - // otherwise the comment is treated as part of the macro definition - return ((s[i+1]=='*' || s[i+1]=='!') && s[i+2]=='<') ? &s[i-1] : ""; - } - else - { - return ""; - } - } - break; - // whitespace or line-continuation - case ' ': - case '\t': - case '\r': - case '\n': - case '\\': - break; - default: - return ""; - } - i--; - } - return ""; -} - -static int getNextChar(const QCString &expr,QCString *rest,uint &pos); -static int getCurrentChar(const QCString &expr,QCString *rest,uint pos); -static void unputChar(const QCString &expr,QCString *rest,uint &pos,char c); -static void expandExpression(QCString &expr,QCString *rest,int pos); - -static QCString stringize(const QCString &s) -{ - QCString result; - uint i=0; - bool inString=FALSE; - bool inChar=FALSE; - char c,pc; - while (i<s.length()) - { - if (!inString && !inChar) - { - while (i<s.length() && !inString && !inChar) - { - c=s.at(i++); - if (c=='"') - { - result+="\\\""; - inString=TRUE; - } - else if (c=='\'') - { - result+=c; - inChar=TRUE; - } - else - { - result+=c; - } - } - } - else if (inChar) - { - while (i<s.length() && inChar) - { - c=s.at(i++); - if (c=='\'') - { - result+='\''; - inChar=FALSE; - } - else if (c=='\\') - { - result+="\\\\"; - } - else - { - result+=c; - } - } - } - else - { - pc=0; - while (i<s.length() && inString) - { - char c=s.at(i++); - if (c=='"') - { - result+="\\\""; - inString= pc=='\\'; - } - else if (c=='\\') - result+="\\\\"; - else - result+=c; - pc=c; - } - } - } - //printf("stringize `%s'->`%s'\n",s.data(),result.data()); - return result; -} - -/*! Execute all ## operators in expr. - * If the macro name before or after the operator contains a no-rescan - * marker (@-) then this is removed (before the concatenated macro name - * may be expanded again. - */ -static void processConcatOperators(QCString &expr) -{ - //printf("processConcatOperators: in=`%s'\n",expr.data()); - QRegExp r("[ \\t\\n]*##[ \\t\\n]*"); - int l,n,i=0; - if (expr.isEmpty()) return; - while ((n=r.match(expr,i,&l))!=-1) - { - //printf("Match: `%s'\n",expr.data()+i); - if (n+l+1<(int)expr.length() && expr.at(n+l)=='@' && expr.at(n+l+1)=='-') - { - // remove no-rescan marker after ID - l+=2; - } - //printf("found `%s'\n",expr.mid(n,l).data()); - // remove the ## operator and the surrounding whitespace - expr=expr.left(n)+expr.right(expr.length()-n-l); - int k=n-1; - while (k>=0 && isId(expr.at(k))) k--; - if (k>0 && expr.at(k)=='-' && expr.at(k-1)=='@') - { - // remove no-rescan marker before ID - expr=expr.left(k-1)+expr.right(expr.length()-k-1); - n-=2; - } - i=n; - } - //printf("processConcatOperators: out=`%s'\n",expr.data()); -} - -static void yyunput (int c,char *buf_ptr ); -static void returnCharToStream(char c) -{ - unput(c); -} - -static inline void addTillEndOfString(const QCString &expr,QCString *rest, - uint &pos,char term,QCString &arg) -{ - int cc; - while ((cc=getNextChar(expr,rest,pos))!=EOF) - { - if (cc=='\\') arg+=(char)cc,cc=getNextChar(expr,rest,pos); - else if (cc==term) return; - arg+=(char)cc; - } -} - -/*! replaces the function macro \a def whose argument list starts at - * \a pos in expression \a expr. - * Notice that this routine may scan beyond the \a expr string if needed. - * In that case the characters will be read from the input file. - * The replacement string will be returned in \a result and the - * length of the (unexpanded) argument list is stored in \a len. - */ -static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int &len,const Define *def,QCString &result) -{ - //printf("replaceFunctionMacro(expr=%s,rest=%s,pos=%d,def=%s) level=%d\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),g_level); - uint j=pos; - len=0; - result.resize(0); - int cc; - while ((cc=getCurrentChar(expr,rest,j))!=EOF && isspace(cc)) - { - len++; - getNextChar(expr,rest,j); - } - if (cc!='(') - { - unputChar(expr,rest,j,' '); - return FALSE; - } - getNextChar(expr,rest,j); // eat the `(' character - - QDict<QCString> argTable; // list of arguments - argTable.setAutoDelete(TRUE); - QCString arg; - int argCount=0; - bool done=FALSE; - - // PHASE 1: read the macro arguments - if (def->nargs==0) - { - while ((cc=getNextChar(expr,rest,j))!=EOF) - { - char c = (char)cc; - if (c==')') break; - } - } - else - { - while (!done && (argCount<def->nargs || def->varArgs) && - ((cc=getNextChar(expr,rest,j))!=EOF) - ) - { - char c=(char)cc; - if (c=='(') // argument is a function => search for matching ) - { - int level=1; - arg+=c; - //char term='\0'; - while ((cc=getNextChar(expr,rest,j))!=EOF) - { - char c=(char)cc; - //printf("processing %c: term=%c (%d)\n",c,term,term); - if (c=='\'' || c=='\"') // skip ('s and )'s inside strings - { - arg+=c; - addTillEndOfString(expr,rest,j,c,arg); - } - if (c==')') - { - level--; - arg+=c; - if (level==0) break; - } - else if (c=='(') - { - level++; - arg+=c; - } - else - arg+=c; - } - } - else if (c==')' || c==',') // last or next argument found - { - if (c==',' && argCount==def->nargs-1 && def->varArgs) - { - arg=arg.stripWhiteSpace(); - arg+=','; - } - else - { - QCString argKey; - argKey.sprintf("@%d",argCount++); // key name - arg=arg.stripWhiteSpace(); - // add argument to the lookup table - argTable.insert(argKey, new QCString(arg)); - arg.resize(0); - if (c==')') // end of the argument list - { - done=TRUE; - } - } - } - else if (c=='\"') // append literal strings - { - arg+=c; - bool found=FALSE; - while (!found && (cc=getNextChar(expr,rest,j))!=EOF) - { - found = cc=='"'; - if (cc=='\\') - { - c=(char)cc; - arg+=c; - if ((cc=getNextChar(expr,rest,j))==EOF) break; - } - c=(char)cc; - arg+=c; - } - } - else if (c=='\'') // append literal characters - { - arg+=c; - bool found=FALSE; - while (!found && (cc=getNextChar(expr,rest,j))!=EOF) - { - found = cc=='\''; - if (cc=='\\') - { - c=(char)cc; - arg+=c; - if ((cc=getNextChar(expr,rest,j))==EOF) break; - } - c=(char)cc; - arg+=c; - } - } - else // append other characters - { - arg+=c; - } - } - } - - // PHASE 2: apply the macro function - if (argCount==def->nargs || - (argCount>def->nargs && def->varArgs)) // matching parameters lists - { - uint k=0; - // substitution of all formal arguments - QCString resExpr; - const QCString d=def->definition.stripWhiteSpace(); - //printf("Macro definition: %s\n",d.data()); - bool inString=FALSE; - while (k<d.length()) - { - if (d.at(k)=='@') // maybe a marker, otherwise an escaped @ - { - if (d.at(k+1)=='@') // escaped @ => copy it (is unescaped later) - { - k+=2; - resExpr+="@@"; // we unescape these later - } - else if (d.at(k+1)=='-') // no-rescan marker - { - k+=2; - resExpr+="@-"; - } - else // argument marker => read the argument number - { - QCString key="@"; - QCString *subst=0; - bool hash=FALSE; - int l=k-1; - // search for ## backward - if (l>=0 && d.at(l)=='"') l--; - while (l>=0 && d.at(l)==' ') l--; - if (l>0 && d.at(l)=='#' && d.at(l-1)=='#') hash=TRUE; - k++; - // scan the number - while (k<d.length() && d.at(k)>='0' && d.at(k)<='9') key+=d.at(k++); - if (!hash) - { - // search for ## forward - l=k; - if (l<(int)d.length() && d.at(l)=='"') l++; - while (l<(int)d.length() && d.at(l)==' ') l++; - if (l<(int)d.length()-1 && d.at(l)=='#' && d.at(l+1)=='#') hash=TRUE; - } - //printf("request key %s result %s\n",key.data(),argTable[key]->data()); - if (key.length()>1 && (subst=argTable[key])) - { - QCString substArg=*subst; - //printf("substArg=`%s'\n",substArg.data()); - // only if no ## operator is before or after the argument - // marker we do macro expansion. - if (!hash) expandExpression(substArg,0,0); - if (inString) - { - //printf("`%s'=stringize(`%s')\n",stringize(*subst).data(),subst->data()); - - // if the marker is inside a string (because a # was put - // before the macro name) we must escape " and \ characters - resExpr+=stringize(substArg); - } - else - { - if (hash && substArg.isEmpty()) - { - resExpr+="@E"; // empty argument will be remove later on - } - else if (g_nospaces) - { - resExpr+=substArg; - } - else - { - resExpr+=" "+substArg+" "; - } - } - } - } - } - else // no marker, just copy - { - if (!inString && d.at(k)=='\"') - { - inString=TRUE; // entering a literal string - } - else if (inString && d.at(k)=='\"' && (d.at(k-1)!='\\' || d.at(k-2)=='\\')) - { - inString=FALSE; // leaving a literal string - } - resExpr+=d.at(k++); - } - } - len=j-pos; - result=resExpr; - //printf("result after substitution `%s' expr=`%s'\n", - // result.data(),expr.mid(pos,len).data()); - return TRUE; - } - return FALSE; -} - - -/*! returns the next identifier in string \a expr by starting at position \a p. - * The position of the identifier is returned (or -1 if nothing is found) - * and \a l is its length. Any quoted strings are skipping during the search. - */ -static int getNextId(const QCString &expr,int p,int *l) -{ - int n; - while (p<(int)expr.length()) - { - char c=expr.at(p++); - if (isdigit(c)) // skip number - { - while (p<(int)expr.length() && isId(expr.at(p))) p++; - } - else if (isalpha(c) || c=='_') // read id - { - n=p-1; - while (p<(int)expr.length() && isId(expr.at(p))) p++; - *l=p-n; - return n; - } - else if (c=='"') // skip string - { - char ppc=0,pc=c; - if (p<(int)expr.length()) c=expr.at(p); - while (p<(int)expr.length() && (c!='"' || (pc=='\\' && ppc!='\\'))) - // continue as long as no " is found, but ignoring \", but not \\" - { - ppc=pc; - pc=c; - c=expr.at(p); - p++; - } - if (p<(int)expr.length()) ++p; // skip closing quote - } - else if (c=='/') // skip C Comment - { - //printf("Found C comment at p=%d\n",p); - char pc=c; - if (p<(int)expr.length()) - { - c=expr.at(p); - if (c=='*') // Start of C comment - { - p++; - while (p<(int)expr.length() && !(pc=='*' && c=='/')) - { - pc=c; - c=expr.at(p++); - } - } - } - //printf("Found end of C comment at p=%d\n",p); - } - } - return -1; -} - -/*! preforms recursive macro expansion on the string \a expr - * starting at position \a pos. - * May read additional characters from the input while re-scanning! - * If \a expandAll is \c TRUE then all macros in the expression are - * expanded, otherwise only the first is expanded. - */ -static void expandExpression(QCString &expr,QCString *rest,int pos) -{ - //printf("expandExpression(%s,%s)\n",expr.data(),rest ? rest->data() : 0); - QCString macroName; - QCString expMacro; - bool definedTest=FALSE; - int i=pos,l,p,len; - while ((p=getNextId(expr,i,&l))!=-1) // search for an macro name - { - bool replaced=FALSE; - macroName=expr.mid(p,l); - //printf("macroName=%s\n",macroName.data()); - if (p<2 || !(expr.at(p-2)=='@' && expr.at(p-1)=='-')) // no-rescan marker? - { - if (g_expandedDict->find(macroName)==0) // expand macro - { - Define *def=DefineManager::instance().isDefined(macroName); - if (definedTest) // macro name was found after defined - { - if (def) expMacro = " 1 "; else expMacro = " 0 "; - replaced=TRUE; - len=l; - definedTest=FALSE; - } - else if (def && def->nargs==-1) // simple macro - { - // substitute the definition of the macro - //printf("macro `%s'->`%s'\n",macroName.data(),def->definition.data()); - if (g_nospaces) - { - expMacro=def->definition.stripWhiteSpace(); - } - else - { - expMacro=" "+def->definition.stripWhiteSpace()+" "; - } - //expMacro=def->definition.stripWhiteSpace(); - replaced=TRUE; - len=l; - //printf("simple macro expansion=`%s'->`%s'\n",macroName.data(),expMacro.data()); - } - else if (def && def->nargs>=0) // function macro - { - replaced=replaceFunctionMacro(expr,rest,p+l,len,def,expMacro); - len+=l; - } - else if (macroName=="defined") - { - //printf("found defined inside macro definition '%s'\n",expr.right(expr.length()-p).data()); - definedTest=TRUE; - } - - if (replaced) // expand the macro and rescan the expression - { - - //printf("replacing `%s'->`%s'\n",expr.mid(p,len).data(),expMacro.data()); - QCString resultExpr=expMacro; - QCString restExpr=expr.right(expr.length()-len-p); - processConcatOperators(resultExpr); - if (def && !def->nonRecursive) - { - g_expandedDict->insert(macroName,def); - expandExpression(resultExpr,&restExpr,0); - g_expandedDict->remove(macroName); - } - expr=expr.left(p)+resultExpr+restExpr; - i=p; - //printf("new expression: %s\n",expr.data()); - } - else // move to the next macro name - { - //printf("moving to the next macro old=%d new=%d\n",i,p+l); - i=p+l; - } - } - else // move to the next macro name - { - expr=expr.left(p)+"@-"+expr.right(expr.length()-p); - //printf("macro already expanded, moving to the next macro expr=%s\n",expr.data()); - i=p+l+2; - //i=p+l; - } - } - else // no re-scan marker found, skip the macro name - { - //printf("skipping marked macro\n"); - i=p+l; - } - } -} - -/*! replaces all occurrences of @@@@ in \a s by @@ - * and removes all occurrences of @@E. - * All identifiers found are replaced by 0L - */ -QCString removeIdsAndMarkers(const char *s) -{ - //printf("removeIdsAndMarkers(%s)\n",s); - const char *p=s; - char c; - bool inNum=FALSE; - QCString result; - if (p) - { - while ((c=*p)) - { - if (c=='@') // replace @@ with @ and remove @E - { - if (*(p+1)=='@') - { - result+=c; - } - else if (*(p+1)=='E') - { - // skip - } - p+=2; - } - else if (isdigit(c)) // number - { - result+=c; - p++; - inNum=TRUE; - } - else if (c=='d' && !inNum) // identifier starting with a `d' - { - if (strncmp(p,"defined ",8)==0 || strncmp(p,"defined(",8)==0) - // defined keyword - { - p+=7; // skip defined - } - else - { - result+="0L"; - p++; - while ((c=*p) && isId(c)) p++; - } - } - else if ((isalpha(c) || c=='_') && !inNum) // replace identifier with 0L - { - result+="0L"; - p++; - while ((c=*p) && isId(c)) p++; - if (*p=='(') // undefined function macro - { - p++; - int count=1; - while ((c=*p++)) - { - if (c=='(') count++; - else if (c==')') - { - count--; - if (count==0) break; - } - else if (c=='/') - { - char pc=c; - c=*++p; - if (c=='*') // start of C comment - { - while (*p && !(pc=='*' && c=='/')) // search end of comment - { - pc=c; - c=*++p; - } - p++; - } - } - } - } - } - else if (c=='/') // skip C comments - { - char pc=c; - c=*++p; - if (c=='*') // start of C comment - { - while (*p && !(pc=='*' && c=='/')) // search end of comment - { - pc=c; - c=*++p; - } - p++; - } - else // oops, not comment but division - { - result+=pc; - goto nextChar; - } - } - else - { -nextChar: - result+=c; - char lc=tolower(c); - if (!isId(lc) && lc!='.' /*&& lc!='-' && lc!='+'*/) inNum=FALSE; - p++; - } - } - } - //printf("removeIdsAndMarkers(%s)=%s\n",s,result.data()); - return result; -} - -/*! replaces all occurrences of @@ in \a s by @ - * \par assumption: - * \a s only contains pairs of @@'s - */ -QCString removeMarkers(const char *s) -{ - const char *p=s; - char c; - QCString result; - if (p) - { - while ((c=*p)) - { - switch(c) - { - case '@': // replace @@ with @ - { - if (*(p+1)=='@') - { - result+=c; - } - p+=2; - } - break; - case '/': // skip C comments - { - result+=c; - char pc=c; - c=*++p; - if (c=='*') // start of C comment - { - while (*p && !(pc=='*' && c=='/')) // search end of comment - { - if (*p=='@' && *(p+1)=='@') - result+=c,p++; - else - result+=c; - pc=c; - c=*++p; - } - if (*p) result+=c,p++; - } - } - break; - case '"': // skip string literals - { - result+=c; - char pc=c; - c=*++p; - while (*p && (c!='"' || pc=='\\')) // no end quote - { - result+=c; - c=*++p; - } - if (*p) result+=c,p++; - } - break; - case '\'': // skip char literals - { - result+=c; - char pc=c; - c=*++p; - while (*p && (c!='\'' || pc=='\\')) // no end quote - { - result+=c; - c=*++p; - } - if (*p) result+=c,p++; - } - break; - default: - { - result+=c; - p++; - } - break; - } - } - } - //printf("RemoveMarkers(%s)=%s\n",s,result.data()); - return result; -} - -/*! compute the value of the expression in string \a expr. - * If needed the function may read additional characters from the input. - */ - -bool computeExpression(const QCString &expr) -{ - QCString e=expr; - expandExpression(e,0,0); - //printf("after expansion `%s'\n",e.data()); - e = removeIdsAndMarkers(e); - if (e.isEmpty()) return FALSE; - //printf("parsing `%s'\n",e.data()); - return parseCppExpression(g_yyFileName,g_yyLineNr,e); -} - -/*! expands the macro definition in \a name - * If needed the function may read additional characters from the input - */ - -QCString expandMacro(const QCString &name) -{ - QCString n=name; - expandExpression(n,0,0); - n=removeMarkers(n); - //printf("expandMacro `%s'->`%s'\n",name.data(),n.data()); - return n; -} - -Define *newDefine() -{ - Define *def=new Define; - def->name = g_defName; - def->definition = g_defText.stripWhiteSpace(); - def->nargs = g_defArgs; - def->fileName = g_yyFileName; - def->fileDef = g_yyFileDef; - def->lineNr = g_yyLineNr; - def->varArgs = g_defVarArgs; - //printf("newDefine: %s %s file: %s\n",def->name.data(),def->definition.data(), - // def->fileDef ? def->fileDef->name().data() : def->fileName.data()); - //printf("newDefine: `%s'->`%s'\n",def->name.data(),def->definition.data()); - if (!def->name.isEmpty() && Doxygen::expandAsDefinedDict[def->name]) - { - def->isPredefined=TRUE; - } - return def; -} - -void addDefine() -{ - if (g_skip) return; // do not add this define as it is inside a - // conditional section (cond command) that is disabled. - if (!Doxygen::gatherDefines) return; - - //printf("addDefine %s %s\n",g_defName.data(),g_defArgsStr.data()); - //ArgumentList *al = new ArgumentList; - //stringToArgumentList(g_defArgsStr,al); - MemberDef *md=new MemberDef( - g_yyFileName,g_yyLineNr, - "#define",g_defName,g_defArgsStr,0, - Public,Normal,FALSE,Member,MemberDef::Define,0,0); - if (!g_defArgsStr.isEmpty()) - { - ArgumentList *argList = new ArgumentList; - //printf("addDefine() g_defName=`%s' g_defArgsStr=`%s'\n",g_defName.data(),g_defArgsStr.data()); - stringToArgumentList(g_defArgsStr,argList); - md->setArgumentList(argList); - } - //printf("Setting initializer for `%s' to `%s'\n",g_defName.data(),g_defText.data()); - int l=g_defLitText.find('\n'); - if (l>0 && g_defLitText.left(l).stripWhiteSpace()=="\\") - { - // strip first line if it only contains a slash - g_defLitText = g_defLitText.right(g_defLitText.length()-l-1); - } - else if (l>0) - { - // align the items on the first line with the items on the second line - int k=l+1; - const char *p=g_defLitText.data()+k; - char c; - while ((c=*p++) && (c==' ' || c=='\t')) k++; - g_defLitText=g_defLitText.mid(l+1,k-l-1)+g_defLitText.stripWhiteSpace(); - } - md->setInitializer(g_defLitText.stripWhiteSpace()); - - //printf("pre.l: md->setFileDef(%p)\n",g_inputFileDef); - md->setFileDef(g_inputFileDef); - md->setDefinition("#define "+g_defName); - - MemberName *mn=Doxygen::functionNameSDict->find(g_defName); - if (mn==0) - { - mn = new MemberName(g_defName); - Doxygen::functionNameSDict->append(g_defName,mn); - } - mn->append(md); - if (g_yyFileDef) - { - g_yyFileDef->insertMember(md); - } - - //Define *d; - //if ((d=defineDict[g_defName])==0) defineDict.insert(g_defName,newDefine()); -} - -static inline void outputChar(char c) -{ - if (g_includeStack.isEmpty() || g_curlyCount>0) g_outputBuf->addChar(c); -} - -static inline void outputArray(const char *a,int len) -{ - if (g_includeStack.isEmpty() || g_curlyCount>0) g_outputBuf->addArray(a,len); -} - -static void readIncludeFile(const QCString &inc) -{ - static bool searchIncludes = Config_getBool("SEARCH_INCLUDES"); - if (!searchIncludes) return; // do not read include files - uint i=0; - - // find the start of the include file name - while (i<inc.length() && - (inc.at(i)==' ' || inc.at(i)=='"' || inc.at(i)=='<') - ) i++; - uint s=i; - - // was it a local include? - bool localInclude = s>0 && inc.at(s-1)=='"'; - - // find the end of the include file name - while (i<inc.length() && inc.at(i)!='"' && inc.at(i)!='>') i++; - - if (s<inc.length() && i>s) // valid include file name found - { - // extract include path+name - QCString incFileName=inc.mid(s,i-s).stripWhiteSpace(); - - QCString dosExt = incFileName.right(4); - if (dosExt==".exe" || dosExt==".dll" || dosExt==".tlb") - { - // skip imported binary files (e.g. M$ type libraries) - return; - } - - QCString oldFileName = g_yyFileName; - FileDef *oldFileDef = g_yyFileDef; - int oldLineNr = g_yyLineNr; - //printf("Searching for `%s'\n",incFileName.data()); - - // absIncFileName avoids difficulties for incFileName starting with "../" (bug 641336) - QCString absIncFileName = incFileName; - { - static bool searchIncludes = Config_getBool("SEARCH_INCLUDES"); - QFileInfo fi(g_yyFileName); - if (fi.exists()) - { - QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+incFileName; - QFileInfo fi2(absName); - if (fi2.exists()) - { - absIncFileName=fi2.absFilePath(); - } - else if (searchIncludes) // search in INCLUDE_PATH as well - { - QStrList &includePath = Config_getList("INCLUDE_PATH"); - char *s=includePath.first(); - while (s) - { - QFileInfo fi(s); - if (fi.exists() && fi.isDir()) - { - QCString absName = QCString(fi.absFilePath())+"/"+incFileName; - //printf("trying absName=%s\n",absName.data()); - QFileInfo fi2(absName); - if (fi2.exists()) - { - absIncFileName=fi2.absFilePath(); - break; - } - //printf( "absIncFileName = %s\n", absIncFileName.data() ); - } - s=includePath.next(); - } - } - //printf( "absIncFileName = %s\n", absIncFileName.data() ); - } - } - DefineManager::instance().addInclude(g_yyFileName,absIncFileName); - DefineManager::instance().addFileToContext(absIncFileName); - - // findFile will overwrite g_yyFileDef if found - FileState *fs; - bool alreadyIncluded = FALSE; - //printf("calling findFile(%s)\n",incFileName.data()); - if ((fs=findFile(incFileName,localInclude,alreadyIncluded))) // see if the include file can be found - { - //printf("Found include file!\n"); - if (Debug::isFlagSet(Debug::Preprocessor)) - { - for (i=0;i<g_includeStack.count();i++) - { - Debug::print(Debug::Preprocessor,0," "); - } - //msg("#include %s: parsing...\n",incFileName.data()); - } - if (oldFileDef) - { - // add include dependency to the file in which the #include was found - bool ambig; - // change to absolute name for bug 641336 - FileDef *incFd = findFileDef(Doxygen::inputNameDict,absIncFileName,ambig); - oldFileDef->addIncludeDependency(ambig ? 0 : incFd,incFileName,localInclude,g_isImported,FALSE); - // add included by dependency - if (g_yyFileDef) - { - //printf("Adding include dependency %s->%s\n",oldFileDef->name().data(),incFileName.data()); - g_yyFileDef->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,g_isImported); - } - } - else if (g_inputFileDef) - { - g_inputFileDef->addIncludeDependency(0,absIncFileName,localInclude,g_isImported,TRUE); - } - fs->bufState = YY_CURRENT_BUFFER; - fs->lineNr = oldLineNr; - fs->fileName = oldFileName; - // push the state on the stack - g_includeStack.push(fs); - // set the scanner to the include file - - // Deal with file changes due to - // #include's within { .. } blocks - QCString lineStr(g_yyFileName.length()+20); - lineStr.sprintf("# 1 \"%s\" 1\n",g_yyFileName.data()); - outputArray(lineStr.data(),lineStr.length()); - - //fprintf(stderr,"Switching to include file %s\n",incFileName.data()); - g_expectGuard=TRUE; - g_inputBuf = &fs->fileBuf; - g_inputBufPos=0; - yy_switch_to_buffer(yy_create_buffer(0, YY_BUF_SIZE)); - } - else - { - //printf(" calling findFile(%s) alreadyInc=%d\n",incFileName.data(),alreadyIncluded); - if (oldFileDef) - { - bool ambig; - //QCString absPath = incFileName; - //if (QDir::isRelativePath(incFileName)) - //{ - // absPath = QDir::cleanDirPath(oldFileDef->getPath()+"/"+incFileName); - // //printf("%s + %s -> resolved path %s\n",oldFileDef->getPath().data(),incFileName.data(),absPath.data()); - //} - - // change to absolute name for bug 641336 - FileDef *fd = findFileDef(Doxygen::inputNameDict,absIncFileName,ambig); - //printf("%s::findFileDef(%s)=%p\n",oldFileDef->name().data(),incFileName.data(),fd); - // add include dependency to the file in which the #include was found - oldFileDef->addIncludeDependency(ambig ? 0 : fd,incFileName,localInclude,g_isImported,FALSE); - // add included by dependency - if (fd) - { - //printf("Adding include dependency (2) %s->%s ambig=%d\n",oldFileDef->name().data(),fd->name().data(),ambig); - fd->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,g_isImported); - } - } - else if (g_inputFileDef) - { - g_inputFileDef->addIncludeDependency(0,absIncFileName,localInclude,g_isImported,TRUE); - } - if (Debug::isFlagSet(Debug::Preprocessor)) - { - if (alreadyIncluded) - { - Debug::print(Debug::Preprocessor,0,"#include %s: already included! skipping...\n",incFileName.data()); - } - else - { - Debug::print(Debug::Preprocessor,0,"#include %s: not found! skipping...\n",incFileName.data()); - } - //printf("error: include file %s not found\n",yytext); - } - if (g_curlyCount>0 && !alreadyIncluded) // failed to find #include inside { ... } - { - warn(g_yyFileName,g_yyLineNr,"Warning: include file %s not found, perhaps you forgot to add its directory to INCLUDE_PATH?",incFileName.data()); - } - } - } -} - -/* ----------------------------------------------------------------- */ - -static void startCondSection(const char *sectId) -{ - g_condStack.push(new bool(g_skip)); - if (Config_getList("ENABLED_SECTIONS").find(sectId)==-1) - { - g_skip=TRUE; - } -} - -static void endCondSection() -{ - if (g_condStack.isEmpty()) - { - g_skip=FALSE; - } - else - { - bool *ctx = g_condStack.pop(); - g_skip=*ctx; - } -} - -static void forceEndCondSection() -{ - while (!g_condStack.isEmpty()) - { - g_condStack.pop(); - } - g_skip=FALSE; -} - -static QCString escapeAt(const char *text) -{ - QCString result; - if (text) - { - char c; - const char *p=text; - while ((c=*p++)) - { - if (c=='@') result+="@@"; else result+=c; - } - } - return result; -} - -static char resolveTrigraph(char c) -{ - switch (c) - { - case '=': return '#'; - case '/': return '\\'; - case '\'': return '^'; - case '(': return '['; - case ')': return ']'; - case '!': return '|'; - case '<': return '{'; - case '>': return '}'; - case '-': return '~'; - } - return '?'; -} - -/* ----------------------------------------------------------------- */ - -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); - -static int yyread(char *buf,int max_size) -{ - int bytesInBuf = g_inputBuf->curPos()-g_inputBufPos; - int bytesToCopy = QMIN(max_size,bytesInBuf); - memcpy(buf,g_inputBuf->data()+g_inputBufPos,bytesToCopy); - g_inputBufPos+=bytesToCopy; - return bytesToCopy; -} - -/* ----------------------------------------------------------------- */ - -%} - -ID [a-z_A-Z][a-z_A-Z0-9]* -B [ \t] -BN [ \t\r\n] -CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) - -%option noyywrap - -%x Start -%x Command -%x SkipCommand -%x SkipLine -%x SkipString -%x CopyLine -%x CopyString -%x Include -%x IncludeID -%x EndImport -%x DefName -%x DefineArg -%x DefineText -%x SkipCPPBlock -%x Ifdef -%x Ifndef -%x SkipCComment -%x CopyCComment -%x SkipVerbatim -%x SkipCPPComment -%x RemoveCComment -%x RemoveCPPComment -%x Guard -%x DefinedExpr1 -%x DefinedExpr2 -%x SkipDoubleQuote -%x SkipSingleQuote -%x UndefName -%x IgnoreLine -%x FindDefineArgs -%x ReadString -%x CondLine - -%% - -<*>\x06 -<*>\x00 -<*>\r -<*>"??"[=/'()!<>-] { // Trigraph - unput(resolveTrigraph(yytext[2])); - } -<Start>^{B}*"#" { BEGIN(Command); } -<Start>^{B}*/[^#] { - outputArray(yytext,yyleng); - BEGIN(CopyLine); - } -<Start>^{B}*[_A-Z][_A-Z0-9]*{B}*"("[^\)\n]*")"/{BN}{1,10}*[:{] { // constructors? - int i; - for (i=yyleng-1;i>=0;i--) - { - unput(yytext[i]); - } - BEGIN(CopyLine); - } -<Start>^{B}*[_A-Z][_A-Z0-9]*{B}*"("[^\(\)\n]*"("[^\)\n]*")"[^\)\n]*")"{B}*\n | // function list macro with one (...) argument, e.g. for K_GLOBAL_STATIC_WITH_ARGS -<Start>^{B}*[_A-Z][_A-Z0-9]*{B}*"("[^\)\n]*")"{B}*\n { // function like macro - static bool skipFuncMacros = Config_getBool("SKIP_FUNCTION_MACROS"); - QCString name(yytext); - name=name.left(name.find('(')).stripWhiteSpace(); - - Define *def=0; - if (skipFuncMacros && - name!="Q_PROPERTY" && - !( - (g_includeStack.isEmpty() || g_curlyCount>0) && - g_macroExpansion && - (def=DefineManager::instance().isDefined(name)) && - /*macroIsAccessible(def) &&*/ - (!g_expandOnlyPredef || def->isPredefined) - ) - ) - { - outputChar('\n'); - g_yyLineNr++; - } - else // don't skip - { - int i; - for (i=yyleng-1;i>=0;i--) - { - unput(yytext[i]); - } - BEGIN(CopyLine); - } - } -<CopyLine>"extern"{BN}{0,80}"\"C\""*{BN}{0,80}"{" { - QCString text=yytext; - g_yyLineNr+=text.contains('\n'); - outputArray(yytext,yyleng); - } -<CopyLine>"{" { // count brackets inside the main file - if (g_includeStack.isEmpty()) - { - g_curlyCount++; - } - outputChar(*yytext); - } -<CopyLine>"}" { // count brackets inside the main file - if (g_includeStack.isEmpty() && g_curlyCount>0) - { - g_curlyCount--; - } - outputChar(*yytext); - } -<CopyLine>"'"\\[0-7]{1,3}"'" { - outputArray(yytext,yyleng); - } -<CopyLine>"'"\\."'" { - outputArray(yytext,yyleng); - } -<CopyLine>"'"."'" { - outputArray(yytext,yyleng); - } -<CopyLine>\" { - outputChar(*yytext); - BEGIN( CopyString ); - } -<CopyString>[^\"\\\r\n]+ { - outputArray(yytext,yyleng); - } -<CopyString>\\. { - outputArray(yytext,yyleng); - } -<CopyString>\" { - outputChar(*yytext); - BEGIN( CopyLine ); - } -<CopyLine>{ID}/{BN}{0,80}"(" { - g_expectGuard = FALSE; - Define *def=0; - //def=g_globalDefineDict->find(yytext); - //def=DefineManager::instance().isDefined(yytext); - //printf("Search for define %s found=%d g_includeStack.isEmpty()=%d " - // "g_curlyCount=%d g_macroExpansion=%d g_expandOnlyPredef=%d " - // "isPreDefined=%d\n",yytext,def ? 1 : 0, - // g_includeStack.isEmpty(),g_curlyCount,g_macroExpansion,g_expandOnlyPredef, - // def ? def->isPredefined : -1 - // ); - if ((g_includeStack.isEmpty() || g_curlyCount>0) && - g_macroExpansion && - (def=DefineManager::instance().isDefined(yytext)) && - /*(def->isPredefined || macroIsAccessible(def)) && */ - (!g_expandOnlyPredef || def->isPredefined) - ) - { - //printf("Found it! #args=%d\n",def->nargs); - g_roundCount=0; - g_defArgsStr=yytext; - if (def->nargs==-1) // no function macro - { - QCString result = def->isPredefined ? def->definition : expandMacro(g_defArgsStr); - outputArray(result,result.length()); - } - else // zero or more arguments - { - g_findDefArgContext = CopyLine; - BEGIN(FindDefineArgs); - } - } - else - { - outputArray(yytext,yyleng); - } - } -<CopyLine>{ID} { - Define *def=0; - if ((g_includeStack.isEmpty() || g_curlyCount>0) && - g_macroExpansion && - (def=DefineManager::instance().isDefined(yytext)) && - def->nargs==-1 && - /*(def->isPredefined || macroIsAccessible(def)) &&*/ - (!g_expandOnlyPredef || def->isPredefined) - ) - { - QCString result=def->isPredefined ? def->definition : expandMacro(yytext); - outputArray(result,result.length()); - } - else - { - outputArray(yytext,yyleng); - } - } -<CopyLine>"\\"\r?/\n { // strip line continuation characters - } -<CopyLine>. { - outputChar(*yytext); - } -<CopyLine>\n { - outputChar('\n'); - BEGIN(Start); - g_yyLineNr++; - } -<FindDefineArgs>"(" { - g_defArgsStr+='('; - g_roundCount++; - } -<FindDefineArgs>")" { - g_defArgsStr+=')'; - g_roundCount--; - if (g_roundCount==0) - { - QCString result=expandMacro(g_defArgsStr); - //printf("g_defArgsStr=`%s'->`%s'\n",g_defArgsStr.data(),result.data()); - if (g_findDefArgContext==CopyLine) - { - outputArray(result,result.length()); - BEGIN(g_findDefArgContext); - } - else // g_findDefArgContext==IncludeID - { - readIncludeFile(result); - g_nospaces=FALSE; - BEGIN(Start); - } - } - } - /* -<FindDefineArgs>")"{B}*"(" { - g_defArgsStr+=yytext; - } - */ -<FindDefineArgs>{CHARLIT} { - g_defArgsStr+=yytext; - } -<FindDefineArgs>\" { - g_defArgsStr+=*yytext; - BEGIN(ReadString); - } -<FindDefineArgs>\n { - g_yyLineNr++; - outputChar('\n'); - } -<FindDefineArgs>"@" { - g_defArgsStr+="@@"; - } -<FindDefineArgs>. { - g_defArgsStr+=*yytext; - } -<ReadString>"\"" { - g_defArgsStr+=*yytext; - BEGIN(FindDefineArgs); - } -<ReadString>"//"|"/*" { - g_defArgsStr+=yytext; - } -<ReadString>\\. { - g_defArgsStr+=yytext; - } -<ReadString>. { - g_defArgsStr+=*yytext; - } -<Command>("include"|"import"){B}+/{ID} { - g_isImported = yytext[1]=='m'; - if (g_macroExpansion) - BEGIN(IncludeID); - } -<Command>("include"|"import"){B}*[<"] { - g_isImported = yytext[1]=='m'; - char c[2]; - c[0]=yytext[yyleng-1];c[1]='\0'; - g_incName=c; - BEGIN(Include); - } -<Command>("cmake")?"define"{B}+ { - //printf("!!!DefName\n"); - BEGIN(DefName); - } -<Command>"ifdef"/{B}*"(" { - incrLevel(); - g_guardExpr.resize(0); - BEGIN(DefinedExpr2); - } -<Command>"ifdef"/{B}+ { - //printf("Pre.l: ifdef\n"); - incrLevel(); - g_guardExpr.resize(0); - BEGIN(DefinedExpr1); - } -<Command>"ifndef"/{B}*"(" { - incrLevel(); - g_guardExpr="! "; - BEGIN(DefinedExpr2); - } -<Command>"ifndef"/{B}+ { - incrLevel(); - g_guardExpr="! "; - BEGIN(DefinedExpr1); - } -<Command>"if"/[ \t(!] { - incrLevel(); - g_guardExpr.resize(0); - BEGIN(Guard); - } -<Command>("elif"|"else"{B}*"if")/[ \t(!] { - if (!otherCaseDone()) - { - g_guardExpr.resize(0); - BEGIN(Guard); - } - else - { - g_ifcount=0; - BEGIN(SkipCPPBlock); - } - } -<Command>"else"/[^a-z_A-Z0-9] { - //printf("else g_levelGuard[%d]=%d\n",g_level-1,g_levelGuard[g_level-1]); - if (otherCaseDone()) - { - g_ifcount=0; - BEGIN(SkipCPPBlock); - } - else - { - setCaseDone(TRUE); - //g_levelGuard[g_level-1]=TRUE; - } - } -<Command>"undef"{B}+ { - BEGIN(UndefName); - } -<Command>("elif"|"else"{B}*"if")/[ \t(!] { - if (!otherCaseDone()) - { - g_guardExpr.resize(0); - BEGIN(Guard); - } - } -<Command>"endif"/[^a-z_A-Z0-9] { - //printf("Pre.l: #endif\n"); - decrLevel(); - } -<Command,IgnoreLine>\n { - outputChar('\n'); - BEGIN(Start); - g_yyLineNr++; - } -<Command>"pragma"{B}+"once" { - g_expectGuard = FALSE; - } -<Command>{ID} { // unknown directive - BEGIN(IgnoreLine); - } -<IgnoreLine>\\[\r]?\n { - outputChar('\n'); - g_yyLineNr++; - } -<IgnoreLine>. -<Command>. -<UndefName>{ID} { - Define *def; - if ((def=DefineManager::instance().isDefined(yytext)) - /*&& !def->isPredefined*/ - && !def->nonRecursive - ) - { - //printf("undefining %s\n",yytext); - def->undef=TRUE; - } - BEGIN(Start); - } -<Guard>\\[\r]?\n { - outputChar('\n'); - g_guardExpr+=' '; - g_yyLineNr++; - } -<Guard>"defined"/{B}*"(" { - BEGIN(DefinedExpr2); - } -<Guard>"defined"/{B}+ { - BEGIN(DefinedExpr1); - } -<Guard>{ID} { g_guardExpr+=yytext; } -<Guard>. { g_guardExpr+=*yytext; } -<Guard>\n { - unput(*yytext); - //printf("Guard: `%s'\n", - // g_guardExpr.data()); - bool guard=computeExpression(g_guardExpr); - setCaseDone(guard); - //printf("if g_levelGuard[%d]=%d\n",g_level-1,g_levelGuard[g_level-1]); - if (guard) - { - BEGIN(Start); - } - else - { - g_ifcount=0; - BEGIN(SkipCPPBlock); - } - } -<DefinedExpr1,DefinedExpr2>\\\n { g_yyLineNr++; outputChar('\n'); } -<DefinedExpr1>{ID} { - if (DefineManager::instance().isDefined(yytext) || g_guardName==yytext) - g_guardExpr+=" 1L "; - else - g_guardExpr+=" 0L "; - g_lastGuardName=yytext; - BEGIN(Guard); - } -<DefinedExpr2>{ID} { - if (DefineManager::instance().isDefined(yytext) || g_guardName==yytext) - g_guardExpr+=" 1L "; - else - g_guardExpr+=" 0L "; - g_lastGuardName=yytext; - } -<DefinedExpr1,DefinedExpr2>\n { // should not happen, handle anyway - g_yyLineNr++; - g_ifcount=0; - BEGIN(SkipCPPBlock); - } -<DefinedExpr2>")" { - BEGIN(Guard); - } -<DefinedExpr1,DefinedExpr2>. -<SkipCPPBlock>^{B}*"#" { BEGIN(SkipCommand); } -<SkipCPPBlock>^{B}*/[^#] { BEGIN(SkipLine); } -<SkipCPPBlock>\n { g_yyLineNr++; outputChar('\n'); } -<SkipCPPBlock>. -<SkipCommand>"if"(("n")?("def"))?/[ \t(!] { - incrLevel(); - g_ifcount++; - //printf("#if... depth=%d\n",g_ifcount); - } -<SkipCommand>"else" { - //printf("Else! g_ifcount=%d otherCaseDone=%d\n",g_ifcount,otherCaseDone()); - if (g_ifcount==0 && !otherCaseDone()) - { - setCaseDone(TRUE); - //outputChar('\n'); - BEGIN(Start); - } - } -<SkipCommand>("elif"|"else"{B}*"if")/[ \t(!] { - if (g_ifcount==0) - { - if (!otherCaseDone()) - { - g_guardExpr.resize(0); - g_lastGuardName.resize(0); - BEGIN(Guard); - } - else - { - BEGIN(SkipCPPBlock); - } - } - } -<SkipCommand>"endif" { - g_expectGuard = FALSE; - decrLevel(); - if (--g_ifcount<0) - { - //outputChar('\n'); - BEGIN(Start); - } - } -<SkipCommand>\n { - outputChar('\n'); - g_yyLineNr++; - BEGIN(SkipCPPBlock); - } -<SkipCommand>{ID} { // unknown directive - BEGIN(SkipLine); - } -<SkipCommand>. -<SkipLine>[^'"/\n]+ -<SkipLine>{CHARLIT} { } -<SkipLine>\" { - BEGIN(SkipString); - } -<SkipLine>. -<SkipString>"//"/[^\n]* { - } -<SkipLine,SkipCommand,SkipCPPBlock>"//"[^\n]* { - g_lastCPPContext=YY_START; - BEGIN(RemoveCPPComment); - } -<SkipString>"/*"/[^\n]* { - } -<SkipLine,SkipCommand,SkipCPPBlock>"/*"/[^\n]* { - g_lastCContext=YY_START; - BEGIN(RemoveCComment); - } -<SkipLine>\n { - outputChar('\n'); - g_yyLineNr++; - BEGIN(SkipCPPBlock); - } -<SkipString>[^"\\\n]+ { } -<SkipString>\\. { } -<SkipString>\" { - BEGIN(SkipLine); - } -<SkipString>. { } -<IncludeID>{ID}{B}*/"(" { - g_nospaces=TRUE; - g_roundCount=0; - g_defArgsStr=yytext; - g_findDefArgContext = IncludeID; - BEGIN(FindDefineArgs); - } -<IncludeID>{ID} { - g_nospaces=TRUE; - readIncludeFile(expandMacro(yytext)); - BEGIN(Start); - } -<Include>[^\">\n]+[\">] { - g_incName+=yytext; - readIncludeFile(g_incName); - if (g_isImported) - { - BEGIN(EndImport); - } - else - { - BEGIN(Start); - } - } -<EndImport>[^\\\n]*/\n { - BEGIN(Start); - } -<EndImport>\\[\r]?"\n" { - outputChar('\n'); - g_yyLineNr++; - } -<EndImport>. { - } -<DefName>{ID}/("\\\n")*"(" { // define with argument - //printf("Define() `%s'\n",yytext); - g_argDict = new QDict<int>(31); - g_argDict->setAutoDelete(TRUE); - g_defArgs = 0; - g_defArgsStr.resize(0); - g_defText.resize(0); - g_defLitText.resize(0); - g_defName = yytext; - g_defVarArgs = FALSE; - g_defExtraSpacing.resize(0); - BEGIN(DefineArg); - } -<DefName>{ID}{B}+"1"/[ \r\t\n] { // special case: define with 1 -> can be "guard" - //printf("Define `%s'\n",yytext); - g_argDict = 0; - g_defArgs = -1; - g_defArgsStr.resize(0); - g_defName = yytext; - g_defName = g_defName.left(g_defName.length()-1).stripWhiteSpace(); - g_defVarArgs = FALSE; - //printf("Guard check: %s!=%s || %d\n", - // g_defName.data(),g_lastGuardName.data(),g_expectGuard); - if ( g_defName!=g_lastGuardName || !g_expectGuard) - { // define may appear in the output - QCString tmp=(QCString)"#define "+g_defName; - outputArray(tmp.data(),tmp.length()); - g_quoteArg=FALSE; - g_insideComment=FALSE; - g_lastGuardName.resize(0); - g_defText="1"; - g_defLitText="1"; - BEGIN(DefineText); - } - else // define is a guard => hide - { - //printf("Found a guard %s\n",yytext); - g_defText.resize(0); - g_defLitText.resize(0); - BEGIN(Start); - } - g_expectGuard=FALSE; - } -<DefName>{ID}/{B}*"\n" { // empty define - g_argDict = 0; - g_defArgs = -1; - g_defName = yytext; - g_defArgsStr.resize(0); - g_defText.resize(0); - g_defLitText.resize(0); - g_defVarArgs = FALSE; - //printf("Guard check: %s!=%s || %d\n", - // g_defName.data(),g_lastGuardName.data(),g_expectGuard); - if ( g_defName!=g_lastGuardName || !g_expectGuard) - { // define may appear in the output - QCString tmp=(QCString)"#define "+g_defName; - outputArray(tmp.data(),tmp.length()); - g_quoteArg=FALSE; - g_insideComment=FALSE; - if (g_insideCS) g_defText="1"; // for C#, use "1" as define text - BEGIN(DefineText); - } - else // define is a guard => hide - { - //printf("Found a guard %s\n",yytext); - g_guardName = yytext; - g_lastGuardName.resize(0); - BEGIN(Start); - } - g_expectGuard=FALSE; - } -<DefName>{ID}/{B}* { // define with content - //printf("Define `%s'\n",yytext); - g_argDict = 0; - g_defArgs = -1; - g_defArgsStr.resize(0); - g_defText.resize(0); - g_defLitText.resize(0); - g_defName = yytext; - g_defVarArgs = FALSE; - QCString tmp=(QCString)"#define "+g_defName+g_defArgsStr; - outputArray(tmp.data(),tmp.length()); - g_quoteArg=FALSE; - g_insideComment=FALSE; - BEGIN(DefineText); - } -<DefineArg>"\\\n" { - g_defExtraSpacing+="\n"; - g_yyLineNr++; - } -<DefineArg>","{B}* { g_defArgsStr+=yytext; } -<DefineArg>"("{B}* { g_defArgsStr+=yytext; } -<DefineArg>{B}*")"{B}* { - g_defArgsStr+=yytext; - QCString tmp=(QCString)"#define "+g_defName+g_defArgsStr+g_defExtraSpacing; - outputArray(tmp.data(),tmp.length()); - g_quoteArg=FALSE; - g_insideComment=FALSE; - BEGIN(DefineText); - } -<DefineArg>"..." { // Variadic macro - g_defVarArgs = TRUE; - g_defArgsStr+=yytext; - g_argDict->insert("__VA_ARGS__",new int(g_defArgs)); - g_defArgs++; - } -<DefineArg>{ID}{B}*("..."?) { - //printf("Define addArg(%s)\n",yytext); - QCString argName=yytext; - g_defVarArgs = yytext[yyleng-1]=='.'; - if (g_defVarArgs) // strip ellipsis - { - argName=argName.left(argName.length()-3); - } - argName = argName.stripWhiteSpace(); - g_defArgsStr+=yytext; - g_argDict->insert(argName,new int(g_defArgs)); - g_defArgs++; - } - /* -<DefineText>"/ **"|"/ *!" { - g_defText+=yytext; - g_defLitText+=yytext; - g_insideComment=TRUE; - } -<DefineText>"* /" { - g_defText+=yytext; - g_defLitText+=yytext; - g_insideComment=FALSE; - } - */ -<DefineText>"/*"[!*]? { - g_defText+=yytext; - g_defLitText+=yytext; - g_lastCContext=YY_START; - g_commentCount=1; - BEGIN(CopyCComment); - } -<DefineText>"//"[!/]? { - outputArray(yytext,yyleng); - g_lastCPPContext=YY_START; - g_defLitText+=' '; - BEGIN(SkipCPPComment); - } -<SkipCComment>[/]?"*/" { - if (yytext[0]=='/') outputChar('/'); - outputChar('*');outputChar('/'); - if (--g_commentCount<=0) - { - if (g_lastCContext==Start) - // small hack to make sure that ^... rule will - // match when going to Start... Example: "/*...*/ some stuff..." - { - YY_CURRENT_BUFFER->yy_at_bol=1; - } - BEGIN(g_lastCContext); - } - } -<SkipCComment>"//"("/")* { - outputArray(yytext,yyleng); - } -<SkipCComment>"/*" { - outputChar('/');outputChar('*'); - //g_commentCount++; - } -<SkipCComment>[\\@][\\@]("f{"|"f$"|"f[") { - outputArray(yytext,yyleng); - } -<SkipCComment>[\\@][\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly"|"dot"|"code"){BN}+ { - outputArray(yytext,yyleng); - g_yyLineNr+=QCString(yytext).contains('\n'); - } -<SkipCComment>[\\@]("verbatim"|"latexonly"|"htmlonly"|"xmlonly"|"rtfonly"|"manonly"|"dot"|"code"){BN}+ { - outputArray(yytext,yyleng); - g_yyLineNr+=QCString(yytext).contains('\n'); - if (yytext[1]=='f') - { - g_blockName="f"; - } - else - { - g_blockName=QCString(&yytext[1]).stripWhiteSpace(); - } - BEGIN(SkipVerbatim); - } -<SkipCComment,SkipCPPComment>[\\@]"cond"[ \t]+ { // conditional section - g_condCtx = YY_START; - outputArray(yytext,yyleng); - BEGIN(CondLine); - } -<CondLine>[a-z_A-Z][a-z_A-Z0-9.\-]* { - startCondSection(yytext); - outputArray(yytext,yyleng); - BEGIN(g_condCtx); - } -<SkipCComment,SkipCPPComment>[\\@]"cond"[ \t\r]*/\n { - g_condCtx = YY_START; - outputArray(yytext,yyleng); - } -<CondLine>. { - unput(*yytext); - startCondSection(" "); - BEGIN(g_condCtx); - } -<SkipCComment,SkipCPPComment>[\\@]"endcond"/[^a-z_A-Z0-9] { - outputArray(yytext,yyleng); - endCondSection(); - } -<SkipVerbatim>[\\@]("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode"|"f$"|"f]"|"f}") { /* end of verbatim block */ - outputArray(yytext,yyleng); - if (yytext[1]=='f' && g_blockName=="f") - { - BEGIN(SkipCComment); - } - else if (&yytext[4]==g_blockName) - { - BEGIN(SkipCComment); - } - } -<SkipVerbatim>"*/"|"/*" { - outputArray(yytext,yyleng); - } -<SkipCComment,SkipVerbatim>[^*\\@\x06\n\/]+ { - outputArray(yytext,yyleng); - } -<SkipCComment,SkipVerbatim>\n { - g_yyLineNr++; - outputChar('\n'); - } -<SkipCComment,SkipVerbatim>. { - outputChar(*yytext); - } -<CopyCComment>[^*a-z_A-Z\n]+ { - g_defLitText+=yytext; - g_defText+=escapeAt(yytext); - } -<CopyCComment>"*/" { - g_defLitText+=yytext; - g_defText+=yytext; - BEGIN(g_lastCContext); - } -<CopyCComment>\n { - g_yyLineNr++; - g_defLitText+=yytext; - g_defText+=' '; - } -<RemoveCComment>"*/"{B}*"#" { // see bug 594021 for a usecase for this rule - if (g_lastCContext==SkipCPPBlock) - { - BEGIN(SkipCommand); - } - else - { - REJECT; - } - } -<RemoveCComment>"*/" { BEGIN(g_lastCContext); } -<RemoveCComment>"//" -<RemoveCComment>"/*" -<RemoveCComment>[^*\x06\n]+ -<RemoveCComment>\n { g_yyLineNr++; outputChar('\n'); } -<RemoveCComment>. -<SkipCPPComment>[^\n\/\\@]+ { - outputArray(yytext,yyleng); - } -<SkipCPPComment,RemoveCPPComment>\n { - unput(*yytext); - BEGIN(g_lastCPPContext); - } -<SkipCPPComment>"/*" { - outputChar('/');outputChar('*'); - } -<SkipCPPComment>"//" { - outputChar('/');outputChar('/'); - } -<SkipCPPComment>[^\x06\@\\\n]+ { - outputArray(yytext,yyleng); - } -<SkipCPPComment>. { - outputChar(*yytext); - } -<RemoveCPPComment>"/*" -<RemoveCPPComment>"//" -<RemoveCPPComment>[^\x06\n]+ -<RemoveCPPComment>. -<DefineText>"#" { - g_quoteArg=TRUE; - g_defLitText+=yytext; - } -<DefineText,CopyCComment>{ID} { - g_defLitText+=yytext; - if (g_quoteArg) - { - g_defText+="\""; - } - if (g_defArgs>0) - { - int *n; - if ((n=(*g_argDict)[yytext])) - { - //if (!g_quoteArg) g_defText+=' '; - g_defText+='@'; - QCString numStr; - numStr.sprintf("%d",*n); - g_defText+=numStr; - //if (!g_quoteArg) g_defText+=' '; - } - else - { - g_defText+=yytext; - } - } - else - { - g_defText+=yytext; - } - if (g_quoteArg) - { - g_defText+="\""; - } - g_quoteArg=FALSE; - } -<CopyCComment>. { - g_defLitText+=yytext; - g_defText+=yytext; - } -<DefineText>\\[\r]?\n { - g_defLitText+=yytext; - outputChar('\n'); - g_defText += ' '; g_yyLineNr++; - } -<DefineText>\n { - QCString comment=extractTrailingComment(g_defLitText); - g_defLitText+=yytext; - if (!comment.isEmpty()) - { - outputArray(comment,comment.length()); - g_defLitText=g_defLitText.left(g_defLitText.length()-comment.length()-1); - } - outputChar('\n'); - Define *def=0; - //printf("Define name=`%s' text=`%s' litTexti=`%s'\n",g_defName.data(),g_defText.data(),g_defLitText.data()); - if (g_includeStack.isEmpty() || g_curlyCount>0) - { - addDefine(); - } - def=DefineManager::instance().isDefined(g_defName); - if (def==0) // new define - { - //printf("new define '%s'!\n",g_defName.data()); - Define *nd = newDefine(); - DefineManager::instance().addDefine(g_yyFileName,nd); - - // also add it to the local file list if it is a source file - //if (g_isSource && g_includeStack.isEmpty()) - //{ - // g_fileDefineDict->insert(g_defName,nd); - //} - } - else if (def /*&& macroIsAccessible(def)*/) - // name already exists - { - //printf("existing define!\n"); - //printf("define found\n"); - if (def->undef) // undefined name - { - def->undef = FALSE; - def->name = g_defName; - def->definition = g_defText.stripWhiteSpace(); - def->nargs = g_defArgs; - def->fileName = g_yyFileName.copy(); - def->lineNr = g_yyLineNr; - } - else - { - //printf("error: define %s is defined more than once!\n",g_defName.data()); - } - } - delete g_argDict; g_argDict=0; - g_yyLineNr++; - g_lastGuardName.resize(0); - BEGIN(Start); - } -<DefineText>{B}* { g_defText += ' '; g_defLitText+=yytext; } -<DefineText>{B}*"##"{B}* { g_defText += "##"; g_defLitText+=yytext; } -<DefineText>"@" { g_defText += "@@"; g_defLitText+=yytext; } -<DefineText>\" { - g_defText += *yytext; - g_defLitText+=yytext; - if (!g_insideComment) - { - BEGIN(SkipDoubleQuote); - } - } -<DefineText>\' { g_defText += *yytext; - g_defLitText+=yytext; - if (!g_insideComment) - { - BEGIN(SkipSingleQuote); - } - } -<SkipDoubleQuote>"//"[/]? { g_defText += yytext; g_defLitText+=yytext; } -<SkipDoubleQuote>"/*" { g_defText += yytext; g_defLitText+=yytext; } -<SkipDoubleQuote>\" { - g_defText += *yytext; g_defLitText+=yytext; - BEGIN(DefineText); - } -<SkipSingleQuote,SkipDoubleQuote>\\. { - g_defText += yytext; g_defLitText+=yytext; - } -<SkipSingleQuote>\' { - g_defText += *yytext; g_defLitText+=yytext; - BEGIN(DefineText); - } -<SkipDoubleQuote>. { g_defText += *yytext; g_defLitText+=yytext; } -<SkipSingleQuote>. { g_defText += *yytext; g_defLitText+=yytext; } -<DefineText>. { g_defText += *yytext; g_defLitText+=yytext; } -<<EOF>> { - //fprintf(stderr,"End of include file\n"); - //printf("Include stack depth=%d\n",g_includeStack.count()); - if (g_includeStack.isEmpty()) - { - //fprintf(stderr,"Terminating scanner!\n"); - yyterminate(); - } - else - { - FileState *fs=g_includeStack.pop(); - //fileDefineCache->merge(g_yyFileName,fs->fileName); - YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER; - yy_switch_to_buffer( fs->bufState ); - yy_delete_buffer( oldBuf ); - g_yyLineNr = fs->lineNr; - //preYYin = fs->oldYYin; - g_inputBuf = fs->oldFileBuf; - g_inputBufPos = fs->oldFileBufPos; - setFileName(fs->fileName); - //fprintf(stderr,"######## FileName %s\n",g_yyFileName.data()); - - // Deal with file changes due to - // #include's within { .. } blocks - QCString lineStr(15+g_yyFileName.length()); - lineStr.sprintf("# %d \"%s\" 2",g_yyLineNr,g_yyFileName.data()); - outputArray(lineStr.data(),lineStr.length()); - - delete fs; fs=0; - } - } -<*>"/*"/"*/" | -<*>"/*"[*]? { - outputArray(yytext,yyleng); - g_lastCContext=YY_START; - g_commentCount=1; - if (yyleng==3) g_lastGuardName.resize(0); // reset guard in case the #define is documented! - BEGIN(SkipCComment); - } -<*>"//"[/]? { - outputArray(yytext,yyleng); - g_lastCPPContext=YY_START; - if (yyleng==3) g_lastGuardName.resize(0); // reset guard in case the #define is documented! - BEGIN(SkipCPPComment); - } -<*>\n { - outputChar('\n'); - g_yyLineNr++; - } -<*>. { - g_expectGuard = FALSE; - outputChar(*yytext); - } - -%% - -/*@ ---------------------------------------------------------------------------- - */ - -static int getNextChar(const QCString &expr,QCString *rest,uint &pos) -{ - //printf("getNextChar(%s,%s,%d)\n",expr.data(),rest ? rest->data() : 0,pos); - if (pos<expr.length()) - { - //printf("%c=expr()\n",expr.at(pos)); - return expr.at(pos++); - } - else if (rest && !rest->isEmpty()) - { - int cc=rest->at(0); - *rest=rest->right(rest->length()-1); - //printf("%c=rest\n",cc); - return cc; - } - else - { - int cc=yyinput(); - //printf("%c=yyinput()\n",cc); - return cc; - } -} - -static int getCurrentChar(const QCString &expr,QCString *rest,uint pos) -{ - //printf("getCurrentChar(%s,%s,%d)\n",expr.data(),rest ? rest->data() : 0,pos); - if (pos<expr.length()) - { - //printf("%c=expr()\n",expr.at(pos)); - return expr.at(pos); - } - else if (rest && !rest->isEmpty()) - { - int cc=rest->at(0); - //printf("%c=rest\n",cc); - return cc; - } - else - { - int cc=yyinput(); - returnCharToStream(cc); - //unput((char)cc); - //printf("%c=yyinput()\n",cc); - return cc; - } -} - -static void unputChar(const QCString &expr,QCString *rest,uint &pos,char c) -{ - //printf("unputChar(%s,%s,%d,%c)\n",expr.data(),rest ? rest->data() : 0,pos,c); - if (pos<expr.length()) - { - pos++; - } - else if (rest) - { - //printf("Prepending to rest!\n"); - char cs[2];cs[0]=c;cs[1]='\0'; - rest->prepend(cs); - } - else - { - //unput(c); - returnCharToStream(c); - } - //printf("result: unputChar(%s,%s,%d,%c)\n",expr.data(),rest ? rest->data() : 0,pos,c); -} - -void addSearchDir(const char *dir) -{ - QFileInfo fi(dir); - if (fi.isDir()) g_pathList->append(fi.absFilePath()); -} - -void initPreprocessor() -{ - g_pathList = new QStrList; - addSearchDir("."); - g_expandedDict = new DefineDict(17); -} - -void cleanUpPreprocessor() -{ - delete g_expandedDict; g_expandedDict=0; - delete g_pathList; g_pathList=0; - DefineManager::deleteInstance(); -} - - -void preprocessFile(const char *fileName,BufStr &input,BufStr &output) -{ - uint orgOffset=output.curPos(); - //printf("##########################\n%s\n####################\n", - // input.data()); - - g_macroExpansion = Config_getBool("MACRO_EXPANSION"); - g_expandOnlyPredef = Config_getBool("EXPAND_ONLY_PREDEF"); - g_curlyCount=0; - g_nospaces=FALSE; - g_inputBuf=&input; - g_inputBufPos=0; - g_outputBuf=&output; - g_includeStack.setAutoDelete(TRUE); - g_includeStack.clear(); - g_expandedDict->setAutoDelete(FALSE); - g_expandedDict->clear(); - g_condStack.clear(); - g_condStack.setAutoDelete(TRUE); - //g_fileDefineDict->clear(); - - setFileName(fileName); - g_inputFileDef = g_yyFileDef; - DefineManager::instance().startContext(g_yyFileName); - - static bool firstTime=TRUE; - if (firstTime) - { - // add predefined macros - char *defStr; - QStrList &predefList = Config_getList("PREDEFINED"); - QStrListIterator sli(predefList); - for (sli.toFirst();(defStr=sli.current());++sli) - { - QCString ds = defStr; - int i_equals=ds.find('='); - int i_obrace=ds.find('('); - int i_cbrace=ds.find(')'); - bool nonRecursive = i_equals>0 && ds.at(i_equals-1)==':'; - - if (i_obrace==0) continue; // no define name - - if (i_obrace<i_equals && i_cbrace<i_equals && - i_obrace!=-1 && i_cbrace!=-1 && - i_obrace<i_cbrace - ) // predefined function macro definition - { - //printf("predefined function macro '%s'\n",defStr); - QRegExp reId("[a-z_A-Z][a-z_A-Z0-9]*"); // regexp matching an id - QDict<int> argDict(17); - argDict.setAutoDelete(TRUE); - int i=i_obrace+1,p,l,count=0; - // gather the formal arguments in a dictionary - while (i<i_cbrace && (p=reId.match(ds,i,&l))) - { - argDict.insert(ds.mid(p,l),new int(count++)); - i=p+l; - } - // strip definition part - QCString tmp=ds.right(ds.length()-i_equals-1); - QCString definition; - i=0; - // substitute all occurrences of formal arguments by their - // corresponding markers - while ((p=reId.match(tmp,i,&l))!=-1) - { - if (p>i) definition+=tmp.mid(i,p-i); - int *argIndex; - if ((argIndex=argDict[tmp.mid(p,l)])!=0) - { - QCString marker; - marker.sprintf(" @%d ",*argIndex); - definition+=marker; - } - else - { - definition+=tmp.mid(p,l); - } - i=p+l; - } - if (i<(int)tmp.length()) definition+=tmp.mid(i,tmp.length()-i); - - // add define definition to the dictionary of defines for this file - QCString dname = ds.left(i_obrace); - if (!dname.isEmpty()) - { - Define *def = new Define; - def->name = dname; - def->definition = definition; - def->nargs = count; - def->isPredefined = TRUE; - def->nonRecursive = nonRecursive; - def->fileDef = g_yyFileDef; - def->fileName = fileName; - DefineManager::instance().addDefine(g_yyFileName,def); - } - - //printf("#define `%s' `%s' #nargs=%d\n", - // def->name.data(),def->definition.data(),def->nargs); - } - else if ((i_obrace==-1 || i_obrace>i_equals) && - (i_cbrace==-1 || i_cbrace>i_equals) && - !ds.isEmpty() && (int)ds.length()>i_equals - ) // predefined non-function macro definition - { - //printf("predefined normal macro '%s'\n",defStr); - Define *def = new Define; - if (i_equals==-1) // simple define without argument - { - def->name = ds; - def->definition = "1"; // substitute occurrences by 1 (true) - } - else // simple define with argument - { - int ine=i_equals - (nonRecursive ? 1 : 0); - def->name = ds.left(ine); - def->definition = ds.right(ds.length()-i_equals-1); - } - if (!def->name.isEmpty()) - { - def->nargs = -1; - def->isPredefined = TRUE; - def->nonRecursive = nonRecursive; - def->fileDef = g_yyFileDef; - def->fileName = fileName; - DefineManager::instance().addDefine(g_yyFileName,def); - } - else - { - delete def; - } - - //printf("#define `%s' `%s' #nargs=%d\n", - // def->name.data(),def->definition.data(),def->nargs); - } - } - //firstTime=FALSE; - } - - g_yyLineNr = 1; - g_level = 0; - g_ifcount = 0; - - BEGIN( Start ); - - g_expectGuard = guessSection(fileName)==Entry::HEADER_SEC; - g_guardName.resize(0); - g_lastGuardName.resize(0); - g_guardExpr.resize(0); - - preYYlex(); - g_lexInit=TRUE; - - // make sure we don't extend a \cond with missing \endcond over multiple files (see bug 624829) - forceEndCondSection(); - - // remove locally defined macros so they can be redefined in another source file - //if (g_fileDefineDict->count()>0) - //{ - // QDictIterator<Define> di(*g_fileDefineDict); - // Define *d; - // for (di.toFirst();(d=di.current());++di) - // { - // g_globalDefineDict->remove(di.currentKey()); - // } - // g_fileDefineDict->clear(); - //} - - if (Debug::isFlagSet(Debug::Preprocessor)) - { - char *orgPos=output.data()+orgOffset; - char *newPos=output.data()+output.curPos(); - Debug::print(Debug::Preprocessor,0,"Preprocessor output (size: %d bytes):\n",newPos-orgPos); - int line=1; - Debug::print(Debug::Preprocessor,0,"---------\n00001 "); - while (orgPos<newPos) - { - putchar(*orgPos); - if (*orgPos=='\n') Debug::print(Debug::Preprocessor,0,"%05d ",++line); - orgPos++; - } - Debug::print(Debug::Preprocessor,0,"\n---------\n"); - if (DefineManager::instance().defineContext().count()>0) - { - Debug::print(Debug::Preprocessor,0,"Macros accessible in this file:\n"); - Debug::print(Debug::Preprocessor,0,"---------\n"); - QDictIterator<Define> di(DefineManager::instance().defineContext()); - Define *def; - for (di.toFirst();(def=di.current());++di) - { - Debug::print(Debug::Preprocessor,0,"%s ",def->name.data()); - } - Debug::print(Debug::Preprocessor,0,"\n---------\n"); - } - else - { - Debug::print(Debug::Preprocessor,0,"No macros accessible in this file.\n"); - } - } - DefineManager::instance().endContext(); -} - -void preFreeScanner() -{ -#if defined(YY_FLEX_SUBMINOR_VERSION) - if (g_lexInit) - { - preYYlex_destroy(); - } -#endif -} - -#if !defined(YY_FLEX_SUBMINOR_VERSION) -extern "C" { // some bogus code to keep the compiler happy -// int preYYwrap() { return 1 ; } - void preYYdummy() { yy_flex_realloc(0,0); } -} -#endif - |