2010-03-26 14 views
10

Opracowuję duży program w C++ i zdecydowałem się teraz udokumentować to za pomocą Doxygen. Istnieje wiele klas, metod, funkcji, makr i tak dalej. Dlatego szukam oprogramowania, które skanowałoby moje drzewo źródłowe i wstawiało bloki komentarzy Doxygen na górze każdego "dokumentalnego elementu", pozwalając mi je później edytować i dodawać szczegóły, takie jak opisy metod i tak dalej.Dowolne oprogramowanie do automatycznego generowania bloków komentarzy doxygen?

Czy istnieje takie oprogramowanie?

Jestem pod GNU/Linux z Code :: Blocks IDE, więc nie są potrzebne wtyczki Visual Studio.

Odpowiedz

1

Możesz ustawić Doxygen, aby wyodrębnić również nieudokumentowane elementy - to może zrobić, co chcesz, bez dodawania DOWOLNYCH bloków komentarzy do kodu.

Po tym można utworzyć szablony/makra (w zależności od IDE), aby utworzyć wstępnie sformatowane bloki dla każdego typu elementu, gdy powoli przejdziemy przez kod dokumentujący elementy jeden po drugim.

[edycja] Jeśli korzystasz z programu Visual Studio, dostępna jest introspekcja na klasach i innych konstrukcjach w pliku, co może pomóc. Alternatywnie spójrz na Doxycomment - może to być coś, co chcesz.

+1

Jestem świadomy tej funkcji, ale wolę mieć te komentarze w kodzie źródłowym. –

+0

Możesz łatwo tworzyć * puste * szablony dla bloków, które chcesz dodać. Pobieranie niektórych danych do tych szablonów może być trudniejsze, ale sprawdź Doxycomment. –

+0

Jestem pod GNU/Linux z Code :: Blocks IDE, więc nie potrzebuję wtyczek VisualStudio. –

5

Jestem bardzo zakłopotany.

Jaki jest cel automatycznego generowania komentarzy?

Komentarze mają przynieść dodatkowe korzyści:

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

to nic innego kodu bałaganu że zapchać mój cenny majątek ekranem. I to tyle, ile można wygenerować automatycznie niestety ... Zwróćmy uwagę, że nie mam pojęcia, co się stanie, jeśli funkcja nie znajdzie osoby, która z pewnością wydaje się prawdopodobna: czy to się kończy? rzuca? (co ...?) zwraca domyślny skonstruowany obiekt?

Z drugiej strony:

/// 
/// 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) 
{ 
} 

jest o wiele bardziej interesujące!

  • Teraz wiem, co to za dziwny zbiór if, który wydaje się być wykonywanie jakiegoś dźwięku uznania ...
  • Znam jego nazwisko, więc mogę to sprawdzić w Internecie, aby sprawdzić jego realizację (funkcjonalność)
  • i wiem, dlaczego został wybrany, a więc kiedy należy ponownie ocenić jej zastosowanie (pasuje western europejskiej klienteli więc jeśli mamy rozwijać się na rynku arabska będzie to potrzebne dostosowanie ...)

Niestety, to nie będzie generowane automatycznie.

+0

Myślę, że to pytanie jest bardzo cenne. W dobrym projekcie jest mnóstwo komentarzy, ponieważ większość procedur może być nietrywialna. Dla osoby, która chce się uczyć lub obsługiwać kod, każda pojedyncza (inteligentna) linia jest cenna. Jeśli masz, powiedzmy, 30 000 wierszy z ledwo udokumentowanym kodem, takie małe narzędzie, o które prosi autor, może być błogością, jeśli chcesz przeczytać cały kod i samemu stworzyć dokumentację. – shuhalo

+0

Zapominasz o ogromnej liczbie wierszy napisanych nie dla własnej radości, ale jako czystej, trzeźwej, suchej pracy kontraktowej, gdzie ktoś! = Utworzyłeś styl kodowania. Możesz próbować walczyć z nieuniknionym lub po prostu starasz się dostosować przy jak najmniejszym wysiłku. – Vroomfondel

+0

@Vroomfondel: jest słynna (i potencjalnie zmyślona) historia o nowym menedżerze, który pyta, że ​​od teraz pod koniec każdego tygodnia programiści powinni zgłosić mu liczbę linii dodanych do bazy kodów. Koniec tygodnia, raport z najczęstszych deweloperów jest: -16.000 linii. Jeśli znajdziesz się w takiej sytuacji, być może nadszedł czas, aby szukać lepszej pracy; ktoś marnujący czas wszystkich na pozycji władzy nigdy nie jest dobry. –

2

OK, więc jest to stary post, ale miałem ten sam problem i znalazłem doxymacs. Integruje się ładnie z emacs i generuje komentarze doxymacs dla twoich funkcji i plików. Po wstawieniu.Plik el na ścieżce emacsa możesz dodać hak, aby był dostępny po otwarciu pliku C/C++ "(dodaj tryb" c-mode-common-hook'doxymacs-mode) "i skomentuj funkcje za pomocą Cc df i pliki z Cc di, dostępne są inne typy komentarzy, po prostu sprawdź stronę projektu: http://doxymacs.sourceforge.net/

1

Istnieje kilka parserów c/cpp w Pythonie, które mogą być używane do określonego celu. Jednak nigdy ich jeszcze nie użyłem.

Dla podobnego celu napisałem skrypt Pythona, który dodaje "doxygen-headers" do metod w pliku nagłówkowym. Użyłem wyrażeń regularnych i mam wersję, która dodaje "nagłówki doxygen" w pliku źródłowym dla definicji metod (użyj RE_M_DEFINITION, podczas wyszukiwania metody).

Kod celach poglądowych, jak poniżej:

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 

Wykorzystanie :: ./genDoxygenC.py file.h

To wygeneruje

file.h.doxygen

a następnie, prawdopodobnie można sprawdzić doxygen-headers dodanej plik z oryginalnego-header-file użyciu dowolnego diff -narzędzie.

Przykład:Meld file.h file.h.doxygen

Uwaga :: Skrypt może pominąć konstruktorów, z definicji nowych wersjach/deklaracje podoba;

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

+0

Czy możesz podać sam plik, ponieważ kopiowanie stąd powoduje tylko zniszczenie kodu. – joaopauloribeiro

+1

proszę odnieść się do próbki na https://github.com/parasrish/selfDoxygenH – parasrish

1

Wpis dla genDoxygenC.py zawiera liczne błędy indeksów/białych znaków. Ponieważ przepływ programu Python zależy od właściwego indeksowania, obawiam się, że wewnętrzny blok metody addDoxygenComment mógł nie być poprawny. Czy jest szansa, że ​​możesz wysłać tutaj rzeczywisty plik źródłowy?

Powiązane problemy