VirtualBox

Changeset 96401 in vbox for trunk/src/bldprogs/scmparser.cpp


Ignore:
Timestamp:
Aug 22, 2022 3:06:19 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
153218
Message:

bldprogs/scm: Teach it to replace the old copyright and license notices with the updated ones (e.g. GPlv2 to GPLv3).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bldprogs/scmparser.cpp

    r93115 r96401  
    9595
    9696
     97/** Macro for checking for a XML comment start. */
     98#define IS_XML_COMMENT_START(a_pch, a_off, a_cch) \
     99        (   (a_off) + 4 <= (a_cch) \
     100         && (a_pch)[(a_off)    ] == '<' \
     101         && (a_pch)[(a_off) + 1] == '!' \
     102         && (a_pch)[(a_off) + 2] == '-' \
     103         && (a_pch)[(a_off) + 3] == '-' \
     104         && ((a_off) + 4 == (a_cch) || RT_C_IS_SPACE((a_pch)[(a_off) + 4])) )
     105
     106/** Macro for checking for a XML comment end. */
     107#define IS_XML_COMMENT_END(a_pch, a_off, a_cch) \
     108        (   (a_off) + 3 <= (a_cch) \
     109         && (a_pch)[(a_off)    ] == '-' \
     110         && (a_pch)[(a_off) + 1] == '-' \
     111         && (a_pch)[(a_off) + 2] == '>')
     112
     113
    97114/** Macro for checking for a batch file comment prefix. */
    98115#define IS_REM(a_pch, a_off, a_cch) \
     
    199216    off += cchSkip;
    200217
    201     /* Determin comment type. */
     218    /* Determine comment type. */
    202219    Info.enmType = kScmCommentType_Line;
    203220    char ch;
     
    340357
    341358/**
    342  * Common string litteral handler.
     359 * Common string literal handler.
    343360 *
    344361 * @returns new pchLine value.
     
    352369 * @param   poff        Pointer to the line offset variable.
    353370 */
    354 static const char *handleStringLitteral(PSCMSTREAM pIn, char chType, const char *pchLine, size_t *pcchLine, PSCMEOL penmEol,
    355                                         uint32_t *piLine, size_t *poff)
     371static const char *handleStringLiteral(PSCMSTREAM pIn, char chType, const char *pchLine, size_t *pcchLine, PSCMEOL penmEol,
     372                                       uint32_t *piLine, size_t *poff)
    356373{
    357374    size_t off = *poff;
     
    443460                        Info.cBlankLinesBefore  = 0;
    444461
    445                         /* Determin comment type (same as for line-comments). */
     462                        /* Determine comment type (same as for line-comments). */
    446463                        Info.enmType = kScmCommentType_MultiLine;
    447464                        if (   off < cchLine
     
    594611            {
    595612                /*
    596                  * String litterals may include sequences that looks like comments.  So,
     613                 * String literal may include sequences that looks like comments.  So,
    597614                 * they needs special handling to avoid confusion.
    598615                 */
    599                 pchLine = handleStringLitteral(pIn, '"', pchLine, &cchLine, &enmEol, &iLine, &off);
     616                pchLine = handleStringLiteral(pIn, '"', pchLine, &cchLine, &enmEol, &iLine, &off);
    600617            }
    601             /* else: We don't have to deal with character litterals as these shouldn't
     618            /* else: We don't have to deal with character literal as these shouldn't
    602619                     include comment-like sequences. */
    603620        } /* for each character in the line */
     
    659676            {
    660677                /*
    661                  * String litterals may be doc strings and they may legally include hashes.
     678                 * String literal may be doc strings and they may legally include hashes.
    662679                 */
    663680                const char chType = ch;
     
    665682                    || pchLine[off] != chType
    666683                    || pchLine[off + 1] != chType)
    667                     pchLine = handleStringLitteral(pIn, chType, pchLine, &cchLine, &enmEol, &iLine, &off);
     684                    pchLine = handleStringLiteral(pIn, chType, pchLine, &cchLine, &enmEol, &iLine, &off);
    668685                else
    669686                {
     
    806823                    break;
    807824            }
    808             /* else: We don't have to deal with character litterals as these shouldn't
     825            /* else: We don't have to deal with character literal as these shouldn't
    809826                     include comment-like sequences. */
     827        } /* for each character in the line */
     828
     829        iLine++;
     830    } /* for each line in the stream */
     831
     832    int rcStream = ScmStreamGetStatus(pIn);
     833    if (RT_SUCCESS(rcStream))
     834        return rcRet;
     835    return rcStream;
     836}
     837
     838
     839/**
     840 * Deals with XML comments.
     841 *
     842 * @returns VBox status code / callback return code.
     843 * @param   pIn                 The stream to parse.
     844 * @param   pfnCallback         The callback.
     845 * @param   pvUser              The user parameter for the callback.
     846 */
     847static int enumerateXmlComments(PSCMSTREAM pIn, PFNSCMCOMMENTENUMERATOR pfnCallback, void *pvUser)
     848{
     849    int             rcRet = VINF_SUCCESS;
     850    uint32_t        iLine = 0;
     851    SCMEOL          enmEol;
     852    size_t          cchLine;
     853    const char     *pchLine;
     854    while ((pchLine = ScmStreamGetLine(pIn, &cchLine, &enmEol)) != NULL)
     855    {
     856        size_t off = 0;
     857        while (off < cchLine)
     858        {
     859            /*
     860             * Skip leading blanks and check for start of XML comment.
     861             */
     862            while (off + 3 < cchLine && RT_C_IS_SPACE(pchLine[off]))
     863                off++;
     864            if (IS_XML_COMMENT_START(pchLine, off, cchLine))
     865            {
     866                /*
     867                 * XML comment.  Find the end.
     868                 *
     869                 * Note! This is very similar to the python doc string handling above.
     870                 */
     871                SCMCOMMENTINFO  Info;
     872                Info.iLineStart         = iLine;
     873                Info.offStart           = (uint32_t)off;
     874                Info.iLineEnd           = UINT32_MAX;
     875                Info.offEnd             = UINT32_MAX;
     876                Info.cBlankLinesBefore  = 0;
     877                Info.enmType            = kScmCommentType_Xml;
     878
     879                off += 4;
     880
     881                /*
     882                 * Copy the body and find the end of the XML comment.
     883                 */
     884                size_t          cbBodyAlloc = 0;
     885                size_t          cchBody     = 0;
     886                char           *pszBody     = NULL;
     887                for (;;)
     888                {
     889                    /* Parse the line up to the end-of-comment or end-of-line. */
     890                    size_t offLineStart     = off;
     891                    size_t offLastNonBlank  = off;
     892                    size_t offFirstNonBlank = ~(size_t)0;
     893                    while (off < cchLine)
     894                    {
     895                        if (!IS_XML_COMMENT_END(pchLine, off, cchLine))
     896                        {
     897                            char ch = pchLine[off++];
     898                            if (RT_C_IS_BLANK(ch))
     899                            {/* kind of likely */}
     900                            else
     901                            {
     902                                offLastNonBlank = off - 1;
     903                                if (offFirstNonBlank != ~(size_t)0)
     904                                {/* likely */}
     905                                else if (   (ch != '*' && ch != '#')    /* ignore continuation-asterisks */
     906                                         || off > Info.offStart + 1 + 1
     907                                         || off > cchLine
     908                                         || (   off < cchLine
     909                                              && !RT_C_IS_SPACE(pchLine[off]))
     910                                         || pszBody == NULL)
     911                                    offFirstNonBlank = off - 1;
     912                            }
     913                        }
     914                        else
     915                        {
     916                            off += 3;
     917                            Info.offEnd   = (uint32_t)off;
     918                            Info.iLineEnd = iLine;
     919                            break;
     920                        }
     921                    }
     922
     923                    /* Append line content to the comment body string. */
     924                    size_t cchAppend;
     925                    if (offFirstNonBlank == ~(size_t)0)
     926                        cchAppend = 0; /* empty line */
     927                    else
     928                    {
     929                        offLineStart = offFirstNonBlank;
     930                        cchAppend = offLastNonBlank + 1 - offLineStart;
     931                        Assert(cchAppend <= cchLine);
     932                    }
     933
     934                    size_t cchNewBody = cchBody + (cchBody > 0) + cchAppend;
     935                    if (cchNewBody >= cbBodyAlloc)
     936                    {
     937                        cbBodyAlloc = RT_MAX(cbBodyAlloc ? cbBodyAlloc * 2 : _1K, RT_ALIGN_Z(cchNewBody + 64, 128));
     938                        void *pvNew = RTMemRealloc(pszBody, cbBodyAlloc);
     939                        if (pvNew)
     940                            pszBody = (char *)pvNew;
     941                        else
     942                        {
     943                            RTMemFree(pszBody);
     944                            return VERR_NO_MEMORY;
     945                        }
     946                    }
     947
     948                    if (cchBody > 0)                        /* no leading blank lines */
     949                        pszBody[cchBody++] = '\n';
     950                    else if (cchAppend == 0)
     951                        Info.cBlankLinesBefore++;
     952                    memcpy(&pszBody[cchBody], &pchLine[offLineStart], cchAppend);
     953                    cchBody += cchAppend;
     954                    pszBody[cchBody] = '\0';
     955
     956                    /* Advance to the next line, if we haven't yet seen the end of this comment. */
     957                    if (Info.iLineEnd != UINT32_MAX)
     958                        break;
     959                    pchLine = ScmStreamGetLine(pIn, &cchLine, &enmEol);
     960                    if (!pchLine)
     961                    {
     962                        Info.offEnd   = (uint32_t)cchLine;
     963                        Info.iLineEnd = iLine;
     964                        break;
     965                    }
     966                    iLine++;
     967                    off = 0;
     968                }
     969
     970                /* Strip trailing empty lines in the body. */
     971                Info.cBlankLinesAfter = 0;
     972                while (cchBody >= 1 && pszBody[cchBody - 1] == '\n')
     973                {
     974                    Info.cBlankLinesAfter++;
     975                    pszBody[--cchBody] = '\0';
     976                }
     977
     978                /* Do the callback. */
     979                int rc = pfnCallback(&Info, pszBody, cchBody, pvUser);
     980                RTMemFree(pszBody);
     981                if (RT_FAILURE(rc))
     982                    return rc;
     983                if (rc > VINF_SUCCESS && rcRet == VINF_SUCCESS)
     984                    rcRet = rc;
     985            }
     986            else
     987                off++;
    810988        } /* for each character in the line */
    811989
     
    8391017        /*
    8401018         * Skip leading blanks and check for 'rem'.
    841          * At the moment we do not parse '::lable-comments'.
     1019         * At the moment we do not parse '::label-comments'.
    8421020         */
    8431021        size_t off = 0;
     
    10021180            return enumerateSimpleLineComments(pIn, '\'', isTickComment, pfnCallback, pvUser);
    10031181
     1182        case kScmCommentStyle_Xml:
     1183            return enumerateXmlComments(pIn, pfnCallback, pvUser);
     1184
    10041185        default:
    10051186            AssertFailedReturn(VERR_INVALID_PARAMETER);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette