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. |
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; |
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); |
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); |
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()); |
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) |
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(); |