Создание документации с использованием исходного кода с комментариями Doxygen и Non Doxygen

Мы получили здесь примерно 10-летний код на C и C ++, без документов или руководства. Тем не менее, источник задокументирован в заголовочных файлах довольно хорошо, но много работы идет по всем файлам в поисках информации. Это выглядит так:

// Description description ....
//
// @param parameter 1 name:
// description of parameter 1
//
// @param parameter 2 name:
// description of parameter 2
//
Returntype Functionname(parameter1, parameter2);

С помощью мастера doxygen можно создать документацию, но все комментарии будут потеряны, потому что они не отформатированы так, как понимает парсер.

Так это формат, который я не знаю? Могу ли я научить парсер, что делать? Или это специальный формат, который используется другим программным обеспечением?

1

Решение

Я написал скрипт на python, чтобы конвертировать комментарии в формат, понятный парсеру. Это не красиво, это не безопасно, но это работает для нас.

import re
import time
import os
import shutil

def convertHeaderDocumentation(file):

with open(file) as f:
lines = f.readlines()
lines = [line.rstrip('\n') for line in lines]

scanning = False
commentLines = []

convertedDocument = ""declaration = ""
for line in lines:

if line == "" or \
line.strip().startswith("#"):
if len(commentLines) > 0:
convertedDocument += ''.join(el + "\n" for el in commentLines)
commentLines.clear()
convertedDocument += line + "\n"
continue

if line.strip().startswith('//'):
if not scanning:
commentLines.clear()
scanning = True

commentLines.append(line)
else:

if scanning:
if line.strip() != "":

declaration = line.strip()

match = re.search('\s*\w*\s*(\w+)\s+(\w+).*\((.*)[^)].*;', declaration)
if not match is None:
# check for function description
description = ""for line in commentLines:
if line[2:].strip().startswith("@") or \
line[2:].strip() == "":
break
else:
description += line[2:].strip()

# scan for parameter description
parameters = []
parameter = ""scanning = False
for line in commentLines:
# start scanning, if line starts with @
if line[2:].strip().startswith("@") and \
scanning == False :
# if present add to parameter lst
if parameter != "":
parameters.append(parameter)

scanning = True
parameter = line[2:].strip() + " "continue

# stop scanning if an empty line is read
if line[2:].strip() == "":
scanning = False

# save if parameter is in buffer
if parameter != "":
parameters.append(parameter)
parameter = ""
if scanning == True and line[2:].strip() != "":
parameter += line[2:].strip()convertedDocument += "/**\n"convertedDocument += " * @fn    " + declaration[:-1] + "\n"convertedDocument += " *\n"
convertedDocument += " * @brief "restLine = 80 - len(" * @brief ")
for index in range(0, len(description), restLine):
convertedDocument += description[index:index + restLine] + "\n *        "convertedDocument += "\n"
for parameter in parameters:
convertedDocument += " * " + parameter + "\n *\n"
convertedDocument += " * @return " + match.group(1) + "\n"convertedDocument += " *\n"
convertedDocument += " * @date  " + time.strftime("%d.%m.%Y") + "<br> parsed using python\n"convertedDocument += " */\n"convertedDocument += declaration + "\n\n"
commentLines.clear()

else :
convertedDocument += ''.join(el + "\n" for el in commentLines)
commentLines.clear();return convertedDocument

projectDir = "path to source files goes here"projectDir = os.abspath(projectDir)
parentProjectDir, projectDirName   = os.path.split(projectDir)
convertedDir     = os.path.join(parentProjectDir, "converted")
print(convertedDir)for root, dirs, files in os.walk(projectDir):

# create directory structure if not present
tmpConvertedDir = os.path.join(convertedDir, root[len(projectDir) + 1:])
if not os.path.exists(tmpConvertedDir):
os.makedirs(tmpConvertedDir)

for file in files:

filename, fileextension = os.path.splitext(file)
# only copy/convert c++/c source files
if fileextension in {'.h','.c','.cpp'} :
newPath = os.path.join(tmpConvertedDir, file)
print(newPath)

# convert header files
if fileextension in {'.h'}:
#print("convert ", os.path.join(root, file), " to ", newPath)
converted = convertHeaderDocumentation(os.path.join(root, file))

with open(newPath, 'w') as f:
f.write(converted)

# copy source files
else:
print("copy ", os.path.join(root, file), " to ", newPath)
shutil.copyfile(os.path.join(root, file), newPath)

Объявление функции было немного сложно поймать с помощью регулярного выражения. Для моего случая
\s*\w*\s*(\w+)\s+(\w+).*\((.*)[^)].*; работает просто отлично, но без каких-либо дополнительных ключевых слов ленивый квантификатор будет более точным для ключевых слов перед повторным типом \s*\w*?\s*(\w+)\s+(\w+).*\((.*)[^)].*;

Все файлы C и C ++ в заданном каталоге и подпапках projectDir преобразуются, если они являются заголовочными файлами, или просто копируются, если они являются исходными файлами. Поэтому создается каталог .. \ преобразованный, который содержит скопированные / преобразованные файлы.

С полученными файлами мастер doxygen создал достаточную документацию. Может быть, это кому-то поможет 🙂

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]