VirtualBox

Changeset 69503 in vbox for trunk/src/bldprogs


Ignore:
Timestamp:
Oct 28, 2017 4:15:10 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
118842
Message:

scm: Added LGPL disclaimer checks.

File:
1 edited

Legend:

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

    r69500 r69503  
    7979    SCMCOMMENTSTYLE     enmCommentStyle;        /**< input */
    8080
     81    /** Number of comments we've parsed. */
     82    uint32_t            cComments;
     83
    8184    /** Copy of the contributed-by line if present. */
    8285    char               *pszContributedBy;
     
    109112    bool                fWellFormedLicense;
    110113    bool                fExternalLicense;
     114    /** @} */
     115
     116    /** @name LGPL licence notice and disclaimer info
     117     * @{ */
     118    /** Wheter to check for LGPL license notices and disclaimers. */
     119    bool                fCheckforLgpl;
     120    /** The approximate line we found the (first) LGPL licence notice on. */
     121    uint32_t            iLineLgplNotice;
     122    /** The LGPL disclaimer line. */
     123    uint32_t            iLineLgplDisclaimer;
    111124    /** @} */
    112125
     
    351364static const char g_szCopyrightHolder[] = "Oracle Corporation";
    352365
     366/** LGPL disclaimer. */
     367static const char g_szLgplDisclaimer[] =
     368    "Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice\n"
     369    "other than GPL or LGPL is available it will apply instead, Oracle elects to use only\n"
     370    "the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where\n"
     371    "a choice of LGPL license versions is made available with the language indicating\n"
     372    "that LGPLv2 or any later version may be used, or where a choice of which version\n"
     373    "of the LGPL is applied is otherwise unspecified.\n";
    353374
    354375/** Copyright+license comment start for each SCMCOMMENTSTYLE. */
     
    10291050}
    10301051
     1052/**
     1053 * Looks for @a pszFragment anywhere in @a pszText, ignoring spaces, punctuation
     1054 * and case.
     1055 *
     1056 * @returns true if found, false if not.
     1057 * @param   pszText             The haystack to search in.
     1058 * @param   cchText             The length @a pszText.
     1059 * @param   pszFragment         The needle to search for.
     1060 * @param   ppszStart           Where to return the address in @a pszText where
     1061 *                              the fragment was found.  Optional.
     1062 * @param   ppszNext            Where to return the pointer to the first char in
     1063 *                              @a pszText after the fragment.  Optional.
     1064 *
     1065 * @remarks First character of @a pszFragment must be an 7-bit ASCII character!
     1066 *          This character must not be space or punctuation.
     1067 */
     1068static bool scmContainsWordByWordIgnoreCase(const char *pszText, size_t cchText, const char *pszFragment,
     1069                                            const char **ppszStart, const char **ppszNext)
     1070{
     1071    Assert(!((unsigned)*pszFragment & 0x80));
     1072    Assert(pszText[cchText] == '\0');
     1073    Assert(RT_C_IS_BLANK(*pszFragment));
     1074    Assert(RT_C_IS_PUNCT(*pszFragment));
     1075
     1076    char chLower = RT_C_TO_LOWER(*pszFragment);
     1077    char chUpper = RT_C_TO_UPPER(*pszFragment);
     1078    for (;;)
     1079    {
     1080        const char *pszHit = (const char *)memchr(pszText, chLower, cchText);
     1081        const char *pszHit2 = (const char *)memchr(pszText, chUpper, cchText);
     1082        if (!pszHit && !pszHit2)
     1083        {
     1084            if (ppszStart)
     1085                *ppszStart = NULL;
     1086            if (ppszNext)
     1087                *ppszNext = NULL;
     1088            return false;
     1089        }
     1090
     1091        if (   pszHit == NULL
     1092            || (   pszHit2 != NULL
     1093                && ((uintptr_t)pszHit2 < (uintptr_t)pszHit)) )
     1094            pszHit = pszHit2;
     1095
     1096        const char *pszNext;
     1097        if (IsEqualWordByWordIgnoreCase(pszFragment, pszHit, &pszNext))
     1098        {
     1099            if (ppszStart)
     1100                *ppszStart = pszHit;
     1101            if (ppszNext)
     1102                *ppszNext = pszNext;
     1103            return true;
     1104        }
     1105
     1106        cchText -= pszHit - pszText + 1;
     1107        pszText = pszHit + 1;
     1108    }
     1109}
     1110
    10311111
    10321112/**
     
    10681148               pInfo->iLineStart, pInfo->offStart, pInfo->iLineEnd - pInfo->iLineStart + 1, pInfo->enmType,
    10691149               pInfo->cBlankLinesBefore, pInfo->cBlankLinesAfter);
     1150
     1151    pState->cComments++;
    10701152
    10711153    uint32_t iLine = pInfo->iLineStart + pInfo->cBlankLinesBefore;
     
    13391421
    13401422    /*
     1423     * Look for LGPL like text in the comment.
     1424     */
     1425    if (pState->fCheckforLgpl && cchBody > 128)
     1426    {
     1427        /* We look for typical LGPL notices. */
     1428        if (pState->iLineLgplNotice == UINT32_MAX)
     1429        {
     1430            static const char * const s_apszFragments[] =
     1431            {
     1432                "under the terms of the GNU Lesser General Public License",
     1433            };
     1434            for (unsigned i = 0; i < RT_ELEMENTS(s_apszFragments); i++)
     1435                if (scmContainsWordByWordIgnoreCase(pszBody, cchBody, s_apszFragments[i], NULL, NULL))
     1436                {
     1437                    pState->iLineLgplNotice = iLine;
     1438                    ScmVerbose(pState->pState, 3, "Found LGPL notice at %u\n", iLine);
     1439                    break;
     1440                }
     1441        }
     1442
     1443        if (   pState->iLineLgplDisclaimer == UINT32_MAX
     1444            && scmContainsWordByWordIgnoreCase(pszBody, cchBody, g_szLgplDisclaimer, NULL, NULL))
     1445        {
     1446            pState->iLineLgplDisclaimer = iLine;
     1447            ScmVerbose(pState->pState, 3, "Found LGPL disclaimer at %u\n", iLine);
     1448        }
     1449    }
     1450
     1451    /*
    13411452     * Look for the license text.
    13421453     */
     
    14201531                    else
    14211532                        ScmError(pState->pState, VERR_WRONG_ORDER, "License should be preceeded by the copyright!\n");
    1422                     if (pState->iLineCopyright != UINT32_MAX)
    1423                         return VERR_CALLBACK_RETURN;
    14241533                    break;
    14251534                }
     
    14281537    }
    14291538
    1430     if (fFoundCopyright)
     1539    if (fFoundCopyright && pState->iLineLicense == UINT32_MAX)
    14311540        ScmError(pState->pState, VERR_WRONG_ORDER, "Copyright should be followed by the license text!\n");
     1541
     1542    /*
     1543     * Stop looking for stuff after 100 comments.
     1544     */
     1545    if (pState->cComments > 100)
     1546        return VERR_CALLBACK_RETURN;
    14321547    return VINF_SUCCESS;
    14331548}
     
    14581573        /*.pState = */                  pState,
    14591574        /*.enmCommentStyle = */         enmCommentStyle,
     1575
     1576        /*.cComments = */               0,
    14601577
    14611578        /*.pszContributedBy = */        NULL,
     
    14821599        /*.fWellFormedLicense = */      false,
    14831600        /*.fExternalLicense = */        false,
     1601
     1602        /*.fCheckForLgpl = */           true,
     1603        /*.iLineLgplNotice = */         UINT32_MAX,
     1604        /*.iLineLgplDisclaimer = */     UINT32_MAX,
    14841605    };
    14851606
     
    15271648        else if (Info.iLineLicense == UINT32_MAX)
    15281649            ScmError(pState, VERR_NOT_FOUND, "Missing license!\n");
     1650        else if (   Info.fCheckforLgpl
     1651                 && Info.iLineLgplNotice != UINT32_MAX
     1652                 && Info.iLineLgplDisclaimer == UINT32_MAX)
     1653            ScmError(pState, VERR_NOT_FOUND, "LGPL licence notice on line %u, but no LGPL disclaimer was found!\n",
     1654                     Info.iLineLgplNotice + 1);
     1655        else if (   Info.fCheckforLgpl
     1656                 && Info.iLineLgplNotice == UINT32_MAX
     1657                 && Info.iLineLgplDisclaimer != UINT32_MAX)
     1658            ScmError(pState, VERR_NOT_FOUND, "LGPL disclaimer on line %u, but no LGPL copyright notice!\n",
     1659                     Info.iLineLgplDisclaimer + 1);
    15291660        else
    15301661        {
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