00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "driver.h"
00021
#include "lexer.h"
00022
#include "parser.h"
00023
#include <kdebug.h>
00024
#include <stdlib.h>
00025
#include <qfile.h>
00026
#include <qfileinfo.h>
00027
#include <qdir.h>
00028
00029 class DefaultSourceProvider:
public SourceProvider
00030 {
00031
public:
00032 DefaultSourceProvider() {}
00033
00034 virtual QString contents(
const QString& fileName )
00035 {
00036
QString source;
00037
00038
QFile f( fileName );
00039
if( f.open(IO_ReadOnly) ){
00040
QTextStream s( &f );
00041 source = s.read();
00042 f.close();
00043 }
00044
return source;
00045 }
00046
00047 virtual bool isModified(
const QString& fileName )
00048 {
00049 Q_UNUSED( fileName );
00050
return true;
00051 }
00052
00053
private:
00054
DefaultSourceProvider(
const DefaultSourceProvider& source );
00055
void operator = (
const DefaultSourceProvider& source );
00056 };
00057
00058
00059 Driver::Driver()
00060 : depresolv( FALSE ), lexer( 0 )
00061 {
00062
m_sourceProvider =
new DefaultSourceProvider();
00063 }
00064
00065 Driver::~Driver()
00066 {
00067
reset();
00068
delete(
m_sourceProvider );
00069 }
00070
00071 SourceProvider*
Driver::sourceProvider()
00072 {
00073
return m_sourceProvider;
00074 }
00075
00076 void Driver::setSourceProvider(
SourceProvider* sourceProvider )
00077 {
00078
if(
m_sourceProvider )
00079
delete(
m_sourceProvider );
00080
m_sourceProvider = sourceProvider;
00081 }
00082
00083 void Driver::reset( )
00084 {
00085
m_dependences.clear();
00086
m_macros.clear();
00087
m_problems.clear();
00088
m_includePaths.clear();
00089
00090
while(
m_parsedUnits.size() ){
00091
TranslationUnitAST* unit = *
m_parsedUnits.begin();
00092
m_parsedUnits.remove(
m_parsedUnits.begin() );
00093
delete( unit );
00094 }
00095 }
00096
00097 void Driver::remove(
const QString & fileName )
00098 {
00099
m_dependences.remove( fileName );
00100
m_problems.remove( fileName );
00101
removeAllMacrosInFile( fileName );
00102
00103
QMap<QString, TranslationUnitAST*>::Iterator it =
m_parsedUnits.find( fileName );
00104
if( it !=
m_parsedUnits.end() ){
00105
TranslationUnitAST* unit = *it;
00106
m_parsedUnits.remove( it );
00107
delete( unit );
00108 }
00109 }
00110
00111 void Driver::removeAllMacrosInFile(
const QString& fileName )
00112 {
00113
QMap<QString, Macro>::Iterator it =
m_macros.begin();
00114
while( it !=
m_macros.end() ){
00115
Macro m = *it++;
00116
if( m.
fileName() == fileName )
00117
removeMacro( m.
name() );
00118 }
00119 }
00120
00121 TranslationUnitAST::Node Driver::takeTranslationUnit(
const QString& fileName )
00122 {
00123
QMap<QString, TranslationUnitAST*>::Iterator it =
m_parsedUnits.find( fileName );
00124 TranslationUnitAST::Node unit( *it );
00125
00126
m_parsedUnits[ fileName] = 0;
00127
return unit;
00128 }
00129
00130 TranslationUnitAST*
Driver::translationUnit(
const QString& fileName )
const
00131
{
00132
QMap<QString, TranslationUnitAST*>::ConstIterator it =
m_parsedUnits.find( fileName );
00133
return it !=
m_parsedUnits.end() ? *it : 0;
00134 }
00135
00136 void Driver::addDependence(
const QString & fileName,
const Dependence & dep )
00137 {
00138
QFileInfo fileInfo( dep.first );
00139
QString fn = fileInfo.absFilePath();
00140
00141
if ( !
depresolv ){
00142
findOrInsertDependenceList( fileName ).insert( fn, dep );
00143
return;
00144 }
00145
00146
QString file =
findIncludeFile( dep );
00147
findOrInsertDependenceList( fileName ).insert(
file, dep );
00148
00149
if (
m_parsedUnits.find(
file) !=
m_parsedUnits.end() )
00150
return;
00151
00152
if ( !QFile::exists(
file ) ) {
00153
Problem p(
"Couldn't find include file " + dep.first,
00154
lexer ?
lexer->
currentLine() : -1,
00155
lexer ?
lexer->
currentColumn() : -1 );
00156
addProblem( fileName, p );
00157
return;
00158 }
00159
00160
QString cfn =
m_currentFileName;
00161
Lexer *l =
lexer;
00162
parseFile(
file );
00163 m_currentFileName = cfn;
00164 lexer = l;
00165 }
00166
00167 void Driver::addMacro(
const Macro & macro )
00168 {
00169
m_macros.insert( macro.
name(), macro );
00170 }
00171
00172 void Driver::addProblem(
const QString & fileName,
const Problem & problem )
00173 {
00174
findOrInsertProblemList( fileName ).append( problem );
00175 }
00176
00177 QMap< QString, Dependence >&
Driver::findOrInsertDependenceList(
const QString & fileName )
00178 {
00179
QMap<QString, QMap<QString, Dependence> >::Iterator it =
m_dependences.find( fileName );
00180
if( it !=
m_dependences.end() )
00181
return it.data();
00182
00183
QMap<QString, Dependence> l;
00184
m_dependences.insert( fileName, l );
00185
return m_dependences[ fileName ];
00186 }
00187
00188 QValueList < Problem >&
Driver::findOrInsertProblemList(
const QString & fileName )
00189 {
00190
QMap<QString, QValueList<Problem> >::Iterator it =
m_problems.find( fileName );
00191
if( it !=
m_problems.end() )
00192
return it.data();
00193
00194
QValueList<Problem> l;
00195
m_problems.insert( fileName, l );
00196
return m_problems[ fileName ];
00197 }
00198
00199 QMap< QString, Dependence > Driver::dependences(
const QString & fileName )
const
00200
{
00201
QMap<QString, QMap<QString, Dependence> >::ConstIterator it =
m_dependences.find( fileName );
00202
if( it !=
m_dependences.end() )
00203
return it.data();
00204
return QMap<QString, Dependence>();
00205 }
00206
00207 QMap< QString, Macro > Driver::macros()
const
00208
{
00209
return m_macros;
00210 }
00211
00212 QValueList < Problem >
Driver::problems(
const QString & fileName )
const
00213
{
00214
QMap<QString, QValueList<Problem> >::ConstIterator it =
m_problems.find( fileName );
00215
if( it !=
m_problems.end() )
00216
return it.data();
00217
return QValueList<Problem>();
00218 }
00219
00220 void Driver::parseFile(
const QString& fileName,
bool onlyPreProcess,
bool force )
00221 {
00222
QFileInfo fileInfo( fileName );
00223
QString absFilePath = fileInfo.absFilePath();
00224
00225
QMap<QString, TranslationUnitAST*>::Iterator it =
m_parsedUnits.find( absFilePath );
00226
00227
if( force && it !=
m_parsedUnits.end() ){
00228
takeTranslationUnit( absFilePath );
00229 }
else if( it !=
m_parsedUnits.end() && *it != 0 ){
00230
00231
return;
00232 }
00233
00234
m_dependences.remove( fileName );
00235
m_problems.remove( fileName );
00236
00237
m_currentFileName = fileName;
00238
00239
Lexer lex(
this );
00240
lexer = &lex;
00241
setupLexer( &lex );
00242
00243 lex.setSource(
sourceProvider()->contents(fileName) );
00244
00245
if( !onlyPreProcess ){
00246
Parser parser(
this, &lex );
00247
setupParser( &parser );
00248
00249 TranslationUnitAST :: Node
translationUnit;
00250 parser.parseTranslationUnit( translationUnit );
00251
m_parsedUnits.insert( fileName, translationUnit.release() );
00252
fileParsed( fileName );
00253 }
00254
00255
m_currentFileName = QString::null;
00256
lexer = 0;
00257 }
00258
00259 void Driver::setupLexer(
Lexer * lexer )
00260 {
00261
00262 lexer->
addSkipWord(
"__STL_BEGIN_NAMESPACE" );
00263 lexer->
addSkipWord(
"__STL_END_NAMESPACE" );
00264 lexer->
addSkipWord(
"__STL_BEGIN_RELOPS_NAMESPACE" );
00265 lexer->
addSkipWord(
"__STL_END_RELOPS_NAMESPACE" );
00266 lexer->
addSkipWord(
"__STL_TEMPLATE_NULL" );
00267 lexer->
addSkipWord(
"__STL_TRY" );
00268 lexer->
addSkipWord(
"__STL_UNWIND" );
00269 lexer->
addSkipWord(
"__STL_NOTHROW" );
00270 lexer->
addSkipWord(
"__STL_NULL_TMPL_ARGS" );
00271 lexer->
addSkipWord(
"__STL_UNWIND",
SkipWordAndArguments );
00272 lexer->
addSkipWord(
"__GC_CONST" );
00273 lexer->
addSkipWord(
"__HASH_ALLOC_INIT",
SkipWordAndArguments );
00274 lexer->
addSkipWord(
"__STL_DEFAULT_ALLOCATOR",
SkipWordAndArguments,
"T" );
00275 lexer->
addSkipWord(
"__STL_MUTEX_INITIALIZER" );
00276 lexer->
addSkipWord(
"__STL_NULL_TMPL_ARGS" );
00277
00278
00279 lexer->
addSkipWord(
"ANTLR_BEGIN_NAMESPACE",
SkipWordAndArguments );
00280 lexer->
addSkipWord(
"ANTLR_USE_NAMESPACE",
SkipWordAndArguments );
00281 lexer->
addSkipWord(
"ANTLR_USING_NAMESPACE",
SkipWordAndArguments );
00282 lexer->
addSkipWord(
"ANTLR_END_NAMESPACE" );
00283 lexer->
addSkipWord(
"ANTLR_C_USING",
SkipWordAndArguments );
00284 lexer->
addSkipWord(
"ANTLR_API" );
00285
00286
00287 lexer->
addSkipWord(
"__extension__",
SkipWordAndArguments );
00288 lexer->
addSkipWord(
"__attribute__",
SkipWordAndArguments );
00289 lexer->
addSkipWord(
"__BEGIN_DECLS" );
00290 lexer->
addSkipWord(
"__END_DECLS" );
00291 lexer->
addSkipWord(
"__THROW" );
00292 lexer->
addSkipWord(
"__restrict" );
00293 lexer->
addSkipWord(
"__restrict__" );
00294 lexer->
addSkipWord(
"__attribute_pure__" );
00295 lexer->
addSkipWord(
"__attribute_malloc__" );
00296 lexer->
addSkipWord(
"__attribute_format_strfmon__" );
00297 lexer->
addSkipWord(
"__asm__",
SkipWordAndArguments );
00298 lexer->
addSkipWord(
"__devinit" );
00299 lexer->
addSkipWord(
"__devinit__" );
00300 lexer->
addSkipWord(
"__init" );
00301 lexer->
addSkipWord(
"__init__" );
00302 lexer->
addSkipWord(
"__signed" );
00303 lexer->
addSkipWord(
"__signed__" );
00304 lexer->
addSkipWord(
"__unsigned" );
00305 lexer->
addSkipWord(
"__unsigned__" );
00306 lexer->
addSkipWord(
"asmlinkage" );
00307 lexer->
addSkipWord(
"____cacheline_aligned" );
00308 lexer->
addSkipWord(
"__glibcpp_class_requires",
SkipWordAndArguments );
00309 lexer->
addSkipWord(
"__glibcpp_class2_requires",
SkipWordAndArguments );
00310 lexer->
addSkipWord(
"__glibcpp_class4_requires",
SkipWordAndArguments );
00311 lexer->
addSkipWord(
"__glibcpp_function_requires",
SkipWordAndArguments );
00312 lexer->
addSkipWord(
"restrict" );
00313
00314 lexer->
addSkipWord(
"__BEGIN_NAMESPACE_STD" );
00315 lexer->
addSkipWord(
"__END_NAMESPACE_STD" );
00316 lexer->
addSkipWord(
"__BEGIN_NAMESPACE_C99" );
00317 lexer->
addSkipWord(
"__END_NAMESPACE_C99" );
00318 lexer->
addSkipWord(
"__USING_NAMESPACE_STD",
SkipWordAndArguments );
00319
00320
00321 lexer->
addSkipWord(
"K_SYCOCATYPE",
SkipWordAndArguments );
00322 lexer->
addSkipWord(
"EXPORT_DOCKCLASS" );
00323 lexer->
addSkipWord(
"K_EXPORT_COMPONENT_FACTORY",
SkipWordAndArguments );
00324 lexer->
addSkipWord(
"K_SYCOCAFACTORY",
SkipWordAndArguments );
00325 lexer->
addSkipWord(
"KDE_DEPRECATED" );
00326
00327
00328 lexer->
addSkipWord(
"Q_OVERRIDE",
SkipWordAndArguments );
00329 lexer->
addSkipWord(
"Q_ENUMS",
SkipWordAndArguments );
00330 lexer->
addSkipWord(
"Q_PROPERTY",
SkipWordAndArguments );
00331 lexer->
addSkipWord(
"Q_CLASSINFO",
SkipWordAndArguments );
00332 lexer->
addSkipWord(
"Q_SETS",
SkipWordAndArguments );
00333 lexer->
addSkipWord(
"Q_UNUSED",
SkipWordAndArguments );
00334 lexer->
addSkipWord(
"Q_CREATE_INSTANCE",
SkipWordAndArguments );
00335 lexer->
addSkipWord(
"Q_DUMMY_COMPARISON_OPERATOR",
SkipWordAndArguments );
00336 lexer->
addSkipWord(
"ACTIVATE_SIGNAL_WITH_PARAM",
SkipWordAndArguments );
00337 lexer->
addSkipWord(
"Q_INLINE_TEMPLATES" );
00338 lexer->
addSkipWord(
"Q_TEMPLATE_EXTERN" );
00339 lexer->
addSkipWord(
"Q_TYPENAME" );
00340 lexer->
addSkipWord(
"Q_REFCOUNT" );
00341 lexer->
addSkipWord(
"Q_EXPLICIT" );
00342 lexer->
addSkipWord(
"QMAC_PASCAL" );
00343 lexer->
addSkipWord(
"QT_STATIC_CONST" );
00344 lexer->
addSkipWord(
"QT_STATIC_CONST_IMPL" );
00345 lexer->
addSkipWord(
"QT_WIN_PAINTER_MEMBERS" );
00346 lexer->
addSkipWord(
"QT_NC_MSGBOX" );
00347 lexer->
addSkipWord(
"Q_VARIANT_AS",
SkipWordAndArguments );
00348 lexer->
addSkipWord(
"CALLBACK_CALL_TYPE" );
00349
00350
00351 lexer->
addSkipWord(
"yyconst" );
00352 lexer->
addSkipWord(
"YY_RULE_SETUP" );
00353 lexer->
addSkipWord(
"YY_BREAK" );
00354 lexer->
addSkipWord(
"YY_RESTORE_YY_MORE_OFFSET" );
00355
00356
00357 lexer->
addSkipWord(
"G_BEGIN_DECLS" );
00358 lexer->
addSkipWord(
"G_END_DECLS" );
00359 lexer->
addSkipWord(
"G_GNUC_CONST" );
00360 lexer->
addSkipWord(
"G_CONST_RETURN" );
00361 lexer->
addSkipWord(
"GTKMAIN_C_VAR" );
00362 lexer->
addSkipWord(
"GTKVAR" );
00363 lexer->
addSkipWord(
"GDKVAR" );
00364 lexer->
addSkipWord(
"G_GNUC_PRINTF",
SkipWordAndArguments );
00365
00366
00367 lexer->
addSkipWord(
"WINAPI" );
00368 lexer->
addSkipWord(
"__stdcall" );
00369 lexer->
addSkipWord(
"__cdecl" );
00370 lexer->
addSkipWord(
"_cdecl" );
00371 lexer->
addSkipWord(
"CALLBACK" );
00372
00373
00374
addMacro(
Macro(
"__asm__",
"asm") );
00375
addMacro(
Macro(
"__inline",
"inline") );
00376
addMacro(
Macro(
"__inline__",
"inline") );
00377
addMacro(
Macro(
"__const",
"const") );
00378
addMacro(
Macro(
"__const__",
"const") );
00379
addMacro(
Macro(
"__volatile__",
"volatile") );
00380
addMacro(
Macro(
"__complex__",
"") );
00381 }
00382
00383 void Driver::setupParser(
Parser * parser )
00384 {
00385 Q_UNUSED( parser );
00386 }
00387
00388 void Driver::removeMacro(
const QString& macroName )
00389 {
00390
m_macros.remove( macroName );
00391 }
00392
00393 void Driver::addIncludePath(
const QString &path )
00394 {
00395
if( !path.stripWhiteSpace().isEmpty() )
00396
m_includePaths << path;
00397 }
00398
00399 QString Driver::findIncludeFile(
const Dependence& dep )
const
00400
{
00401
QString fileName = dep.first;
00402
00403
if( dep.second ==
Dep_Local ){
00404
QString path =
QFileInfo(
currentFileName() ).dirPath(
true );
00405 QFileInfo fileInfo( QFileInfo(path, fileName) );
00406
if ( fileInfo.exists() && fileInfo.isFile() )
00407
return fileInfo.absFilePath();
00408
00409 }
00410
00411
for ( QStringList::ConstIterator it =
m_includePaths.begin(); it !=
m_includePaths.end(); ++it ) {
00412
QFileInfo fileInfo( *it, fileName );
00413
if ( fileInfo.exists() && fileInfo.isFile() )
00414
return fileInfo.absFilePath();
00415 }
00416
00417
return QString::null;
00418 }
00419
00420 void Driver::setResolveDependencesEnabled(
bool enabled )
00421 {
00422
depresolv = enabled;
00423
if (
depresolv )
00424
setupPreProcessor();
00425 }
00426
00427 void Driver::setupPreProcessor()
00428 {
00429 }
00430
00431 void Driver::fileParsed(
const QString & fileName )
00432 {
00433 Q_UNUSED( fileName );
00434 }