在CPP文件中自动添加函数注释的ADDIN

原创 2002年03月09日 18:02:00

当公司要求你用统一的格式写函数注释时,这个小东西也许可以帮些忙。


ma2jun@sina.com


设计目标:




1. 自动提取函数名称;2. 自动提取函数功能注释(假设在头文件中);3. 自动列出参数列表;4.自动提取返回值;5.自动填写作者及日期(作者名称可以设置)



例如:



//------------------------------------------------
// 名称:CDSAddIn::OnConnection
// 功能:
// 参数:[IApplication* pApp] ---
//       [VARIANT_BOOL bFirstTime] ---
//       [long dwCookie] ---
//       [VARIANT_BOOL* OnConnection] ---
// 返回:STDMETHODIMP ---
// 作者:JM 2002-3-4
//------------------------------------------------
STDMETHODIMP CDSAddIn::OnConnection(IApplication* pApp, VARIANT_BOOL bFirstTime, long dwCookie, VARIANT_BOOL* OnConnection)


设计思想:




1. 使用IDSAddIn接口;2. 设计CCmtBlock(COMMENT BLOCK)类维护注释中的各个字段,用来提供扩展灵活性。


实现:


//-----------------------------------------------------------------------------------------------------


// CmtBlock.h: interface for the CCmtBlock class.
//
//////////////////////////////////////////////////////////////////////


#if !defined(AFX_CMTBLOCK_H__51B4002A_A935_4764_80B5_03103D5E716E__INCLUDED_)
#define AFX_CMTBLOCK_H__51B4002A_A935_4764_80B5_03103D5E716E__INCLUDED_


#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <vector>


class CCmtBlock 
{
public:
 CCmtBlock();
 ~CCmtBlock();


private:
 CString m_szBegin;       // 注释首行(hard coded)
 CString m_szName;        // 函数名称(auto)
 CString m_szPurpose;     // 函数功能(auto)
 CString m_szParam;       // 函数参数列表(auto)
 CString m_szReturn;      // 函数返回(can change)
 CString m_szAuthor;      // 函数作者(auto)
 CString m_szEnd;         // 注释尾行(hard coded)


 CString m_szFuncDefine;  // 函数定义(自动获得)
// CString m_szBlock;       // 函数注释块


 std::vector< CString* > m_arrSort;  // 注释部分的排列顺序


private:
 void ExtractName();      // 提取名称
 void ExtractPurpose();   // 提取功能
 void ExtractParam();     // 提取参数列表
 void ExtractReturn();    // 提取返回类型
 void ComposeAuthorAndDate(); // 编辑作者和日期时间


public:
 void SetFunctionDefine( CString szFuncDefine );   // 设置函数定义(自动获得)
 CString ComposeComment();   // 编辑函数注释
 void SetPurpose( CString& szFuncPurpose ) {
  m_szPurpose = szFuncPurpose; }  // 设置函数头文件中的注释


};


#endif // !defined(AFX_CMTBLOCK_H__51B4002A_A935_4764_80B5_03103D5E716E__INCLUDED_)


//-----------------------------------------------------------------------------------------------------


// CmtBlock.cpp: implementation of the CCmtBlock class.
//
//////////////////////////////////////////////////////////////////////


#include "stdafx.h"
#include "AutoComment.h"
#include "CmtBlock.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CCmtBlock::CCmtBlock()
{
 m_szBegin = _T("//------------------------------------------------/r/n");
 m_szEnd   = _T("//------------------------------------------------/r/n");


 m_arrSort.clear();
 m_arrSort.push_back( &m_szBegin );
 m_arrSort.push_back( &m_szName );
 m_arrSort.push_back( &m_szPurpose );
 m_arrSort.push_back( &m_szParam );
 m_arrSort.push_back( &m_szReturn );
 m_arrSort.push_back( &m_szAuthor );
 m_arrSort.push_back( &m_szEnd );
}


CCmtBlock::~CCmtBlock()
{
 m_arrSort.clear();
}


void CCmtBlock::ExtractName()
{
 int iPosSpace = m_szFuncDefine.FindOneOf(_T(" "));
 int iPosBracket = m_szFuncDefine.FindOneOf(_T("("));
 CString szName = m_szFuncDefine.Mid( iPosSpace, iPosBracket-iPosSpace );
 szName.TrimLeft();
 szName.TrimRight();
 m_szName = _T("// 名称:") + szName + _T("/r/n");
}


void CCmtBlock::ExtractPurpose()
{
 CString szTemp = m_szPurpose;
 m_szPurpose = _T("// 功能:") + szTemp + _T("/r/n");
}


void CCmtBlock::ExtractParam()
{
 // 得到参数表
 int iPosLeftBracket = m_szFuncDefine.FindOneOf(_T("("));
 int iPosRightBracket = m_szFuncDefine.ReverseFind(_T(')'));
 CString szParamTable = m_szFuncDefine.Mid( iPosLeftBracket+1, iPosRightBracket-iPosLeftBracket-1 );


 // 分解参数
 // 判断是否具有参数
 szParamTable.TrimLeft();
 szParamTable.TrimRight();
 if( szParamTable == _T("") )
 {
  // 没有参数
  m_szParam = _T("// 参数:无/r/n");
  return;
 }
 m_szParam = _T("// 参数:");
 int iPos1 = 0;
 int iPos2 = 0;
 CString szOneParam = _T("");
 CString szOneLine;
 int iLineCount = 0;
 szParamTable += _T(",");
 while( ( iPos2 = szParamTable.Find( _T(','), iPos1 ) ) != -1 )
 {
  iLineCount++;


  // 找到参数
  szOneParam = szParamTable.Mid( iPos1, iPos2-iPos1 );
  szOneParam.TrimLeft();
  szOneParam.TrimRight();
  if( iLineCount == 1 )
   szOneLine = _T("[") + szOneParam + _T("] --- ");
  else
   szOneLine = _T("//       [") + szOneParam + _T("] --- ");
  szOneLine += _T("/r/n");


  // 添加到函数列表上
  m_szParam += szOneLine;


  iPos1 = iPos2 + 1;
 }


// ::MessageBox( NULL, szParamTable, NULL, MB_OK );


}


void CCmtBlock::ExtractReturn()
{
 CString szRet = m_szFuncDefine.Mid( 0, m_szFuncDefine.FindOneOf( _T(" ") ) );
 m_szReturn = _T("// 返回:") + szRet + _T(" --- /r/n");
}


extern CString g_szAuthor;  // 作者名称


void CCmtBlock::ComposeAuthorAndDate()
{
 CString szAuthor = g_szAuthor;//_T("Author");


 COleDateTime& date = COleDateTime::GetCurrentTime();
 CString szDate = date.Format( VAR_DATEVALUEONLY );


 m_szAuthor = _T("// 作者:") + szAuthor + _T("  ") + szDate + _T("/r/n");
}


void CCmtBlock::SetFunctionDefine( CString szFuncDefine )
{
 m_szFuncDefine = szFuncDefine;
}


CString CCmtBlock::ComposeComment()
{
 ExtractName();      // 提取名称
 ExtractPurpose();   // 提取功能
 ExtractParam();     // 提取参数列表
 ExtractReturn();    // 提取返回类型
 ComposeAuthorAndDate(); // 编辑作者和日期时间


 CString szBlock = _T("");
 for( int i=0;i<m_arrSort.size();i++)
  szBlock += *m_arrSort[i];


 return szBlock;
}

//-----------------------------------------------------------------------------------------------------


AutoCommentCommandMethod 函数是ADDIN向导自动建立的那个函数


/////////////////////////////////////////////////////////////////////////////
// CCommands methods


STDMETHODIMP CCommands::AutoCommentCommandMethod()
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());


 // TODO: Replace this with the actual code to execute this command
 //  Use m_pApplication to access the Developer Studio Application object,
 //  and VERIFY_OK to see error strings in DEBUG builds of your add-in
 //  (see stdafx.h)


// VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));
// ::MessageBox(NULL, "AutoComment Command invoked.", "AutoComment", MB_OK | MB_ICONINFORMATION);
// VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));


 // 得到当前文档
 CComPtr<IDispatch> pDispActDocument = NULL;
 m_pApplication->get_ActiveDocument( &pDispActDocument );
 if( !pDispActDocument )
  return E_FAIL;
 CComQIPtr< ITextDocument, &IID_ITextDocument > pDoc( pDispActDocument );


 // 得到选择对象
 CComPtr< IDispatch > pDispSelection;
 pDoc->get_Selection( &pDispSelection );
 if( !pDispSelection )
  return E_FAIL;
 CComQIPtr< ITextSelection, &IID_ITextSelection > pSelection( pDispSelection );


 // 得到函数定义(假设光标插在函数定义中)
 //    -- 寻找的标志是:头(NewLine),尾({)>> 将来实现
 // 选择函数定义的第一行
 CComBSTR bstrFuncDefine;
 pSelection->SelectLine();
 pSelection->get_Text( &bstrFuncDefine );


 // 将光标插入行的起始位置
 VARIANT var1,var2;
 VariantInit( &var1 );
 VariantInit( &var2 );
 pSelection->StartOfLine( var1, var2 );


 if( bstrFuncDefine.Length() == 0 )
  return E_FAIL;  // 不是函数定义
 USES_CONVERSION;
 CString szFuncDefine = W2A(bstrFuncDefine);
 m_CmtBlock.SetFunctionDefine( szFuncDefine );


 // 找到头文件中函数定义的注释
 CString& szFuncComm = FindFunctionPurposeInHeader( szFuncDefine );
 m_CmtBlock.SetPurpose( szFuncComm );


 // 构成函数注释字符串
 CString szBlock = m_CmtBlock.ComposeComment();
 BSTR bstrBlock;
 bstrBlock = A2W( szBlock );
 pSelection->put_Text( bstrBlock );


 return S_OK;
}


CString CCommands::FindFunctionPurposeInHeader( CString& szDefine )
{
 CString szRet;
 // 得到当前文档
 CComPtr<IDispatch> pDispActDocument = NULL;
 m_pApplication->get_ActiveDocument( &pDispActDocument );
 if( !pDispActDocument )
  return "";
 CComQIPtr< ITextDocument, &IID_ITextDocument > pDoc( pDispActDocument );
 if( !pDoc )
  return "";


 // 得到函数名称
 CString szFuncName;
 int iPosSpace = szDefine.FindOneOf(_T(":"));
 int iPosBracket = szDefine.FindOneOf(_T("("));
 szFuncName = szDefine.Mid( iPosSpace+2, iPosBracket-iPosSpace-2 );
 szFuncName.TrimLeft();
 szFuncName.TrimRight();


 // 打开对应的.h文件
 CComBSTR bstrFullName;
 pDoc->get_FullName( &bstrFullName );
 CString szFullName( bstrFullName );
 szFullName.MakeLower();
 CString szExt = szFullName.Right( 3 );
 if( szExt != "cpp" )   // 不是.cpp
  return "";
 szFullName.TrimRight( "cpp" );
 szFullName += "h";  // 转换成.h


 CStdioFile file;
 if( !file.Open( szFullName, CFile::modeRead ) )
  return "";
 CString szLine;
 CString szPurpose;
 int pos;
 while( file.ReadString( szLine ) )
 {
  // 检查每一行是否有函数名称
  if( (pos=szLine.Find( szFuncName )) != -1 )
  {
   // 检查szFuncName的前后字符是否为空格and'('
   // 构造一个字符串在szFuncName的前后个加一个字符
   CString szTemp = szLine.Mid( pos-1, szFuncName.GetLength()+2 );
   if( szTemp.Left(1) != " " ||
    ( szTemp.Right(1) != " " && szTemp.Right(1) != "(" ) )
    szRet = "";
   else
   {
    // 找到函数声明
    // 查看当前行的末尾有没有注释
    int posSplash = 0;
    if( ( posSplash = szLine.ReverseFind( '/' ) ) != -1 )
     szRet = szLine.Right( szLine.GetLength() - posSplash - 1 );
    else
    {
     // 查看下一行有没有注释
     if( file.ReadString( szLine ) )
     {
      szLine.TrimLeft();
      szLine.TrimRight();
      if( szLine.Left(1) == "/" )
      {
       // 有注释
       szLine.TrimLeft("//");
       szRet = szLine;
      }
      else
       szRet = "";
     }
     else
      szRet = "";


    }


   }
  }


 }
 file.Close();


 szRet.TrimRight();
 szRet.TrimLeft();
 return szRet;
}

 

//-----------------------------------------------------------------------------------------------


// 在CDSAddIn::OnConnection函数中改写以下代码,注意:CParamDlg 类是一个输入作者名称的对话框类


 if (bFirstTime == VARIANT_TRUE)
 {
  VERIFY_OK(pApplication->
   AddCommandBarButton(dsGlyph, bszCmdName, m_dwCookie));
  // 第一次使用让用户输入姓名
  CParamDlg dlgParam;
  if( dlgParam.DoModal() == IDOK )
  {
   g_szAuthor = dlgParam.m_szAuthor;
   // 存入注册表
   ::WriteProfileString("DSAddIn_AutoComment","Author",g_szAuthor);
  }
 }
 else
 {
  char szAuthor[255];
  ::GetProfileString("DSAddIn_AutoComment","Author","Author",szAuthor,sizeof(szAuthor));
  g_szAuthor = CString(szAuthor);
 }


//-------------------------------------------------------------------------------------------------


希望大家能提出宝贵意见 :-)


JM -----  ma2jun@sina.com

 

vs2010中点击新建项,为c++头文件和cpp文件,添加文件头注释

单独的添加项,只需要修改
  • ly20056402006
  • ly20056402006
  • 2015年06月05日 18:36
  • 1507

cocos2dx 自动添加所有cpp文件到android.mk

做一个懒COCOS2D-X程序猿(一)停止手打所有cpp文件到android.mk 前言:”懒”在这里当然不是贬义词,而是追求高效,拒绝重复劳动的代名词!做一个懒COCOS2D-X程序猿的系...
  • bark2003
  • bark2003
  • 2014年12月03日 14:05
  • 1145

在vs2010中如何自动给函数或者类加上注释

1. 打开vs2010,依次点击工具->Macro 资源管理器,会在右侧出现宏资源管理器。如下图所示: 2.在资源管理器的Samples模块上右键->新建模块,弹出如下对话框,输入模块名Funct...
  • a549875231
  • a549875231
  • 2015年10月16日 12:04
  • 1134

MyEclipse新建文件时自动添加注释

windows->preferences->java->Code Templates->comments->Type->edit  Eclipse注释规范模版总结 新建类文件 ...
  • u011199063
  • u011199063
  • 2017年01月11日 16:28
  • 1063

VS2010 Addin 插件添加菜单和命令

VS2015开始就已经不支持Addin插件了,替代的是VSPackage插件;也许是因为这个原因网上关于Addin的中文资料比较少。可是并不想学VSPackage开发,还是弄一个简单的吧。还是一点点的...
  • tom06
  • tom06
  • 2017年09月13日 17:01
  • 328

tortoiseSvn自动添加文件注释

自动添加文件注释方法: %APPDATA%\Subversion\config  编辑此文件 1启用auto-props [miscellany] enable-auto-pr...
  • u012867952
  • u012867952
  • 2015年11月10日 16:35
  • 315

Netbeans 自带注释插件的使用

先输入 /** 然后回车,就会将注释写出来了,必须先把函数写完整。
  • yage10548
  • yage10548
  • 2015年12月14日 14:49
  • 1551

PyCharm创建文件时自动添加头注释

进入设置 File->settings->Editor->File and Code Templates->Python Script添加以下代码:#!/usr/bin/env python # -...
  • windfz
  • windfz
  • 2017年02月22日 21:03
  • 3010

C和CPP注释转换

注释转换是将如下几种情况的注释分别按情况转换为相应注释风格(将C注释转换为C++注释风格)首先我们需要两个文件来分别存储需要修改的源码和修改之后的代码,这里我将文件创建在当前目录之下注释转换的实现依据...
  • centor
  • centor
  • 2017年06月03日 14:34
  • 545

C++ 在.h文件中声明,在.cpp文件中定义 模板函数和模板类

C++ 需要模板函数的定义和声明要放在一起,这样才能根据调用需要选择编译具体的实例。如果我们需要多种实例,每个实例要编译一次,就需要编译多次。在模板函数实现妥当以后,当我们在其它文件中使用某些模板函数...
  • bendanban
  • bendanban
  • 2016年05月05日 12:39
  • 3383
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在CPP文件中自动添加函数注释的ADDIN
举报原因:
原因补充:

(最多只允许输入30个字)