VirtualBox

Changeset 41186 in vbox


Ignore:
Timestamp:
May 7, 2012 1:42:20 PM (13 years ago)
Author:
vboxsync
Message:

More preprocessing (disabled).

Location:
trunk/src/bldprogs
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bldprogs/Makefile.kmk

    r41179 r41186  
    5050        scmstream.cpp
    5151
    52  BLDPROGS += VBoxCPP
     52 #BLDPROGS += VBoxCPP
    5353 VBoxCPP_TEMPLATE = VBoxAdvBldProg
    5454 VBoxCPP_SOURCES = \
  • trunk/src/bldprogs/VBoxCPP.cpp

    r41179 r41186  
    11/* $Id$ */
    22/** @file
    3  * VBox Build Tool - A mini C Preprocessor.
    4  * 
    5  * This is not attempting to be standard compliant, just get the job done!
     3 * VBox Build Tool - A mini C Preprocessor.
     4 *
     5 * Purpuses to which this preprocessor will be put:
     6 *      - Preprocessig vm.h into dtrace/lib/vm.d so we can access the VM
     7 *        structure (as well as substructures) from DTrace without having
     8 *        to handcraft it all.
     9 *      - Removing \#ifdefs relating to a new feature that has become
     10 *        stable and no longer needs \#ifdef'ing.
     11 *      - Pretty printing preprocessor directives.  This will be used by
     12 *        SCM.
    613 */
    714
     
    7582
    7683
    77 /** 
     84/**
    7885 * A define.
    7986 */
     
    120127typedef VBCPPCTX *PVBCPPCTX;
    121128
     129/**
     130 * Evaluation result.
     131 */
     132typedef enum VBCPPEVAL
     133{
     134    kVBCppEval_Invalid = 0,
     135    kVBCppEval_True,
     136    kVBCppEval_False,
     137    kVBCppEval_Undecided,
     138    kVBCppEval_End
     139} VBCPPEVAL;
     140
     141
     142/**
     143 * The condition kind.
     144 */
     145typedef enum VBCPPCONDKIND
     146{
     147    kVBCppCondKind_Invalid = 0,
     148    /** \#if expr  */
     149    kVBCppCondKind_If,
     150    /** \#ifdef define  */
     151    kVBCppCondKind_IfDef,
     152    /** \#ifndef define  */
     153    kVBCppCondKind_IfNDef,
     154    /** \#elif expr */
     155    kVBCppCondKind_ElIf,
     156    /** The end of valid values. */
     157    kVBCppCondKind_End
     158} VBCPPCONDKIND;
     159
     160
     161/**
     162 * Conditional stack entry.
     163 */
     164typedef struct VBCPPCOND
     165{
     166    /** The next conditional on the stack. */
     167    struct VBCPPCOND   *pUp;
     168    /** The kind of conditional. This changes on encountering \#elif. */
     169    VBCPPCONDKIND       enmKind;
     170    /** Evaluation result. */
     171    VBCPPEVAL           enmResult;
     172    /** The evaluation result of the whole stack. */
     173    VBCPPEVAL           enmStackResult;
     174
     175    /** Whether we've seen the last else. */
     176    bool                fSeenElse;
     177    /** The nesting level of this condition. */
     178    uint16_t            iLevel;
     179    /** The nesting level of this condition wrt the ones we keep. */
     180    uint16_t            iKeepLevel;
     181
     182    /** The condition string. (Points within the stream buffer.) */
     183    const char         *pchCond;
     184    /** The condition length. */
     185    size_t              cchCond;
     186} VBCPPCOND;
     187/** Pointer to a conditional stack entry. */
     188typedef VBCPPCOND *PVBCPPCOND;
     189
     190
     191/**
     192 * Input buffer stack entry.
     193 */
     194typedef struct VBCPPINPUT
     195{
     196    /** Pointer to the next input on the stack. */
     197    struct VBCPPINPUT  *pUp;
     198    /** The input stream. */
     199    SCMSTREAM           StrmInput;
     200    /** Pointer into szName to the part which was specified. */
     201    const char         *pszSpecified;
     202    /** The input file name with include path. */
     203    char                szName[1];
     204} VBCPPINPUT;
     205/** Pointer to a input buffer stack entry */
     206typedef VBCPPINPUT *PVBCPPINPUT;
     207
    122208
    123209/**
     
    127213{
    128214    /** @name Options
    129      * @{ */ 
     215     * @{ */
    130216    /** The preprocessing mode. */
    131217    VBCPPMODE           enmMode;
     
    143229    const char         *pszOutput;
    144230    /** @} */
    145    
     231
    146232    /** The define string space. */
    147233    RTSTRSPACE          StrSpace;
     234    /** The string space holding explicitly undefined macros for selective
     235     * preprocessing runs. */
     236    RTSTRSPACE          UndefStrSpace;
    148237    /** Indicates whether a C-word might need expansion.
    149      * The bitmap is indexed by C-word lead character.  Bits that are set 
    150      * indicates that the lead character is used in a \#define that we know and 
    151      * should expand. */ 
     238     * The bitmap is indexed by C-word lead character.  Bits that are set
     239     * indicates that the lead character is used in a \#define that we know and
     240     * should expand. */
    152241    VBCPP_BITMAP_TYPE   bmDefined[VBCPP_BITMAP_SIZE];
    153242    /** Indicates whether a C-word might need argument expansion.
    154      * The bitmap is indexed by C-word lead character.  Bits that are set 
    155      * indicates that the lead character is used in an argument of an currently 
     243     * The bitmap is indexed by C-word lead character.  Bits that are set
     244     * indicates that the lead character is used in an argument of an currently
    156245     * expanding  \#define. */
    157246    VBCPP_BITMAP_TYPE   bmArgs[VBCPP_BITMAP_SIZE];
    158247
    159248    /** Expansion context stack. */
    160     PVBCPPCTX           pStack;
    161     /** The current stack depth. */
    162     uint32_t            cStackDepth;
     249    PVBCPPCTX           pExpStack;
     250    /** The current expansion stack depth. */
     251    uint32_t            cExpStackDepth;
     252
     253    /** The current depth of the conditional stack. */
     254    uint32_t            cCondStackDepth;
     255    /** Conditional stack. */
     256    PVBCPPCOND          pCondStack;
     257    /** The current condition evaluates to kVBCppEval_False, don't output. */
     258    bool                fIf0Mode;
     259
    163260    /** Whether the current line could be a preprocessor line.
    164      * This is set when EOL is encountered and cleared again when a 
    165      * non-comment-or-space character is encountered.  See vbcppPreprocess. */ 
     261     * This is set when EOL is encountered and cleared again when a
     262     * non-comment-or-space character is encountered.  See vbcppPreprocess. */
    166263    bool                fMaybePreprocessorLine;
    167264
    168     /** The current input stream. */
    169     PSCMSTREAM          pCurStrmInput;
    170     /** The input stream. */
    171     SCMSTREAM           StrmInput;
     265    /** The input stack depth */
     266    uint32_t            cInputStackDepth;
     267    /** The input buffer stack. */
     268    PVBCPPINPUT         pInputStack;
     269
    172270    /** The output stream. */
    173271    SCMSTREAM           StrmOutput;
     
    198296    pThis->pszOutput        = NULL;
    199297    pThis->StrSpace         = NULL;
    200     pThis->pStack           = NULL;
    201     pThis->cStackDepth      = 0;
     298    pThis->UndefStrSpace    = NULL;
     299    pThis->pExpStack        = NULL;
     300    pThis->cExpStackDepth   = 0;
     301    pThis->cCondStackDepth  = 0;
     302    pThis->pCondStack       = NULL;
     303    pThis->fIf0Mode         = false;
     304    pThis->fMaybePreprocessorLine = true;
    202305    VBCPP_BITMAP_EMPTY(pThis->bmDefined);
    203306    VBCPP_BITMAP_EMPTY(pThis->bmArgs);
    204     RT_ZERO(pThis->StrmInput);
     307    pThis->cCondStackDepth  = 0;
     308    pThis->pInputStack      = NULL;
    205309    RT_ZERO(pThis->StrmOutput);
    206310    pThis->rcExit           = RTEXITCODE_SUCCESS;
     
    210314
    211315/**
    212  * Displays an error message. 
    213  * 
     316 * Displays an error message.
     317 *
    214318 * @returns RTEXITCODE_FAILURE
    215319 * @param   pThis               The C preprocessor instance.
     
    220324{
    221325    NOREF(pThis);
    222     va_list va;
    223     va_start(va, pszMsg);
    224     RTMsgErrorV(pszMsg, va);
    225     va_end(va);
     326    if (pThis->pInputStack)
     327    {
     328        PSCMSTREAM pStrm = &pThis->pInputStack->StrmInput;
     329
     330        size_t const off     = ScmStreamTell(pStrm);
     331        size_t const iLine   = ScmStreamTellLine(pStrm);
     332        ScmStreamSeekByLine(pStrm, iLine);
     333        size_t const offLine = ScmStreamTell(pStrm);
     334
     335        va_list va;
     336        va_start(va, pszMsg);
     337        RTPrintf("%s:%d:%zd: error: %N.\n", pThis->pInputStack->szName, iLine + 1, off - offLine + 1, pszMsg, va);
     338        va_end(va);
     339
     340        size_t cchLine;
     341        SCMEOL enmEof;
     342        const char *pszLine = ScmStreamGetLineByNo(pStrm, iLine, &cchLine, &enmEof);
     343        if (pszLine)
     344            RTPrintf("  %.*s\n"
     345                     "  %*s^\n",
     346                     cchLine, pszLine, off - offLine, "");
     347
     348        ScmStreamSeekAbsolute(pStrm, off);
     349    }
     350    else
     351    {
     352        va_list va;
     353        va_start(va, pszMsg);
     354        RTMsgErrorV(pszMsg, va);
     355        va_end(va);
     356    }
    226357    return pThis->rcExit = RTEXITCODE_FAILURE;
    227358}
     
    229360
    230361/**
    231  * Displays an error message. 
    232  * 
     362 * Displays an error message.
     363 *
    233364 * @returns RTEXITCODE_FAILURE
    234  * @param   pThis               The C preprocessor instance. 
     365 * @param   pThis               The C preprocessor instance.
    235366 * @param   pszPos              Pointer to the offending character.
    236367 * @param   pszMsg              The message.
     
    249380
    250381/**
    251  * Checks if the given character is a valid C identifier lead character. 
    252  * 
     382 * Checks if the given character is a valid C identifier lead character.
     383 *
    253384 * @returns true / false.
    254385 * @param   ch                  The character to inspect.
     
    262393
    263394/**
    264  * Checks if the given character is a valid C identifier character. 
    265  * 
     395 * Checks if the given character is a valid C identifier character.
     396 *
    266397 * @returns true / false.
    267398 * @param   ch                  The character to inspect.
     
    276407
    277408/**
    278  * 
    279  * @returns @c true if valid, @c false if not. Error message already displayed 
     409 *
     410 * @returns @c true if valid, @c false if not. Error message already displayed
    280411 *          on failure.
    281412 * @param   pThis           The C preprocessor instance.
    282413 * @param   pchIdentifier   The start of the identifier to validate.
    283  * @param   cchIdentifier   The length of the identifier. RTSTR_MAX if not 
     414 * @param   cchIdentifier   The length of the identifier. RTSTR_MAX if not
    284415 *                          known.
    285416 */
     
    315446
    316447/**
    317  * Frees a define. 
    318  * 
     448 * Frees a define.
     449 *
    319450 * @returns VINF_SUCCESS (used when called by RTStrSpaceDestroy)
    320451 * @param   pStr                Pointer to the VBCPPDEF::Core member.
     
    331462/**
    332463 * Removes a define.
    333  * 
     464 *
    334465 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg.
    335466 * @param   pThis               The C preprocessor instance.
    336  * @param   pszDefine           The define name, no argument list or anything. 
     467 * @param   pszDefine           The define name, no argument list or anything.
    337468 * @param   cchDefine           The length of the name. RTSTR_MAX is ok.
    338  */
    339 static RTEXITCODE vbcppRemoveDefine(PVBCPP pThis, const char *pszDefine, size_t cchDefine)
     469 * @param   fExplicitUndef      Explicit undefinition, that is, in a selective
     470 *                              preprocessing run it will evaluate to undefined.
     471 */
     472static RTEXITCODE vbcppDefineUndef(PVBCPP pThis, const char *pszDefine, size_t cchDefine, bool fExplicitUndef)
    340473{
    341474    PRTSTRSPACECORE pHit = RTStrSpaceGetN(&pThis->StrSpace, pszDefine, cchDefine);
     
    345478        vbcppFreeDefine(pHit, NULL);
    346479    }
     480
     481    if (fExplicitUndef)
     482    {
     483        if (cchDefine == RTSTR_MAX)
     484            cchDefine = strlen(pszDefine);
     485
     486        PRTSTRSPACECORE pStr = (PRTSTRSPACECORE)RTMemAlloc(sizeof(*pStr) + cchDefine + 1);
     487        if (!pStr)
     488            return vbcppError(pThis, "out of memory");
     489        char *pszDst = (char *)(pStr + 1);
     490        pStr->pszString = pszDst;
     491        memcpy(pszDst, pszDefine, cchDefine);
     492        pszDst[cchDefine] = '\0';
     493        if (!RTStrSpaceInsert(&pThis->UndefStrSpace, pStr))
     494            RTMemFree(pStr);
     495    }
     496
    347497    return RTEXITCODE_SUCCESS;
    348498}
    349499
    350 /**
    351  * Inserts a define.
    352  * 
     500
     501/**
     502 * Inserts a define.
     503 *
    353504 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg.
    354505 * @param   pThis               The C preprocessor instance.
    355506 * @param   pDef                The define to insert.
    356507 */
    357 static RTEXITCODE vbcppInsertDefine(PVBCPP pThis, PVBCPPDEF pDef)
     508static RTEXITCODE vbcppDefineInsert(PVBCPP pThis, PVBCPPDEF pDef)
    358509{
    359510    if (RTStrSpaceInsert(&pThis->StrSpace, &pDef->Core))
     
    362513    {
    363514        RTMsgWarning("Redefining '%s'\n", pDef->Core.pszString);
    364         PVBCPPDEF pOld = (PVBCPPDEF)vbcppRemoveDefine(pThis, pDef->Core.pszString, pDef->Core.cchString);
     515        PVBCPPDEF pOld = (PVBCPPDEF)vbcppDefineUndef(pThis, pDef->Core.pszString, pDef->Core.cchString, false);
    365516        bool fRc = RTStrSpaceInsert(&pThis->StrSpace, &pDef->Core);
    366517        Assert(fRc); Assert(pOld);
     
    373524
    374525/**
    375  * Adds a define. 
    376  * 
     526 * Adds a define.
     527 *
    377528 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg.
    378529 * @param   pThis               The C preprocessor instance.
    379530 * @param   pszDefine           The define name, no parameter list.
    380531 * @param   cchDefine           The length of the name.
    381  * @param   pszParams           The parameter list. 
    382  * @param   cchParams           The length of the parameter list. 
    383  * @param   pszValue            The value. 
     532 * @param   pszParams           The parameter list.
     533 * @param   cchParams           The length of the parameter list.
     534 * @param   pszValue            The value.
    384535 * @param   cchDefine           The length of the value.
    385536 */
    386 static RTEXITCODE vbcppAddDefineFn(PVBCPP pThis, const char *pszDefine, size_t cchDefine,
     537static RTEXITCODE vbcppDefineAddFn(PVBCPP pThis, const char *pszDefine, size_t cchDefine,
    387538                                   const char *pszParams, size_t cchParams,
    388539                                   const char *pszValue, size_t cchValue)
     
    393544    Assert(RTStrNLen(pszValue,  cchValue)  == cchValue);
    394545
    395     /* 
     546    /*
    396547     * Determin the number of arguments and how much space their names
    397548     * requires.  Performing syntax validation while parsing.
    398      */ 
     549     */
    399550    uint32_t cchArgNames = 0;
    400551    uint32_t cArgs       = 0;
     
    486637    Assert((uintptr_t)pszDst <= (uintptr_t)pDef->papszArgs);
    487638
    488     return vbcppInsertDefine(pThis, pDef);
    489 }
    490 
    491 
    492 /**
    493  * Adds a define. 
    494  * 
     639    return vbcppDefineInsert(pThis, pDef);
     640}
     641
     642
     643/**
     644 * Adds a define.
     645 *
    495646 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg.
    496647 * @param   pThis               The C preprocessor instance.
    497  * @param   pszDefine           The define name and optionally the argument 
     648 * @param   pszDefine           The define name and optionally the argument
    498649 *                              list.
    499650 * @param   cchDefine           The length of the name. RTSTR_MAX is ok.
    500  * @param   pszValue            The value. 
     651 * @param   pszValue            The value.
    501652 * @param   cchDefine           The length of the value. RTSTR_MAX is ok.
    502653 */
    503 static RTEXITCODE vbcppAddDefine(PVBCPP pThis, const char *pszDefine, size_t cchDefine,
     654static RTEXITCODE vbcppDefineAdd(PVBCPP pThis, const char *pszDefine, size_t cchDefine,
    504655                                 const char *pszValue, size_t cchValue)
    505656{
     
    537688        pszParams++;
    538689        cchParams -= 2;
    539         return vbcppAddDefineFn(pThis, pszDefine, cchDefine, pszParams, cchParams, pszValue, cchValue);
     690        return vbcppDefineAddFn(pThis, pszDefine, cchDefine, pszParams, cchParams, pszValue, cchValue);
    540691    }
    541692
     
    561712    pDef->szValue[cchValue] = '\0';
    562713
    563     return vbcppInsertDefine(pThis, pDef);
     714    return vbcppDefineInsert(pThis, pDef);
     715}
     716
     717
     718/**
     719 * Checks if a define exists.
     720 *
     721 * @returns true or false.
     722 * @param   pThis               The C preprocessor instance.
     723 * @param   pszDefine           The define name and optionally the argument
     724 *                              list.
     725 * @param   cchDefine           The length of the name. RTSTR_MAX is ok.
     726 */
     727static bool vbcppDefineExists(PVBCPP pThis, const char *pszDefine, size_t cchDefine)
     728{
     729    return cchDefine > 0
     730        && VBCPP_BITMAP_IS_SET(pThis->bmDefined, *pszDefine)
     731        && RTStrSpaceGetN(&pThis->StrSpace, pszDefine, cchDefine) != NULL;
    564732}
    565733
     
    567735/**
    568736 * Adds an include directory.
    569  * 
     737 *
    570738 * @returns Program exit code, with error message on failure.
    571739 * @param   pThis               The C preprocessor instance.
     
    593761
    594762/**
    595  * Parses the command line options. 
    596  * 
     763 * Parses the command line options.
     764 *
    597765 * @returns Program exit code. Exit on non-success or if *pfExit is set.
    598766 * @param   pThis               The C preprocessor instance.
     
    649817                const char *pszEqual = strchr(ValueUnion.psz, '=');
    650818                if (pszEqual)
    651                     rcExit = vbcppAddDefine(pThis, ValueUnion.psz, pszEqual - ValueUnion.psz, pszEqual + 1, RTSTR_MAX);
     819                    rcExit = vbcppDefineAdd(pThis, ValueUnion.psz, pszEqual - ValueUnion.psz, pszEqual + 1, RTSTR_MAX);
    652820                else
    653                     rcExit = vbcppAddDefine(pThis, ValueUnion.psz, RTSTR_MAX, "1", 1);
     821                    rcExit = vbcppDefineAdd(pThis, ValueUnion.psz, RTSTR_MAX, "1", 1);
    654822                if (rcExit != RTEXITCODE_SUCCESS)
    655823                    return rcExit;
     
    664832
    665833            case 'U':
    666                 rcExit = vbcppRemoveDefine(pThis, ValueUnion.psz, RTSTR_MAX);
     834                rcExit = vbcppDefineUndef(pThis, ValueUnion.psz, RTSTR_MAX, true);
    667835                break;
    668836
     
    687855                else if (!pThis->pszOutput)
    688856                    pThis->pszOutput = ValueUnion.psz;
    689                 else 
     857                else
    690858                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "too many file arguments");
    691859                break;
     
    706874/**
    707875 * Opens the input and output streams.
    708  * 
     876 *
    709877 * @returns Exit code.
    710878 * @param   pThis               The C preprocessor instance.
     
    715883        return vbcppError(pThis, "Preprocessing the standard input stream is currently not supported");
    716884
    717     int rc = ScmStreamInitForReading(&pThis->StrmInput, pThis->pszInput);
     885    size_t      cchName = strlen(pThis->pszInput);
     886    PVBCPPINPUT pInput = (PVBCPPINPUT)RTMemAlloc(RT_OFFSETOF(VBCPPINPUT, szName[cchName + 1]));
     887    if (!pInput)
     888        return vbcppError(pThis, "out of memory");
     889    pInput->pUp          = pThis->pInputStack;
     890    pInput->pszSpecified = pInput->szName;
     891    memcpy(pInput->szName, pThis->pszInput, cchName + 1);
     892    pThis->pInputStack   = pInput;
     893    int rc = ScmStreamInitForReading(&pInput->StrmInput, pThis->pszInput);
    718894    if (RT_FAILURE(rc))
    719895        return vbcppError(pThis, "ScmStreamInitForReading returned %Rrc when opening input file (%s)",
    720896                          rc, pThis->pszInput);
    721897
    722     rc = ScmStreamInitForWriting(&pThis->StrmOutput, &pThis->StrmInput);
     898    rc = ScmStreamInitForWriting(&pThis->StrmOutput, &pInput->StrmInput);
    723899    if (RT_FAILURE(rc))
    724900        return vbcppError(pThis, "ScmStreamInitForWriting returned %Rrc", rc);
     
    730906
    731907/**
    732  * Outputs a character. 
    733  * 
     908 * Outputs a character.
     909 *
    734910 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
    735911 * @param   pThis               The C preprocessor instance.
     
    747923/**
    748924 * Outputs a string.
    749  * 
     925 *
    750926 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
    751927 * @param   pThis               The C preprocessor instance.
    752  * @param   pch                 The string. 
    753  * @param   cch                 The number of characters to write. 
     928 * @param   pch                 The string.
     929 * @param   cch                 The number of characters to write.
    754930 */
    755931static RTEXITCODE vbcppOutputWrite(PVBCPP pThis, const char *pch, size_t cch)
     
    764940/**
    765941 * Processes a multi-line comment.
    766  * 
    767  * Must either string the comment or keep it. If the latter, we must refrain 
    768  * from replacing C-words in it. 
    769  * 
     942 *
     943 * Must either string the comment or keep it. If the latter, we must refrain
     944 * from replacing C-words in it.
     945 *
    770946 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
    771947 * @param   pThis               The C preprocessor instance.
     
    814990
    815991/**
    816  * Processes a single line comment. 
    817  * 
    818  * Must either string the comment or keep it. If the latter, we must refrain 
    819  * from replacing C-words in it. 
    820  * 
     992 * Processes a single line comment.
     993 *
     994 * Must either string the comment or keep it. If the latter, we must refrain
     995 * from replacing C-words in it.
     996 *
    821997 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
    822998 * @param   pThis               The C preprocessor instance.
     
    8521028
    8531029/**
    854  * Processes a double quoted string. 
    855  * 
    856  * Must not replace any C-words in strings. 
    857  * 
     1030 * Processes a double quoted string.
     1031 *
     1032 * Must not replace any C-words in strings.
     1033 *
    8581034 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
    8591035 * @param   pThis               The C preprocessor instance.
     
    8821058                break;
    8831059            fEscaped = !fEscaped && ch == '\\';
    884         } 
     1060        }
    8851061    }
    8861062    return rcExit;
     
    8901066/**
    8911067 * Processes a single quoted litteral.
    892  * 
    893  * Must not replace any C-words in strings. 
    894  * 
     1068 *
     1069 * Must not replace any C-words in strings.
     1070 *
    8951071 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
    8961072 * @param   pThis               The C preprocessor instance.
     
    9191095                break;
    9201096            fEscaped = !fEscaped && ch == '\\';
    921         } 
     1097        }
    9221098    }
    9231099    return rcExit;
     
    9261102
    9271103/**
    928  * Processes a preprocessor directive.
    929  * 
     1104 * Skips white spaces, including escaped new-lines.
     1105 *
     1106 * @param   pStrmInput          The input stream.
     1107 */
     1108static void vbcppProcessSkipWhiteAndEscapedEol(PSCMSTREAM pStrmInput)
     1109{
     1110    unsigned chPrev = ~(unsigned)0;
     1111    unsigned ch;
     1112    while ((ch = ScmStreamPeekCh(pStrmInput)) != ~(unsigned)0)
     1113    {
     1114        if (ch == '\r' || ch == '\n')
     1115        {
     1116            if (chPrev != '\\')
     1117                break;
     1118            chPrev = ch;
     1119            ScmStreamSeekByLine(pStrmInput, ScmStreamTellLine(pStrmInput) + 1);
     1120        }
     1121        else if (RT_C_IS_SPACE(ch))
     1122        {
     1123            ch = chPrev;
     1124            ch = ScmStreamGetCh(pStrmInput);
     1125            Assert(ch == chPrev);
     1126        }
     1127        else
     1128            break;
     1129    }
     1130}
     1131
     1132
     1133/**
     1134 * Skips white spaces, escaped new-lines and multi line comments.
     1135 *
     1136 * @param   pThis               The C preprocessor instance.
     1137 * @param   pStrmInput          The input stream.
     1138 */
     1139static RTEXITCODE vbcppProcessSkipWhiteEscapedEolAndComments(PVBCPP pThis, PSCMSTREAM pStrmInput)
     1140{
     1141    unsigned chPrev = ~(unsigned)0;
     1142    unsigned ch;
     1143    while ((ch = ScmStreamPeekCh(pStrmInput)) != ~(unsigned)0)
     1144    {
     1145        if (!RT_C_IS_SPACE(ch))
     1146        {
     1147            /* Multi-line Comment? */
     1148            if (ch != '/')
     1149                break;                  /* most definitely, not. */
     1150
     1151            size_t offSaved = ScmStreamTell(pStrmInput);
     1152            ScmStreamGetCh(pStrmInput);
     1153            if (ScmStreamPeekCh(pStrmInput) != '*')
     1154            {
     1155                ScmStreamSeekAbsolute(pStrmInput, offSaved);
     1156                break;              /* no */
     1157            }
     1158
     1159            /* Skip to the end of the comment. */
     1160            while ((ch = ScmStreamGetCh(pStrmInput)) != ~(unsigned)0)
     1161            {
     1162                if (ch == '*')
     1163                {
     1164                    ch = ScmStreamGetCh(pStrmInput);
     1165                    if (ch == '/')
     1166                        break;
     1167                    if (ch == ~(unsigned)0)
     1168                        break;
     1169                }
     1170            }
     1171            if (ch == ~(unsigned)0)
     1172                return vbcppError(pThis, "unterminated multi-line comment");
     1173            chPrev = '/';
     1174        }
     1175        /* New line (also matched by RT_C_IS_SPACE). */
     1176        else if (ch == '\r' || ch == '\n')
     1177        {
     1178            /* Stop if not escaped. */
     1179            if (chPrev != '\\')
     1180                break;
     1181            chPrev = ch;
     1182            ScmStreamSeekByLine(pStrmInput, ScmStreamTellLine(pStrmInput) + 1);
     1183        }
     1184        /* Real space char. */
     1185        else
     1186        {
     1187            chPrev = ch;
     1188            ch = ScmStreamGetCh(pStrmInput);
     1189            Assert(ch == chPrev);
     1190        }
     1191    }
     1192    return RTEXITCODE_SUCCESS;
     1193}
     1194
     1195
     1196/**
     1197 * Skips white spaces, escaped new-lines, and multi line comments, then checking
     1198 * that we're at the end of a line.
     1199 *
     1200 * @param   pThis               The C preprocessor instance.
     1201 * @param   pStrmInput          The input stream.
     1202 */
     1203static RTEXITCODE vbcppProcessSkipWhiteEscapedEolAndCommentsCheckEol(PVBCPP pThis, PSCMSTREAM pStrmInput)
     1204{
     1205    RTEXITCODE rcExit = vbcppProcessSkipWhiteEscapedEolAndComments(pThis, pStrmInput);
     1206    if (rcExit == RTEXITCODE_SUCCESS)
     1207    {
     1208        unsigned ch = ScmStreamPeekCh(pStrmInput);
     1209        if (   ch != ~(unsigned)0
     1210            && ch != '\r'
     1211            && ch != '\n')
     1212            rcExit = vbcppError(pThis, "Did not expected anything more on this line");
     1213    }
     1214    return rcExit;
     1215}
     1216
     1217
     1218/**
     1219 * Skips white spaces.
     1220 *
     1221 * @param   pStrmInput          The input stream.
     1222 */
     1223static void vbcppProcessSkipWhite(PSCMSTREAM pStrmInput)
     1224{
     1225    unsigned ch;
     1226    while ((ch = ScmStreamPeekCh(pStrmInput)) != ~(unsigned)0)
     1227    {
     1228        if (!RT_C_IS_SPACE(ch) || ch == '\r' || ch == '\n')
     1229            break;
     1230        unsigned chCheck = ScmStreamGetCh(pStrmInput);
     1231        AssertBreak(chCheck == ch);
     1232    }
     1233}
     1234
     1235
     1236
     1237/**
     1238 * Processes a abbreviated line number directive.
     1239 *
    9301240 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
    9311241 * @param   pThis               The C preprocessor instance.
    9321242 * @param   pStrmInput          The input stream.
     1243 * @param   offStart            The stream position where the directive
     1244 *                              started (for pass thru).
     1245 */
     1246static RTEXITCODE vbcppProcessInclude(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
     1247{
     1248    /*
     1249     * Parse it.
     1250     */
     1251    RTEXITCODE rcExit = vbcppProcessSkipWhiteEscapedEolAndComments(pThis, pStrmInput);
     1252    if (rcExit == RTEXITCODE_SUCCESS)
     1253    {
     1254        size_t      cchFilename;
     1255        const char *pchFilename;
     1256
     1257        unsigned ch = ScmStreamPeekCh(pStrmInput);
     1258        unsigned chType = ch;
     1259        if (ch == '"' || ch == '<')
     1260        {
     1261            ScmStreamGetCh(pStrmInput);
     1262            pchFilename = ScmStreamGetCur(pStrmInput);
     1263            unsigned chPrev = ch;
     1264            while (   (ch = ScmStreamGetCh(pStrmInput)) != ~(unsigned)0
     1265                   &&  ch != chType)
     1266            {
     1267                if (ch == '\r' || ch == '\n')
     1268                {
     1269                    rcExit = vbcppError(pThis, "Multi-line include file specfications are not supported");
     1270                    break;
     1271                }
     1272            }
     1273
     1274            if (rcExit != RTEXITCODE_SUCCESS)
     1275            {
     1276                if (ch != ~(unsigned)0)
     1277                    cchFilename = ScmStreamGetCur(pStrmInput) - pchFilename;
     1278                else
     1279                    rcExit = vbcppError(pThis, "Expected '%c'", chType);
     1280            }
     1281        }
     1282        else if (vbcppIsCIdentifierLeadChar(ch))
     1283        {
     1284            //size_t      cchDefine;
     1285            //const char *pchDefine = ScmStreamCGetWord(pStrmInput, &cchDefine);
     1286            rcExit = vbcppError(pThis, "Including via a define is not implemented yet")
     1287        }
     1288        else
     1289            rcExit = vbcppError(pThis, "Malformed include directive")
     1290
     1291        /*
     1292         * Take down the location of the next non-white space, if we need to
     1293         * pass thru the directive further down. Then skip to the end of the
     1294         * line.
     1295         */
     1296        if (rcExit != RTEXITCODE_SUCCESS)
     1297            vbcppProcessSkipWhite(pStrmInput);
     1298        size_t const offIncEnd = ScmStreamTell(pStrmInput);
     1299        if (rcExit != RTEXITCODE_SUCCESS)
     1300            rcExit = vbcppProcessSkipWhiteEscapedEolAndCommentsCheckEol(pThis, pStrmInput);
     1301
     1302        if (rcExit != RTEXITCODE_SUCCESS)
     1303        {
     1304            /*
     1305             * Execute it.
     1306             */
     1307            if (pThis->enmMode < kVBCppMode_Selective)
     1308            {
     1309                /** @todo Search for the include file and push it onto the input stack.
     1310                 *  Not difficult, just unnecessary rigth now. */
     1311                rcExit = vbcppError(pThis, "Includes are fully implemented");
     1312            }
     1313            else if (pThis->enmMode != kVBCppMode_SelectiveD)
     1314            {
     1315/** @todo put this in a function or smth. */
     1316                ssize_t cch = ScmStreamPrintf(&pThis->StrmOutput, "#%*sinclude %.*s",
     1317                                              pCond->iKeepLevel - 1, "", pchCondition);
     1318                if (cch < 0)
     1319                    return vbcppError(pThis, "Output error %Rrc", (int)cch);
     1320                if (offIncEnd < ScmStreamTell(pStrmInput))
     1321                {
     1322                    /** @todo  */
     1323                    ScmStreamPrintf(&pThis->StrmOutput, "/* missing comment - fixme */");
     1324                }
     1325
     1326            }
     1327            /* else: strip it */
     1328        }
     1329    }
     1330    return rcExit;
     1331}
     1332
     1333
     1334/**
     1335 * Processes a abbreviated line number directive.
     1336 *
     1337 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1338 * @param   pThis               The C preprocessor instance.
     1339 * @param   pStrmInput          The input stream.
     1340 * @param   offStart            The stream position where the directive
     1341 *                              started (for pass thru).
     1342 */
     1343static RTEXITCODE vbcppProcessDefine(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
     1344{
     1345    return vbcppError(pThis, "Not implemented %s", __FUNCTION__);
     1346}
     1347
     1348
     1349/**
     1350 * Processes a abbreviated line number directive.
     1351 *
     1352 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1353 * @param   pThis               The C preprocessor instance.
     1354 * @param   pStrmInput          The input stream.
     1355 * @param   offStart            The stream position where the directive
     1356 *                              started (for pass thru).
     1357 */
     1358static RTEXITCODE vbcppProcessUndef(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
     1359{
     1360    return vbcppError(pThis, "Not implemented %s", __FUNCTION__);
     1361}
     1362
     1363
     1364static VBCPPEVAL vbcppCondCombine(VBCPPEVAL enmEvalPush, VBCPPEVAL enmEvalTop)
     1365{
     1366    if (enmEvalTop == kVBCppEval_False)
     1367        return kVBCppEval_False;
     1368    return enmEvalPush;
     1369}
     1370
     1371
     1372static RTEXITCODE vbcppCondPush(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart,
     1373                                VBCPPCONDKIND enmKind, VBCPPEVAL enmResult,
     1374                                const char *pchCondition, size_t cchCondition)
     1375{
     1376    if (pThis->cCondStackDepth >= _64K)
     1377        return vbcppError(pThis, "Too many nested #if/#ifdef/#ifndef statements");
     1378
     1379    /*
     1380     * Allocate a new entry and push it.
     1381     */
     1382    PVBCPPCOND pCond = (PVBCPPCOND)RTMemAlloc(sizeof(*pCond));
     1383    if (!pCond)
     1384        return vbcppError(pThis, "out of memory");
     1385
     1386    PVBCPPCOND pUp = pThis->pCondStack;
     1387    pCond->enmKind          = enmKind;
     1388    pCond->enmResult        = enmResult;
     1389    pCond->enmStackResult   = pUp ? vbcppCondCombine(enmResult, pUp->enmStackResult) : enmResult;
     1390    pCond->fSeenElse        = false;
     1391    pCond->iLevel           = pThis->cCondStackDepth;
     1392    pCond->iKeepLevel       = (pUp ? pUp->iKeepLevel : 0) + enmResult == kVBCppEval_Undecided;
     1393    pCond->pchCond          = pchCondition;
     1394    pCond->cchCond          = cchCondition;
     1395
     1396    pCond->pUp              = pThis->pCondStack;
     1397    pThis->pCondStack       = pCond;
     1398    pThis->fIf0Mode         = pCond->enmStackResult == kVBCppEval_False;
     1399
     1400    /*
     1401     * Do pass thru.
     1402     */
     1403    if (   !pThis->fIf0Mode
     1404        && enmResult == kVBCppEval_Undecided)
     1405    {
     1406        /** @todo this is stripping comments of \#ifdef and \#ifndef atm. */
     1407        const char *pszDirective;
     1408        switch (enmKind)
     1409        {
     1410            case kVBCppCondKind_If:     pszDirective = "if"; break;
     1411            case kVBCppCondKind_IfDef:  pszDirective = "ifdef"; break;
     1412            case kVBCppCondKind_IfNDef: pszDirective = "ifndef"; break;
     1413            case kVBCppCondKind_ElIf:   pszDirective = "elif"; break;
     1414            default: AssertFailedReturn(RTEXITCODE_FAILURE);
     1415        }
     1416        ssize_t cch = ScmStreamPrintf(&pThis->StrmOutput, "#%*s%s %.*s",
     1417                                      pCond->iKeepLevel - 1, "", pszDirective, cchCondition, pchCondition);
     1418        if (cch < 0)
     1419            return vbcppError(pThis, "Output error %Rrc", (int)cch);
     1420    }
     1421
     1422    return RTEXITCODE_SUCCESS;
     1423}
     1424
     1425
     1426/**
     1427 * Processes a abbreviated line number directive.
     1428 *
     1429 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1430 * @param   pThis               The C preprocessor instance.
     1431 * @param   pStrmInput          The input stream.
     1432 * @param   offStart            The stream position where the directive
     1433 *                              started (for pass thru).
     1434 */
     1435static RTEXITCODE vbcppProcessIf(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
     1436{
     1437    return vbcppError(pThis, "Not implemented %s", __FUNCTION__);
     1438}
     1439
     1440
     1441/**
     1442 * Processes a abbreviated line number directive.
     1443 *
     1444 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1445 * @param   pThis               The C preprocessor instance.
     1446 * @param   pStrmInput          The input stream.
     1447 * @param   offStart            The stream position where the directive
     1448 *                              started (for pass thru).
     1449 */
     1450static RTEXITCODE vbcppProcessIfDef(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
     1451{
     1452    /*
     1453     * Parse it.
     1454     */
     1455    RTEXITCODE rcExit = vbcppProcessSkipWhiteEscapedEolAndComments(pThis, pStrmInput);
     1456    if (rcExit == RTEXITCODE_SUCCESS)
     1457    {
     1458        size_t      cchDefine;
     1459        const char *pchDefine = ScmStreamCGetWord(pStrmInput, &cchDefine);
     1460        if (pchDefine)
     1461        {
     1462            rcExit = vbcppProcessSkipWhiteEscapedEolAndCommentsCheckEol(pThis, pStrmInput);
     1463            if (rcExit == RTEXITCODE_SUCCESS)
     1464            {
     1465                /*
     1466                 * Evaluate it.
     1467                 */
     1468                VBCPPEVAL enmEval;
     1469                if (vbcppDefineExists(pThis, pchDefine, cchDefine))
     1470                    enmEval = kVBCppEval_True;
     1471                else if (   pThis->enmMode < kVBCppMode_Selective
     1472                         || RTStrSpaceGetN(&pThis->UndefStrSpace, pchDefine, cchDefine) != NULL)
     1473                    enmEval = kVBCppEval_False;
     1474                else
     1475                    enmEval = kVBCppEval_Undecided;
     1476                rcExit = vbcppCondPush(pThis, pStrmInput, offStart, kVBCppCondKind_IfDef, enmEval,
     1477                                       pchDefine, cchDefine);
     1478            }
     1479        }
     1480        else
     1481            rcExit = vbcppError(pThis, "Malformed #ifdef");
     1482    }
     1483    return rcExit;
     1484}
     1485
     1486
     1487/**
     1488 * Processes a abbreviated line number directive.
     1489 *
     1490 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1491 * @param   pThis               The C preprocessor instance.
     1492 * @param   pStrmInput          The input stream.
     1493 * @param   offStart            The stream position where the directive
     1494 *                              started (for pass thru).
     1495 */
     1496static RTEXITCODE vbcppProcessIfNDef(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
     1497{
     1498    /*
     1499     * Parse it.
     1500     */
     1501    RTEXITCODE rcExit = vbcppProcessSkipWhiteEscapedEolAndComments(pThis, pStrmInput);
     1502    if (rcExit == RTEXITCODE_SUCCESS)
     1503    {
     1504        size_t      cchDefine;
     1505        const char *pchDefine = ScmStreamCGetWord(pStrmInput, &cchDefine);
     1506        if (pchDefine)
     1507        {
     1508            rcExit = vbcppProcessSkipWhiteEscapedEolAndCommentsCheckEol(pThis, pStrmInput);
     1509            if (rcExit == RTEXITCODE_SUCCESS)
     1510            {
     1511                /*
     1512                 * Evaluate it.
     1513                 */
     1514                VBCPPEVAL enmEval;
     1515                if (vbcppDefineExists(pThis, pchDefine, cchDefine))
     1516                    enmEval = kVBCppEval_False;
     1517                else if (   pThis->enmMode < kVBCppMode_Selective
     1518                         || RTStrSpaceGetN(&pThis->UndefStrSpace, pchDefine, cchDefine) != NULL)
     1519                    enmEval = kVBCppEval_True;
     1520                else
     1521                    enmEval = kVBCppEval_Undecided;
     1522                rcExit = vbcppCondPush(pThis, pStrmInput, offStart, kVBCppCondKind_IfNDef, enmEval,
     1523                                       pchDefine, cchDefine);
     1524            }
     1525        }
     1526        else
     1527            rcExit = vbcppError(pThis, "Malformed #ifdef");
     1528    }
     1529    return rcExit;
     1530}
     1531
     1532
     1533/**
     1534 * Processes a abbreviated line number directive.
     1535 *
     1536 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1537 * @param   pThis               The C preprocessor instance.
     1538 * @param   pStrmInput          The input stream.
     1539 * @param   offStart            The stream position where the directive
     1540 *                              started (for pass thru).
     1541 */
     1542static RTEXITCODE vbcppProcessElse(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
     1543{
     1544    return vbcppError(pThis, "Not implemented %s", __FUNCTION__);
     1545}
     1546
     1547
     1548/**
     1549 * Processes a abbreviated line number directive.
     1550 *
     1551 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1552 * @param   pThis               The C preprocessor instance.
     1553 * @param   pStrmInput          The input stream.
     1554 * @param   offStart            The stream position where the directive
     1555 *                              started (for pass thru).
     1556 */
     1557static RTEXITCODE vbcppProcessEndif(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
     1558{
     1559    return vbcppError(pThis, "Not implemented %s", __FUNCTION__);
     1560}
     1561
     1562
     1563/**
     1564 * Processes a abbreviated line number directive.
     1565 *
     1566 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1567 * @param   pThis               The C preprocessor instance.
     1568 * @param   pStrmInput          The input stream.
     1569 * @param   offStart            The stream position where the directive
     1570 *                              started (for pass thru).
     1571 */
     1572static RTEXITCODE vbcppProcessPragma(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
     1573{
     1574    return vbcppError(pThis, "Not implemented %s", __FUNCTION__);
     1575}
     1576
     1577
     1578/**
     1579 * Processes a abbreviated line number directive.
     1580 *
     1581 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1582 * @param   pThis               The C preprocessor instance.
     1583 * @param   pStrmInput          The input stream.
     1584 * @param   offStart            The stream position where the directive
     1585 *                              started (for pass thru).
     1586 */
     1587static RTEXITCODE vbcppProcessLineNo(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
     1588{
     1589    return vbcppError(pThis, "Not implemented %s", __FUNCTION__);
     1590}
     1591
     1592
     1593/**
     1594 * Processes a abbreviated line number directive.
     1595 *
     1596 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1597 * @param   pThis               The C preprocessor instance.
     1598 * @param   pStrmInput          The input stream.
     1599 * @param   offStart            The stream position where the directive
     1600 *                              started (for pass thru).
     1601 */
     1602static RTEXITCODE vbcppProcessLineNoShort(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
     1603{
     1604    return vbcppError(pThis, "Not implemented %s", __FUNCTION__);
     1605}
     1606
     1607
     1608/**
     1609 * Handles a preprocessor directive.
     1610 *
     1611 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1612 * @param   pThis               The C preprocessor instance.
     1613 * @param   pStrmInput          The input stream.
    9331614 */
    9341615static RTEXITCODE vbcppProcessDirective(PVBCPP pThis, PSCMSTREAM pStrmInput)
    9351616{
    936 #if 0
    937     size_t const offStart = ScmStreamTell(pStrmInput);
    938 
    939     /*
    940      * Skip spaces.
     1617    /*
     1618     * Get the directive and do a string switch on it.
    9411619     */
    942     unsigned chPrev = ~(unsigned)0;
    943     unsigned ch;                 
    944     while ((ch = ScmStreamGetCh(pStrmInput)) != ~(unsigned)0)
    945     {
    946         if (!RT_C_IS_SPACE(ch))
    947         {
    948             if ()
    949             {
    950             }
    951         }
    952         ch = chPrev;
    953     }
    954 #endif
    955     return vbcppError(pThis, "Not implemented");
     1620    RTEXITCODE  rcExit = vbcppProcessSkipWhiteEscapedEolAndComments(pThis, pStrmInput);
     1621    if (rcExit != RTEXITCODE_SUCCESS)
     1622        return rcExit;
     1623    size_t      cchDirective;
     1624    const char *pchDirective = ScmStreamCGetWord(pStrmInput, &cchDirective);
     1625    if (pchDirective)
     1626    {
     1627        size_t const offStart = ScmStreamTell(pStrmInput);
     1628#define IS_DIRECTIVE(a_sz) ( sizeof(a_sz) - 1 == cchDirective && strncmp(pchDirective, a_sz, sizeof(a_sz) - 1) == 0)
     1629        if (IS_DIRECTIVE("if"))
     1630            rcExit = vbcppProcessIf(pThis, pStrmInput, offStart);
     1631        else if (IS_DIRECTIVE("ifdef"))
     1632            rcExit = vbcppProcessIfDef(pThis, pStrmInput, offStart);
     1633        else if (IS_DIRECTIVE("ifndef"))
     1634            rcExit = vbcppProcessIfNDef(pThis, pStrmInput, offStart);
     1635        else if (IS_DIRECTIVE("else"))
     1636            rcExit = vbcppProcessElse(pThis, pStrmInput, offStart);
     1637        else if (IS_DIRECTIVE("endif"))
     1638            rcExit = vbcppProcessEndif(pThis, pStrmInput, offStart);
     1639        else if (!pThis->fIf0Mode)
     1640        {
     1641            if (IS_DIRECTIVE("include"))
     1642                rcExit = vbcppProcessInclude(pThis, pStrmInput, offStart);
     1643            else if (IS_DIRECTIVE("define"))
     1644                rcExit = vbcppProcessDefine(pThis, pStrmInput, offStart);
     1645            else if (IS_DIRECTIVE("undef"))
     1646                rcExit = vbcppProcessUndef(pThis, pStrmInput, offStart);
     1647            else if (IS_DIRECTIVE("pragma"))
     1648                rcExit = vbcppProcessPragma(pThis, pStrmInput, offStart);
     1649            else if (IS_DIRECTIVE("line"))
     1650                rcExit = vbcppProcessLineNo(pThis, pStrmInput, offStart);
     1651            else
     1652                rcExit = vbcppError(pThis, "Unknown preprocessor directive '#%.*s'", cchDirective, pchDirective);
     1653        }
     1654#undef IS_DIRECTIVE
     1655    }
     1656    else if (!pThis->fIf0Mode)
     1657    {
     1658        /* Could it be a # <num> "file" directive? */
     1659        unsigned ch = ScmStreamPeekCh(pStrmInput);
     1660        if (RT_C_IS_DIGIT(ch))
     1661            rcExit = vbcppProcessLineNoShort(pThis, pStrmInput);
     1662        else
     1663            rcExit = vbcppError(pThis, "Malformed preprocessor directive");
     1664    }
     1665    return rcExit;
    9561666}
    9571667
     
    9591669/**
    9601670 * Processes a C word, possibly replacing it with a definition.
    961  * 
     1671 *
    9621672 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
    9631673 * @param   pThis               The C preprocessor instance.
     
    9741684/**
    9751685 * Does the actually preprocessing of the input file.
    976  * 
     1686 *
    9771687 * @returns Exit code.
    978  * @param   pThis               The C preprocessor instance.
    979  * @param   pStrmInput          The input stream.
    980  */
    981 static RTEXITCODE vbcppPreprocess(PVBCPP pThis, PSCMSTREAM pStrmInput)
    982 {
    983     /*
    984      * Push.
     1688 * @param   pThis               The C preprocessor instance.
     1689 */
     1690static RTEXITCODE vbcppPreprocess(PVBCPP pThis)
     1691{
     1692    RTEXITCODE  rcExit = RTEXITCODE_SUCCESS;
     1693
     1694    /*
     1695     * Parse.
    9851696     */
    986     PSCMSTREAM pStrmInputOld = pThis->pCurStrmInput;
    987     pThis->pCurStrmInput = pStrmInput;
    988     pThis->fMaybePreprocessorLine = true;
    989 
    990     /*
    991      * Parse.
    992      */
    993     RTEXITCODE  rcExit = RTEXITCODE_SUCCESS;
    994     unsigned    ch;
    995     while ((ch = ScmStreamGetCh(pStrmInput)) != ~(unsigned)0)
    996     {
    997         if (ch == '/')
    998         {
    999             ch = ScmStreamPeekCh(pStrmInput);
    1000             if (ch == '*')
    1001                 rcExit = vbcppProcessMultiLineComment(pThis, pStrmInput);
    1002             else if (ch == '/')
    1003                 rcExit = vbcppProcessOneLineComment(pThis, pStrmInput);
     1697    while (pThis->pInputStack)
     1698    {
     1699        pThis->fMaybePreprocessorLine = true;
     1700
     1701        PSCMSTREAM  pStrmInput = &pThis->pInputStack->StrmInput;
     1702        unsigned    ch;
     1703        while ((ch = ScmStreamGetCh(pStrmInput)) != ~(unsigned)0)
     1704        {
     1705            if (ch == '/')
     1706            {
     1707                ch = ScmStreamPeekCh(pStrmInput);
     1708                if (ch == '*')
     1709                    rcExit = vbcppProcessMultiLineComment(pThis, pStrmInput);
     1710                else if (ch == '/')
     1711                    rcExit = vbcppProcessOneLineComment(pThis, pStrmInput);
     1712                else
     1713                {
     1714                    pThis->fMaybePreprocessorLine = false;
     1715                    if (!pThis->fIf0Mode)
     1716                        rcExit = vbcppOutputCh(pThis, '/');
     1717                }
     1718            }
     1719            else if (ch == '#' && pThis->fMaybePreprocessorLine)
     1720            {
     1721                rcExit = vbcppProcessDirective(pThis, pStrmInput);
     1722                pStrmInput = &pThis->pInputStack->StrmInput;
     1723            }
     1724            else if (ch == '\r' || ch == '\n')
     1725            {
     1726                pThis->fMaybePreprocessorLine = true;
     1727                rcExit = vbcppOutputCh(pThis, ch);
     1728            }
     1729            else if (RT_C_IS_SPACE(ch))
     1730            {
     1731                if (!pThis->fIf0Mode)
     1732                    rcExit = vbcppOutputCh(pThis, ch);
     1733            }
    10041734            else
    10051735            {
    10061736                pThis->fMaybePreprocessorLine = false;
    1007                 rcExit = vbcppOutputCh(pThis, '/');
    1008             }
    1009         }
    1010         else if (ch == '#' && pThis->fMaybePreprocessorLine)
    1011             rcExit = vbcppProcessDirective(pThis, pStrmInput);
    1012         else if (ch == '\r' || ch == '\n')
    1013         {
    1014             pThis->fMaybePreprocessorLine = true;
    1015             rcExit = vbcppOutputCh(pThis, ch);
    1016         }
    1017         else if (RT_C_IS_SPACE(ch))
    1018             rcExit = vbcppOutputCh(pThis, ch);
    1019         else
    1020         {
    1021             pThis->fMaybePreprocessorLine = false;
    1022             if (ch == '"')
    1023                 rcExit = vbcppProcessDoubleQuotedString(pThis, pStrmInput);
    1024             else if (ch == '\'')
    1025                 rcExit = vbcppProcessSingledQuotedString(pThis, pStrmInput);
    1026             else if (vbcppIsCIdentifierLeadChar(ch))
    1027                 rcExit = vbcppProcessCWord(pThis, pStrmInput, ch);
    1028             else
    1029                 rcExit = vbcppOutputCh(pThis, ch);
    1030         }
     1737                if (!pThis->fIf0Mode)
     1738                {
     1739                    if (ch == '"')
     1740                        rcExit = vbcppProcessDoubleQuotedString(pThis, pStrmInput);
     1741                    else if (ch == '\'')
     1742                        rcExit = vbcppProcessSingledQuotedString(pThis, pStrmInput);
     1743                    else if (vbcppIsCIdentifierLeadChar(ch))
     1744                        rcExit = vbcppProcessCWord(pThis, pStrmInput, ch);
     1745                    else
     1746                        rcExit = vbcppOutputCh(pThis, ch);
     1747                }
     1748            }
     1749            if (rcExit != RTEXITCODE_SUCCESS)
     1750                break;
     1751        }
     1752
     1753        /*
     1754         * Check for errors.
     1755         */
    10311756        if (rcExit != RTEXITCODE_SUCCESS)
    10321757            break;
    1033     }
    1034    
    1035     /*
    1036      * Pop.
    1037      */
    1038     pThis->pCurStrmInput = pStrmInputOld;
    1039     pThis->fMaybePreprocessorLine = true;
     1758
     1759        /*
     1760         * Pop the input stack.
     1761         */
     1762        PVBCPPINPUT pPopped = pThis->pInputStack;
     1763        pThis->pInputStack = pPopped->pUp;
     1764        RTMemFree(pPopped);
     1765    }
     1766
    10401767    return rcExit;
    10411768}
     
    10431770
    10441771/**
    1045  * Terminates the preprocessor. 
    1046  * 
    1047  * This may return failure if an error was delayed. 
    1048  * 
     1772 * Terminates the preprocessor.
     1773 *
     1774 * This may return failure if an error was delayed.
     1775 *
    10491776 * @returns Exit code.
    10501777 * @param   pThis               The C preprocessor instance.
     
    10741801     * Cleanup.
    10751802     */
    1076     ScmStreamDelete(&pThis->StrmInput);
     1803    while (pThis->pInputStack)
     1804    {
     1805        ScmStreamDelete(&pThis->pInputStack->StrmInput);
     1806        void *pvFree = pThis->pInputStack;
     1807        pThis->pInputStack = pThis->pInputStack->pUp;
     1808        RTMemFree(pvFree);
     1809    }
     1810
    10771811    ScmStreamDelete(&pThis->StrmOutput);
    10781812
     
    11081842        rcExit = vbcppOpenStreams(&This);
    11091843        if (rcExit == RTEXITCODE_SUCCESS)
    1110             rcExit = vbcppPreprocess(&This, &This.StrmInput);
     1844            rcExit = vbcppPreprocess(&This);
    11111845    }
    11121846
  • trunk/src/bldprogs/VBoxTpG.cpp

    r41176 r41186  
    369369    ScmStreamDelete(&Strm);
    370370    return rcExit;
    371 }
    372 
    373 
    374 /**
    375  * Formats a string and writes it to the SCM stream.
    376  *
    377  * @returns The number of bytes written (>= 0). Negative value are IPRT error
    378  *          status codes.
    379  * @param   pStream             The stream to write to.
    380  * @param   pszFormat           The format string.
    381  * @param   va                  The arguments to format.
    382  */
    383 static ssize_t ScmStreamPrintfV(PSCMSTREAM pStream, const char *pszFormat, va_list va)
    384 {
    385     char   *psz;
    386     ssize_t cch = RTStrAPrintfV(&psz, pszFormat, va);
    387     if (cch)
    388     {
    389         int rc = ScmStreamWrite(pStream, psz, cch);
    390         RTStrFree(psz);
    391         if (RT_FAILURE(rc))
    392             cch = rc;
    393     }
    394     return cch;
    395 }
    396 
    397 
    398 /**
    399  * Formats a string and writes it to the SCM stream.
    400  *
    401  * @returns The number of bytes written (>= 0). Negative value are IPRT error
    402  *          status codes.
    403  * @param   pStream             The stream to write to.
    404  * @param   pszFormat           The format string.
    405  * @param   ...                 The arguments to format.
    406  */
    407 static ssize_t ScmStreamPrintf(PSCMSTREAM pStream, const char *pszFormat, ...)
    408 {
    409     va_list va;
    410     va_start(va, pszFormat);
    411     ssize_t cch = ScmStreamPrintfV(pStream, pszFormat, va);
    412     va_end(va);
    413     return cch;
    414371}
    415372
     
    10771034}
    10781035
    1079 /**
    1080  * If the given C word is at off - 1, return @c true and skip beyond it,
    1081  * otherwise return @c false.
    1082  *
    1083  * @retval  true if the given C-word is at the current position minus one char.
    1084  *          The stream position changes.
    1085  * @retval  false if not. The stream position is unchanged.
    1086  *
    1087  * @param   pStream             The stream.
    1088  * @param   cchWord             The length of the word.
    1089  * @param   pszWord             The word.
    1090  */
    1091 bool ScmStreamCMatchingWordM1(PSCMSTREAM pStream, const char *pszWord, size_t cchWord)
    1092 {
    1093     /* Check stream state. */
    1094     AssertReturn(!pStream->fWriteOrRead, false);
    1095     AssertReturn(RT_SUCCESS(pStream->rc), false);
    1096     AssertReturn(pStream->fFullyLineated, false);
    1097 
    1098     /* Sufficient chars left on the line? */
    1099     size_t const    iLine   = pStream->iLine;
    1100     AssertReturn(pStream->off > pStream->paLines[iLine].off, false);
    1101     size_t const    cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - (pStream->off - 1);
    1102     if (cchWord > cchLeft)
    1103         return false;
    1104 
    1105     /* Do they match? */
    1106     const char     *psz     = &pStream->pch[pStream->off - 1];
    1107     if (memcmp(psz, pszWord, cchWord))
    1108         return false;
    1109 
    1110     /* Is it the end of a C word? */
    1111     if (cchWord < cchLeft)
    1112     {
    1113         psz += cchWord;
    1114         if (RT_C_IS_ALNUM(*psz) || *psz == '_')
    1115             return false;
    1116     }
    1117 
    1118     /* Skip ahead. */
    1119     pStream->off += cchWord - 1;
    1120     return true;
    1121 }
    1122 
    1123 /**
    1124  * Get's the C word starting at the current position.
    1125  *
    1126  * @returns Pointer to the word on success and the stream position advanced to
    1127  *          the end of it.
    1128  *          NULL on failure, stream position normally unchanged.
    1129  * @param   pStream             The stream to get the C word from.
    1130  * @param   pcchWord            Where to return the word length.
    1131  */
    1132 const char *ScmStreamCGetWord(PSCMSTREAM pStream, size_t *pcchWord)
    1133 {
    1134     /* Check stream state. */
    1135     AssertReturn(!pStream->fWriteOrRead, NULL);
    1136     AssertReturn(RT_SUCCESS(pStream->rc), NULL);
    1137     AssertReturn(pStream->fFullyLineated, NULL);
    1138 
    1139     /* Get the number of chars left on the line and locate the current char. */
    1140     size_t const    iLine   = pStream->iLine;
    1141     size_t const    cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - pStream->off;
    1142     const char     *psz     = &pStream->pch[pStream->off];
    1143 
    1144     /* Is it a leading C character. */
    1145     if (!RT_C_IS_ALPHA(*psz) && *psz == '_')
    1146         return NULL;
    1147 
    1148     /* Find the end of the word. */
    1149     char    ch;
    1150     size_t  off = 1;
    1151     while (     off < cchLeft
    1152            &&  (   (ch = psz[off]) == '_'
    1153                 || RT_C_IS_ALNUM(ch)))
    1154         off++;
    1155 
    1156     pStream->off += off;
    1157     *pcchWord = off;
    1158     return psz;
    1159 }
    1160 
    1161 
    1162 /**
    1163  * Get's the C word starting at the current position minus one.
    1164  *
    1165  * @returns Pointer to the word on success and the stream position advanced to
    1166  *          the end of it.
    1167  *          NULL on failure, stream position normally unchanged.
    1168  * @param   pStream             The stream to get the C word from.
    1169  * @param   pcchWord            Where to return the word length.
    1170  */
    1171 const char *ScmStreamCGetWordM1(PSCMSTREAM pStream, size_t *pcchWord)
    1172 {
    1173     /* Check stream state. */
    1174     AssertReturn(!pStream->fWriteOrRead, NULL);
    1175     AssertReturn(RT_SUCCESS(pStream->rc), NULL);
    1176     AssertReturn(pStream->fFullyLineated, NULL);
    1177 
    1178     /* Get the number of chars left on the line and locate the current char. */
    1179     size_t const    iLine   = pStream->iLine;
    1180     size_t const    cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - (pStream->off - 1);
    1181     const char     *psz     = &pStream->pch[pStream->off - 1];
    1182 
    1183     /* Is it a leading C character. */
    1184     if (!RT_C_IS_ALPHA(*psz) && *psz == '_')
    1185         return NULL;
    1186 
    1187     /* Find the end of the word. */
    1188     char    ch;
    1189     size_t  off = 1;
    1190     while (     off < cchLeft
    1191            &&  (   (ch = psz[off]) == '_'
    1192                 || RT_C_IS_ALNUM(ch)))
    1193         off++;
    1194 
    1195     pStream->off += off - 1;
    1196     *pcchWord = off;
    1197     return psz;
    1198 }
    1199 
    12001036
    12011037/**
  • trunk/src/bldprogs/scmstream.cpp

    r41180 r41186  
    706706}
    707707
     708/**
     709 * Get the current buffer pointer.
     710 * 
     711 * @returns Buffer pointer on success, NULL on failure (asserted).
     712 * @param   pStream             The stream.  Must be in read mode.
     713 */
     714const char *ScmStreamGetCur(PSCMSTREAM pStream)
     715{
     716    AssertReturn(!pStream->fWriteOrRead, NULL);
     717    return pStream->pch + pStream->off;
     718}
    708719
    709720/**
     
    11091120
    11101121/**
     1122 * Formats a string and writes it to the SCM stream.
     1123 *
     1124 * @returns The number of bytes written (>= 0). Negative value are IPRT error
     1125 *          status codes.
     1126 * @param   pStream             The stream to write to.
     1127 * @param   pszFormat           The format string.
     1128 * @param   va                  The arguments to format.
     1129 */
     1130ssize_t ScmStreamPrintfV(PSCMSTREAM pStream, const char *pszFormat, va_list va)
     1131{
     1132    char   *psz;
     1133    ssize_t cch = RTStrAPrintfV(&psz, pszFormat, va);
     1134    if (cch)
     1135    {
     1136        int rc = ScmStreamWrite(pStream, psz, cch);
     1137        RTStrFree(psz);
     1138        if (RT_FAILURE(rc))
     1139            cch = rc;
     1140    }
     1141    return cch;
     1142}
     1143
     1144/**
     1145 * Formats a string and writes it to the SCM stream.
     1146 *
     1147 * @returns The number of bytes written (>= 0). Negative value are IPRT error
     1148 *          status codes.
     1149 * @param   pStream             The stream to write to.
     1150 * @param   pszFormat           The format string.
     1151 * @param   ...                 The arguments to format.
     1152 */
     1153ssize_t ScmStreamPrintf(PSCMSTREAM pStream, const char *pszFormat, ...)
     1154{
     1155    va_list va;
     1156    va_start(va, pszFormat);
     1157    ssize_t cch = ScmStreamPrintfV(pStream, pszFormat, va);
     1158    va_end(va);
     1159    return cch;
     1160}
     1161
     1162/**
    11111163 * Copies @a cLines from the @a pSrc stream onto the @a pDst stream.
    11121164 *
     
    11441196}
    11451197
     1198
     1199/**
     1200 * If the given C word is at off - 1, return @c true and skip beyond it,
     1201 * otherwise return @c false.
     1202 *
     1203 * @retval  true if the given C-word is at the current position minus one char.
     1204 *          The stream position changes.
     1205 * @retval  false if not. The stream position is unchanged.
     1206 *
     1207 * @param   pStream             The stream.
     1208 * @param   cchWord             The length of the word.
     1209 * @param   pszWord             The word.
     1210 */
     1211bool ScmStreamCMatchingWordM1(PSCMSTREAM pStream, const char *pszWord, size_t cchWord)
     1212{
     1213    /* Check stream state. */
     1214    AssertReturn(!pStream->fWriteOrRead, false);
     1215    AssertReturn(RT_SUCCESS(pStream->rc), false);
     1216    AssertReturn(pStream->fFullyLineated, false);
     1217
     1218    /* Sufficient chars left on the line? */
     1219    size_t const    iLine   = pStream->iLine;
     1220    AssertReturn(pStream->off > pStream->paLines[iLine].off, false);
     1221    size_t const    cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - (pStream->off - 1);
     1222    if (cchWord > cchLeft)
     1223        return false;
     1224
     1225    /* Do they match? */
     1226    const char     *psz     = &pStream->pch[pStream->off - 1];
     1227    if (memcmp(psz, pszWord, cchWord))
     1228        return false;
     1229
     1230    /* Is it the end of a C word? */
     1231    if (cchWord < cchLeft)
     1232    {
     1233        psz += cchWord;
     1234        if (RT_C_IS_ALNUM(*psz) || *psz == '_')
     1235            return false;
     1236    }
     1237
     1238    /* Skip ahead. */
     1239    pStream->off += cchWord - 1;
     1240    return true;
     1241}
     1242
     1243/**
     1244 * Get's the C word starting at the current position.
     1245 *
     1246 * @returns Pointer to the word on success and the stream position advanced to
     1247 *          the end of it.
     1248 *          NULL on failure, stream position normally unchanged.
     1249 * @param   pStream             The stream to get the C word from.
     1250 * @param   pcchWord            Where to return the word length.
     1251 */
     1252const char *ScmStreamCGetWord(PSCMSTREAM pStream, size_t *pcchWord)
     1253{
     1254    /* Check stream state. */
     1255    AssertReturn(!pStream->fWriteOrRead, NULL);
     1256    AssertReturn(RT_SUCCESS(pStream->rc), NULL);
     1257    AssertReturn(pStream->fFullyLineated, NULL);
     1258
     1259    /* Get the number of chars left on the line and locate the current char. */
     1260    size_t const    iLine   = pStream->iLine;
     1261    size_t const    cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - pStream->off;
     1262    const char     *psz     = &pStream->pch[pStream->off];
     1263
     1264    /* Is it a leading C character. */
     1265    if (!RT_C_IS_ALPHA(*psz) && *psz == '_')
     1266        return NULL;
     1267
     1268    /* Find the end of the word. */
     1269    char    ch;
     1270    size_t  off = 1;
     1271    while (     off < cchLeft
     1272           &&  (   (ch = psz[off]) == '_'
     1273                || RT_C_IS_ALNUM(ch)))
     1274        off++;
     1275
     1276    pStream->off += off;
     1277    *pcchWord = off;
     1278    return psz;
     1279}
     1280
     1281
     1282/**
     1283 * Get's the C word starting at the current position minus one.
     1284 *
     1285 * @returns Pointer to the word on success and the stream position advanced to
     1286 *          the end of it.
     1287 *          NULL on failure, stream position normally unchanged.
     1288 * @param   pStream             The stream to get the C word from.
     1289 * @param   pcchWord            Where to return the word length.
     1290 */
     1291const char *ScmStreamCGetWordM1(PSCMSTREAM pStream, size_t *pcchWord)
     1292{
     1293    /* Check stream state. */
     1294    AssertReturn(!pStream->fWriteOrRead, NULL);
     1295    AssertReturn(RT_SUCCESS(pStream->rc), NULL);
     1296    AssertReturn(pStream->fFullyLineated, NULL);
     1297
     1298    /* Get the number of chars left on the line and locate the current char. */
     1299    size_t const    iLine   = pStream->iLine;
     1300    size_t const    cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - (pStream->off - 1);
     1301    const char     *psz     = &pStream->pch[pStream->off - 1];
     1302
     1303    /* Is it a leading C character. */
     1304    if (!RT_C_IS_ALPHA(*psz) && *psz == '_')
     1305        return NULL;
     1306
     1307    /* Find the end of the word. */
     1308    char    ch;
     1309    size_t  off = 1;
     1310    while (     off < cchLeft
     1311           &&  (   (ch = psz[off]) == '_'
     1312                || RT_C_IS_ALNUM(ch)))
     1313        off++;
     1314
     1315    pStream->off += off - 1;
     1316    *pcchWord = off;
     1317    return psz;
     1318}
     1319
     1320
     1321
  • trunk/src/bldprogs/scmstream.h

    r41179 r41186  
    9999int         ScmStreamWriteToFile(PSCMSTREAM pStream, const char *pszFilenameFmt, ...);
    100100int         ScmStreamWriteToStdOut(PSCMSTREAM pStream);
     101
    101102size_t      ScmStreamTell(PSCMSTREAM pStream);
    102103size_t      ScmStreamTellLine(PSCMSTREAM pStream);
     
    106107int         ScmStreamSeekRelative(PSCMSTREAM pStream, ssize_t offRelative);
    107108int         ScmStreamSeekByLine(PSCMSTREAM pStream, size_t iLine);
     109
    108110const char *ScmStreamGetLineByNo(PSCMSTREAM pStream, size_t iLine, size_t *pcchLine, PSCMEOL penmEol);
    109111const char *ScmStreamGetLine(PSCMSTREAM pStream, size_t *pcchLine, PSCMEOL penmEol);
    110112unsigned    ScmStreamGetCh(PSCMSTREAM pStream);
     113const char *ScmStreamGetCur(PSCMSTREAM pStream);
    111114unsigned    ScmStreamPeekCh(PSCMSTREAM pStream);
    112115int         ScmStreamRead(PSCMSTREAM pStream, void *pvBuf, size_t cbToRead);
     
    114117SCMEOL      ScmStreamGetEol(PSCMSTREAM pStream);
    115118SCMEOL      ScmStreamGetEolByLine(PSCMSTREAM pStream, size_t iLine);
     119
    116120int         ScmStreamPutLine(PSCMSTREAM pStream, const char *pchLine, size_t cchLine, SCMEOL enmEol);
    117121int         ScmStreamWrite(PSCMSTREAM pStream, const char *pchBuf, size_t cchBuf);
    118122int         ScmStreamPutCh(PSCMSTREAM pStream, char ch);
     123ssize_t     ScmStreamPrintf(PSCMSTREAM pStream, const char *pszFormat, ...);
     124ssize_t     ScmStreamPrintfV(PSCMSTREAM pStream, const char *pszFormat, va_list va);
    119125int         ScmStreamCopyLines(PSCMSTREAM pDst, PSCMSTREAM pSrc, size_t cLines);
     126
     127bool        ScmStreamCMatchingWordM1(PSCMSTREAM pStream, const char *pszWord, size_t cchWord);
     128const char *ScmStreamCGetWord(PSCMSTREAM pStream, size_t *pcchWord);
     129const char *ScmStreamCGetWordM1(PSCMSTREAM pStream, size_t *pcchWord);
    120130
    121131RT_C_DECLS_END
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