2017-08-10 9 views
1

文書またはマニュアルなしで、10年前のCおよびC++コードのようになりました。しかし、ソースはヘッダーファイルで非常に良好に文書化されていますが、情報を探しているすべてのファイルを調べる作業がたくさんあります。彼らはパーサが理解できる方法でフォーマットされていないので、ドキュメントは、作成することができますが、すべてのコメントが失われました。doxygenウィザードを使用してDoxygenとnon-Doxygenのコメント付きソースコードを使用した文書作成

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

:それはこのようになります。

これは私が知らない形式ですか?パーサーに何をすべきか教えてもいいですか?それとも別のソフトウェアで使用されている特別なフォーマットですか?

+0

'//'を '//!'や他のdoxygenコメントに置き換えるスクリプトを作成することができます。 – Serge

答えて

0

私は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+).*\((.*)[^)].*;うまく動作しますが、彼らはしている場合与えられたPROJECTDIRディレクトリおよびサブフォルダで戻り値の\s*\w*?\s*(\w+)\s+(\w+).*\((.*)[^)].*;

すべてのCおよびC++ファイルを変換する前に、余分なキーワードを指定せずに怠惰な数量詞キーワードのためのより多くのacurateになるだろうヘッダーファイル、またはソースファイルの場合はコピーしてください。そのため、コピーされた/変換されたファイルを含む\ .. convertedというディレクトリが作成されます。

結果ファイルのdoxygenウィザードを使用すると、十分な文書を作成できます。たぶんこれは誰かを助けるつもりです:-)

+0

[私自身の質問に答えることができますか?](http://stackoverflow.com/help/self-answer)を見て、2日後に戻ってきて、答えにチェックを入れてください。 –

+0

ありがとう、私は次の時間のことを念頭に置いておきます。 – Aeonos

関連する問題