1. 程式人生 > >給source insight新增doxygen註釋風格

給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    @

[email protected]")
    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  @
[email protected]
")
    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