#include #include "driver.h" #include "ast.h" #include "lexer.h" #include "tag_creator.h" #include "setuphelper.h" #include #include #include #include #include #include #include #include #include #include class RppDriver: public Driver { public: RppDriver( Catalog* c ) : catalog( c ), m_generateTags( true ) { setup(); } virtual ~RppDriver() { TagCreator::destroyDocumentation(); } void setGenerateTags( bool b ) { m_generateTags = b; } void addDocDirectory( const TQString& dir ) { m_docDirectoryList.append( dir ); TagCreator::setDocumentationDirectories( m_docDirectoryList ); } void fileParsed( const ParsedFile& fileName ) { std::cout << ( m_generateTags ? "generate tags for " : "checking " ) << TQFile::encodeName( fileName.fileName() ).data() << std::endl; TQValueList l = problems( fileName.fileName() ); TQValueList::Iterator it = l.begin(); while ( it != l.end() ) { const Problem & p = *it; ++it; std::cout << TQFile::encodeName( fileName.fileName() ).data() << ":" << p.line() << ":" << p.column() << ": " << p.text().latin1() << std::endl; } takeTranslationUnit( fileName ); if ( m_generateTags ) { TagCreator w( fileName.fileName(), catalog ); w.parseTranslationUnit( fileName ); } if ( !isResolveDependencesEnabled() ) removeAllMacrosInFile( fileName.fileName() ); } void setupLexer( Lexer* lex ) { //lex->disableSkipWords(); Driver::setupLexer( lex ); } // setup the preprocessor // code provided by Reginald Stadlbauer void setup() { TQString tdedir = getenv( "TDEDIR" ); if ( !tdedir.isNull() ) addIncludePath( tdedir + "/include" ); TQString qtdir = getenv( "TQTDIR" ); if ( !qtdir.isNull() ) addIncludePath( qtdir + "/include" ); TQString qmakespec = getenv( "QMAKESPEC" ); if ( qmakespec.isNull() ) qmakespec = "linux-g++"; // #### implement other mkspecs and find a better way to find the // #### proper mkspec (althoigh this will be no fun :-) addIncludePath( qtdir + "/mkspecs/" + qmakespec ); if ( qmakespec == "linux-g++" ) { addIncludePath( "/include" ); addIncludePath( "/usr/include" ); addIncludePath( "/ust/local/include" ); bool ok; TQString gccLibPath = SetupHelper::getGccIncludePath(&ok); if (!ok) return; gccLibPath = gccLibPath.replace( TQRegExp( "[\r\n]" ), "" ); addIncludePath( gccLibPath ); addIncludePath( "/usr/include/g++-3" ); addIncludePath( "/usr/include/g++" ); TQStringList lines = SetupHelper::getGccMacros(&ok); if (!ok) return; for (TQStringList::ConstIterator it = lines.constBegin(); it != lines.constEnd(); ++it) { TQStringList lst = TQStringList::split( ' ', *it ); if ( lst.count() != 3 ) continue; addMacro( Macro( lst[1], lst[2] ) ); } addMacro( Macro( "__cplusplus", "1" ) ); TQString incl = getenv( "INCLUDE" ); TQStringList includePaths = TQStringList::split( ':', incl ); TQStringList::Iterator it = includePaths.begin(); while ( it != includePaths.end() ) { addIncludePath( ( *it ).stripWhiteSpace() ); ++it; } } } private: Catalog* catalog; bool m_generateTags; TQStringList m_docDirectoryList; }; void parseDirectory( Driver& driver, TQDir& dir, bool rec, bool parseAllFiles ) { TQStringList fileList; if ( parseAllFiles ) fileList = dir.entryList( TQDir::Files ); else fileList = dir.entryList( "*.h;*.H;*.hh;*.hxx;*.hpp;*.tlh" ); TQStringList::Iterator it = fileList.begin(); while ( it != fileList.end() ) { TQString fn = dir.path() + "/" + ( *it ); ++it; driver.parseFile( fn ); } if ( rec ) { TQStringList fileList = dir.entryList( TQDir::Dirs ); TQStringList::Iterator it = fileList.begin(); while ( it != fileList.end() ) { if ( ( *it ).startsWith( "." ) ) { ++it; continue; } TQDir subdir( dir.path() + "/" + ( *it ) ); ++it; parseDirectory( driver, subdir, rec, parseAllFiles ); } } } int main( int argc, char* argv[] ) { TDEStandardDirs stddir; if ( argc < 3 ) { std::cerr << "usage: r++ dbname directories..." << std::endl << std::endl; return -1; } bool rec = false; bool parseAllFiles = false; TQString datadir = stddir.localtdedir() + "/" + TDEStandardDirs::kde_default( "data" ); if ( ! TDEStandardDirs::makeDir( datadir + "/kdevcppsupport/pcs/" ) ) { kdWarning() << "*error* " << "could not create " << datadir + "/kdevcppsupport/pcs/" << endl << endl; return -1; } if ( !TQFile::exists( datadir + "/kdevcppsupport/pcs/" ) ) { kdWarning() << "*error* " << datadir + "/kdevcppsupport/pcs/" << " doesn't exists!!" << endl << endl; return -1; } TQString dbFileName = datadir + "/kdevcppsupport/pcs/" + argv[ 1 ] + ".db"; // std::cout << "dbFileName = " << dbFileName << std::endl; if ( TQFile::exists( dbFileName ) ) { kdWarning() << "*error* " << "database " << dbFileName << " already exists!" << endl << endl; return -1; } Catalog catalog; catalog.open( dbFileName ); catalog.addIndex( "kind" ); catalog.addIndex( "name" ); catalog.addIndex( "scope" ); catalog.addIndex( "fileName" ); RppDriver driver( &catalog ); driver.setResolveDependencesEnabled( true ); for ( int i = 2; i < argc; ++i ) { TQString s( argv[ i ] ); if ( s == "-r" || s == "--recursive" ) { rec = true; continue; } else if ( s == "-a" || s == "--all" ) { parseAllFiles = true; continue; } else if ( s == "-f" || s == "--fast" ) { driver.setResolveDependencesEnabled( false ); continue; } else if ( s == "-c" || s == "--check-only" ) { driver.setGenerateTags( false ); continue; } else if ( s.startsWith( "-d" ) ) { driver.addDocDirectory( s.mid( 2 ) ); continue; } TQDir dir( s ); if ( !dir.exists() ) { kdWarning() << "*error* " << "the directory " << dir.path() << " doesn't exists!" << endl << endl; continue; } parseDirectory( driver, dir, rec, parseAllFiles ); } return 0; }