Ejemplo n.º 1
0
static void PreprocessLine (void)
/* Translate one line. */
{
    /* Trim whitespace and remove comments. The function returns the number of
     * identifiers found. If there were any, we will have to check for macros.
     */
    SB_Clear (MLine);
    if (Pass1 (Line, MLine) > 0) {
        MLine = InitLine (MLine);
        SB_Reset (Line);
        SB_Clear (MLine);
        MacroReplacement (Line, MLine);
    }

    /* Read from the new line */
    SB_Reset (MLine);
    MLine = InitLine (MLine);
}
Ejemplo n.º 2
0
static void DoPragma (void)
/* Handle a #pragma line by converting the #pragma preprocessor directive into
 * the _Pragma() compiler operator.
 */
{
    /* Skip blanks following the #pragma directive */
    SkipWhitespace (0);

    /* Copy the remainder of the line into MLine removing comments and ws */
    SB_Clear (MLine);
    Pass1 (Line, MLine);

    /* Convert the directive into the operator */
    SB_CopyStr (Line, "_Pragma (");
    SB_Reset (MLine);
    Stringize (MLine, Line);
    SB_AppendChar (Line, ')');

    /* Initialize reading from line */
    SB_Reset (Line);
    InitLine (Line);
}
Ejemplo n.º 3
0
static void MacroArgSubst (MacroExp* E)
/* Argument substitution according to ISO/IEC 9899:1999 (E), 6.10.3.1ff */
{
    ident       Ident;
    int         ArgIdx;
    StrBuf*     OldSource;
    StrBuf*     Arg;
    int         HaveSpace;


    /* Remember the current input and switch to the macro replacement. */
    int OldIndex = SB_GetIndex (&E->M->Replacement);
    SB_Reset (&E->M->Replacement);
    OldSource = InitLine (&E->M->Replacement);

    /* Argument handling loop */
    while (CurC != '\0') {

        /* If we have an identifier, check if it's a macro */
        if (IsSym (Ident)) {

            /* Check if it's a macro argument */
            if ((ArgIdx = FindMacroArg (E->M, Ident)) >= 0) {

                /* A macro argument. Get the corresponding actual argument. */
                Arg = ME_GetActual (E, ArgIdx);

                /* Copy any following whitespace */
                HaveSpace = SkipWhitespace (0);

                /* If a ## operator follows, we have to insert the actual
                 * argument as is, otherwise it must be macro replaced.
                 */
                if (CurC == '#' && NextC == '#') {

                    /* ### Add placemarker if necessary */
                    SB_Append (&E->Replacement, Arg);

                } else {

                    /* Replace the formal argument by a macro replaced copy
                     * of the actual.
                     */
                    SB_Reset (Arg);
                    MacroReplacement (Arg, &E->Replacement);

                    /* If we skipped whitespace before, re-add it now */
                    if (HaveSpace) {
                        SB_AppendChar (&E->Replacement, ' ');
                    }
                }


            } else {

                /* An identifier, keep it */
                SB_AppendStr (&E->Replacement, Ident);

            }

        } else if (CurC == '#' && NextC == '#') {

            /* ## operator. */
            NextChar ();
            NextChar ();
            SkipWhitespace (0);

            /* Since we need to concatenate the token sequences, remove
             * any whitespace that was added to target, since it must come
             * from the input.
             */
            while (IsSpace (SB_LookAtLast (&E->Replacement))) {
                SB_Drop (&E->Replacement, 1);
            }

            /* If the next token is an identifier which is a macro argument,
             * replace it, otherwise do nothing.
             */
            if (IsSym (Ident)) {

                /* Check if it's a macro argument */
                if ((ArgIdx = FindMacroArg (E->M, Ident)) >= 0) {

                    /* Get the corresponding actual argument and add it. */
                    SB_Append (&E->Replacement, ME_GetActual (E, ArgIdx));

                } else {

                    /* Just an ordinary identifier - add as is */
                    SB_AppendStr (&E->Replacement, Ident);

                }
            }

        } else if (CurC == '#' && E->M->ArgCount >= 0) {

            /* A # operator within a macro expansion of a function like
             * macro. Read the following identifier and check if it's a
             * macro parameter.
             */
            NextChar ();
            SkipWhitespace (0);
            if (!IsSym (Ident) || (ArgIdx = FindMacroArg (E->M, Ident)) < 0) {
                PPError ("`#' is not followed by a macro parameter");
            } else {
                /* Make a valid string from Replacement */
                Arg = ME_GetActual (E, ArgIdx);
                SB_Reset (Arg);
                Stringize (Arg, &E->Replacement);
            }

        } else if (IsQuote (CurC)) {
            CopyQuotedString (&E->Replacement);
        } else {
            SB_AppendChar (&E->Replacement, CurC);
            NextChar ();
        }
    }

#if 0
    /* Remove whitespace from the end of the line */
    while (IsSpace (SB_LookAtLast (&E->Replacement))) {
        SB_Drop (&E->Replacement, 1);
    }
#endif

    /* Switch back the input */
    InitLine (OldSource);
    SB_SetIndex (&E->M->Replacement, OldIndex);
}
Ejemplo n.º 4
0
static void FuncIdent (void)
/* Handle the .IDENT function */
{
    StrBuf    Buf = STATIC_STRBUF_INITIALIZER;
    token_t   Id;
    unsigned  I;

    /* Skip it */
    NextTok ();

    /* Left paren expected */
    ConsumeLParen ();

    /* The function expects a string argument */
    if (!LookAtStrCon ()) {
        return;
    }

    /* Check that the string contains a valid identifier. While doing so,
     * determine if it is a cheap local, or global one.
     */
    SB_Reset (&CurTok.SVal);

    /* Check for a cheap local symbol */
    if (SB_Peek (&CurTok.SVal) == LocalStart) {
        SB_Skip (&CurTok.SVal);
        Id = TOK_LOCAL_IDENT;
    } else {
        Id = TOK_IDENT;
    }

    /* Next character must be a valid identifier start */
    if (!IsIdStart (SB_Get (&CurTok.SVal))) {
        NoIdent ();
        return;
    }
    for (I = SB_GetIndex (&CurTok.SVal); I < SB_GetLen (&CurTok.SVal); ++I) {
        if (!IsIdChar (SB_AtUnchecked (&CurTok.SVal, I))) {
            NoIdent ();
            return;
        }
    }
    if (IgnoreCase) {
        UpcaseSVal ();
    }

    /* If anything is ok, save and skip the string. Check that the next token
     * is a right paren, then replace the token by an identifier token.
     */
    SB_Copy (&Buf, &CurTok.SVal);
    NextTok ();
    if (CurTok.Tok != TOK_RPAREN) {
        Error ("`)' expected");
    } else {
        CurTok.Tok = Id;
        SB_Copy (&CurTok.SVal, &Buf);
        SB_Terminate (&CurTok.SVal);
    }

    /* Free buffer memory */
    SB_Done (&Buf);
}
Ejemplo n.º 5
0
static void NumericConst (void)
/* Parse a numeric constant */
{
    unsigned Base;              /* Temporary number base */
    unsigned Prefix;            /* Base according to prefix */
    StrBuf   S = STATIC_STRBUF_INITIALIZER;
    int      IsFloat;
    char     C;
    unsigned DigitVal;
    unsigned long IVal;         /* Value */

    /* Check for a leading hex or octal prefix and determine the possible
    ** integer types.
    */
    if (CurC == '0') {
        /* Gobble 0 and examine next char */
        NextChar ();
        if (toupper (CurC) == 'X') {
            Base = Prefix = 16;
            NextChar ();        /* gobble "x" */
        } else {
            Base = 10;          /* Assume 10 for now - see below */
            Prefix = 8;         /* Actual prefix says octal */
        }
    } else {
        Base  = Prefix = 10;
    }

    /* Because floating point numbers don't have octal prefixes (a number
    ** with a leading zero is decimal), we first have to read the number
    ** before converting it, so we can determine if it's a float or an
    ** integer.
    */
    while (IsXDigit (CurC) && HexVal (CurC) < Base) {
        SB_AppendChar (&S, CurC);
        NextChar ();
    }
    SB_Terminate (&S);

    /* The following character tells us if we have an integer or floating
    ** point constant. Note: Hexadecimal floating point constants aren't
    ** supported in C89.
    */
    IsFloat = (CurC == '.' ||
               (Base == 10 && toupper (CurC) == 'E') ||
               (Base == 16 && toupper (CurC) == 'P' && IS_Get (&Standard) >= STD_C99));

    /* If we don't have a floating point type, an octal prefix results in an
    ** octal base.
    */
    if (!IsFloat && Prefix == 8) {
        Base = 8;
    }

    /* Since we do now know the correct base, convert the remembered input
    ** into a number.
    */
    SB_Reset (&S);
    IVal = 0;
    while ((C = SB_Get (&S)) != '\0') {
        DigitVal = HexVal (C);
        if (DigitVal >= Base) {
            Error ("Numeric constant contains digits beyond the radix");
        }
        IVal = (IVal * Base) + DigitVal;
    }

    /* We don't need the string buffer any longer */
    SB_Done (&S);

    /* Distinguish between integer and floating point constants */
    if (!IsFloat) {

        unsigned Types;
        int      HaveSuffix;

        /* Check for a suffix and determine the possible types */
        HaveSuffix = 1;
        if (toupper (CurC) == 'U') {
            /* Unsigned type */
            NextChar ();
            if (toupper (CurC) != 'L') {
                Types = IT_UINT | IT_ULONG;
            } else {
                NextChar ();
                Types = IT_ULONG;
            }
        } else if (toupper (CurC) == 'L') {
            /* Long type */
            NextChar ();
            if (toupper (CurC) != 'U') {
                Types = IT_LONG | IT_ULONG;
            } else {
                NextChar ();
                Types = IT_ULONG;
            }
        } else {
            HaveSuffix = 0;
            if (Prefix == 10) {
                /* Decimal constants are of any type but uint */
                Types = IT_INT | IT_LONG | IT_ULONG;
            } else {
                /* Octal or hex constants are of any type */
                Types = IT_INT | IT_UINT | IT_LONG | IT_ULONG;
            }
        }

        /* Check the range to determine the type */
        if (IVal > 0x7FFF) {
            /* Out of range for int */
            Types &= ~IT_INT;
            /* If the value is in the range 0x8000..0xFFFF, unsigned int is not
            ** allowed, and we don't have a type specifying suffix, emit a
            ** warning, because the constant is of type long.
            */
            if (IVal <= 0xFFFF && (Types & IT_UINT) == 0 && !HaveSuffix) {
                Warning ("Constant is long");
            }
        }
        if (IVal > 0xFFFF) {
            /* Out of range for unsigned int */
            Types &= ~IT_UINT;
        }
        if (IVal > 0x7FFFFFFF) {
            /* Out of range for long int */
            Types &= ~IT_LONG;
        }

        /* Now set the type string to the smallest type in types */
        if (Types & IT_INT) {
            NextTok.Type = type_int;
        } else if (Types & IT_UINT) {
            NextTok.Type = type_uint;
        } else if (Types & IT_LONG) {
            NextTok.Type = type_long;
        } else {
            NextTok.Type = type_ulong;
        }

        /* Set the value and the token */
        NextTok.IVal = IVal;
        NextTok.Tok  = TOK_ICONST;

    } else {

        /* Float constant */
        Double FVal = FP_D_FromInt (IVal);      /* Convert to double */

        /* Check for a fractional part and read it */
        if (CurC == '.') {

            Double Scale;

            /* Skip the dot */
            NextChar ();

            /* Read fractional digits */
            Scale  = FP_D_Make (1.0);
            while (IsXDigit (CurC) && (DigitVal = HexVal (CurC)) < Base) {
                /* Get the value of this digit */
                Double FracVal = FP_D_Div (FP_D_FromInt (DigitVal * Base), Scale);
                /* Add it to the float value */
                FVal = FP_D_Add (FVal, FracVal);
                /* Scale base */
                Scale = FP_D_Mul (Scale, FP_D_FromInt (DigitVal));
                /* Skip the digit */
                NextChar ();
            }
        }

        /* Check for an exponent and read it */
        if ((Base == 16 && toupper (CurC) == 'F') ||
            (Base == 10 && toupper (CurC) == 'E')) {

            unsigned Digits;
            unsigned Exp;

            /* Skip the exponent notifier */
            NextChar ();

            /* Read an optional sign */
            if (CurC == '-') {
                NextChar ();
            } else if (CurC == '+') {
                NextChar ();
            }

            /* Read exponent digits. Since we support only 32 bit floats
            ** with a maximum exponent of +-/127, we read the exponent
            ** part as integer with up to 3 digits and drop the remainder.
            ** This avoids an overflow of Exp. The exponent is always
            ** decimal, even for hex float consts.
            */
            Digits = 0;
            Exp    = 0;
            while (IsDigit (CurC)) {
                if (++Digits <= 3) {
                    Exp = Exp * 10 + HexVal (CurC);
                }
                NextChar ();
            }

            /* Check for errors: We must have exponent digits, and not more
            ** than three.
            */
            if (Digits == 0) {
                Error ("Floating constant exponent has no digits");
            } else if (Digits > 3) {
                Warning ("Floating constant exponent is too large");
            }

            /* Scale the exponent and adjust the value accordingly */
            if (Exp) {
                FVal = FP_D_Mul (FVal, FP_D_Make (pow (10, Exp)));
            }
        }

        /* Check for a suffix and determine the type of the constant */
        if (toupper (CurC) == 'F') {
            NextChar ();
            NextTok.Type = type_float;
        } else {
            NextTok.Type = type_double;
        }

        /* Set the value and the token */
        NextTok.FVal = FVal;
        NextTok.Tok  = TOK_FCONST;

    }
}
Ejemplo n.º 6
0
void SB_ioport_out( WORD port, BYTE val )
{
    switch(port)
    {
    /* DSP - Reset */
    case 0x226:
        TRACE("Resetting DSP.\n");
        SB_Reset();
        break;
    /* DSP - Write Data or Command */
    case 0x22c:
        TRACE("val=%x\n",val);
        if (command == -1) {
          /* Clear input buffer and set the current command */
          command = val;
          InSize = 0;
        }
        if (InSize!=DSP_Command[command])
	   /* Fill the input buffer the command parameters if any */
           DSP_InBuffer[InSize++]=val;
        else {
	    /* Process command */
            switch(command)
            {
            case 0x10: /* SB */
                FIXME("Direct DAC (8-bit) - Not Implemented\n");
                break;
            case 0x14: /* SB */
                SamplesCount = DSP_InBuffer[1]+(val<<8)+1;
                TRACE("DMA DAC (8-bit) for %x samples\n",SamplesCount);
                dma_enable = 1;
                break;
            case 0x20:
                FIXME("Direct ADC (8-bit) - Not Implemented\n");
                break;
            case 0x24: /* SB */
                FIXME("DMA ADC (8-bit) - Not Implemented\n");
                break;
            case 0x40: /* SB */
                SampleRate = 1000000/(256-val);
                TRACE("Set Time Constant (%d <-> %d Hz => %d Hz)\n",DSP_InBuffer[0],
                    SampleRate,SB_StdSampleRate(SampleRate));
                SampleRate = SB_StdSampleRate(SampleRate);
                wav_fmt.nSamplesPerSec = SampleRate;
                wav_fmt.nAvgBytesPerSec = SampleRate;
                IDirectSoundBuffer_SetFormat(lpdsbuf,&wav_fmt);
                break;
	    /* case 0xBX/0xCX -> See below */
            case 0xD0: /* SB */
                TRACE("Halt DMA operation (8-bit)\n");
                dma_enable = 0;
                break;
            case 0xD1: /* SB */
                FIXME("Enable Speaker - Not Implemented\n");
                break;
            case 0xD3: /* SB */
                FIXME("Disable Speaker - Not Implemented\n");
                break;
            case 0xD4: /* SB */
                FIXME("Continue DMA operation (8-bit) - Not Implemented\n");
                break;
            case 0xD8: /* SB */
                FIXME("Speaker Status - Not Implemented\n");
                break;
	    case 0xE0: /* SB 2.0 */
                TRACE("DSP Identification\n");
                DSP_OutBuffer[OutSize++] = ~val;
                break;
            case 0xE1: /* SB */
               TRACE("DSP Version\n");
               OutSize=2;
               DSP_OutBuffer[0]=0; /* returns version 1.0 */
               DSP_OutBuffer[1]=1;
                break;
            case 0xF2: /* SB */
                TRACE("IRQ Request (8-bit)\n");
                DOSVM_QueueEvent(SB_IRQ,SB_IRQ_PRI,NULL,NULL);
                break;
            default:
	      if (((command&0xF0)==0xB0)||((DSP_InBuffer[0]&0xF0)==0xC0)) {
		    /* SB16 */
                    FIXME("Generic DAC/ADC DMA (16-bit, 8-bit) - %d % d\n",command,DSP_InBuffer[1]);
                    if (command&0x02)
		        FIXME("Generic DAC/ADC fifo mode not supported\n");
                    if (command&0x04)
		        FIXME("Generic DAC/ADC autoinit dma mode not supported\n");
                    if (command&0x08)
		        FIXME("Generic DAC/ADC adc mode not supported\n");
                    switch(command>>4) {
                    case 0xB:
		        FIXME("Generic DAC/ADC 8-bit not supported\n");
                        SampleMode = 0;
                        break;
                    case 0xC:
		        FIXME("Generic DAC/ADC 16-bit not supported\n");
                        SampleMode = 1;
                        break;
                    default:
		        ERR("Generic DAC/ADC resolution unknown\n");
                        break;
                    }
                    if (DSP_InBuffer[1]&0x010)
		        FIXME("Generic DAC/ADC signed sample mode not supported\n");
                    if (DSP_InBuffer[1]&0x020)
		        FIXME("Generic DAC/ADC stereo mode not supported\n");
                    SamplesCount = DSP_InBuffer[2]+(val<<8)+1;
                    TRACE("Generic DMA for %x samples\n",SamplesCount);
                    dma_enable = 1;
	        }
                else
                    FIXME("DSP command %x not supported\n",val);
            }
            /* Empty the input buffer and end the command */
            InSize = 0;
            command = -1;
        }