Reputation: 4733
I'm developing a large C++ program and I've now decided to document it with Doxygen. There are plenty of classes, methods, functions, macros and so on. Therefore I'm searching for software that would scan my source tree and insert Doxygen comment blocks on top of every "documentable item" to let me edit them later and add details such as method descriptions and so on.
Does any such software exist?
I'm under GNU/Linux with the Code::Blocks IDE, so no Visual Studio plugins are needed.
Upvotes: 17
Views: 23428
Reputation: 4127
Check your editor. I have been using the CodeWright editor, and it has a feature called selective display. Configured properly I can press the icon, and only the first line of function definitions is displayed. Alternatively, you can use block collapse/expand in some other editors. Either way makes it easy to speedily navigate through your source code to headers/definitions, etc and then paste some boiler plate comment to be filled in later. I often use my own search tags, e.g. COMMENTME in my code that I can get back to with simple searches.
Upvotes: 0
Reputation:
There is also a free Doxygen generator for C++ that uses the macro explorer plugin for Visual Studio 2015, which can be found here: https://github.com/cppocl/visual_studio_macros
Upvotes: 0
Reputation: 29
The posting for genDoxygenC.py has numerous index/whitespace errors. Since Python program flow is dependent on proper indexing I am concerned that the inner block the addDoxygenComment method might not have been correct. Is there a chance you could post the actual source file to here?
Upvotes: 1
Reputation: 4152
There are some c/cpp parsers in python, that might be used for your specific purpose. However, I have never used those yet.
For a similar objective, I wrote a python script that adds "doxygen-headers" to the methods in the header-file majorly. I have used regular expression, and I have a version that adds "doxygen headers" in the source file for the method-definitions (use RE_M_DEFINITION, at method-lookup).
Code for your reference, as below:
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
This will generate
file.h.doxygen
and then, you can probably check the doxygen-headers-added-file, with original-header-file using any diff-tool.
Example : meld file.h file.h.doxygen
Note:: The script might skip constructors, with new versions definitions/declarations like;
S() : n(7)) {};
Upvotes: 1
Reputation: 21
Ok, so this is an old post, but I just had the same problem and I've found doxymacs. It integrates nicely with emacs and generates doxymacs comments for your functions and files. After putting the .el file in your emacs path you can add a hook to make it available whenever you open a C/C++ file "(add-hook 'c-mode-common-hook'doxymacs-mode)" and comment the functions with C-c d f and the files with C-c d i, there are other comment types available, just check the project page: http://doxymacs.sourceforge.net/
Upvotes: 2
Reputation: 299730
I am quite perplex here.
What is the goal of automatically generating comments ?
Comments are meant to bring additional value:
/**
* \brief: finds the person based on its name
* \param: name, the name of the person
* \result: the person
*/
Person findPerson(Name name);
Is nothing but code clutter that clog my valuable screen estate. And that's about as much as can be generated automatically unfortunately... Notice in particular that I have no idea of what happens if ever the function does not find the person, which certainly seems likely: does it abort ? throws ? (what... ?) returns a default constructed object ?
On the other hand:
///
/// 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)
{
}
is much more interesting!
if
that seems to be performing some kind of sound recognition...Unfortunately, that's not going to be generated automatically.
Upvotes: 6
Reputation: 10968
You can set Doxygen to extract non-documented items as well - that may do what you want without adding ANY comment blocks to the code yet.
After that you can create templates / macros (depends on your IDE) to create pre-formatted blocks for each type of item, as you slowly work through the code documenting items one by one.
[edit] If you're using Visual Studio, some introspection is available on the classes and other constructs in the file, that may help. Alternatively take a look at Doxycomment - it might be some of what you want.
Upvotes: 2