コード例 #1
0
ファイル: defgen.cpp プロジェクト: vscosta/doxygen-yap
void generateDEFForMember(MemberDef *md,
    FTextStream &t,
    Definition *def,
    const char* Prefix)
{
  QCString memPrefix;

  // + declaration
  // - reimplements
  // - reimplementedBy
  // - exceptions
  // - const/volatile specifiers
  // - examples
  // + source definition
  // - source references
  // - source referenced by
  // - include code 

  if (md->memberType()==MemberType_EnumValue) return;

  QCString scopeName;
  if (md->getClassDef()) 
    scopeName=md->getClassDef()->name();
  else if (md->getNamespaceDef()) 
    scopeName=md->getNamespaceDef()->name();

  t << "    " << Prefix << "-member = {" << endl;
  memPrefix = "      ";
  memPrefix.append( Prefix );
  memPrefix.append( "-mem-" );

  QCString memType;
  bool isFunc=FALSE;
  switch (md->memberType())
  {
    case MemberType_Define:      memType="define";    break;
    case MemberType_EnumValue:   ASSERT(0);           break;
    case MemberType_Property:    memType="property";  break;
    case MemberType_Event:       memType="event";     break;
    case MemberType_Variable:    memType="variable";  break;
    case MemberType_Typedef:     memType="typedef";   break;
    case MemberType_Enumeration: memType="enum";      break;
    case MemberType_Interface:   memType="interface"; break;
    case MemberType_Service:     memType="service";   break;
    case MemberType_Clause:      memType="clause";   break;
    case MemberType_Function:    memType="function";  isFunc=TRUE; break;
    case MemberType_Signal:      memType="signal";    isFunc=TRUE; break;
    case MemberType_Friend:      memType="friend";    isFunc=TRUE; break;
    case MemberType_DCOP:        memType="dcop";      isFunc=TRUE; break;
    case MemberType_Slot:        memType="slot";      isFunc=TRUE; break;
  }

  t << memPrefix << "kind = '" << memType << "';" << endl;
  t << memPrefix << "id   = '"
    << md->getOutputFileBase() << "_1" << md->anchor()
    << "';" << endl;

  t << memPrefix << "virt = ";
  switch (md->virtualness())
  {
    case Normal:  t << "normal;"       << endl; break;
    case Virtual: t << "virtual;"      << endl; break;
    case Pure:    t << "pure-virtual;" << endl; break;
    default: ASSERT(0);
  }

  t << memPrefix << "prot = ";
  switch(md->protection())
  {
    case Public:    t << "public;"    << endl; break;
    case Protected: t << "protected;" << endl; break;
    case Private:   t << "private;"   << endl; break;
    case Package:   t << "package;"   << endl; break;
  }

  if (md->memberType()!=MemberType_Define &&
      md->memberType()!=MemberType_Enumeration
     )
  {
    QCString typeStr = replaceAnonymousScopes(md->typeString());
    t << memPrefix << "type = <<_EnD_oF_dEf_TeXt_" << endl << typeStr << endl
      << "_EnD_oF_dEf_TeXt_;" << endl;
  }

  t << memPrefix << "name = '" << md->name() << "';" << endl;

  if (isFunc) //function
  {
    ArgumentList *declAl = new ArgumentList;
    ArgumentList *defAl = md->argumentList();
    stringToArgumentList(md->argsString(),declAl);
    QCString fcnPrefix = "  " + memPrefix + "param-";

    if (declAl->count()>0)
    {
      ArgumentListIterator declAli(*declAl);
      ArgumentListIterator defAli(*defAl);
      Argument *a;
      for (declAli.toFirst();(a=declAli.current());++declAli)
      {
        Argument *defArg = defAli.current();
        t << memPrefix << "param = {" << endl;
        if (!a->attrib.isEmpty())
        {
          t << fcnPrefix << "attributes = ";
          writeDEFString(t,a->attrib);
          t << ';' << endl;
        }
        if (!a->type.isEmpty())
        {
          t << fcnPrefix << "type = <<_EnD_oF_dEf_TeXt_" << endl
            << a->type << endl << "_EnD_oF_dEf_TeXt_;" << endl;
        }
        if (!a->name.isEmpty())
        {
          t << fcnPrefix << "declname = ";
          writeDEFString(t,a->name);
          t << ';' << endl;
        }
        if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
        {
          t << fcnPrefix << "defname = ";
          writeDEFString(t,defArg->name);
          t << ';' << endl;
        }
        if (!a->array.isEmpty())
        {
          t << fcnPrefix << "array = ";
          writeDEFString(t,a->array); 
          t << ';' << endl;
        }
        if (!a->defval.isEmpty())
        {
          t << fcnPrefix << "defval = <<_EnD_oF_dEf_TeXt_" << endl
            << a->defval << endl << "_EnD_oF_dEf_TeXt_;" << endl;
        }
        if (defArg) ++defAli;
        t << "      }; /*" << fcnPrefix << "-param */" << endl;
      }
    }
    delete declAl;
  }
  else if (  md->memberType()==MemberType_Define
      && md->argsString()!=0)
  {
    ArgumentListIterator ali(*md->argumentList());
    Argument *a;
    QCString defPrefix = "  " + memPrefix + "def-";

    for (ali.toFirst();(a=ali.current());++ali)
    {
      t << memPrefix << "param  = {" << endl;
      t << defPrefix << "name = '" << a->type << "';" << endl;
      t << "      }; /*" << defPrefix << "-param */" << endl;
    }
  }

  if (!md->initializer().isEmpty())
  {
    t << memPrefix << "initializer = <<_EnD_oF_dEf_TeXt_" << endl
      << md->initializer() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
  }
  // TODO: exceptions, const volatile
  if (md->memberType()==MemberType_Enumeration) // enum
  {
    MemberList *enumList = md->enumFieldList();
    if (enumList!=0)
    {
      MemberListIterator emli(*enumList);
      MemberDef *emd;
      for (emli.toFirst();(emd=emli.current());++emli)
      {
        t << memPrefix << "enum = { enum-name = " << emd->name() << ';';
        if (!emd->initializer().isEmpty())
        {
          t << " enum-value = ";
          writeDEFString(t,emd->initializer());
          t << ';';
        }
        t << " };" << endl;
      }
    }
  }

  t << memPrefix << "desc-file = '" << md->getDefFileName() << "';" << endl;
  t << memPrefix << "desc-line = '" << md->getDefLine()     << "';" << endl;
  t << memPrefix << "briefdesc =    <<_EnD_oF_dEf_TeXt_"    << endl
    << md->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
  t << memPrefix << "documentation = <<_EnD_oF_dEf_TeXt_"   << endl
    << md->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;

  //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers());

  MemberSDict *mdict = md->getReferencesMembers();
  if (mdict)
  {
    MemberSDict::Iterator mdi(*mdict);
    MemberDef *rmd;
    QCString refPrefix = "  " + memPrefix + "ref-";

    for (mdi.toFirst();(rmd=mdi.current());++mdi)
    {
      if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
      {
        t << memPrefix << "referenceto = {" << endl;
        t << refPrefix << "id = '"
          << rmd->getBodyDef()->getOutputFileBase()
          << "_1"   // encoded `:' character (see util.cpp:convertNameToFile)
          << rmd->anchor() << "';" << endl;

        t << refPrefix << "line = '"
          << rmd->getStartBodyLine() << "';" << endl;

        QCString scope = rmd->getScopeString();
        QCString name = rmd->name();
        if (!scope.isEmpty() && scope!=def->name())
        {
          name.prepend(scope+"::");
        }

        t << refPrefix << "name = ";
        writeDEFString(t,name);
        t << ';' << endl << "    };" << endl;
      }
    } /* for (mdi.toFirst...) */
  }
  mdict = md->getReferencedByMembers();
  if (mdict)
  {
    MemberSDict::Iterator mdi(*mdict);
    MemberDef *rmd;
    QCString refPrefix = "  " + memPrefix + "ref-";

    for (mdi.toFirst();(rmd=mdi.current());++mdi)
    {
      if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
      {
        t << memPrefix << "referenceby = {" << endl;
        t << refPrefix << "id = '"
          << rmd->getBodyDef()->getOutputFileBase()
          << "_1"   // encoded `:' character (see util.cpp:convertNameToFile)
          << rmd->anchor() << "';" << endl;

        t << refPrefix << "line = '"
          << rmd->getStartBodyLine() << "';" << endl;

        QCString scope = rmd->getScopeString();
        QCString name = rmd->name();
        if (!scope.isEmpty() && scope!=def->name())
        {
          name.prepend(scope+"::");
        }

        t << refPrefix << "name = ";
        writeDEFString(t,name);
        t << ';' << endl << "    };" << endl;
      }
    } /* for (mdi.toFirst...) */
  }

  t << "    }; /* " << Prefix << "-member */" << endl;
}
コード例 #2
0
extern "C" KDE_EXPORT int kdemain( int argc, char **argv )
{
  // here we go, construct the Kate version
  QString kateVersion = KateApp::kateVersion();

  KAboutData aboutData ("kate", I18N_NOOP("Kate"), kateVersion.latin1(),
                        I18N_NOOP( "Kate - Advanced Text Editor" ), KAboutData::License_LGPL_V2,
                        I18N_NOOP( "(c) 2000-2005 The Kate Authors" ), 0, "http://kate.kde.org");

  aboutData.addAuthor ("Christoph Cullmann", I18N_NOOP("Maintainer"), "*****@*****.**", "http://www.babylon2k.de");
  aboutData.addAuthor ("Anders Lund", I18N_NOOP("Core Developer"), "*****@*****.**", "http://www.alweb.dk");
  aboutData.addAuthor ("Joseph Wenninger", I18N_NOOP("Core Developer"), "*****@*****.**","http://stud3.tuwien.ac.at/~e9925371");
  aboutData.addAuthor ("Hamish Rodda",I18N_NOOP("Core Developer"), "*****@*****.**");
  aboutData.addAuthor ("Waldo Bastian", I18N_NOOP( "The cool buffersystem" ), "*****@*****.**" );
  aboutData.addAuthor ("Charles Samuels", I18N_NOOP("The Editing Commands"), "*****@*****.**");
  aboutData.addAuthor ("Matt Newell", I18N_NOOP("Testing, ..."), "*****@*****.**");
  aboutData.addAuthor ("Michael Bartl", I18N_NOOP("Former Core Developer"), "*****@*****.**");
  aboutData.addAuthor ("Michael McCallum", I18N_NOOP("Core Developer"), "*****@*****.**");
  aboutData.addAuthor ("Jochen Wilhemly", I18N_NOOP( "KWrite Author" ), "*****@*****.**" );
  aboutData.addAuthor ("Michael Koch",I18N_NOOP("KWrite port to KParts"), "*****@*****.**");
  aboutData.addAuthor ("Christian Gebauer", 0, "*****@*****.**" );
  aboutData.addAuthor ("Simon Hausmann", 0, "*****@*****.**" );
  aboutData.addAuthor ("Glen Parker",I18N_NOOP("KWrite Undo History, Kspell integration"), "*****@*****.**");
  aboutData.addAuthor ("Scott Manson",I18N_NOOP("KWrite XML Syntax highlighting support"), "*****@*****.**");
  aboutData.addAuthor ("John Firebaugh",I18N_NOOP("Patches and more"), "*****@*****.**");
  aboutData.addAuthor ("Dominik Haumann", I18N_NOOP("Developer & Highlight wizard"), "*****@*****.**");

  aboutData.addCredit ("Matteo Merli",I18N_NOOP("Highlighting for RPM Spec-Files, Perl, Diff and more"), "*****@*****.**");
  aboutData.addCredit ("Rocky Scaletta",I18N_NOOP("Highlighting for VHDL"), "*****@*****.**");
  aboutData.addCredit ("Yury Lebedev",I18N_NOOP("Highlighting for SQL"),"");
  aboutData.addCredit ("Chris Ross",I18N_NOOP("Highlighting for Ferite"),"");
  aboutData.addCredit ("Nick Roux",I18N_NOOP("Highlighting for ILERPG"),"");
  aboutData.addCredit ("Carsten Niehaus", I18N_NOOP("Highlighting for LaTeX"),"");
  aboutData.addCredit ("Per Wigren", I18N_NOOP("Highlighting for Makefiles, Python"),"");
  aboutData.addCredit ("Jan Fritz", I18N_NOOP("Highlighting for Python"),"");
  aboutData.addCredit ("Daniel Naber","","");
  aboutData.addCredit ("Roland Pabel",I18N_NOOP("Highlighting for Scheme"),"");
  aboutData.addCredit ("Cristi Dumitrescu",I18N_NOOP("PHP Keyword/Datatype list"),"");
  aboutData.addCredit ("Carsten Pfeiffer", I18N_NOOP("Very nice help"), "");
  aboutData.addCredit (I18N_NOOP("All people who have contributed and I have forgotten to mention"),"","");

  aboutData.setTranslator(I18N_NOOP2("NAME OF TRANSLATORS","Your names"), I18N_NOOP2("EMAIL OF TRANSLATORS","Your emails"));

  // command line args init and co
  KCmdLineArgs::init (argc, argv, &aboutData);
  KCmdLineArgs::addCmdLineOptions (options);
  KCmdLineArgs::addTempFileOption();
  KateApp::addCmdLineOptions ();

  // get our command line args ;)
  KCmdLineArgs* args = KCmdLineArgs::parsedArgs();

  // now, first try to contact running kate instance if needed
  if ( args->isSet("use") || (::getenv("KATE_PID")!=0) )
  {
    DCOPClient client;
    client.attach ();

    // get all attached clients ;)
    QCStringList allClients = client.registeredApplications();

    // search for a kate app client, use the first found
    QCString kateApp;

    if ( args->isSet("start") )
    {
      for (unsigned int i=0; i < allClients.count(); i++)
      {
        if (allClients[i] == "kate" || allClients[i].left(5) == "kate-")
        {
          DCOPRef ref( allClients[i], "KateApplication" );
          QString s = ref.call( "session" );
          if ( QString(args->getOption("start")) == s )
          {
            kateApp = allClients[i];
            break;
          }
        }
      }
    }
    else if ( (args->isSet("pid")) || (::getenv("KATE_PID") !=0 ) )
    {
      QCString tryApp;
      if ( args->isSet("pid") )
        tryApp = args->getOption("pid");
      else
        tryApp = ::getenv("KATE_PID");

      if ( client.isApplicationRegistered( tryApp.prepend("kate-") ) )
        kateApp = tryApp;
    }
    else
    {
      for (unsigned int i=0; i < allClients.count(); ++i)
      {
        if (allClients[i] == "kate" || allClients[i].left(5) == "kate-")
        {
          kateApp = allClients[i];
          break;
        }
      }
    }

    // found a matching kate client ;)
    if (!kateApp.isEmpty())
    {
      kdDebug () << "kate app: " << kateApp << endl;
      // make kdeinit happy
      client.registerAs( "kate" );

      DCOPRef kRef (kateApp, "KateApplication");

      if (args->isSet ("start"))
        kRef.call( "activateSession", QString (args->getOption("start")) );

      QString enc = args->isSet("encoding") ? args->getOption("encoding") : QCString("");

      bool tempfileSet = KCmdLineArgs::isTempFileSet();

      for (int z=0; z<args->count(); z++)
        kRef.call( "openURL", args->url(z), enc, tempfileSet );

      if( args->isSet( "stdin" ) )
      {
        QTextIStream input(stdin);

        // set chosen codec
        QTextCodec *codec = args->isSet("encoding") ? QTextCodec::codecForName(args->getOption("encoding")) : 0;

        if (codec)
          input.setCodec (codec);

        QString line;
        QString text;

        do
        {
          line = input.readLine();
          text.append( line + "\n" );
        } while( !line.isNull() );

        kRef.call( "openInput", text );
      }

      int line = 0;
      int column = 0;
      bool nav = false;

      if (args->isSet ("line"))
      {
        line = args->getOption ("line").toInt();
        nav = true;
      }

      if (args->isSet ("column"))
      {
        column = args->getOption ("column").toInt();
        nav = true;
      }

      if (nav)
         kRef.call( "setCursor", line, column );

      // since the user tried to open a document, let us assume [s]he
      // wants to see that document.
      // ### what to do about the infamous focus stealing prevention?
      uint mwn = kRef.call("activeMainWindowNumber");
      QCString smwn;
      DCOPRef wRef( kateApp, QCString( "__KateMainWindow#") + smwn.setNum(mwn) );
      if ( wRef.call("minimized") )
      {
        if ( wRef.call( "maximized" ) )
          wRef.call( "maximize" );
        else
          wRef.call("restore");
      }
      wRef.call( "raise" );

      // stop startup notification
      KStartupInfo::appStarted(  );

      return 0;
    }
  }

  // construct the real kate app object ;)
  KateApp app (args);

  // app execution should already end :)
  if (app.shouldExit())
  {
    return 0;
  }

  // execute ourself ;)
  return app.exec();
}
コード例 #3
0
ファイル: fetchtr.cpp プロジェクト: opieproject/opie
static void parse( MetaTranslator *tor, const char *initialContext,
		   const char *defaultContext )
{
    QMap<QCString, QCString> qualifiedContexts;
    QStringList namespaces;
    QCString context;
    QCString text;
    QCString com;
    QCString functionContext = initialContext;
    QCString prefix;
    bool utf8 = FALSE;
    bool missing_Q_OBJECT = FALSE;

    yyTok = getToken();
    while ( yyTok != Tok_Eof ) {
	switch ( yyTok ) {
	case Tok_class:
	    /*
	      Partial support for inlined functions.
	    */
	    yyTok = getToken();
	    if ( yyBraceDepth == (int) namespaces.count() &&
		 yyParenDepth == 0 ) {
		do {
		    /*
		      This code should execute only once, but we play
		      safe with impure definitions such as
		      'class Q_EXPORT QMessageBox', in which case
		      'QMessageBox' is the class name, not 'Q_EXPORT'.
		    */
		    functionContext = yyIdent;
		    yyTok = getToken();
		} while ( yyTok == Tok_Ident );

		while ( yyTok == Tok_Gulbrandsen ) {
		    yyTok = getToken();
		    functionContext += "::";
		    functionContext += yyIdent;
		    yyTok = getToken();
		}

		if ( yyTok == Tok_Colon ) {
		    missing_Q_OBJECT = TRUE;
		} else {
		    functionContext = defaultContext;
		}
	    }
	    break;
	case Tok_namespace:
	    yyTok = getToken();
	    if ( yyTok == Tok_Ident ) {
		QCString ns = yyIdent;
		yyTok = getToken();
		if ( yyTok == Tok_LeftBrace &&
		     yyBraceDepth == (int) namespaces.count() + 1 )
		    namespaces.append( QString(ns) );
	    }
	    break;
	case Tok_tr:
	case Tok_trUtf8:
	    utf8 = ( yyTok == Tok_trUtf8 );
	    yyTok = getToken();
	    if ( match(Tok_LeftParen) && matchString(&text) ) {
		com = "";
		if ( match(Tok_RightParen) || (match(Tok_Comma) &&
			matchString(&com) && match(Tok_RightParen)) ) {
		    if ( prefix.isNull() ) {
			context = functionContext;
			if ( !namespaces.isEmpty() )
			    context.prepend( (namespaces.join(QString("::")) +
					      QString("::")).latin1() );
		    } else {
			context = prefix;
		    }
		    prefix = (const char *) 0;

		    if ( qualifiedContexts.contains(context) )
			context = qualifiedContexts[context];
		    tor->insert( MetaTranslatorMessage(context, text, com,
						       QString::null, utf8) );

		    if ( lacks_Q_OBJECT.contains(context) ) {
			qWarning( "%s:%d: Class '%s' lacks Q_OBJECT macro",
				  (const char *) yyFileName, yyLineNo,
				  (const char *) context );
			lacks_Q_OBJECT.remove( context );
		    } else {
			needs_Q_OBJECT.insert( context, 0 );
		    }
		}
	    }
	    break;
	case Tok_translate:
	    utf8 = FALSE;
	    yyTok = getToken();
	    if ( match(Tok_LeftParen) &&
		 matchString(&context) &&
		 match(Tok_Comma) &&
		 matchString(&text) ) {
		com = "";
		if ( match(Tok_RightParen) ||
		     (match(Tok_Comma) &&
		      matchString(&com) &&
		      (match(Tok_RightParen) ||
		       match(Tok_Comma) &&
		       matchEncoding(&utf8) &&
		       match(Tok_RightParen))) )
		    tor->insert( MetaTranslatorMessage(context, text, com,
						       QString::null, utf8) );
	    }
	    break;
	case Tok_Q_OBJECT:
	    missing_Q_OBJECT = FALSE;
	    yyTok = getToken();
	    break;
	case Tok_Ident:
	    if ( !prefix.isNull() )
		prefix += "::";
	    prefix += yyIdent;
	    yyTok = getToken();
	    if ( yyTok != Tok_Gulbrandsen )
		prefix = (const char *) 0;
	    break;
	case Tok_Comment:
	    com = yyComment;
	    com = com.simplifyWhiteSpace();
	    if ( com.left(sizeof(MagicComment) - 1) == MagicComment ) {
		com.remove( 0, sizeof(MagicComment) - 1 );
		int k = com.find( ' ' );
		if ( k == -1 ) {
		    context = com;
		} else {
		    context = com.left( k );
		    com.remove( 0, k + 1 );
		    tor->insert( MetaTranslatorMessage(context, "", com,
						       QString::null, FALSE) );
		}

		/*
		  Provide a backdoor for people using "using
		  namespace". See the manual for details.
		*/
		k = 0;
		while ( (k = context.find("::", k)) != -1 ) {
		    qualifiedContexts.insert( context.mid(k + 2), context );
		    k++;
		}
	    }
	    yyTok = getToken();
	    break;
	case Tok_Arrow:
	    yyTok = getToken();
	    if ( yyTok == Tok_tr || yyTok == Tok_trUtf8 )
		qWarning( "%s:%d: Cannot invoke tr() like this",
			  (const char *) yyFileName, yyLineNo );
	    break;
	case Tok_Gulbrandsen:
	    // at top level?
	    if ( yyBraceDepth == (int) namespaces.count() && yyParenDepth == 0 )
		functionContext = prefix;
	    yyTok = getToken();
	    break;
	case Tok_RightBrace:
	case Tok_Semicolon:
	    if ( yyBraceDepth >= 0 &&
		 yyBraceDepth + 1 == (int) namespaces.count() )
		namespaces.remove( namespaces.fromLast() );
	    if ( yyBraceDepth == (int) namespaces.count() ) {
		if ( missing_Q_OBJECT ) {
		    if ( needs_Q_OBJECT.contains(functionContext) ) {
			qWarning( "%s:%d: Class '%s' lacks Q_OBJECT macro",
				  (const char *) yyFileName, yyLineNo,
				  (const char *) functionContext );
		    } else {
			lacks_Q_OBJECT.insert( functionContext, 0 );
		    }
		}
		functionContext = defaultContext;
		missing_Q_OBJECT = FALSE;
	    }
	    yyTok = getToken();
	    break;
	default:
	    yyTok = getToken();
	}
    }

    if ( yyBraceDepth != 0 )
	fprintf( stderr,
		 "%s:%d: Unbalanced braces in C++ code (or abuse of the C++"
		  " preprocessor)\n",
		  (const char *)yyFileName, yyBraceLineNo );
    else if ( yyParenDepth != 0 )
	fprintf( stderr,
		 "%s:%d: Unbalanced parentheses in C++ code (or abuse of the C++"
		 " preprocessor)\n",
		 (const char *)yyFileName, yyParenLineNo );
}
コード例 #4
0
void
CollectionScanner::readDir( const QString& dir, QStringList& entries )
{
    static DCOPRef dcopRef( "amarok", "collection" );

    // linux specific, but this fits the 90% rule
    if( dir.startsWith( "/dev" ) || dir.startsWith( "/sys" ) || dir.startsWith( "/proc" ) )
        return;

    const QCString dir8Bit = QFile::encodeName( dir );
    DIR *d = opendir( dir8Bit );
    if( d == NULL ) {
        warning() << "Skipping, " << strerror(errno) << ": " << dir << endl;
        return;
    }
#ifdef USE_SOLARIS
    int dfd = d->d_fd;
#else
    int dfd = dirfd(d);
#endif
    if (dfd == -1) {
	warning() << "Skipping, unable to obtain file descriptor: " << dir << endl;
	closedir(d);
	return;
    }

    struct stat statBuf;
    struct stat statBuf_symlink;
    fstat( dfd, &statBuf );

    struct direntry de;
    memset(&de, 0, sizeof(struct direntry));
    de.dev = statBuf.st_dev;
    de.ino = statBuf.st_ino;

    int f = -1;
#if __GNUC__ < 4
    for( unsigned int i = 0; i < m_processedDirs.size(); ++i )
        if( memcmp( &m_processedDirs[i], &de, sizeof( direntry ) ) == 0 ) {
            f = i; break;
        }
#else
    f = m_processedDirs.find( de );
#endif

    if ( ! S_ISDIR( statBuf.st_mode ) || f != -1 ) {
        debug() << "Skipping, already scanned: " << dir << endl;
        closedir(d);
        return;
    }

    AttributeMap attributes;
    attributes["path"] = dir;
    writeElement( "folder", attributes );

    m_processedDirs.resize( m_processedDirs.size() + 1 );
    m_processedDirs[m_processedDirs.size() - 1] = de;

    for( dirent *ent; ( ent = readdir( d ) ); ) {
        QCString entry (ent->d_name);
        QCString entryname (ent->d_name);

        if ( entry == "." || entry == ".." )
            continue;

        entry.prepend( dir8Bit );

        if ( stat( entry, &statBuf ) != 0 )
            continue;
        if ( lstat( entry, &statBuf_symlink ) != 0 )
            continue;

        // loop protection
        if ( ! ( S_ISDIR( statBuf.st_mode ) || S_ISREG( statBuf.st_mode ) ) )
            continue;

        if ( S_ISDIR( statBuf.st_mode ) && m_recursively && entry.length() && entryname[0] != '.' )
        {
            if ( S_ISLNK( statBuf_symlink.st_mode ) ) {
                char nosymlink[PATH_MAX];
                if ( realpath( entry, nosymlink ) ) {
                    debug() << entry << " is a symlink. Using: " << nosymlink << endl;
                    entry = nosymlink;
                }
            }
            const QString file = QFile::decodeName( entry );

            bool isInCollection = false;
            if( m_incremental )
                dcopRef.call( "isDirInCollection", file ).get( isInCollection );

            if( !m_incremental || !isInCollection )
                // we MUST add a '/' after the dirname
                readDir( file + '/', entries );
        }

        else if( S_ISREG( statBuf.st_mode ) )
            entries.append( QFile::decodeName( entry ) );
    }

    closedir( d );
}