2011-09-20 23 views
7

Io uso le macro per generare classi nel seguente modo:Come documentare le classi generate da macro con Doxygen?

generator.h:

class CLASS_NAME : public parent 
{ 
    //generate variables with names given by CLASS_VARIABLES using complicated 
    //Boost.Preprocessor stuff. 
}; 

#undef CLASS_NAME 
#undef CLASS_VARIABLES 

MyClass.h:

#define CLASS_NAME MyClass 
#define CLASS_VARIABLES (a, b, c, x, y, z) 
#include "generator.h" 

La classe reale è più complicato e utilizza vari Boost. Macro preprocessore. C'è un modo per documentare automaticamente le classi generate con Doxygen aggiungendo commenti a generator.h, o in alternativa per generare una classe di esempio con la documentazione? Ho provato a abilitare ENABLE_PREPROCESSING e MACRO_EXPANSION, ma questo non sembra essere sufficiente.

risposta

1

Non funzionerà. Il preprocessore di Doxygen non esegue realmente l'inclusione di file completi (solo nei file inclusi per le definizioni di macro, altrimenti la direttiva ENABLE_PREPROCESSING sarebbe totalmente inutile!). Quindi lo #include "generator.h" non ha alcun effetto.

Se si sostituisce fisicamente la direttiva #include con il contenuto del file incluso, funzionerà. (Non molto utile, lo so).

Un altro modo per farlo è quello di modificare i file in questo modo:

generator.h:

#define DEFCLASS class CLASS_NAME : public parent \ 
{ \ 
    ... whatever ... \ 
}; 

MyClass.h:

#define CLASS_NAME MyClass 
#define CLASS_VARIABLES (a, b, c, x, y, z) 
#include "generator.h" 
DEFCLASS 

ma questo non funzionerà se si usa DEFCLASS più di una volta per file sorgente (probabilmente un bug/difetto di Doxygen).

+0

Penso di non poter usare la tua modifica perché uso ancora '# include's e' # define's nella mia definizione di classe. Potrei mettere il '# define's davanti alla classe, ma non credo di poter liberare il' # include's ... – AbuBakr

+0

Come indicato da spyderfreek qui sotto, se # include un { } blocco, l'inclusione funzionerà. – Heyji

1

A proposito di "Documentazione in altri luoghi" pararaph in http://www.stack.nl/~dimitri/doxygen/docblocks.html

/*! \class CLASS_NAME 
    \brief An auto generated class 

    A more detailed class description. 
*/ 

/*! \fn CLASS_NAME::CLASS_NAME() 
    \brief Default constuctor 
*/ 
+0

Hmm, questo in qualche modo non funziona. Non posso farlo esattamente come mi hai proposto perché il mio nome effettivo della classe è una concatenazione di CLASS_NAME e una stringa. Ho provato ad usare '\ class MyClass', ma non sembra che la documentazione sia stata generata. Forse perché Doxygen cerca MyClass ma non lo trova? Ho anche provato '\ class CLASS_NAMEConcatenatedString', ma ancora: niente. – AbuBakr

1

Si consiglia di inserire le classi generate in un'intestazione separata e di documentare semplicemente l'intestazione. Nel migliore dei casi, le classi generate sono più di un dettaglio di implementazione.

L'altra opzione potrebbe essere qualcosa di script. O usando il tuo linguaggio di scripting preferito, o qualcosa come cheetah non sarebbe terribile.

Immagino che il tuo generatore abbia un aspetto semplice per generare una piastra di riscaldamento, i tratti o qualsiasi altra cosa.

GENERATE_CLASS(Foo); 
GENERATE_CLASS(Bar); 

Qualcosa del genere è un foraggio grep abbastanza ragionevole.

+0

Non sono sicuro di aver compreso correttamente il tuo primo paragrafo. Suggerite di creare un'intestazione di esempio contenente l'output del preprocessore? Questa sarebbe solo una buona soluzione se questa intestazione potesse essere creata automaticamente. Dato che uso cmake, questo potrebbe essere possibile. Potrei quindi creare commenti in generator.h usando il suggerimento di sweetrommie. – AbuBakr

+0

Nel primo paragrafo, non intendevo l'output generato. Intendevo separare il codice nella sua intestazione. Quindi fornire un sommario esecutivo di uso generale, non specifiche delle classi. Un'altra opzione sarebbe quella di creare un'interfaccia virtuale pura che tutte le classi generate "ereditino" (letteralmente o semplicemente mimiche) e le documentino. Se volessi generare qualcosa, userei il ghepardo. –

4

Nel momento in cui sto scrivendo, Doxygen comporterà l'inclusione di file in piena regola, a condizione che siano presenti un paio di condizioni. Dal Doxygen internals documentation:

... il preprocessore analizza, ma in realtà non include il codice quando si incontra un # include (con l'eccezione di # include trovato all'interno { ...} blocchi)

L'altro presupposto non documentata, ma intuitivo ho trovato attraverso la sperimentazione è che qualunque {...} bloccare la # include è necessario per sé essere documentati. Ad esempio, l'esecuzione di Doxygen sul seguente file di test utilizzando Boost.Preprocessor genererà voci per le strutture FOO::A, FOO::B e FOO::C, a condizione che MACRO_EXPANSION sia abilitato nel file di configurazione, che la modalità di estrazione desiderata sia impostata su "Tutte le entità" e la cartella Boost sia correttamente impostato in INCLUDE_PATH:

#include <boost/preprocessor/iteration/local.hpp> 
#include <boost/preprocessor/tuple/elem.hpp> 

#define STRUCTS (A, B, C) 

namespace FOO { 
    #define BOOST_PP_LOCAL_MACRO(n) struct BOOST_PP_TUPLE_ELEM(3,n, STRUCTS) {}; 
    #define BOOST_PP_LOCAL_LIMITS (0,2) 
    #include BOOST_PP_LOCAL_ITERATE() 
} 

Tuttavia, la rimozione FOO collocare le struct in un namespace anonimo comporterà alcuna documentazione. Quindi, se puoi sopportare lo #include "generator.h" all'interno di uno spazio dei nomi esplicito, funzionerà.

+0

Non sono sicuro della tua seconda precondizione sulla documentazione del blocco in cui si trova la direttiva #include. Credo che non sia necessario. – Heyji

Problemi correlati