Orb/Doxygen/src/pre.l
changeset 4 468f4c8d3d5b
parent 3 d8fccb2cd802
equal deleted inserted replaced
3:d8fccb2cd802 4:468f4c8d3d5b
     1 /******************************************************************************
     1 /******************************************************************************
     2  *
     2  *
     3  * 
     3  * 
     4  *
     4  *
     5  * Copyright (C) 1997-2008 by Dimitri van Heesch.
     5  * Copyright (C) 1997-2010 by Dimitri van Heesch.
     6  *
     6  *
     7  * Permission to use, copy, modify, and distribute this software and its
     7  * Permission to use, copy, modify, and distribute this software and its
     8  * documentation under the terms of the GNU General Public License is hereby 
     8  * documentation under the terms of the GNU General Public License is hereby 
     9  * granted. No representations are made about the suitability of this software 
     9  * granted. No representations are made about the suitability of this software 
    10  * for any purpose. It is provided "as is" without express or implied warranty.
    10  * for any purpose. It is provided "as is" without express or implied warranty.
    48 #include "bufstr.h"
    48 #include "bufstr.h"
    49 #include "portable.h"
    49 #include "portable.h"
    50 #include "bufstr.h"
    50 #include "bufstr.h"
    51 
    51 
    52 #define YY_NEVER_INTERACTIVE 1
    52 #define YY_NEVER_INTERACTIVE 1
       
    53   
    53 
    54 
    54 struct FileState
    55 struct FileState
    55 {
    56 {
    56   FileState(int size) : fileBuf(size), oldFileBuf(0), oldFileBufPos(0) {}
    57   FileState(int size) : fileBuf(size), 
       
    58                         oldFileBuf(0), oldFileBufPos(0) {}
    57   int lineNr;
    59   int lineNr;
    58   //FILE *filePtr;
    60   //FILE *filePtr;
    59   BufStr fileBuf;
    61   BufStr fileBuf;
    60   //FILE *oldYYin;
    62   //FILE *oldYYin;
    61   BufStr *oldFileBuf;
    63   BufStr *oldFileBuf;
    94 static int                g_roundCount;
    96 static int                g_roundCount;
    95 static bool               g_quoteArg;
    97 static bool               g_quoteArg;
    96 static DefineDict        *g_fileDefineDict = new DefineDict(10009);
    98 static DefineDict        *g_fileDefineDict = new DefineDict(10009);
    97 static DefineDict        *g_expandedDict;
    99 static DefineDict        *g_expandedDict;
    98 static int                g_findDefArgContext;
   100 static int                g_findDefArgContext;
       
   101 static bool               g_expectGuard;
    99 static QCString           g_lastGuardName;
   102 static QCString           g_lastGuardName;
   100 static QCString           g_incName;
   103 static QCString           g_incName;
   101 static QCString           g_guardExpr;
   104 static QCString           g_guardExpr;
   102 static int                g_curlyCount;
   105 static int                g_curlyCount;
   103 static bool               g_nospaces; // add extra spaces during macro expansion
   106 static bool               g_nospaces; // add extra spaces during macro expansion
   124 {
   127 {
   125   bool ambig;
   128   bool ambig;
   126   QFileInfo fi(name);
   129   QFileInfo fi(name);
   127   g_yyFileName=convertToQCString(fi.absFilePath());
   130   g_yyFileName=convertToQCString(fi.absFilePath());
   128   g_yyFileDef=findFileDef(Doxygen::inputNameDict,g_yyFileName,ambig);
   131   g_yyFileDef=findFileDef(Doxygen::inputNameDict,g_yyFileName,ambig);
       
   132   //printf("setFileName(%s) g_yyFileName=%s g_yyFileDef=%p\n",
       
   133   //    name,g_yyFileName.data(),g_yyFileDef);
   129   if (g_yyFileDef == 0 && Config_getBool("PREPROCESS_INCLUDES")) {
   134   if (g_yyFileDef == 0 && Config_getBool("PREPROCESS_INCLUDES")) {
   130 		// Search again using Doxygen::includeNameDict
   135 		// Search again using Doxygen::includeNameDict
   131 	    // First insert the include file in the Doxygen::includeNameDict if
   136 	    // First insert the include file in the Doxygen::includeNameDict if
   132 	    // it is not there already. This can happen if the Doxygen::includeNameDict
   137 	    // it is not there already. This can happen if the Doxygen::includeNameDict
   133 	    // has scanned .../inc but the #include "usr/usr.h"
   138 	    // has scanned .../inc but the #include "usr/usr.h"
   204 static void setCaseDone(bool value)
   209 static void setCaseDone(bool value)
   205 {
   210 {
   206   g_levelGuard[g_level-1]=value;
   211   g_levelGuard[g_level-1]=value;
   207 }
   212 }
   208 
   213 
       
   214 static bool macroIsAccessible(Define *def)
       
   215 {
       
   216   //printf("macroIsAccessible(%s) input=%s def=%s\n",
       
   217   //    def->name.data(),g_inputFileDef?g_inputFileDef->name().data():"<none>",
       
   218   //    def->fileDef ? def->fileDef->name().data() : "<none>");
       
   219   if (def && def->isPredefined) // predefined macro -> globally accessible
       
   220   {
       
   221     //printf("%s: predefined macro %s\n",g_inputFileDef->name().data(),def->name.data());
       
   222     return TRUE;
       
   223   }
       
   224   if (def && def->fileDef==g_inputFileDef)
       
   225   {
       
   226     //printf("%s: macro %s defined in this file at line %d now at %d\n",
       
   227     //	g_inputFileDef->name().data(),def->name.data(),def->lineNr,g_yyLineNr);
       
   228     return def->lineNr<=g_yyLineNr;
       
   229   }
       
   230   if (g_inputFileDef && def && def->fileDef) // check if g_inputFileDef actually includes def->fileDef
       
   231   {
       
   232     QDict<FileDef> includedFiles(257);
       
   233     bool b = g_inputFileDef->includes(def->fileDef,&includedFiles);
       
   234     //printf("%s: Checking for accessibility of define '%s' (defined in %s): result=%d\n",
       
   235     //       g_inputFileDef->name().data(),def->name.data(),def->fileDef->name().data(),b);
       
   236     return b;
       
   237   }
       
   238   //printf("not accessible!\n");
       
   239   return FALSE;
       
   240 }
       
   241 
   209 static Define *isDefined(const char *name)
   242 static Define *isDefined(const char *name)
   210 {
   243 {
       
   244   Define *def=0;
   211   if (name)
   245   if (name)
   212   {
   246   {
   213     Define *def;
   247     def=g_fileDefineDict->find(name);
   214     //if ((def=fileDefineCache->findDefine(g_yyFileName,name)) && !def->undef) 
   248     //if ((def=fileDefineCache->findDefine(g_yyFileName,name)) && !def->undef) 
   215     //	return def;
   249     //	return def;
   216     if ((def=g_fileDefineDict->find(name)) && !def->undef) return def; 
   250     if (def && def->undef) def=0;
   217   }
   251     if (def && !macroIsAccessible(def)) def=0;
   218   return 0;
   252   }
   219 }
   253   return def;
       
   254 }
       
   255 
   220 
   256 
   221 static QDict<void> g_allIncludes(10009);
   257 static QDict<void> g_allIncludes(10009);
   222 
   258 
   223 static FileState *checkAndOpenFile(const QCString &fileName,bool &alreadyIncluded)
   259 static FileState *checkAndOpenFile(const QCString &fileName,bool &alreadyIncluded)
   224 {
   260 {
   225   alreadyIncluded = FALSE;
   261   alreadyIncluded = FALSE;
   226   FileState *fs = 0;
   262   FileState *fs = 0;
   227   //msg("checkAndOpenFile(%s)\n", fileName.data());
   263   //printf("checkAndOpenFile(%s)\n",fileName.data());
   228   QFileInfo fi(fileName);
   264   QFileInfo fi(fileName);
   229   if (fi.exists() && fi.isFile())
   265   if (fi.exists() && fi.isFile())
   230   {
   266   {
       
   267     static QStrList &exclPatterns = Config_getList("EXCLUDE_PATTERNS");
       
   268     if (patternMatch(fi,&exclPatterns)) return 0;
       
   269 
   231     QCString absName = convertToQCString(fi.absFilePath());
   270     QCString absName = convertToQCString(fi.absFilePath());
   232 	//msg("checkAndOpenFile() found: %s\n", absName.data());
   271 	//msg("checkAndOpenFile() found: %s\n", absName.data());
   233     // global guard
   272     // global guard
   234     if (g_curlyCount==0) // not #include inside { ... }
   273     if (g_curlyCount==0) // not #include inside { ... }
   235     {
   274     {
   278     else
   317     else
   279     {
   318     {
   280       fs->oldFileBuf    = g_inputBuf;
   319       fs->oldFileBuf    = g_inputBuf;
   281       fs->oldFileBufPos = g_inputBufPos;
   320       fs->oldFileBufPos = g_inputBufPos;
   282     }
   321     }
   283 
       
   284 #if 0
       
   285     QCString filterName = getFileFilter(absName);
       
   286     if (!filterName.isEmpty())
       
   287     {
       
   288       fs->isPlainFile = FALSE;
       
   289       QCString cmd = filterName+" \""+absName+"\"";
       
   290       fs->filePtr=portable_popen(cmd,"r");
       
   291       if (!fs->filePtr)
       
   292       {
       
   293         err("Error: could not execute filter %s, reason: %s\n",cmd.data(),
       
   294             strerror(errno));
       
   295       }
       
   296     }
       
   297     else
       
   298     {
       
   299       fs->isPlainFile = TRUE;
       
   300       fs->filePtr=fopen(absName,"r");
       
   301       if (!fs->filePtr)
       
   302       {
       
   303         err("Error: could not open file %s for reading, reason: %s \n",
       
   304             absName.data(),strerror(errno));
       
   305       }
       
   306     }
       
   307     if (!fs->filePtr) // error -> cleanup
       
   308     {
       
   309       delete fs;
       
   310       fs=0;
       
   311     }
       
   312     else
       
   313     {
       
   314       fs->oldYYin = preYYin;
       
   315     }
       
   316 #endif
       
   317 
       
   318   }
   322   }
   319   return fs;
   323   return fs;
   320 }
   324 }
   321 
   325 
   322 static FileState *findFile(const char *fileName,bool localInclude,bool &alreadyIncluded)
   326 static FileState *findFile(const char *fileName,bool localInclude,bool &alreadyIncluded)
  1129 }
  1133 }
  1130 
  1134 
  1131 Define *newDefine()
  1135 Define *newDefine()
  1132 {
  1136 {
  1133   Define *def=new Define;
  1137   Define *def=new Define;
  1134   def->name = g_defName;
  1138   def->name       = g_defName;
  1135   def->definition = g_defText.stripWhiteSpace();
  1139   def->definition = g_defText.stripWhiteSpace();
  1136   def->nargs = g_defArgs;
  1140   def->nargs      = g_defArgs;
  1137   def->fileName = g_yyFileName; 
  1141   def->fileName   = g_yyFileName; 
  1138   def->lineNr = g_yyLineNr;
  1142   def->fileDef    = g_yyFileDef;
  1139   def->varArgs = g_defVarArgs;
  1143   def->lineNr     = g_yyLineNr;
       
  1144   def->varArgs    = g_defVarArgs;
       
  1145   //printf("newDefine: %s->%s\n",def->name.data(),
       
  1146   //    def->fileDef ? def->fileDef->name().data() : "<none>");
  1140   //printf("newDefine: `%s'->`%s'\n",def->name.data(),def->definition.data());
  1147   //printf("newDefine: `%s'->`%s'\n",def->name.data(),def->definition.data());
  1141   if (!def->name.isEmpty() && Doxygen::expandAsDefinedDict[def->name])
  1148   if (!def->name.isEmpty() && Doxygen::expandAsDefinedDict[def->name])
  1142   {
  1149   {
  1143     def->isPredefined=TRUE;
  1150     def->isPredefined=TRUE;
  1144   }
  1151   }
  1181     while ((c=*p++) && (c==' ' || c=='\t')) k++;
  1188     while ((c=*p++) && (c==' ' || c=='\t')) k++;
  1182     g_defLitText=g_defLitText.mid(l+1,k-l-1)+g_defLitText.stripWhiteSpace();
  1189     g_defLitText=g_defLitText.mid(l+1,k-l-1)+g_defLitText.stripWhiteSpace();
  1183   }
  1190   }
  1184   md->setInitializer(g_defLitText.stripWhiteSpace());
  1191   md->setInitializer(g_defLitText.stripWhiteSpace());
  1185 
  1192 
       
  1193   //printf("pre.l: md->setFileDef(%p)\n",g_inputFileDef);
  1186   md->setFileDef(g_inputFileDef);
  1194   md->setFileDef(g_inputFileDef);
  1187   md->setDefinition("#define "+g_defName);
  1195   md->setDefinition("#define "+g_defName);
  1188 
  1196 
  1189   MemberName *mn=Doxygen::functionNameSDict->find(g_defName);
  1197   MemberName *mn=Doxygen::functionNameSDict->find(g_defName);
  1190   if (mn==0)
  1198   if (mn==0)
  1191   {
  1199   {
  1192     mn = new MemberName(g_defName);
  1200     mn = new MemberName(g_defName);
  1193     Doxygen::functionNameSDict->append(g_defName,mn);
  1201     Doxygen::functionNameSDict->append(g_defName,mn);
  1194   }
  1202   }
  1195   mn->append(md);
  1203   mn->append(md);
  1196   if (g_yyFileDef) g_yyFileDef->insertMember(md);
  1204   if (g_yyFileDef) 
       
  1205   {
       
  1206     g_yyFileDef->insertMember(md);
       
  1207   }
  1197 
  1208 
  1198   //Define *d;
  1209   //Define *d;
  1199   //if ((d=defineDict[g_defName])==0) defineDict.insert(g_defName,newDefine()); 
  1210   //if ((d=defineDict[g_defName])==0) defineDict.insert(g_defName,newDefine()); 
  1200 }
  1211 }
  1201 
  1212 
  1243   if (s<inc.length() && i>s) // valid include file name found
  1254   if (s<inc.length() && i>s) // valid include file name found
  1244   {
  1255   {
  1245     // extract include path+name
  1256     // extract include path+name
  1246     QCString incFileName=inc.mid(s,i-s).stripWhiteSpace();
  1257     QCString incFileName=inc.mid(s,i-s).stripWhiteSpace();
  1247 
  1258 
  1248     QCString oldFileName = g_yyFileName.copy();
  1259     QCString oldFileName = g_yyFileName;
  1249     FileDef *oldFileDef  = g_yyFileDef;
  1260     FileDef *oldFileDef  = g_yyFileDef;
  1250     int oldLineNr        = g_yyLineNr;
  1261     int oldLineNr        = g_yyLineNr;
  1251     //printf("Searching for `%s'\n",incFileName.data());
  1262     //printf("Searching for `%s'\n",incFileName.data());
  1252 
  1263 
  1253     // findFile will overwrite g_yyFileDef if found
  1264     // findFile will overwrite g_yyFileDef if found
  1272         {
  1283         {
  1273           //printf("Adding include dependency %s->%s\n",oldFileDef->name().data(),incFileName.data());
  1284           //printf("Adding include dependency %s->%s\n",oldFileDef->name().data(),incFileName.data());
  1274           g_yyFileDef->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,g_isImported);
  1285           g_yyFileDef->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,g_isImported);
  1275         }
  1286         }
  1276       }
  1287       }
  1277       fs->bufState=YY_CURRENT_BUFFER;
  1288       fs->bufState = YY_CURRENT_BUFFER;
  1278       fs->lineNr=oldLineNr;
  1289       fs->lineNr   = oldLineNr;
  1279       fs->fileName=oldFileName;
  1290       fs->fileName = oldFileName;
  1280       // push the state on the stack
  1291       // push the state on the stack
  1281       g_includeStack.push(fs);
  1292       g_includeStack.push(fs);
  1282       // set the scanner to the include file
  1293       // set the scanner to the include file
  1283 
  1294 
  1284       // Deal with file changes due to 
  1295       // Deal with file changes due to 
  1286       QCString lineStr(g_yyFileName.length()+20);
  1297       QCString lineStr(g_yyFileName.length()+20);
  1287       lineStr.sprintf("# 1 \"%s\" 1\n",g_yyFileName.data());
  1298       lineStr.sprintf("# 1 \"%s\" 1\n",g_yyFileName.data());
  1288       outputArray(lineStr.data(),lineStr.length());
  1299       outputArray(lineStr.data(),lineStr.length());
  1289 
  1300 
  1290       //fprintf(stderr,"Switching to include file %s\n",incFileName.data());
  1301       //fprintf(stderr,"Switching to include file %s\n",incFileName.data());
  1291       //preYYin=fs->filePtr;
  1302       g_expectGuard=TRUE;
  1292       //yy_switch_to_buffer(yy_create_buffer(preYYin, YY_BUF_SIZE));
  1303       g_inputBuf   = &fs->fileBuf;
  1293       g_inputBuf=&fs->fileBuf;
       
  1294       g_inputBufPos=0;
  1304       g_inputBufPos=0;
  1295       yy_switch_to_buffer(yy_create_buffer(0, YY_BUF_SIZE));
  1305       yy_switch_to_buffer(yy_create_buffer(0, YY_BUF_SIZE));
  1296     }
  1306     }
  1297     else
  1307     else
  1298     {
  1308     {
  1385 #undef  YY_INPUT
  1395 #undef  YY_INPUT
  1386 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
  1396 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
  1387 
  1397 
  1388 static int yyread(char *buf,int max_size)
  1398 static int yyread(char *buf,int max_size)
  1389 {
  1399 {
  1390 #if 0
       
  1391   int len = fread( buf, 1, max_size, preYYin );
       
  1392   if (len==0 && ferror( yyin ))
       
  1393   {
       
  1394     yy_fatal_error( "input in flex scanner failed" );
       
  1395     return len;
       
  1396   }
       
  1397   return filterCRLF(buf,len);
       
  1398 #endif
       
  1399 
       
  1400   int bytesInBuf = g_inputBuf->curPos()-g_inputBufPos;
  1400   int bytesInBuf = g_inputBuf->curPos()-g_inputBufPos;
  1401   int bytesToCopy = QMIN(max_size,bytesInBuf);
  1401   int bytesToCopy = QMIN(max_size,bytesInBuf);
  1402   memcpy(buf,g_inputBuf->data()+g_inputBufPos,bytesToCopy);
  1402   memcpy(buf,g_inputBuf->data()+g_inputBufPos,bytesToCopy);
  1403   g_inputBufPos+=bytesToCopy;
  1403   g_inputBufPos+=bytesToCopy;
  1404   return bytesToCopy;
  1404   return bytesToCopy;
  1479 					      name!="Q_PROPERTY" &&
  1479 					      name!="Q_PROPERTY" &&
  1480 					      !(
  1480 					      !(
  1481 					         (g_includeStack.isEmpty() || g_curlyCount>0) &&
  1481 					         (g_includeStack.isEmpty() || g_curlyCount>0) &&
  1482 					         g_macroExpansion &&
  1482 					         g_macroExpansion &&
  1483 					         (def=g_fileDefineDict->find(name)) &&
  1483 					         (def=g_fileDefineDict->find(name)) &&
       
  1484 						 macroIsAccessible(def) &&
  1484 					         (!g_expandOnlyPredef || def->isPredefined)
  1485 					         (!g_expandOnlyPredef || def->isPredefined)
  1485 					       )
  1486 					       )
  1486 					     )
  1487 					     )
  1487 					  {
  1488 					  {
  1488 					    outputChar('\n');
  1489 					    outputChar('\n');
  1538 					}
  1539 					}
  1539 <CopyString>\"				{
  1540 <CopyString>\"				{
  1540 					  outputChar(*yytext);
  1541 					  outputChar(*yytext);
  1541 					  BEGIN( CopyLine );
  1542 					  BEGIN( CopyLine );
  1542 					}
  1543 					}
  1543 <CopyLine>{ID}/{BN}{0,80}"("			{
  1544 <CopyLine>{ID}/{BN}{0,80}"("		{
       
  1545   					  g_expectGuard = FALSE;
  1544   					  Define *def=0;
  1546   					  Define *def=0;
  1545 					  def=g_fileDefineDict->find(yytext);
  1547 					  def=g_fileDefineDict->find(yytext);
  1546 					  //printf("Search for define %s found=%d g_includeStack.count()=%d "
  1548 					  //printf("Search for define %s found=%d g_includeStack.count()=%d "
  1547 					  //       "g_curlyCount=%d g_macroExpansion=%d g_expandOnlyPredef=%d "
  1549 					  //       "g_curlyCount=%d g_macroExpansion=%d g_expandOnlyPredef=%d "
  1548 					  //	 "isPreDefined=%d tu=%d\n",yytext,def ? 1 : 0,
  1550 					  //	 "isPreDefined=%d tu=%d\n",yytext,def ? 1 : 0,
  1554 					      g_macroExpansion &&
  1556 					      g_macroExpansion &&
  1555 					      (def=g_fileDefineDict->find(yytext)) &&
  1557 					      (def=g_fileDefineDict->find(yytext)) &&
  1556 					      (!g_expandOnlyPredef || def->isPredefined || Config_getBool("PREPROCCESS_FULL_TU"))
  1558 					      (!g_expandOnlyPredef || def->isPredefined || Config_getBool("PREPROCCESS_FULL_TU"))
  1557 					     )
  1559 					     )
  1558 					  {
  1560 					  {
  1559 					    //printf("Found it!\n");
  1561 					    //printf("Found it! #args=%d\n",def->nargs);
  1560 					    g_roundCount=0;
  1562 					    g_roundCount=0;
  1561 					    g_defArgsStr=yytext;
  1563 					    g_defArgsStr=yytext;
  1562 					    if (def->nargs==-1) // no function macro
  1564 					    if (def->nargs==-1) // no function macro
  1563 					    {
  1565 					    {
  1564 					      QCString result = expandMacro(g_defArgsStr);
  1566 					      QCString result = expandMacro(g_defArgsStr);
  1580 					  //printf("Search for define %s\n",yytext);
  1582 					  //printf("Search for define %s\n",yytext);
  1581   					  if ((g_includeStack.isEmpty() || g_curlyCount>0) && 
  1583   					  if ((g_includeStack.isEmpty() || g_curlyCount>0) && 
  1582 					      g_macroExpansion &&
  1584 					      g_macroExpansion &&
  1583 					      (def=g_fileDefineDict->find(yytext)) &&
  1585 					      (def=g_fileDefineDict->find(yytext)) &&
  1584 					      def->nargs==-1 &&
  1586 					      def->nargs==-1 &&
       
  1587 				              macroIsAccessible(def) &&
  1585 					      (!g_expandOnlyPredef || def->isPredefined)
  1588 					      (!g_expandOnlyPredef || def->isPredefined)
  1586 					     )
  1589 					     )
  1587 					  {
  1590 					  {
  1588 					    //printf("Found it!\n");
  1591 					    //printf("Found it!\n");
  1589                                             QCString name=yytext;
  1592                                             QCString name=yytext;
  1814 <DefinedExpr2>{ID}			{
  1817 <DefinedExpr2>{ID}			{
  1815   					  if (isDefined(yytext))
  1818   					  if (isDefined(yytext))
  1816 					    g_guardExpr+=" 1L ";
  1819 					    g_guardExpr+=" 1L ";
  1817 					  else
  1820 					  else
  1818 					    g_guardExpr+=" 0L ";
  1821 					    g_guardExpr+=" 0L ";
  1819 					  g_lastGuardName.resize(0);
  1822 					  g_lastGuardName=yytext;
  1820   					}
  1823   					}
  1821 <DefinedExpr1,DefinedExpr2>\n		{ // should not happen, handle anyway
  1824 <DefinedExpr1,DefinedExpr2>\n		{ // should not happen, handle anyway
  1822                                           g_yyLineNr++;
  1825                                           g_yyLineNr++;
  1823   					  g_ifcount=0;
  1826   					  g_ifcount=0;
  1824  					  BEGIN(SkipCPPBlock); 
  1827  					  BEGIN(SkipCPPBlock); 
  1923 					  outputChar('\n');
  1926 					  outputChar('\n');
  1924 					  g_yyLineNr++;
  1927 					  g_yyLineNr++;
  1925 					}
  1928 					}
  1926 <EndImport>.				{
  1929 <EndImport>.				{
  1927   					}
  1930   					}
  1928 <DefName>{ID}/"("			{
  1931 <DefName>{ID}/"("			{ // define with argument
  1929   					  //printf("Define() `%s'\n",yytext);
  1932   					  //printf("Define() `%s'\n",yytext);
  1930 					  g_argDict = new QDict<int>(31);
  1933 					  g_argDict = new QDict<int>(31);
  1931 					  g_argDict->setAutoDelete(TRUE);
  1934 					  g_argDict->setAutoDelete(TRUE);
  1932 					  g_defArgs = 0; 
  1935 					  g_defArgs = 0; 
  1933                                           g_defArgsStr.resize(0);
  1936                                           g_defArgsStr.resize(0);
  1935 					  g_defLitText.resize(0);
  1938 					  g_defLitText.resize(0);
  1936 					  g_defName = yytext;
  1939 					  g_defName = yytext;
  1937 					  g_defVarArgs = FALSE;
  1940 					  g_defVarArgs = FALSE;
  1938 					  BEGIN(DefineArg);
  1941 					  BEGIN(DefineArg);
  1939   					}
  1942   					}
  1940 <DefName>{ID}/{B}*			{
  1943 <DefName>{ID}{B}+"1"			{ // special case: define with 1 -> can be "guard"
       
  1944   					  //printf("Define `%s'\n",yytext);
       
  1945   					  g_argDict = 0;
       
  1946 					  g_defArgs = -1;
       
  1947                                           g_defArgsStr.resize(0);
       
  1948 					  g_defName = yytext;
       
  1949 					  g_defName = g_defName.left(g_defName.length()-1).stripWhiteSpace();
       
  1950 					  g_defVarArgs = FALSE;
       
  1951 					  //printf("Guard check: %s!=%s || %d\n",
       
  1952 					  //    g_defName.data(),g_lastGuardName.data(),g_expectGuard);
       
  1953 					  if ( g_defName!=g_lastGuardName || !g_expectGuard)
       
  1954 					  { // define may appear in the output
       
  1955 					    QCString tmp=(QCString)"#define "+g_defName;
       
  1956 					    outputArray(tmp.data(),tmp.length());
       
  1957 					    g_quoteArg=FALSE;
       
  1958 					    g_insideComment=FALSE;
       
  1959 					    g_lastGuardName.resize(0);
       
  1960 				            g_defText="1"; 
       
  1961 					    g_defLitText="1"; 
       
  1962 					    BEGIN(DefineText); 
       
  1963 					  }
       
  1964 					  else // define is a guard => hide
       
  1965 					  {
       
  1966 					    g_defText.resize(0);
       
  1967 					    g_defLitText.resize(0);
       
  1968 					    BEGIN(Start);
       
  1969 					  }
       
  1970   					}
       
  1971 <DefName>{ID}/{B}*			{ // define with content
  1941   					  //printf("Define `%s'\n",yytext);
  1972   					  //printf("Define `%s'\n",yytext);
  1942   					  g_argDict = 0;
  1973   					  g_argDict = 0;
  1943 					  g_defArgs = -1;
  1974 					  g_defArgs = -1;
  1944                                           g_defArgsStr.resize(0);
  1975                                           g_defArgsStr.resize(0);
  1945 					  g_defText.resize(0);
  1976 					  g_defText.resize(0);
  1950 					  outputArray(tmp.data(),tmp.length());
  1981 					  outputArray(tmp.data(),tmp.length());
  1951 					  g_quoteArg=FALSE;
  1982 					  g_quoteArg=FALSE;
  1952 					  g_insideComment=FALSE;
  1983 					  g_insideComment=FALSE;
  1953 					  BEGIN(DefineText); 
  1984 					  BEGIN(DefineText); 
  1954   					}
  1985   					}
  1955 <DefName>{ID}/{B}*"\n"			{ // bare define
  1986 <DefName>{ID}/{B}*"\n"			{ // empty define
  1956   					  g_argDict = 0;
  1987   					  g_argDict = 0;
  1957 					  g_defArgs = -1;
  1988 					  g_defArgs = -1;
  1958 					  g_defName = yytext;
  1989 					  g_defName = yytext;
  1959                                           g_defArgsStr.resize(0);
  1990                                           g_defArgsStr.resize(0);
  1960 					  g_defText.resize(0);
  1991 					  g_defText.resize(0);
  1970 					    BEGIN(DefineText);
  2001 					    BEGIN(DefineText);
  1971 					  }
  2002 					  }
  1972 					  else // define is a guard => hide
  2003 					  else // define is a guard => hide
  1973 					  {
  2004 					  {
  1974 					    //printf("Found a guard %s\n",yytext);
  2005 					    //printf("Found a guard %s\n",yytext);
  1975 #if 0
       
  1976   					    Define *def=g_fileDefineDict->find(g_defName);
       
  1977 					    if (def==0) // new define name for this file
       
  1978 					    {
       
  1979 					      g_fileDefineDict->insert(g_defName,newDefine());
       
  1980 					    }
       
  1981 					    else // name already exists
       
  1982 					    {
       
  1983 					      if (def->undef) // undefined name
       
  1984 					      {
       
  1985 					        def->undef = FALSE;
       
  1986 					        def->name = g_defName;
       
  1987 					        def->definition = g_defText.stripWhiteSpace();
       
  1988 					        def->nargs = g_defArgs;
       
  1989 					        def->fileName = g_yyFileName.copy(); 
       
  1990 					        def->lineNr = g_yyLineNr;
       
  1991 					      }
       
  1992 					      else
       
  1993 					      {
       
  1994 					        //printf("Error: define %s is defined more than once!\n",g_defName.data());
       
  1995 					      }
       
  1996 					    }
       
  1997 #endif
       
  1998 					    g_lastGuardName.resize(0);
  2006 					    g_lastGuardName.resize(0);
  1999 					    BEGIN(Start);
  2007 					    BEGIN(Start);
  2000 					  }
  2008 					  }
       
  2009 					  g_expectGuard=FALSE;
  2001   					}
  2010   					}
  2002 <DefineArg>","{B}*			{ g_defArgsStr+=yytext; }
  2011 <DefineArg>","{B}*			{ g_defArgsStr+=yytext; }
  2003 <DefineArg>"("{B}*                      { g_defArgsStr+=yytext; }
  2012 <DefineArg>"("{B}*                      { g_defArgsStr+=yytext; }
  2004 <DefineArg>{B}*")"{B}*			{
  2013 <DefineArg>{B}*")"{B}*			{
  2005                                           g_defArgsStr+=yytext; 
  2014                                           g_defArgsStr+=yytext; 
  2038   					  g_defText+=yytext;
  2047   					  g_defText+=yytext;
  2039 					  g_defLitText+=yytext;
  2048 					  g_defLitText+=yytext;
  2040 					  g_insideComment=FALSE;
  2049 					  g_insideComment=FALSE;
  2041   					}
  2050   					}
  2042   */
  2051   */
  2043 <DefineText>"/*"			{
  2052 <DefineText>"/*"[!*]?			{
  2044 					  g_defText+=yytext;
  2053 					  g_defText+=yytext;
  2045 					  g_defLitText+=yytext;
  2054 					  g_defLitText+=yytext;
  2046 					  g_lastCContext=YY_START;
  2055 					  g_lastCContext=YY_START;
  2047 					  g_commentCount=1;
  2056 					  g_commentCount=1;
  2048   					  BEGIN(CopyCComment);
  2057   					  BEGIN(CopyCComment);
  2049   					}
  2058   					}
  2050 <DefineText>"//"			{
  2059 <DefineText>"//"[!/]?			{
  2051   				          outputChar('/');outputChar('/');
  2060   				          outputChar('/');outputChar('/');
  2052   					  g_lastCPPContext=YY_START;
  2061   					  g_lastCPPContext=YY_START;
  2053 					  g_defLitText+=' ';
  2062 					  g_defLitText+=' ';
  2054   					  BEGIN(SkipCPPComment);
  2063   					  BEGIN(SkipCPPComment);
  2055   					}
  2064   					}
  2247 					  if (def==0) // new define
  2256 					  if (def==0) // new define
  2248 					  {
  2257 					  {
  2249 					    //printf("new define!\n");
  2258 					    //printf("new define!\n");
  2250 					    g_fileDefineDict->insert(g_defName,newDefine());
  2259 					    g_fileDefineDict->insert(g_defName,newDefine());
  2251 					  }
  2260 					  }
  2252 					  else if (def)// name already exists
  2261 					  else if (def && macroIsAccessible(def))
       
  2262 					       // name already exists
  2253 					  {
  2263 					  {
  2254 					    //printf("existing define!\n");
  2264 					    //printf("existing define!\n");
  2255 					    //printf("define found\n");
  2265 					    //printf("define found\n");
  2256 					    if (def->undef) // undefined name
  2266 					    if (def->undef) // undefined name
  2257 					    {
  2267 					    {
  2316 					  }
  2326 					  }
  2317 					  else
  2327 					  else
  2318 					  {
  2328 					  {
  2319 					    FileState *fs=g_includeStack.pop();
  2329 					    FileState *fs=g_includeStack.pop();
  2320 					    //fileDefineCache->merge(g_yyFileName,fs->fileName);
  2330 					    //fileDefineCache->merge(g_yyFileName,fs->fileName);
  2321 #if 0
       
  2322 					    if (fs->isPlainFile)
       
  2323 					    {
       
  2324 					      if (fs->filePtr && fclose(fs->filePtr)!=0)
       
  2325 					      {
       
  2326 						err("Error: could not close file %s: %s\n",fs->fileName.data(),strerror(errno));
       
  2327 					      }
       
  2328 				              fs->filePtr=0;
       
  2329 					    }
       
  2330 					    else
       
  2331 					    {
       
  2332 					      if (fs->filePtr && portable_pclose(fs->filePtr)!=0)
       
  2333 					      {
       
  2334 						err("Error: could not close pipe: %s\n",strerror(errno));
       
  2335 					      }
       
  2336 				    	      fs->filePtr=0;
       
  2337 					    }
       
  2338 #endif
       
  2339 					    YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
  2331 					    YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
  2340 					    yy_switch_to_buffer( fs->bufState );
  2332 					    yy_switch_to_buffer( fs->bufState );
  2341 					    yy_delete_buffer( oldBuf );
  2333 					    yy_delete_buffer( oldBuf );
  2342 					    g_yyLineNr=fs->lineNr;
  2334 					    g_yyLineNr    = fs->lineNr;
  2343                                             //preYYin = fs->oldYYin;
  2335                                             //preYYin = fs->oldYYin;
  2344                                             g_inputBuf = fs->oldFileBuf;
  2336                                             g_inputBuf    = fs->oldFileBuf;
  2345 					    g_inputBufPos = fs->oldFileBufPos;
  2337 					    g_inputBufPos = fs->oldFileBufPos;
  2346 					    setFileName(fs->fileName.copy());
  2338 					    setFileName(fs->fileName);
  2347 					    //fprintf(stderr,"######## FileName %s\n",g_yyFileName.data());
  2339 					    //fprintf(stderr,"######## FileName %s\n",g_yyFileName.data());
  2348 					    
  2340 					    
  2349                                             // Deal with file changes due to 
  2341                                             // Deal with file changes due to 
  2350                                             // #include's within { .. } blocks
  2342                                             // #include's within { .. } blocks
  2351                                             QCString lineStr(15+g_yyFileName.length());
  2343                                             QCString lineStr(15+g_yyFileName.length());
  2372 <*>\n					{ 
  2364 <*>\n					{ 
  2373   					  outputChar('\n');
  2365   					  outputChar('\n');
  2374   					  g_yyLineNr++; 
  2366   					  g_yyLineNr++; 
  2375 					}
  2367 					}
  2376 <*>.				        {
  2368 <*>.				        {
       
  2369   					  g_expectGuard = FALSE;
  2377   					  outputChar(*yytext);
  2370   					  outputChar(*yytext);
  2378   					}
  2371   					}
  2379 
  2372 
  2380 %%
  2373 %%
  2381 
  2374 
  2458 
  2451 
  2459 void initPreprocessor()
  2452 void initPreprocessor()
  2460 {
  2453 {
  2461   g_pathList = new QStrList;
  2454   g_pathList = new QStrList;
  2462   addSearchDir(".");
  2455   addSearchDir(".");
  2463   //defineNameList.setAutoDelete(TRUE);
       
  2464   //defineNameList.clear();
       
  2465   //defineDict.clear();
       
  2466   //fileDefineCache = new DefineCache(1009);
       
  2467   g_expandedDict = new DefineDict(17);
  2456   g_expandedDict = new DefineDict(17);
  2468   //g_fileDefineDict = new DefineDict(1009);
       
  2469 }
  2457 }
  2470 
  2458 
  2471 void cleanUpPreprocessor()
  2459 void cleanUpPreprocessor()
  2472 {
  2460 {
  2473   //delete fileDefineCache;
       
  2474   //delete g_fileDefineDict; g_fileDefineDict=0;
       
  2475   delete g_expandedDict; g_expandedDict=0;
  2461   delete g_expandedDict; g_expandedDict=0;
  2476   delete g_pathList; g_pathList=0;
  2462   delete g_pathList; g_pathList=0;
  2477 }
  2463 }
  2478 
  2464 
  2479 void dumpDefineDict(const DefineDict *theDefDict)
  2465 void dumpDefineDict(const DefineDict *theDefDict)
  2532   g_inputBuf=&input;
  2518   g_inputBuf=&input;
  2533   g_inputBufPos=0;
  2519   g_inputBufPos=0;
  2534   g_outputBuf=&output;
  2520   g_outputBuf=&output;
  2535   g_includeStack.setAutoDelete(TRUE);
  2521   g_includeStack.setAutoDelete(TRUE);
  2536   g_includeStack.clear();
  2522   g_includeStack.clear();
  2537   //g_fileDefineDict->setAutoDelete(TRUE);
       
  2538   //g_fileDefineDict->clear();
       
  2539   g_expandedDict->setAutoDelete(FALSE);
  2523   g_expandedDict->setAutoDelete(FALSE);
  2540   g_expandedDict->clear();
  2524   g_expandedDict->clear();
  2541   g_condStack.clear();
  2525   g_condStack.clear();
  2542   g_condStack.setAutoDelete(TRUE);
  2526   g_condStack.setAutoDelete(TRUE);
  2543   static bool firstTime=TRUE;
  2527   static bool firstTime=TRUE;
  2560       if (i_obrace<i_equals && i_cbrace<i_equals && 
  2544       if (i_obrace<i_equals && i_cbrace<i_equals && 
  2561 	  i_obrace!=-1      && i_cbrace!=-1      && 
  2545 	  i_obrace!=-1      && i_cbrace!=-1      && 
  2562 	  i_obrace<i_cbrace
  2546 	  i_obrace<i_cbrace
  2563 	 ) // predefined function macro definition
  2547 	 ) // predefined function macro definition
  2564       {
  2548       {
       
  2549 	//printf("predefined function macro '%s'\n",defStr);
  2565 	QRegExp reId("[a-z_A-Z][a-z_A-Z0-9]*"); // regexp matching an id
  2550 	QRegExp reId("[a-z_A-Z][a-z_A-Z0-9]*"); // regexp matching an id
  2566 	QDict<int> argDict(17);
  2551 	QDict<int> argDict(17);
  2567 	argDict.setAutoDelete(TRUE);
  2552 	argDict.setAutoDelete(TRUE);
  2568 	int i=i_obrace+1,p,l,count=0;
  2553 	int i=i_obrace+1,p,l,count=0;
  2569 	// gather the formal arguments in a dictionary 
  2554 	// gather the formal arguments in a dictionary 
  2599 	// add define definition to the dictionary of defines for this file
  2584 	// add define definition to the dictionary of defines for this file
  2600 	QCString dname = ds.left(i_obrace);
  2585 	QCString dname = ds.left(i_obrace);
  2601 	if (!dname.isEmpty())
  2586 	if (!dname.isEmpty())
  2602 	{
  2587 	{
  2603 	  Define *def = new Define;
  2588 	  Define *def = new Define;
  2604 	  def->name = dname;
  2589 	  def->name         = dname;
  2605 	  def->definition = definition; 
  2590 	  def->definition   = definition; 
  2606 	  def->nargs = count;
  2591 	  def->nargs        = count;
  2607 	  def->isPredefined = TRUE;
  2592 	  def->isPredefined = TRUE;
  2608 	  def->nonRecursive = nonRecursive;
  2593 	  def->nonRecursive = nonRecursive;
       
  2594 	  def->fileDef      = g_yyFileDef;
       
  2595 	  def->fileName     = fileName;
  2609 	  g_fileDefineDict->insert(def->name,def);
  2596 	  g_fileDefineDict->insert(def->name,def);
  2610 	}
  2597 	}
  2611 
  2598 
  2612 	//printf("#define `%s' `%s' #nargs=%d\n",
  2599 	//printf("#define `%s' `%s' #nargs=%d\n",
  2613 	//  def->name.data(),def->definition.data(),def->nargs);
  2600 	//  def->name.data(),def->definition.data(),def->nargs);
  2615       else if ((i_obrace==-1 || i_obrace>i_equals) &&
  2602       else if ((i_obrace==-1 || i_obrace>i_equals) &&
  2616 	  (i_cbrace==-1 || i_cbrace>i_equals) &&
  2603 	  (i_cbrace==-1 || i_cbrace>i_equals) &&
  2617 	  !ds.isEmpty() && (int)ds.length()>i_equals
  2604 	  !ds.isEmpty() && (int)ds.length()>i_equals
  2618 	  ) // predefined non-function macro definition
  2605 	  ) // predefined non-function macro definition
  2619       {
  2606       {
       
  2607 	//printf("predefined normal macro '%s'\n",defStr);
  2620 	Define *def = new Define;
  2608 	Define *def = new Define;
  2621 	if (i_equals==-1) // simple define without argument
  2609 	if (i_equals==-1) // simple define without argument
  2622 	{
  2610 	{
  2623 	  def->name = ds;
  2611 	  def->name = ds;
  2624 	  def->definition = "1"; // substitute occurrences by 1 (true)
  2612 	  def->definition = "1"; // substitute occurrences by 1 (true)
  2632 	if (!def->name.isEmpty())
  2620 	if (!def->name.isEmpty())
  2633 	{
  2621 	{
  2634 	  def->nargs = -1;
  2622 	  def->nargs = -1;
  2635 	  def->isPredefined = TRUE;
  2623 	  def->isPredefined = TRUE;
  2636 	  def->nonRecursive = nonRecursive;
  2624 	  def->nonRecursive = nonRecursive;
       
  2625 	  def->fileDef      = g_yyFileDef;
       
  2626 	  def->fileName     = fileName;
  2637 	  g_fileDefineDict->insert(def->name,def);
  2627 	  g_fileDefineDict->insert(def->name,def);
  2638 	}
  2628 	}
  2639 	else
  2629 	else
  2640 	{
  2630 	{
  2641 	  delete def;
  2631 	  delete def;
  2646       }
  2636       }
  2647     }
  2637     }
  2648     firstTime=FALSE;
  2638     firstTime=FALSE;
  2649   }
  2639   }
  2650  
  2640  
  2651 #if 0
       
  2652   QCString inputFilter = getFileFilter(fileName);
       
  2653   if (inputFilter.isEmpty())
       
  2654   {
       
  2655     preYYin = fopen(fileName,"r");
       
  2656     if (!preYYin)
       
  2657     {
       
  2658       err("Error: could not open file %s\n",fileName);
       
  2659       return;
       
  2660     }
       
  2661   }
       
  2662   else
       
  2663   {
       
  2664     QCString cmd = inputFilter+" \""+fileName+"\"";
       
  2665     Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",cmd.data());
       
  2666     preYYin = portable_popen(cmd,"r");
       
  2667     if (!preYYin)
       
  2668     {
       
  2669       err("Error: could not execute filter %s\n",cmd.data());
       
  2670       return;
       
  2671     }
       
  2672   }
       
  2673 #endif
       
  2674   g_yyLineNr = 1;
  2641   g_yyLineNr = 1;
  2675   g_level    = 0;
  2642   g_level    = 0;
  2676   g_ifcount  = 0;
  2643   g_ifcount  = 0;
  2677   setFileName(fileName);
  2644   setFileName(fileName);
  2678   g_inputFileDef = g_yyFileDef;
  2645   g_inputFileDef = g_yyFileDef;
       
  2646 
  2679   BEGIN( Start );
  2647   BEGIN( Start );
  2680   
  2648   
       
  2649   g_expectGuard = TRUE;
  2681   g_lastGuardName.resize(0);
  2650   g_lastGuardName.resize(0);
  2682   g_guardExpr.resize(0);
  2651   g_guardExpr.resize(0);
  2683   
  2652   
  2684   preYYlex();
  2653   preYYlex();
  2685   g_lexInit=TRUE;
  2654   g_lexInit=TRUE;
  2686 
  2655 
  2687 #if 0
       
  2688   if (inputFilter.isEmpty())
       
  2689     fclose(preYYin);
       
  2690   else
       
  2691     portable_pclose(preYYin);
       
  2692 #endif
       
  2693   
       
  2694   if (Debug::isFlagSet(Debug::Preprocessor))
  2656   if (Debug::isFlagSet(Debug::Preprocessor))
  2695   {
  2657   {
  2696 	printf("preprocessFile() dump from %d to %d\n", orgOffset, output.curPos());
  2658 	printf("preprocessFile() dump from %d to %d\n", orgOffset, output.curPos());
  2697     char *orgPos=output.data()+orgOffset;
  2659     char *orgPos=output.data()+orgOffset;
  2698     char *newPos=output.data()+output.curPos();
  2660     char *newPos=output.data()+output.curPos();