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
00073 Driver::setupLexer( lex );
00074 }
00075
00076
00077
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
00092
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
00156
00157
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
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 }
This file is part of the documentation for KDevelop Version 3.1.2.