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 }