2010-03-26 4 views
10

Sto sviluppando un grande programma C++ e ora ho deciso di documentarlo con Doxygen. Ci sono un sacco di classi, metodi, funzioni, macro e così via. Pertanto, sto cercando un software che analizzi il mio albero dei sorgenti e inserisca i blocchi di commenti Doxygen sopra ogni "elemento documentabile" per permettermi di modificarli in seguito e aggiungere dettagli come le descrizioni dei metodi e così via.Qualsiasi software per generare automaticamente blocchi di commenti doxygen?

Esiste un software del genere?

Sono sotto GNU/Linux con l'IDE Code :: Blocks, quindi non sono necessari plug-in di Visual Studio.

risposta

1

È possibile impostare Doxygen per estrarre anche gli elementi non documentati, il che potrebbe fare ciò che si desidera senza aggiungere ancora alcun blocco di commento al codice.

Dopodiché è possibile creare modelli/macro (a seconda dell'IDE) per creare blocchi preformattati per ciascun tipo di articolo, mentre si lavora lentamente attraverso il codice che documenta gli elementi uno per uno.

[modifica] Se si utilizza Visual Studio, è possibile che alcune introspezioni siano disponibili nelle classi e in altri costrutti nel file. In alternativa, dai un'occhiata a Doxycomment - potrebbe essere un po 'quello che vuoi.

+1

Sono a conoscenza di questa funzionalità, ma preferisco avere quei commenti nel codice sorgente. –

+0

Bene, puoi facilmente creare * vuoti * modelli per i blocchi che desideri aggiungere. Ottenere automaticamente alcuni dati in questi modelli potrebbe essere più complicato, ma controlla Doxycomment. –

+0

Sono sotto GNU/Linux con Code :: Blocks IDE, quindi non sono necessari plug-in di VisualStudio. –

5

Sono abbastanza perplesso qui.

Qual è l'obiettivo della generazione automatica di commenti?

commenti hanno lo scopo di portare un valore aggiunto:

/** 
* \brief: finds the person based on its name 
* \param: name, the name of the person 
* \result: the person 
*/ 
Person findPerson(Name name); 

è nulla, ma il disordine codice che intasare il mio immobile dello schermo prezioso. E questo è tanto quanto può essere generato automaticamente sfortunatamente ... Si noti in particolare che non ho idea di cosa succederà se mai la funzione non trova la persona, che sembra certamente probabile: si interrompe? getta? (cosa ...?) restituisce un oggetto costruito di default?

D'altra parte:

/// 
/// Try an exact match approach to begin with 
/// Uses the double metaphone algorithm 
/// if none was found as we have 
/// a western european clientele 
/// 
Person findPerson(Name name) 
{ 
} 

è molto più interessante!

  • Ora so che cosa è questa strana collezione di if che sembra essere l'esecuzione di un qualche tipo di riconoscimento suono ...
  • So che il suo nome così posso cercare su Internet per controllare la sua attuazione (funzionalità)
  • e so il motivo per cui è stato selezionato e quindi quando avrei dovuto rivalutare il suo utilizzo (si adatta ad una clientela dell'Europa occidentale così se vogliamo sviluppare il mercato arabo avrà bisogno adattamento ...)

Purtroppo, questo è non verrà generato automaticamente.

+0

Penso che la domanda sia molto preziosa. In un buon progetto, ci sono un sacco di commenti dappertutto, dal momento che la maggior parte delle routine può non essere banale. Per una persona che sta per apprendere o mantenere il codice, ogni singola riga (intelligente) è preziosa. Nel caso in cui si abbiano, ad esempio, 30.000 righe di codice appena documentato male, uno strumento così piccolo come richiesto dall'autore può essere un piacere, se si desidera leggere il codice e creare una documentazione da soli. – shuhalo

+0

Stai dimenticando il vasto numero di righe scritte non per la gioia di qualcuno ma come puro, sobrio, asciutto lavoro a contratto, in cui qualcuno! = Hai impostato uno stile di codifica. Puoi provare a combattere l'inevitabile o semplicemente provare ad adattarti con il minimo sforzo possibile. – Vroomfondel

+0

@Vroomfondel: c'è una famosa (e potenzialmente inventata) storia su un nuovo manager che entra nel cast e chiede che da ora alla fine di ogni settimana gli sviluppatori dovrebbero riferirgli il numero di linee aggiunte alla base di codice. Alla fine della settimana, il rapporto dello sviluppatore seniormost arriva a: -16.000 righe. Se ti trovi in ​​una situazione del genere, potrebbe essere il momento di cercare un lavoro migliore; qualcuno che spreca il tempo di tutti in una posizione di potere non è mai buono. –

2

Ok, quindi questo è un vecchio post, ma ho appena avuto lo stesso problema e ho trovato doxymacs. Si integra bene con emacs e genera commenti doxymacs per le tue funzioni e file. Dopo aver messo il.el file nel tuo percorso emacs puoi aggiungere un hook per renderlo disponibile ogni volta che apri un file C/C++ "(add-hook 'c-mode-common-hook'doxymacs-mode)" e commenta le funzioni con Cc df e i file con Cc di, ci sono altri tipi di commenti disponibili, basta controllare la pagina del progetto: http://doxymacs.sourceforge.net/

1

Ci sono alcuni parser c/cpp in python, che potrebbero essere usati per lo scopo specifico. Tuttavia, non li ho mai usati ancora.

Per un obiettivo simile, ho scritto uno script python che aggiunge "doxygen-headers" ai metodi nel file di intestazione in modo rilevante. Ho usato espressioni regolari e ho una versione che aggiunge "doxygen headers" nel file sorgente per le definizioni dei metodi (usa RE_M_DEFINITION, a method-lookup).

Codice per il vostro riferimento, come di seguito:

genDoxygenC.py

#!/usr/bin/python 

import os 
import sys 
import re 

################################################################ 

RE_MULTI_LINE_PARAMS = ".*" 

# could be used in header/source files, for method-definition extraction 
RE_M_DEFINITION = r'[A-Za-z0-9*]*\s*[A-Za-z0-9_*]+\s*[A-Za-z0-9_~:*]+\(.*\)\s*\{\s*.*?\s*\}' #TODO: this needs to be more generic to              be able to parse for methods only 
# used in header-files in major for method declaration extraction 
RE_M_DECLERATION = r"[A-Za-z0-9*]*\s*[A-Za-z0-9_*]+\s+[A-Za-z0-9_~*]+\s*\(%s\)\s*;"%RE_MULTI_LINE_PARAMS 

################################################################ 

# C/CPP CMD List 
cmdList = ["for","if","while","switch","else"]; 

########################## 
# exit errors enumerations 
class EErrors() : 
    IncorrectUsage, FileOpenError = range(2) 

################### 
# exception handler 
def handleException(e, mssg) : 
    if e == EErrors.IncorrectUsage : 
     print "Usage : "+mssg 
     elif e == EErrors.FileOpenError : 
     print "Unable to open \"" + mssg + "\" file !" 
    sys.exit(2) 

############################### 
# creates method doxygen header 
def frameDoxygenHeader(param_count, paramList) : 
    commentStr = "/**\n * @brief \n"  
    if param_count > 0 : 
     for param in paramList: 
      commentStr = commentStr + " * @param \n" 

    # comment for return values 
    commentStr = commentStr + " * @return \n */ \n" 

    return commentStr 

############################################## 
# adds the doxygen comments, on method lookup 
def addDoxygenComment(file_name, funcList) : 
    try:  
     fh = open(file_name, 'rb') 
     f_old = open(file_name, 'r+') 
    except: 
       handleException(EErrors.FileOpenError, file_name) 

    f_new = open(out_file_name, "w") 
    final_loc = 0 
    next_split_loc = 0 
    last_write_loc = 0 
    fContent = str(f_old.read()) 
    for func in funcList: 
     SEARCH_TEXT = func 
     print "SEARCH_TEXT "+SEARCH_TEXT 
      fsize = os.path.getsize(file_name) 
      bsize = fsize 
      word_len = len(SEARCH_TEXT) 
     fh.seek(0) 

     # doxygen comment header generation 
     paramListStr = re.findall(r'\(.*\)', SEARCH_TEXT) 
     paramListStr[0] = paramListStr[0].replace('(','') 
     paramListStr[0] = paramListStr[0].replace(')','') 
     paramList = paramListStr[0].split(",") 
     comment_text = frameDoxygenHeader(len(paramList),paramList) 

     while True: 
        found = 0 
        pr = fh.read(bsize) 
        pf = pr.find(SEARCH_TEXT, next_split_loc) 
        if pf > -1: 
          found = 1 
          pos_dec = fh.tell() - (bsize - pf) 
          fh.seek(pos_dec + word_len) 
          bsize = fsize - fh.tell() 
       print "Case-I:"+str(fh.tell()) 
        if fh.tell() < fsize: 
            seek = fh.tell() - word_len + 1 
            print "seek"+str(seek) 
         fh.seek(seek) 
            if 1==found: 
              final_loc = seek 
          next_split_loc = final_loc + word_len - 1 
              print "loc: "+str(final_loc) 
         print "Case-IIa:"+str(fh.tell()) 
        else: 
            break 

     # create file with doxygen comments 
     if final_loc != -1 : 
      #f_new.write(fContent[0:final_loc-1]); 
      #not to miss the contents, between two methods   
      if last_write_loc < final_loc : 
       f_new.write(fContent[last_write_loc:final_loc-1]); 

      f_new.write(comment_text); 
      f_new.write(fContent[final_loc-1:next_split_loc]) 
      last_write_loc = next_split_loc 

      #reset values 
      final_loc = -1 
     else: 
      print "method not found !!" 

    # last of the file should not be missed either 
    if last_write_loc < len(fContent) : 
     f_new.write(fContent[last_write_loc:]); 
    f_new.close() 
    f_old.close() 


############################################# 
############################################# 
# main execution of the code starts from here 
############################################# 
argc = len(sys.argv) 
if (argc == 1 or argc >2) : 
    handleException(EErrors.IncorrectUsage, "genDoxygenC.py <cpp source file>") 
else : 
    # Correct Input as per USAGE. 
    fname = sys.argv[1] 
    out_file_name = fname+'.doxygen' 
    fcontent='' 
    try: 
     # read file 
     fh = open(fname) 
     fcontent = fh.read() 
    # print fcontent 
    except: 
     handleException(EErrors.FileOpenError, fname) 

    # lookup for methods in file 
    funcList = re.findall(RE_M_DECLERATION, fcontent, re.VERBOSE) 
    fh.close() 

    funcListCopy = funcList 
    for fStr in funcListCopy : 
     fStr = fStr.lstrip() 
     startW = fStr.partition(' ')[0] 
     startW = fStr.partition('(')[0] 
     #print startW 
     if startW in cmdList : 
      # invalid method extraction 
      funcList.remove(fStr) 

    # process valid methods-list for doxygen header 
    addDoxygenComment(fname, funcList) 
    #print funcList 

Usage :: ./genDoxygenC.py file.h

Questo genererà

file.h.doxygen

e poi, probabilmente si può controllare la Doxygen-headers-aggiunto file, con originale-header file utilizzando qualsiasi diff -strumento.

Esempio:fusione file.h file.h.doxygen

Nota :: Lo script potrebbe saltare i costruttori, con le definizioni nuove versioni/dichiarazioni simili;

S(): n (7)) {};

+0

Puoi fornire il file stesso perché copiare da qui rovina il codice. – joaopauloribeiro

+1

fare riferimento al campione all'indirizzo https://github.com/parasrish/selfDoxygenH – parasrish

1

La pubblicazione di genDoxygenC.py presenta numerosi errori di indice/spazi vuoti. Poiché il flusso del programma Python dipende dall'indicizzazione corretta, sono preoccupato che il blocco interno del metodo addDoxygenComment non sia stato corretto. C'è la possibilità che tu possa pubblicare il vero file sorgente qui?