VirtualBox

Changeset 40557 in vbox for trunk


Ignore:
Timestamp:
Mar 20, 2012 10:24:36 PM (13 years ago)
Author:
vboxsync
Message:

RT_STR_TUPLE: Switch the length and string so it'll work with functions like RTStrAAppendN. VBoxTpG: Parser works.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/cdefs.h

    r40427 r40557  
    10741074
    10751075/**
    1076  * String constant tuple - strlen(string constant), string constant.
     1076 * String constant tuple - string constant, strlen(string constant).
    10771077 *
    10781078 * @param   a_szConst   String constant.
    10791079 */
    1080 #define RT_STR_TUPLE(a_szConst)  sizeof(a_szConst) - 1, a_szConst
     1080#define RT_STR_TUPLE(a_szConst)  a_szConst, (sizeof(a_szConst) - 1)
    10811081
    10821082
  • trunk/src/VBox/VMM/VMMR3/DBGFR3Trace.cpp

    r40413 r40557  
    5252static const struct
    5353{
     54    /** The group name. */
     55    const char *pszName;
     56    /** The name length. */
     57    uint32_t    cchName;
    5458    /** The mask. */
    5559    uint32_t    fMask;
    56     /** The name length. */
    57     uint32_t    cchName;
    58     /** The group name. */
    59     const char *pszName;
    6060}   g_aVmmTpGroups[] =
    6161{
    62     {  VMMTPGROUP_EM,   RT_STR_TUPLE("em") },
    63     {  VMMTPGROUP_HM,   RT_STR_TUPLE("hm") },
    64     {  VMMTPGROUP_TM,   RT_STR_TUPLE("tm") },
     62    {  RT_STR_TUPLE("em"), VMMTPGROUP_EM },
     63    {  RT_STR_TUPLE("hm"), VMMTPGROUP_HM },
     64    {  RT_STR_TUPLE("tm"), VMMTPGROUP_TM },
    6565};
    6666
  • trunk/src/bldprogs/VBoxTpG.cpp

    r40556 r40557  
    4242*   Structures and Typedefs                                                    *
    4343*******************************************************************************/
     44/**
     45 * Code/data stability.
     46 */
     47typedef enum kVTGStability
     48{
     49    kVTGStability_Invalid = 0,
     50    kVTGStability_Internal,
     51    kVTGStability_Private,
     52    kVTGStability_Obsolete,
     53    kVTGStability_External,
     54    kVTGStability_Unstable,
     55    kVTGStability_Evolving,
     56    kVTGStability_Stable,
     57    kVTGStability_Standard
     58} kVTGStability;
     59
     60/**
     61 * Data dependency.
     62 */
     63typedef enum kVTGClass
     64{
     65    kVTGClass_Invalid = 0,
     66    kVTGClass_Unknown,
     67    kVTGClass_Cpu,
     68    kVTGClass_Platform,
     69    kVTGClass_Group,
     70    kVTGClass_Isa,
     71    kVTGClass_Common
     72} kVTGClass;
     73
     74typedef struct VTGATTRS
     75{
     76    kVTGStability   enmCode;
     77    kVTGStability   enmData;
     78    kVTGClass       enmDataDep;
     79} VTGATTRS;
     80typedef VTGATTRS *PVTGATTRS;
     81
     82
    4483typedef struct VTGARG
    4584{
     85    RTLISTNODE      ListEntry;
    4686    const char     *pszName;
    47     const char     *pszType;
     87    char           *pszType;
    4888} VTGARG;
    4989typedef VTGARG *PVTGARG;
     
    5393    RTLISTNODE      ListEntry;
    5494    const char     *pszName;
     95    RTLISTANCHOR    ArgHead;
    5596    uint32_t        cArgs;
    56     PVTGARG         paArgs;
    5797} VTGPROBE;
    5898typedef VTGPROBE *PVTGPROBE;
     
    62102    RTLISTNODE      ListEntry;
    63103    const char     *pszName;
     104
     105    VTGATTRS        AttrSelf;
     106    VTGATTRS        AttrModules;
     107    VTGATTRS        AttrFunctions;
     108    VTGATTRS        AttrName;
     109    VTGATTRS        AttrArguments;
     110
    64111    RTLISTANCHOR    ProbeHead;
    65112} VTGPROVIDER;
     
    218265 * @param   pszWord             The word.
    219266 */
    220 bool ScmStreamCMatchingWordM1(PSCMSTREAM pStream, size_t cchWord, const char *pszWord)
     267bool ScmStreamCMatchingWordM1(PSCMSTREAM pStream, const char *pszWord, size_t cchWord)
    221268{
    222269    /* Check stream state. */
     
    339386static RTEXITCODE parseError(PSCMSTREAM pStrm, size_t cb, const char *pszMsg)
    340387{
    341     ScmStreamSeekRelative(pStrm, -cb);
     388    if (cb)
     389        ScmStreamSeekRelative(pStrm, -cb);
    342390    size_t const off     = ScmStreamTell(pStrm);
    343391    size_t const iLine   = ScmStreamTellLine(pStrm);
     
    345393    size_t const offLine = ScmStreamTell(pStrm);
    346394
    347     RTPrintf("%s:%d:%zd: error: %s\n", g_pszScript, iLine + 1, off - offLine, pszMsg);
     395    RTPrintf("%s:%d:%zd: error: %s.\n", g_pszScript, iLine + 1, off - offLine + 1, pszMsg);
    348396
    349397    size_t cchLine;
     
    424472        if (!RT_C_IS_SPACE(ch) && ch != '/')
    425473            return RTEXITCODE_SUCCESS;
    426         ch = ScmStreamGetCh(pStrm);
    427         AssertBreak(ch != ~(unsigned)0);
     474        unsigned ch2 = ScmStreamGetCh(pStrm); AssertBreak(ch == ch2); NOREF(ch2);
    428475        if (ch == '/')
    429476        {
     
    480527
    481528/**
     529 * Get the next non-space-non-comment character on a preprocessor line.
     530 *
     531 * @returns The next character. On error message and ~(unsigned)0.
     532 * @param   pStrm               The stream.
     533 */
     534static unsigned parseGetNextNonSpaceNonCommentChOnPpLine(PSCMSTREAM pStrm)
     535{
     536    size_t   off = ScmStreamTell(pStrm) - 1;
     537    unsigned ch;
     538    while ((ch = ScmStreamGetCh(pStrm)) != ~(unsigned)0)
     539    {
     540        if (RT_C_IS_SPACE(ch))
     541        {
     542            if (ch == '\n' || ch == '\r')
     543            {
     544                parseErrorAbs(pStrm, off, "Invalid preprocessor statement");
     545                break;
     546            }
     547        }
     548        else if (ch == '\\')
     549        {
     550            size_t off2 = ScmStreamTell(pStrm) - 1;
     551            ch = ScmStreamGetCh(pStrm);
     552            if (ch == '\r')
     553                ch = ScmStreamGetCh(pStrm);
     554            if (ch != '\n')
     555            {
     556                parseErrorAbs(pStrm, off2, "Expected new line");
     557                break;
     558            }
     559        }
     560        else
     561            return ch;
     562    }
     563    return ~(unsigned)0;
     564}
     565
     566
     567
     568/**
    482569 * Skips spaces and comments.
    483570 *
     
    494581
    495582
    496 /**
    497  * Parses a D probe statement.
     583
     584/**
     585 * Parses interface stability.
     586 *
     587 * @returns Interface stability if parsed correctly, otherwise error message and
     588 *          kVTGStability_Invalid.
     589 * @param   pStrm               The stream.
     590 * @param   ch                  The first character in the stability spec.
     591 */
     592static kVTGStability parseStability(PSCMSTREAM pStrm, unsigned ch)
     593{
     594    switch (ch)
     595    {
     596        case 'E':
     597            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("External")))
     598                return kVTGStability_External;
     599            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Evolving")))
     600                return kVTGStability_Evolving;
     601            break;
     602        case 'I':
     603            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Internal")))
     604                return kVTGStability_Internal;
     605            break;
     606        case 'O':
     607            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Obsolete")))
     608                return kVTGStability_Obsolete;
     609            break;
     610        case 'P':
     611            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Private")))
     612                return kVTGStability_Private;
     613            break;
     614        case 'S':
     615            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Stable")))
     616                return kVTGStability_Stable;
     617            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Standard")))
     618                return kVTGStability_Standard;
     619            break;
     620        case 'U':
     621            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Unstable")))
     622                return kVTGStability_Unstable;
     623            break;
     624    }
     625    parseError(pStrm, 1, "Unknown stability specifier");
     626    return kVTGStability_Invalid;
     627}
     628
     629
     630/**
     631 * Parses data depndency class.
     632 *
     633 * @returns Data dependency class if parsed correctly, otherwise error message
     634 *          and kVTGClass_Invalid.
     635 * @param   pStrm               The stream.
     636 * @param   ch                  The first character in the stability spec.
     637 */
     638static kVTGClass parseDataDepClass(PSCMSTREAM pStrm, unsigned ch)
     639{
     640    switch (ch)
     641    {
     642        case 'C':
     643            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Common")))
     644                return kVTGClass_Common;
     645            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Cpu")))
     646                return kVTGClass_Cpu;
     647            break;
     648        case 'G':
     649            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Group")))
     650                return kVTGClass_Group;
     651            break;
     652        case 'I':
     653            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Isa")))
     654                return kVTGClass_Isa;
     655            break;
     656        case 'P':
     657            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Platform")))
     658                return kVTGClass_Platform;
     659            break;
     660        case 'U':
     661            if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Unknown")))
     662                return kVTGClass_Unknown;
     663            break;
     664    }
     665    parseError(pStrm, 1, "Unknown data dependency class specifier");
     666    return kVTGClass_Invalid;
     667}
     668
     669/**
     670 * Parses a pragma D attributes statement.
    498671 *
    499672 * @returns Suitable exit code, errors message already written on failure.
    500673 * @param   pStrm               The stream.
     674 */
     675static RTEXITCODE parsePragmaDAttributes(PSCMSTREAM pStrm)
     676{
     677    /*
     678     * "CodeStability/DataStability/DataDepClass" - no spaces allowed.
     679     */
     680    unsigned ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
     681    if (ch == ~(unsigned)0)
     682        return RTEXITCODE_FAILURE;
     683
     684    kVTGStability enmCode = parseStability(pStrm, ch);
     685    if (enmCode == kVTGStability_Invalid)
     686        return RTEXITCODE_FAILURE;
     687    ch = ScmStreamGetCh(pStrm);
     688    if (ch != '/')
     689        return parseError(pStrm, 1, "Expected '/' following the code stability specifier");
     690
     691    kVTGStability enmData = parseStability(pStrm, ScmStreamGetCh(pStrm));
     692    if (enmData == kVTGStability_Invalid)
     693        return RTEXITCODE_FAILURE;
     694    ch = ScmStreamGetCh(pStrm);
     695    if (ch != '/')
     696        return parseError(pStrm, 1, "Expected '/' following the data stability specifier");
     697
     698    kVTGClass enmDataDep =  parseDataDepClass(pStrm, ScmStreamGetCh(pStrm));
     699    if (enmDataDep == kVTGClass_Invalid)
     700        return RTEXITCODE_FAILURE;
     701
     702    /*
     703     * Expecting 'provider' followed by the name of an provider defined earlier.
     704     */
     705    ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
     706    if (ch == ~(unsigned)0)
     707        return RTEXITCODE_FAILURE;
     708    if (ch != 'p' || !ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("provider")))
     709        return parseError(pStrm, 1, "Expected 'provider'");
     710
     711    size_t      cchName;
     712    const char *pszName = parseGetNextCWord(pStrm, &cchName);
     713    if (!pszName)
     714        return parseError(pStrm, 1, "Expected provider name");
     715
     716    PVTGPROVIDER pProv;
     717    RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry)
     718    {
     719        if (   !strncmp(pProv->pszName, pszName, cchName)
     720            && pProv->pszName[cchName] == '\0')
     721            break;
     722    }
     723    if (!pProv)
     724        return parseError(pStrm, cchName, "Provider not found");
     725
     726    /*
     727     * Which aspect of the provider?
     728     */
     729    size_t      cchAspect;
     730    const char *pszAspect = parseGetNextCWord(pStrm, &cchAspect);
     731    if (!pszAspect)
     732        return parseError(pStrm, 1, "Expected provider aspect");
     733
     734    PVTGATTRS pAttrs;
     735    if (cchAspect == 8 && !memcmp(pszAspect, "provider", 8))
     736        pAttrs = &pProv->AttrSelf;
     737    else if (cchAspect == 8 && !memcmp(pszAspect, "function", 8))
     738        pAttrs = &pProv->AttrFunctions;
     739    else if (cchAspect == 6 && !memcmp(pszAspect, "module", 6))
     740        pAttrs = &pProv->AttrModules;
     741    else if (cchAspect == 4 && !memcmp(pszAspect, "name", 4))
     742        pAttrs = &pProv->AttrName;
     743    else if (cchAspect == 4 && !memcmp(pszAspect, "args", 4))
     744        pAttrs = &pProv->AttrArguments;
     745    else
     746        return parseError(pStrm, cchAspect, "Unknown aspect");
     747
     748    if (pAttrs->enmCode != kVTGStability_Invalid)
     749        return parseError(pStrm, cchAspect, "You have already specified these attributes");
     750
     751    pAttrs->enmCode     = enmCode;
     752    pAttrs->enmData     = enmData;
     753    pAttrs->enmDataDep  = enmDataDep;
     754    return RTEXITCODE_SUCCESS;
     755}
     756
     757/**
     758 * Parses a D pragma statement.
     759 *
     760 * @returns Suitable exit code, errors message already written on failure.
     761 * @param   pStrm               The stream.
     762 */
     763static RTEXITCODE parsePragma(PSCMSTREAM pStrm)
     764{
     765    RTEXITCODE rcExit;
     766    unsigned   ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
     767    if (ch == ~(unsigned)0)
     768        rcExit = RTEXITCODE_FAILURE;
     769    else if (ch == 'D' && ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("D")))
     770    {
     771        ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
     772        if (ch == ~(unsigned)0)
     773            rcExit = RTEXITCODE_FAILURE;
     774        else if (ch == 'a' && ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("attributes")))
     775            rcExit = parsePragmaDAttributes(pStrm);
     776        else
     777            rcExit = parseError(pStrm, 1, "Unknown pragma D");
     778    }
     779    else
     780        rcExit = parseError(pStrm, 1, "Unknown pragma");
     781    return rcExit;
     782}
     783
     784
     785/**
     786 * Parses a D probe statement.
     787 *
     788 * @returns Suitable exit code, errors message already written on failure.
     789 * @param   pStrm               The stream.
     790 * @param   pProv               The provider being parsed.
    501791 */
    502792static RTEXITCODE parseProbe(PSCMSTREAM pStrm, PVTGPROVIDER pProv)
     
    519809    if (!pProbe)
    520810        return parseError(pStrm, 0, "Out of memory");
     811    RTListInit(&pProbe->ArgHead);
    521812    RTListAppend(&pProv->ProbeHead, &pProbe->ListEntry);
    522813    pProbe->pszName = RTStrCacheEnterN(g_hStrCache, pszProbe, cchProbe);
    523814    if (!pProbe->pszName)
    524815        return parseError(pStrm, 0, "Out of memory");
    525 #if 0
     816
    526817    /*
    527      * Parse loop.
     818     * Parse loop for the argument.
    528819     */
    529     char *pszArg = NULL;
     820    PVTGARG pArg    = NULL;
     821    size_t  cchName = 0;
    530822    for (;;)
    531823    {
    532824        ch = parseGetNextNonSpaceNonCommentCh(pStrm);
    533         RTEXITCODE rcExit;
    534825        switch (ch)
    535826        {
     
    537828            case ',':
    538829            {
    539                 if (pszType)
     830                /* commit the argument */
     831                if (pArg)
    540832                {
     833                    if (!cchName)
     834                        return parseError(pStrm, 1, "Argument has no name");
     835                    char *pszName;
     836                    pArg->pszName = pszName = strchr(pArg->pszType, '\0') - cchName;
     837                    pszName[-1] = '\0';
     838                    pArg = NULL;
    541839                }
    542                 size_t off = ScmStreamTell(pStrm);
    543                 if ()
     840                if (ch == ')')
    544841                {
     842                    size_t off = ScmStreamTell(pStrm);
     843                    ch = parseGetNextNonSpaceNonCommentCh(pStrm);
     844                    if (ch != ';')
     845                        return parseErrorAbs(pStrm, off, "Expected ';'");
     846                    return RTEXITCODE_SUCCESS;
    545847                }
    546 
    547                 ch = parseGetNextNonSpaceNonCommentCh(pStrm);
    548                 if (ch == ';')
    549                     return RTEXITCODE_SUCCESS;
    550                 rcExit = parseErrorAbs(pStrm, off, "Expected ';'");
    551848                break;
    552849            }
     
    554851            default:
    555852            {
     853                int         rc;
    556854                size_t      cchWord;
    557855                const char *pszWord = ScmStreamCGetWordM1(pStrm, &cchWord);
    558856                if (!pszWord)
    559                 else
    560                     rcExit = parseError(pStrm, 0, "Expected argument");
    561                 break;
    562             }
    563 
    564             case '*':
    565                 if (pszArg)
    566                     int rc = RTStrAAppendExN(&pszArg, 2, " ");
     857                    return parseError(pStrm, 0, "Expected argument");
     858                if (!pArg)
     859                {
     860                    pArg = (PVTGARG)RTMemAllocZ(sizeof(*pArg));
     861                    if (!pArg)
     862                        return parseError(pStrm, 1, "Out of memory");
     863                    RTListAppend(&pProbe->ArgHead, &pArg->ListEntry);
     864                    pProbe->cArgs++;
     865
     866                    rc = RTStrAAppendN(&pArg->pszType, pszWord, cchWord);
     867                    cchName = 0;
    567868                }
    568869                else
    569                     rcExit = parseError(pStrm, 0, "Expected argument");
     870                {
     871                    rc = RTStrAAppendExN(&pArg->pszType, 2, RT_STR_TUPLE(" "), pszWord, cchWord);
     872                    cchName = cchWord;
     873                }
     874                if (RT_FAILURE(rc))
     875                    return parseError(pStrm, 1, "Out of memory");
     876                break;
     877            }
     878
     879            case '*':
     880            {
     881                if (!pArg)
     882                    return parseError(pStrm, 1, "A parameter type does not start with an asterix");
     883                int rc = RTStrAAppend(&pArg->pszType, " *");
     884                if (RT_FAILURE(rc))
     885                    return parseError(pStrm, 1, "Out of memory");
     886                cchName = 0;
     887                break;
     888            }
    570889
    571890            case ~(unsigned)0:
    572                 rcExit = parseError(pStrm, 0, "Missing closing ')' on probe");
    573                 break;
    574 
    575             default:
    576                 rcExit = parseError(pStrm, 1, "Unexpected character");
    577                 break;
     891                return parseError(pStrm, 0, "Missing closing ')' on probe");
    578892        }
    579         if (rcExit != RTEXITCODE_SUCCESS)
    580             return rcExit;
    581     }
    582 #endif
    583     return parseError(pStrm, 0, "probe todo");
     893    }
    584894}
    585895
     
    6951005
    6961006            case '#':
    697                 rcExit = parseError(&Strm, 1, "Not implemented");
    698                 break;
     1007            {
     1008                ch = parseGetNextNonSpaceNonCommentChOnPpLine(&Strm);
     1009                if (ch == ~(unsigned)0)
     1010                    rcExit != RTEXITCODE_FAILURE;
     1011                else if (ch == 'p' && ScmStreamCMatchingWordM1(&Strm, RT_STR_TUPLE("pragma")))
     1012                    rcExit = parsePragma(&Strm);
     1013                else
     1014                    rcExit = parseError(&Strm, 1, "Unsupported preprocessor directive");
     1015                break;
     1016            }
    6991017
    7001018            default:
  • trunk/src/bldprogs/scmstream.cpp

    r40554 r40557  
    711711
    712712    /* Peek at the next character. */
    713     char ch = pStream->pch[pStream->off++];
     713    char ch = pStream->pch[pStream->off];
    714714    return (unsigned)ch;
    715715}
Note: See TracChangeset for help on using the changeset viewer.

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