KDevelop API Documentation

main.cpp

Go to the documentation of this file.
00001 
00002 #include <iostream>
00003 
00004 #include "driver.h"
00005 #include "ast.h"
00006 #include "lexer.h"
00007 #include "tag_creator.h"
00008 
00009 #include <qfileinfo.h>
00010 #include <qfile.h>
00011 #include <qtextstream.h>
00012 #include <qregexp.h>
00013 #include <qprocess.h>
00014 
00015 #include <catalog.h>
00016 #include <kdebug.h>
00017 #include <kstandarddirs.h>
00018 
00019 #include <stdlib.h>
00020 #include <unistd.h>
00021 
00022 class RppDriver: public Driver
00023 {
00024 public:
00025     RppDriver( Catalog* c )
00026         : catalog( c ), m_generateTags( true )
00027     {
00028         setup();
00029     }
00030 
00031     virtual ~RppDriver()
00032     {
00033         TagCreator::destroyDocumentation();
00034     }
00035 
00036     void setGenerateTags( bool b )
00037     {
00038         m_generateTags = b;
00039     }
00040 
00041     void addDocDirectory( const QString& dir )
00042     {
00043         m_docDirectoryList.append( dir );
00044         TagCreator::setDocumentationDirectories( m_docDirectoryList );
00045     }
00046 
00047     void fileParsed( const QString& fileName )
00048     {
00049         std::cout << (m_generateTags ? "generate tags for " : "checking ") << QFile::encodeName( fileName ).data() << std::endl;
00050 
00051         QValueList<Problem> l = problems( fileName );
00052         QValueList<Problem>::Iterator it = l.begin();
00053         while( it != l.end() ){
00054             const Problem& p = *it;
00055             ++it;
00056             std::cout << QFile::encodeName( fileName ).data() << ":" << p.line() << ":" << p.column() << ": " << p.text().latin1() << std::endl;
00057         }
00058 
00059         TranslationUnitAST::Node ast = takeTranslationUnit( fileName );
00060 
00061         if( m_generateTags ){
00062             TagCreator w( fileName, catalog );
00063             w.parseTranslationUnit( ast.get() );
00064         }
00065 
00066     if( !isResolveDependencesEnabled() )
00067         removeAllMacrosInFile( fileName );
00068     }
00069 
00070     void setupLexer( Lexer* lex )
00071     {
00072         //lex->disableSkipWords();
00073         Driver::setupLexer( lex );
00074     }
00075 
00076     // setup the preprocessor
00077     // code provided by Reginald Stadlbauer <reggie@trolltech.com>
00078     void setup()
00079     {
00080     QString kdedir = getenv( "KDEDIR" );
00081     if( !kdedir.isNull() )
00082         addIncludePath( kdedir + "/include" );
00083 
00084     QString qtdir = getenv( "QTDIR" );
00085     if( !qtdir.isNull() )
00086         addIncludePath( qtdir + "/include" );
00087 
00088     QString qmakespec = getenv( "QMAKESPEC" );
00089     if ( qmakespec.isNull() )
00090         qmakespec = "linux-g++";
00091     // #### implement other mkspecs and find a better way to find the
00092     // #### proper mkspec (althoigh this will be no fun :-)
00093 
00094     addIncludePath( qtdir + "/mkspecs/" + qmakespec );
00095 
00096     if ( qmakespec == "linux-g++" ) {
00097         addIncludePath( "/include" );
00098         addIncludePath( "/usr/include" );
00099         addIncludePath( "/ust/local/include" );
00100         QProcess proc;
00101         proc.addArgument( "gcc" );
00102         proc.addArgument( "-print-file-name=include" );
00103         if ( !proc.start() ) {
00104         std::cerr << "*error* Couldn't start gcc" << std::endl;
00105         return;
00106         }
00107         while ( proc.isRunning() )
00108         usleep( 1 );
00109 
00110             QString gccLibPath = proc.readStdout();
00111             gccLibPath = gccLibPath.replace( QRegExp("[\r\n]"), "" );
00112         addIncludePath( gccLibPath );
00113         addIncludePath( "/usr/include/g++-3" );
00114         addIncludePath( "/usr/include/g++" );
00115         proc.clearArguments();
00116         proc.addArgument( "gcc" );
00117         proc.addArgument( "-E" );
00118         proc.addArgument( "-dM" );
00119         proc.addArgument( "-ansi" );
00120         proc.addArgument( "-" );
00121         if ( !proc.start() ) {
00122         std::cerr << "*error* Couldn't start gcc" << std::endl;
00123         return;
00124         }
00125         while ( !proc.isRunning() )
00126         usleep( 1 );
00127         proc.closeStdin();
00128         while ( proc.isRunning() )
00129         usleep( 1 );
00130         while ( proc.canReadLineStdout() ) {
00131         QString l = proc.readLineStdout();
00132         QStringList lst = QStringList::split( ' ', l );
00133         if ( lst.count() != 3 )
00134             continue;
00135         addMacro( Macro( lst[1], lst[2] ) );
00136         }
00137         addMacro( Macro( "__cplusplus", "1" ) );
00138 
00139         QString incl = getenv( "INCLUDE" );
00140         QStringList includePaths = QStringList::split( ':', incl );
00141         QStringList::Iterator it = includePaths.begin();
00142         while( it != includePaths.end() ){
00143         addIncludePath( (*it).stripWhiteSpace() );
00144         ++it;
00145         }
00146 
00147     } else if ( qmakespec == "win32-borland" ) {
00148         QString incl = getenv( "INCLUDE" );
00149         QStringList includePaths = QStringList::split( ';', incl );
00150         QStringList::Iterator it = includePaths.begin();
00151         while( it != includePaths.end() ){
00152         addIncludePath( (*it).stripWhiteSpace() );
00153         ++it;
00154         }
00155         // ### I am sure there are more standard include paths on
00156         // ### windows. I will fix that soon
00157         // ### Also do the compiler specific defines on windows
00158     }
00159     }
00160 
00161 private:
00162     Catalog* catalog;
00163     bool m_generateTags;
00164     QStringList m_docDirectoryList;
00165 };
00166 
00167 void parseDirectory( Driver& driver, QDir& dir, bool rec, bool parseAllFiles )
00168 {
00169     {
00170     QStringList fileList;
00171     if( parseAllFiles )
00172         fileList = dir.entryList( QDir::Files );
00173     else
00174         fileList = dir.entryList( "*.h;*.H;*.hh;*.hxx;*.hpp;*.tlh" );
00175 
00176     QStringList::Iterator it = fileList.begin();
00177     while( it != fileList.end() ){
00178         QString fn = dir.path() + "/" + (*it);
00179         ++it;
00180 
00181         driver.parseFile( fn );
00182     }
00183     }
00184 
00185     if( rec ) {
00186     QStringList fileList = dir.entryList( QDir::Dirs );
00187     QStringList::Iterator it = fileList.begin();
00188     while( it != fileList.end() ){
00189         if( (*it).startsWith(".") ){
00190         ++it;
00191         continue;
00192         }
00193 
00194         QDir subdir( dir.path() + "/" + (*it) );
00195         ++it;
00196 
00197         parseDirectory( driver, subdir, rec, parseAllFiles );
00198     }
00199     }
00200 }
00201 
00202 int main( int argc, char* argv[] )
00203 {
00204     KStandardDirs stddir;
00205 
00206     if( argc < 3 ){
00207         std::cerr << "usage: r++ dbname directories..." << std::endl << std::endl;
00208         return -1;
00209     }
00210 
00211     bool rec = false;
00212     bool parseAllFiles = false;
00213 
00214     QString datadir = stddir.localkdedir() + "/" + KStandardDirs::kde_default( "data" );
00215     if (! KStandardDirs::makeDir(datadir + "/kdevcppsupport/pcs/")){
00216         kdWarning() << "*error* " << "could not create " << datadir + "/kdevcppsupport/pcs/" << endl << endl;
00217         return -1;
00218     }
00219 
00220 
00221     if( !QFile::exists(datadir + "/kdevcppsupport/pcs/") ){
00222         kdWarning() << "*error* " << datadir + "/kdevcppsupport/pcs/" << " doesn't exists!!" << endl << endl;
00223         return -1;
00224     }
00225 
00226     QString dbFileName = datadir + "/kdevcppsupport/pcs/" + argv[ 1 ] + ".db";
00227     // std::cout << "dbFileName = " << dbFileName << std::endl;
00228     if( QFile::exists(dbFileName) ){
00229         kdWarning() << "*error* " << "database " << dbFileName << " already exists!" << endl << endl;
00230         return -1;
00231     }
00232 
00233 
00234     Catalog catalog;
00235     catalog.open( dbFileName );
00236     catalog.addIndex( "kind" );
00237     catalog.addIndex( "name" );
00238     catalog.addIndex( "scope" );
00239     catalog.addIndex( "fileName" );
00240 
00241     RppDriver driver( &catalog );
00242     driver.setResolveDependencesEnabled( true );
00243 
00244     for( int i=2; i<argc; ++i ){
00245         QString s( argv[i] );
00246         if( s == "-r" || s == "--recursive" ){
00247            rec = true;
00248            continue;
00249        } else if( s == "-a" || s == "--all" ){
00250        parseAllFiles = true;
00251        continue;
00252        } else if( s == "-f" || s == "--fast" ){
00253        driver.setResolveDependencesEnabled( false );
00254        continue;
00255        } else if( s == "-c" || s == "--check-only" ){
00256            driver.setGenerateTags( false );
00257        continue;
00258        }  else if ( s.startsWith("-d") ){
00259            driver.addDocDirectory( s.mid(2) );
00260            continue;
00261        }
00262 
00263        QDir dir( s );
00264        if( !dir.exists() ){
00265            kdWarning() << "*error* " << "the directory " << dir.path() << " doesn't exists!" << endl << endl;
00266            continue;
00267        }
00268 
00269        parseDirectory( driver, dir, rec, parseAllFiles );
00270     }
00271 
00272     return 0;
00273 }
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:42 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003