給source insight新增doxygen註釋風格
目前專案組對於註釋的要求比較高,導致我添加註釋的時候非常煩,大量的重複勞動確實很煩人,自己也一直打算給source insight新增類似的功能,可能是本人比較懶,一直不想做這樣的工作。不過,既然可以一勞永逸,何樂而不為呢。
後來發現有個叫doxygen的工具,看了介紹,覺得還比較實用,所以就在網上找了些資料,不過他們給SI新增的那些方法好像不能滿足我的要求,所以還是自己動手吧。以下是我新增的SI 指令碼內容,可能存在一定的問題和缺陷,但是能夠滿足我的要求,湊合著用了,誰叫咱懶呢。在這裡算是做個安全的備份吧,呵呵。
以下的巨集程式碼在SI 的3.50.0070版本上可以工作,好像3.50.0064版本有些bug(比如說++之類的操作符),可能部分程式碼存在問題,其它版本未知。
GCPPDoxygen.em
/*!
* Insert the doxygen style comments of file.
*/
macro GDoxyFileHeaderComment()
{
var hwnd
var hbuf
/*prepare*/
hwnd = GetCurrentWnd()
hbuf = GetCurrentBuf()
if(hbuf == hNil || hwnd == hNil)
{
Msg("Can't open file")
stop
}
/*Get need information*/
var fFullName
var fName
fFullName = GetBufName(hbuf)
fName = GGetFileName(fFullName)
var szTime
var Year
var Month
var Day
szTime = GetSysTime(1)
Year = szTime.Year
Month = szTime.Month
Day = szTime.Day
var user
var siInfo
siInfo = GetProgramEnvironmentInfo()
user = siInfo.UserName
/*Insert comments*/
ln = 0 //this will cause the file comments will always stay on the top of file
InsBufLine(hbuf, ln++, "/*!")
InsBufLine(hbuf, ln++, " * @@file @
InsBufLine(hbuf, ln++, " * @@brief")
InsBufLine(hbuf, ln++, " *")
InsBufLine(hbuf, ln++, " * \\n")/*This will let doxygen doc has a empty line*/
InsBufLine(hbuf, ln++, " * @@details")
InsBufLine(hbuf, ln++, " *")
InsBufLine(hbuf, ln++, " * \\n")/*This will let doxygen doc has a empty line*/
InsBufLine(hbuf, ln++, " * @@version ")
InsBufLine(hbuf, ln++, " * @@author @
InsBufLine(hbuf, ln++, " * @@date @[email protected]@[email protected]@[email protected]")
InsBufLine(hbuf, ln++, " *")
InsBufLine(hbuf, ln++, " * @@history")
InsBufLine(hbuf, ln++, " *")
InsBufLine(hbuf, ln++, " */")
/*Locate to the file begin*/
ScrollWndToLine(hwnd, 0)
}
/*!
* Insert doxygen style comments of c++ class.
*/
macro GDoxyClassHeaderComment()
{
var hwnd
var hbuf
var ln
var symbolrecord
var name
var strHeader
/*prepare*/
hwnd = GetCurrentWnd()
hbuf = GetCurrentBuf()
if(hwnd == hNil || hwnd == hNil)
{
Msg("Can't open file")
stop
}
ln = GetBufLnCur(hbuf)
symbolrecord = GetSymbolLocationFromLn(hbuf, ln)
if(symbolrecord == Nil)
{
Msg("Can't get current symbol record info.")
stop
}
/*check current symbol type*/
if(symbolrecord.Type != "Class")
{
Msg("Current symbol is not a class.")
stop
}
/*Get need info*/
name = symbolrecord.Symbol
/*Insert comments*/
ln = symbolrecord.lnFirst
strHeader = GGetHeaderSpaceByLn(hbuf, ln)
InsBufLine(hbuf, ln++, strHeader#"/*!")
InsBufLine(hbuf, ln++, strHeader#" * @@class @[email protected]")
InsBufLine(hbuf, ln++, strHeader#" * @@brief")
InsBufLine(hbuf, ln++, strHeader#" *")
InsBufLine(hbuf, ln++, strHeader#" * \\n")
InsBufLine(hbuf, ln++, strHeader#" * @@detail")
InsBufLine(hbuf, ln++, strHeader#" *")
InsBufLine(hbuf, ln++, strHeader#" * \\n")
InsBufLine(hbuf, ln++, strHeader#" */")
/*Relocate window*/
ScrollWndToLine(hwnd, symbolrecord.lnFirst)
}
/*!
* Insert the doxygen style comments of function.
*/
macro GDoxyFunctionComment()
{
var hWnd
var hBuf
var ln
var symbolrecord
var strHeader
var locateLn //locate info after insert comments
var locateCur //locate info after insert comments
/*prepare*/
hWnd = GetCurrentWnd()
hBuf = GetCurrentBuf()
if(hBuf == hNil || hWnd == hNil)
{
Msg("Can't open the file")
stop
}
ln = GetBufLnCur(hBuf)
symbolrecord = GetSymbolLocationFromLn(hBuf, ln)
if(symbolrecord == Nil)
{
Msg("Can't get current symbol record info.")
stop
}
/*check current symbol type*/
var type
type = symbolrecord.Type
if(type != "Function" && type != "Function Prototype" &&
type != "Method" && type != "Method Prototype")
{
Msg("Current symbol is not a function.")
stop
}
/*Get need information*/
ln = symbolrecord.lnFirst
locateLn = ln + 1 //locate info after insert comments
strHeader = GGetHeaderSpaceByLn(hBuf, ln)//align with the current function
//analysis function
var name
var type
var childrenInfo//construct a record.Because SI macro language doesn't have array type, so we append all the info into one string
var strSeparate
childrenInfo.count = 0
childrenInfo.name = ""
childrenInfo.type = ""
strSeparate = "?"
var nChild
var listChild
listChild = SymbolChildren(symbolrecord)
nChild = SymListCount(listChild)
if(nChild != invalid)
{
var idxChildList
var childsym
idxChildList = 0
while(idxChildList < nChild)
{
childsym = SymListItem(listChild, idxChildList)
if(childsym.Type == "Parameter")//function param
{
name = GGetSymExactName(childsym.Symbol)
childrenInfo.count = childrenInfo.count + 1
childrenInfo.name = childrenInfo.name#name#strSeparate
childrenInfo.type = childrenInfo.type#"FuncParam"#strSeparate
}
else if(childsym.Type == "Type Reference")//function type, it referes to the return type
{
name = GGetSymExactName(childsym.Symbol)
childrenInfo.count = childrenInfo.count + 1
childrenInfo.name = childrenInfo.name#name#strSeparate
childrenInfo.type = childrenInfo.type#"FuncType"#strSeparate
}
idxChildList++
}
}
SymListFree(listChild)
/*Insert comments*/
InsBufLine(hBuf, ln++, strHeader#"/*!")
InsBufLine(hBuf, ln++, strHeader#" * ")//Function description
locateCur = strlen(strHeader#" * ")//locate info after insert comments
InsBufLine(hBuf, ln++, strHeader#" * \\n")
InsBufLine(hBuf, ln++, strHeader#" *")
var index
index = 0
while(index < childrenInfo.count)
{
type = GGetStringBySeparateCh(childrenInfo.type, strSeparate, index)
name = GGetStringBySeparateCh(childrenInfo.name, strSeparate, index)
if(type == "FuncParam")
{
InsBufLine(hBuf, ln++, strHeader#" * @@param @[email protected]")//[in/out]
}
else if(type == "FuncType" && name != "void")
{
InsBufLine(hBuf, ln++, strHeader#" * @@return")
//InsBufLine(hBuf, ln++, strHeader#" * @@retval value description")//different style
}
++index
}
InsBufLine(hBuf, ln++, strHeader#" * \\n")
InsBufLine(hBuf, ln++, strHeader#" * @@see")
InsBufLine(hBuf, ln++, strHeader#" */")
//locate the cursor
SetBufIns(hBuf, locateLn, locateCur)
}
/*!
* Insert example codes after the cursor line with doxygen style in the block
*comments.
*/
macro GDoxyInsExampleCodes()
{
var hbuf
hbuf = GetCurrentBuf()
if(hbuf == hNil)
{
Msg("Current file handler is invalid.")
stop
}
var lnCursor
lnCursor = GetBufLnCur(hbuf)
var strHead
strHead = GGetHeaderSpaceByLn(hbuf, lnCursor)
lnCursor++ ///<after the line of the cursor to insert the codes
InsBufLine(hbuf, lnCursor++, strHead#"*")
InsBufLine(hbuf, lnCursor++, strHead#"* @@code")
///reserve four line to insert example codes
var locateLn
var locateCol
locateLn = lnCursor
locateCol = strlen(strHead#"*")
InsBufLine(hbuf, lnCursor++, strHead#"*")
InsBufLine(hbuf, lnCursor++, strHead#"*")
InsBufLine(hbuf, lnCursor++, strHead#"*")
InsBufLine(hbuf, lnCursor++, strHead#"*")
InsBufLine(hbuf, lnCursor++, strHead#"* @@endcode")
//locate cursor
SetBufIns(hbuf, locateLn, locateCol)
}
/*!
*Insert a doxygen common comments before the line of cursor.
*/
macro GDoxyInsBlockComment()
{
var hbuf
hbuf = GetCurrentBuf()
if(hbuf == hnil)
{
msg("Current file handler is invalid.")
stop
}
var lnCursor
lnCursor = GetBufLnCur(hbuf)
var strHeader
var lnIter
lnIter = lnCursor
strHeader = GGetHeaderSpaceByLn(hbuf, lnCursor)
InsBufLine(hbuf, lnIter++, strHeader#"/*!")
InsBufLine(hbuf, lnIter++, strHeader#" *")
InsBufLine(hbuf, lnIter++, strHeader#" *")
InsBufLine(hbuf, lnIter++, strHeader#" */")
SetBufIns(hbuf, lnCursor + 1, strlen(strHeader#" *"))
}
/*!
* Insert the doxygen style comments of enumeration.
* @note
* Make sure the cursor in the enumeration region before call this macro.
*/
macro GDoxyEnumComment()
{
var hbuf
hbuf = GetCurrentBuf()
if(hbuf == hNil)
{
Msg("Current file handler is invalid.")
stop
}
var lnCursor
lnCursor = GetBufLnCur(hbuf)
var eSymbol
eSymbol = GGetEnumSymbol(hbuf, lnCursor)
if(eSymbol == Nil)
{
Msg("The symbol at the cursor looks like not a enumeration.")
stop
}
var strHeader
var strTemp
strHeader = GGetHeaderSpaceByLn(hbuf, eSymbol.lnFirst)
//reset the symbol's first and last line text
strTemp = GetBufLine(hbuf, eSymbol.lnFirst)
idxSearch = GStrStr(strTemp, "{")
strTemp = strmid(strTemp, 0, idxSearch + 1)
PutBufLine(hbuf, eSymbol.lnFirst, strTemp)
strTemp = GetBufLine(hbuf, eSymbol.lnLast)
idxSearch = GStrStr(strTemp, "}")
strTemp = strmid(strTemp, idxSearch, strlen(strTemp))
PutBufLine(hbuf, eSymbol.lnLast, strTemp)
//delete the lines text before
var lnIter
lnIter = eSymbol.lnLast - 1
while(lnIter > eSymbol.lnFirst)
{
DelBufLine(hbuf, lnIter)
lnIter--
}
//rewrite members and insert comments
var nMembers
nMembers = 0
lnIter = eSymbol.lnFirst + 1
while(nMembers < eSymbol.count)
{
strTemp = GGetStringBySeparateCh(eSymbol.members, eSymbol.chSeparator, nMembers)
if(!(GStrBeginWith(strTemp, "#if") || GStrBeginWith(strTemp, "#end") || GStrBeginWith("#else")))
{
strTemp = GStrAppendTailSpace(strTemp, eSymbol.maxMemberLen)
strTemp = strHeader#" "#strTemp#" ///!<"
}
InsBufLine(hbuf, lnIter, strTemp)
nMembers++
lnIter++
}
//locate cursor
SetBufIns(hbuf, eSymbol.lnFirst + 1, strlen(strTemp))
}
///////////////////////////////////////////////////////////////////////////////
/// Tool macros under.These macros are offering service for the other macros.
///Note:It's not need to assign keys or menus for the macros under, even if you
///can do this operation.
///////////////////////////////////////////////////////////////////////////////
/*!
* Get the enumeration info,if the symbol at the cursor is not a enumeration,
*it will return a Nil symbol recorder.
*
*construct an enumeration symbol recorder,it contains the fields:
* type enum type name
* members string of members which is separated by specail character, and the spaces will be deleted
* chSeparator the separate character of members
* count the number of the members
* lnFirst symbol first line
* lnLast symbol last line
* maxMemberLen the longest member's character number
*/
macro GGetEnumSymbol(hbuf, lnCursor)
{
var eSymbol
var region
region = GGetEnumRegion(hbuf, lnCursor)
if(region == Nil)
{//can't get enumeration symbol info
return Nil
}
eSymbol.type = nil
eSymbol.members = nil
eSymbol.chSeparator = ";"
eSymbol.count = 0
eSymbol.maxMemberLen= 0
eSymbol.lnFirst = region.first
eSymbol.lnLast = region.last
//analysis codes
var lenMember//the length of the enumeration's one member
var lnIter //line iterator from the enumeration's first line to the last
var lnString //used to get the string text of one line
var tempStr //used to contains the member string
var lenLnStr //the character num of the string of line
var isComment//indicate whether need to skip the characters
lnIter = eSymbol.lnFirst
isComment = false
lenMember = 0
while(lnIter <= eSymbol.lnLast)
{
tempStr = nil
lnString = Nil
//get line text
lnString = GetBufLine(hbuf, lnIter)
lenLnStr = strlen(lnString)
if(lenLnStr == 0)
{
lnIter++
continue
}
//deal with the indicator
lenLnStr = strlen(lnString)
lIndicate= GStrStr(lnString, "{")
if(lIndicate != invalid)
{
lIndicate++//skip "{" character
lnString = strmid(lnString, lIndicate, lenLnStr)
}
rIndicate= GStrStr(lnString, "}")
lenLnStr = strlen(lnString)
if(rIndicate != invalid)
{
lnString = strmid(lnString, 0, rIndicate)
}
//prepare the pure string
lnString = GStrTrimJustify(lnString)//GStrRemoveAllSpace(lnString)
lenLnStr = strlen(lnString)
if(lenLnStr == 0)
{
lnIter++
continue
}
//analysising
ich = 0
while(ich < lenLnStr)
{
if(!isComment && lnString[ich] == "/" && lnString[ich+1] == "/")
{//don't need to analysis the rest charaters in this line
break
}
if(lnString[ich] == "/" && lnString[ich+1] == "*")
{
isComment = true
}
if(!isComment)
{
if(lnString[ich] == "," && tempStr != nil)
{//it is possible that one line has several members
tempStr = GStrTrimJustify(tempStr)
tempStr = cat(tempStr, lnString[ich])
lenMember = strlen(tempStr)
if(lenMember != 0)
{
eSymbol.members = eSymbol.members#tempStr#";"
eSymbol.count = eSymbol.count + 1
if(lenMember > eSymbol.maxMemberLen)
{
eSymbol.maxMemberLen = lenMember
}
}
tempStr = nil
}
else
{
tempStr = cat(tempStr, lnString[ich])
}
}
if(lnString[ich] == "*" && lnString[ich+1] == "/")
{
ich++
isComment = false
}
ich++
}
tempStr = GStrTrimJustify(tempStr)
lenMember = strlen(tempStr)
if(lenMember != 0)
{
eSymbol.members = eSymbol.members#tempStr#";"
eSymbol.count = eSymbol.count + 1
if(lenMember > eSymbol.maxMemberLen)
{
eSymbol.maxMemberLen = lenMember
}
}
lnIter++
}
return eSymbol
}
/*!
*Get the enumeration region which contains the first line and last line.
*The first line is the "{" appears line.
*The last line is the "}" appears line.
*/
macro GGetEnumRegion(hbuf, lnCursor)
{
//variables
var region
var tempStr
var lnIter
var iAppear
var lnMax//file line count
region = Nil
tempStr = Nil
iAppear = invalid
//first line
lnIter = lnCursor
while(lnIter >= 0)
{
tempStr = GetBufLine(hbuf, lnIter)
iAppear = GStrStr(tempStr, "{")
if(iAppear != invalid)
{
region.first = lnIter
break
}
lnIter--
}
if(lnIter < 0)
{
return Nil
}
//last line
lnIter = lnCursor
iAppear = invalid
lnMax = GetBufLineCount(hbuf)
while(lnIter < lnMax)
{
tempStr = GetBufLine(hbuf, lnIter)
iAppear = GStrStr(tempStr, "}")
if(iAppear != invalid)
{
region.last = lnIter
break
}
lnIter++
}
if(lnIter == lnMax)
{
return Nil
}
return region
}
/*!
* Get a string from strParent which is separate by character.
* @note
* The separate character that at the begining will be ignored.
*
* Example 1:
* ch = ";"
* strParent = "first;second;third;"
* If index equals 0, it will return "first"
* If index equals 1, it will return "second"
* If index equals 2, it will return "third"
* If index equals 3, it will return ""
* ...
*
* Example 2:
* ch = ";"
* strParent = ";first;second;third;"
* If index equals 0, it will return "first"
* If index equals 1, it will return "second"
* If index equals 2, it will return "third"
* ...
*/
macro GGetStringBySeparateCh(strParent, ch, index)
{
/*variables*/
var len
var iChBeg
var iChEnd
var iLoop
var countIdx
var checkEndIdx
/*codes*/
len = strlen(strParent)
if(0 == len)
{
return Nil
}
iChBeg = 0 //result begin index
while(iChBeg < len)
{//ignore all the characters ch that at the begin o strParent
if(strParent[iChBeg] == ch)
{
iChBeg++
}
else
{
break
}
}
iChEnd = iChBeg //result end index
iLoop = iChBeg
countIdx = 0
checkEndIdx = False
while(iLoop < len)
{
if(countIdx == index)
{
checkEndIdx = True
}
if(strParent[iLoop] == ch)
{
if(checkEndIdx)
{//get end index
iChEnd = iLoop
break
}
else
{//get begin index
countIdx++
iChBeg = iLoop + 1
}
}
iLoop++
}
if(iChBeg == iChEnd)
{
if(index == 0)
{
return strParent
}
else
{
return Nil
}
}
if(index != countIdx)
{
return Nil
}
return strmid(strParent, iChBeg, iChEnd)
}
以下是工具巨集,GToolMacros.em:
/******************************************************************************
* String macros definition
*****************************************************************************/
/*!
* Insert spaces at the begining of string until the string's length reaches
* lenMax.It will return string itself if the string's length is less then
* lenMax.
*/
macro GStrInsertHeadSpace(string, lenMax)
{
var len
var nSpace
var tempStr
len = strlen(string)
nSpace = lenMax - len
tempStr= nil
while(nSpace > 0)
{
tempStr = cat(tempStr, " ")
nSpace--
}
return cat(tempStr, string)
}
/*!
* Append spaces at the end of string until string's length reaches lenMax.It
* will returns the string itself if the string's length is less then lenMax.
*/
macro GStrAppendTailSpace(string, lenMax)
{
nStr = strlen(string)
while(nStr < lenMax)
{
string = cat(string, " ")
nStr++
}
return string
}
/*!
*Test whether the string contains the character ch.
*/
macro GStrContainsCh(string, ch)
{
var index
index = GStrStr(string, ch)
if(index == invalid)
{
return False
}
return True
}
/*!
* Returns the last place of appearance that the ch appears in string.
* If the ch is not appears in string, it will returns invalid(-1).
*/
macro GStrRFind(string, ch)
{
var len
var idx
len = strlen(string)
idx = len - 1
while(idx >= 0)
{
if(string[idx] == ch)
{
break
}
idx--
}
return idx
}
/*!
* Test whether all the characters in the string are spaces.
*/
macro GStrAllSpace(string)
{
len = strlen(string)
iter = 0
while(iter < len)
{
if(!GIsCharSpace(string[iter]))
{
return false
}
iter++
}
return true
}
/*!
*Test if string is empty.
* @param string need to be tested string
* @retval True the string is empty
* @retval False the string is not empty
*/
macro GStrEmpty(string)
{
var len
len = strlen(string)
if(len == 0)
{
return True
}
return False
}
/*!
*Remove all the space and tab characters in the string.
*/
macro GStrRemoveAllSpace(string)
{
var len
var idx
var str
len = strlen(string)
idx = 0
str = Nil
while(idx < len)
{
if(!GIsCharSpace(string[idx]))
{
str = cat(str, string[idx])
}
idx++
}
return str
}
/*!
*Remove the space and tab characters at the begin and end of string.
*/
macro GStrTrimJustify(string)
{
var len
var index //first not space character index
var rIndex //last not space character index
len = strlen(string)
index = 0
while(index < len)
{
if(GIsCharSpace(string[index]))
{
index++
}
else
{
break
}
}
if(index == len)
{
return nil
}
rIndex = len - 1
while(rIndex >= 0)
{
if(GIsCharSpace(string[rIndex]))
{
rIndex--
}
else
{
break
}
}
rIndex++ //strmid function will not get the character at rIndex palce
return strmid(string, index, rIndex)
}
/*!
* Remove the characters between the index iFirst and index iEnd from string.
* The character at iFirst and iEnd will be deleted also.
*/
macro GStrRemoveStrByIndex(string, iFirst, iEnd)
{
var len
len = strlen(string)
if(iFirst < 0 || iEnd < 0 || iEnd > len || iFirst > len || iEnd < iFirst)
{
return string
}
var temp
temp = nil
temp = strmid(string, 0, iFirst)
temp = cat(temp, strmid(string, iEnd + 1, len))
return temp
}
/*!
*GStrStr
* Test whether the strTest is existing in strSrc.And returns
*the place where the strTest first appears.Otherwise returns
*-1.
*/
macro GStrStr(strSrc, strTest)
{
var nSrc
var nTest
nSrc = strlen(strSrc)
nTest = strlen(strTest)
if(nTest == 0)
{
return 0
}
else if(nSrc == 0)
{
return invalid
}
var iSrc
var iTest
iSrc = 0
iTest = 0
while(iSrc < nSrc)
{
iTest = 0
while(iTest < nTest)
{
if(strSrc[iSrc+iTest] == strTest[iTest])
{
iTest++
}
else
{
break
}
}
if(iTest == nTest)
{
return iSrc
}
iSrc++
}
return invalid
}
/*!
*GIsCharSpace
* Test whether the char ch is a space or a tab character.
*/
macro GIsCharSpace(ch)
{
if(ch == Nil)
{
return False
}
if(AsciiFromChar(ch) == 9 || AsciiFromChar(ch) == 32)
{
return True
}
return False
}
/*!
*Test whether the string is begin wiht string with.
*note:
* it will ignore the first spaces
*/
macro GStrBeginWith(string, with)
{
string = GStrTrimJustify(string)
index = GStrStr(string, with)
if(index == 0)
{
return true
}
return false
}
/******************************************************************************
* File and buffer macros definition
*****************************************************************************/
/*!
*GGetHeaderSpaceByLn
* Get the spaces that at the begin of line in the hbuf file.
*note
* Make sure the hbuf is a valid handler, and the line number is a
*valid line for hbuf.
*/
macro GGetHeaderSpaceByLn(hbuf, line)
{
var headSpace
headSpace = ""
var strContent
var len
strContent = GetBufLine(hbuf, line)
len = strlen(strContent)
var idx
idx = 0
while(idx < len)
{
if(GIsCharSpace(strContent[idx]))
{
headSpace = cat(headSpace, strContent[idx])
}
else
{
break
}
idx++
}
return headSpace
}
/*
*GGetFileName
* Get file name from file full path.
*/
macro GGetFileName(fFullName)
{
var nLength
var fName
nLength = strlen(fFullName)
fName = ""
var i
var ch
i = nLength - 1
while(i >= 0)
{
ch = fFullName[i]
if("@[email protected]" == "\\")
{
i++ //don't take the '\' charater
break
}
i--
}
fName = strmid(fFullName, i, nLength)
return fName
}
/******************************************************************************
* Symbol macros definition
*****************************************************************************/
/*!
* If we get the symbol name by symbolrecord.Symbol, we will get the string
*like class.func, func.void, et.This function will get the last one name that
*seperate by ".".
* @param[in] symbol is the Symbol Record's Symbol field
*note
* see Symbol Record of SI macro language
*/
macro GGetSymExactName(symbol)
{
var len
var idxAppear
var strRet
len = strlen(symbol)
idxAppear = GStrRFind(symbol, ".")
if(idxAppear == invalid)
{//can't get the expectant name, return the default one
return symbol
}
idxAppear++
strRet = strmid(symbol, idxAppear, len)
return strRet
}
在編寫的過程中,發現SI指令碼中沒有陣列的功能,但是又經常需要用到這樣的功能,所以寫了幾個方法,來模仿陣列:
/******************************************************************************
* self-defining array macros definition
*
*Note the under ideas:
* 1.Since the source insight macro language is only support string variable,
*so the array is implemented as string.
* 2.The array string looks like string "item1;item2;item3".And the separator
*character is ";" which can be specified by yourself.
* 3.The array index is begin with 0.And the separator can't be a string, it
*only can contains one character.
* 4.The item can be a empty string, such as set array like this "item1;;item3",
*and the second item is a empty string.
* 5.When using this array type, please reset the array value when the array
*changed no matter whatever the operation is.Because the source insight don't
*support the output parameter.
* 6.If you assign the array string by yourself, please make sure the end
*character is separator.
* 7.The character separator is not a part of item string.And it must be not
*empty.Don't set it as the character that source insight not support in string.
*****************************************************************************/
/*!
* Append an item at the back.If the separator is empty, it will do nothing.
* Returns the new array string.
*
* @code
* item = "itemN"
* separator = "?"
* array = GArrayAppendItem(array, item, separator)
* @endcode
*/
macro GArrayAppendItem(array, item, separator)
{
if(GStrEmpty(separator))
{//separator is needed even though the arry or item is empty
return array
}
return array#item#separator
}
/*!
* Insert an item at index place, and after this operation, the item at the
* index will be the inserted item.
* If the index is larger then the array's count,the item will not be appended.
* If the index is a negative number or the separator is empty, this macro
* will do nothing.
* Returns the new array string.
*/
macro GArrayInsertItem(array, index, item, separator)
{
if(index < 0 || GStrEmpty(separator))
{
return array
}
var cItem
var len
var iter
var iInsert
iter = 0
len = strlen(array)
cItem = 0
iInsert = 0
while(iter < len)
{
if(cItem == index)
{
iInsert = iter
break
}
if(array[iter] == separator)
{
cItem++
}
iter++
}
if(iter == len && cItem <= index)
{
return GArrayAppendItem(array, item, separator)
}
return cat(strmid(array, 0, iInsert)#item#separator, strmid(array, iInsert, len))
}
/*!
* Returns the count of array.That is the array's items num.It will returns
* an error if the separator is empty.
*/
macro GArrayGetCount(array, separator)
{
if(GStrEmpty(separator))
{
return invalid
}
var count
var len
count = 0
len = strlen(array)
if(len == 0)
{
return count
}
var ich
ich = 0
while(ich < len)
{
if(array[ich] == separator)
{
count++
}
ich++
}
return count
}
/*!
* Remove the items that is referened by item string from array and returns
* the new array string.
* It will do nothing if the item is not in the array.If item string appears
* not one time in array it will revome all the item string from array.
*/
macro GArrayRemoveItemByItem(array, item, separator)
{
if(GStrEmpty(separator))
{
return array
}
var iter
var itemIter //one item string
var len
var itemIdx//current item index
var nArray //new array string
iter = 0
itemIdx = -1
len = strlen(array)
nArray = nil
iBegin = 0 //current item start index
while(iter < len)
{
if(array[iter] == separator)
{
iEnd = iter //set current item end index
itemIdx++
itemIter = strmid(array, iBegin, iEnd)
if(itemIter != item)
{
nArray = cat(nArray, itemIter#separator)
}
iBegin = iter + 1
}
iter++
}
return nArray
}
/*!
* Remove an item that is at the index of array.It will do nothing if the
* index is larger then the array's count.
* Returns the new array string.
*/
macro GArrayRemoveItemByIndex(array, index, separator)
{
if(index < 0 || GStrEmpty(separator))
{
return array
}
var iter //character iterator of array
var itemStart //the index item string's start character index
var itemEnd //the index item string's end character index
var cItem //indicates the current item index that is dealing with
var len //character num of array
itemStart = 0
itemEnd = invalid
iter = 0
cItem = -1
len = strlen(array)
while(iter < len)
{
if(array[iter] == separator)
{
cItem++
if(cItem == index)
{
itemEnd = iter + 1
}
else
{
itemStart = iter + 1
}
}
if(itemEnd != invalid)
{
break
}
iter++
}
if(itemEnd == invalid)
{
return array
}
return cat(strmid(array, 0, itemStart), strmid(array, itemEnd, len))
}
/*!
* Get the index item from array.It will returns an empty string if the index
* is larger then the array's count or the item at index is empty.
* Returns the item string at index.
*/
macro GArrayGetItemByIndex(array, index, separator)
{
if(index < 0 || GStrEmpty(separator))
{
return nil
}
var item
var iter
var cItem
var len
item = nil
iter = 0
len = strlen(array)
cItem = -1 //It starts at 0
while(iter < len)
{
if(array[iter] == separator)
{
cItem++
if(cItem == index)
{
break
}
item = nil
}
else
{
item = cat(item, array[iter])
}
iter++
}
return item
}
/*!
* Get the index of the item.It will returns -1 if the item is not in the
* array.It will only get the index of the item that first appears in array if
* the item is not a only one.
* If the separator is empty it will return -1.
*/
macro GArrayGetItemIndex(array, item, separator)
{
if(GStrEmpty(separator))
{
return invalid
}
var iter
var len
var itemIdx//current item index
iter = 0
itemIdx = -1
len = strlen(array)
iBegin = 0 //current item start index
while(iter < len)
{
if(array[iter] == separator)
{
iEnd = iter //set current item end index
itemIdx++
if(strmid(array, iBegin, iEnd) == item)
{
return itemIdx
}
else
{
iBegin = iter + 1
}
}
iter++
}
return invalid
}
/*!
* Check whether the item is in the array.
* If the separator is empty, it will always returns false.
*/
macro GArrayIsItemExist(array, item, separator)
{
if(GStrEmpty(separator))
{
return false
}
else
{
if(GArrayGetItemIndex(array, item, separator) != invalid)
{
return true
}
}
return false
}
以上的巨集並沒有花費很多時間去測試是否存在問題,但是基本上能夠工作吧我想,呵呵,大家要是願意,如果發現問題可以告知我。
使用的時候只要把檔案加入到SI的base工程裡面,然後把功能巨集新增到選單就能夠使用了,如果有什麼問題可以上網搜尋下就好了。
相關推薦
給source insight新增doxygen註釋風格
目前專案組對於註釋的要求比較高,導致我添加註釋的時候非常煩,大量的重複勞動確實很煩人,自己也一直打算給source insight新增類似的功能,可能是本人比較懶,一直不想做這樣的工作。不過,既然可以一勞永逸,何樂而不為呢。 後來發現有個叫doxygen的工
為Source Insight新增TODO、FIXME等註釋標籤的高亮
在程式中加入TODO、FIXME等特殊的註釋標籤有助於提高程式碼編寫效率,特別是多人協作的情況下。一般用法如下: TODO: + 說明: 如果程式碼中有該標識,說明在標識處有功能程式碼待編寫,待實現的功能在說明中會簡略說明。 FIXME:
[Xcode10 實際操作]九、實用進階-(3)給程式碼方法新增巨集註釋
本文將演示如何在方法列表中,對方法名稱進行註釋。 這樣可以使程式,按功能分塊,使方法清晰、易讀並且方便定位。 在專案導航區,開啟檢視控制器的程式碼檔案【ViewController.swift】 1 import UIKit 2 3 class ViewController: UIVi
source insight 新增系統庫函式原始碼(包含原始碼下載下載地址)
1、在BASE專案下新增Project->Open Project ,開啟Base專案2、開啟PreferencesProject->Preferences,選擇Symbol Lookups選項卡3、開啟Import Symbols for All
符合 Doxygen 註釋風格的 SourceInsight 巨集
Source-Insight-Macro 一、簡介 1.自定義組織資訊 2.Doxygen風格的函式註釋以及Todo標籤 3.Doxygen格式的單行註釋風格 二、FAQ 1.關於SourceIn
如何使用PDF編輯軟體給PDF檔案新增文字註釋
現在PDF檔案使用的越來越普遍了,PDF檔案在我們日常的工作中,甚至生活中都會使用的到,PDF檔案的修改是需要使用PDF編輯軟體,那麼,如何使用PDF編輯軟體給PDF檔案新增文字註釋呢,不會的小夥伴可以跟小編一起來看看下面的文章,沒準就知道該怎樣操作了哦。
Python:給圖形中新增文字註釋(text函式)
以下這個案例,基本上是我們平時註釋用的最多的,其基本思想就是,找到你想要註釋的那個位置,進行註釋,有的時候可以覺得用定死的方式來做,顯示出的效果也會很好。 平時可以多看看官網教程:text #!/usr/bin/python #coding: utf-8
source Insight 解決中文註釋亂碼問題
繼上次SI多標籤外掛之後,因為公司內部編碼改為utf8編碼,因此特意做了這個Source Insight 3.X utf8外掛. 下載地址:[點我] 安裝說明: 解壓msimg32.dll sihook.dll siutf8.dll 到Source Insight 3.X安裝目錄 msimg32.dll
Source insight新增工具自動排版 20170307
當在網上找了一些別人的程式拿來學習,用Source insight來看時,會不會因為程式碼太亂看了義憤填膺呢? 有很多整合的開發環境可以自動排版,但source insight卻不行!不過,有工具和配置,可以幫助完成這個事情: 1,下載astyle工具:http://download.csdn.net
Source Insight通過快捷按鍵新增多種程式碼註釋
Base project -> Utils.em: macro getTime() { Time = GetSysTime(1) Year = Time.Year Mon = Time.Month Day = Time
使用source insight 巨集來插入doxygen可處理的註釋
巨集檔案如下。 設定快捷鍵後,雙擊高亮要註釋的內容,使用快捷鍵觸發即可。 可自動識別 普通:在頭部新增 巨集:在末尾添加註釋 變數:在末尾新增 函式:在頭部新增,並自動識別函式個數 類:在頭部新增 程式碼如下:儲存為m.em即可加入source insight m
Source Insight 中文註釋為亂碼解決辦法(完美解決,一鍵搞定)【轉】
ash save sys lan sim edit ext pan character 轉自:http://blog.csdn.net/bjarnecpp/article/details/70174752 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 S
Doxygen 常用指令以及C++註釋風格
在註釋中加一些Doxygen支援的指令,主要作用是控制輸出文件的排版格式,使用這些指令時需要在前面加上“\”或者“@”(JavaDoc風格)符號,告訴Doxygen這些是一些特殊的指令,通過加入這些指令以及配備相應的文字,可以生成更加豐富的文件
Source Insight 中文註釋為亂碼解決辦法(完美解決,一鍵搞定)
我從網上查了一堆解決辦法,但是都是2017年以前的解決方案,並且都是針對於source insight 3.5及以下版本的,目前SI軟體版本都到4.0了,應該有新方法出現了。 —————————————————————————————————————— 乾貨:Source
source insight配置(自動排版,多標籤顯示,註釋,刪除中文亂碼)
一.下載ASTYLE_2.0(自動排版) 1,http://pan.baidu.com/s/1nu5Apdv 2,開啟你的SourceInsight, 選擇選單“Options–>Custom Commands–>Add”, 輸入Artistic
Source Insight中文註釋為亂碼解決方案
我從網上查了一堆解決辦法,但是都是2017年以前的解決方案,並且都是針對於source insight 3.5及以下版本的,目前SI軟體版本都到4.0了,應該有新方法出現了。 —————————————————————————————————————— 乾貨:Source
sql server2008給資料表,欄位,新增修改註釋
1、sqlserver用語句給表註釋 EXECUTE sp_addextendedproperty N'MS_Description', N'表註釋', N'user', N'dbo', N'table', N'表名', NULL, NULL 2、sqlserver用語句給表的“欄位”註釋 EXECUT
ubuntu14.04中 gedit 註釋能顯示中文,而source insight中顯示為亂碼的解決辦法
1.亂碼顯示情況: 2.用gedit開啟檔案,並用ctrl+shift+s(另存為),其中charactor coding選為chinese simplified(GB2312); 2.修改個檔名, 並點選save. 3.用source insight開啟,看看是不是不
Source Insight中文註釋字間距過大問題的解決
Source Insight是一個面向專案開發的程式編輯器和程式碼閱讀工具,它擁有內建的對C/C++, C#和Java等程式的分析,分析你的原始碼並在你工作的同時動態維護它自己的符號資料庫,並自動為你顯示有用的上下文資訊。 Source Insight不僅僅是一個強大的程式編輯器,它還能顯示referen
source insight筆記___批量註釋,去掉中文註釋文字間的空格
-------------------------------------------------------------------------------------------------------------------------- Source Insight