/******************************************************************************
 *
 * Module Name: aslsupport.l - Flex/lex scanner C support routines.
 *              NOTE: Included into aslcompile.l, not compiled by itself.
 *
 *****************************************************************************/

/*
 * Copyright (C) 2000 - 2016, Intel Corp.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

/* Configuration */

#define ASL_SPACES_PER_TAB      4

#define ASL_NORMAL_CHAR         0
#define ASL_ESCAPE_SEQUENCE     1
#define ASL_OCTAL_CONSTANT      2
#define ASL_HEX_CONSTANT        3


/* File node - used for "Include" operator file stack */

typedef struct asl_file_node
{
    FILE                    *File;
    UINT32                  CurrentLineNumber;
    YY_BUFFER_STATE         State;
    char                    *Filename;
    struct asl_file_node    *Next;

} ASL_FILE_NODE;

/* File stack for the "Include" operator (NOT #include operator) */

ASL_FILE_NODE               *Gbl_IncludeFileStack = NULL;


/*******************************************************************************
 *
 * FUNCTION:    AslParserCleanup
 *
 * Used to delete the current buffer
 *
 ******************************************************************************/

void
AslParserCleanup (
    void)
{

    yy_delete_buffer (YY_CURRENT_BUFFER);
}


/*******************************************************************************
 *
 * FUNCTION:    AslDoLineDirective
 *
 * PARAMETERS:  None. Uses input() to access current source code line
 *
 * RETURN:      Updates global line number and filename
 *
 * DESCRIPTION: Handle #line directives emitted by the preprocessor.
 *
 * The #line directive is emitted by the preprocesser, and is used to
 * pass through line numbers from the original source code file to the
 * preprocessor output file (.i). This allows any compiler-generated
 * error messages to be displayed with the correct line number.
 *
 ******************************************************************************/

static void
AslDoLineDirective (
    void)
{
    int                     c;
    char                    *Token;
    UINT32                  LineNumber;
    char                    *Filename;
    UINT32                  i;

   Gbl_HasIncludeFiles = TRUE;

    /* Eat the entire line that contains the #line directive */

    Gbl_LineBufPtr = Gbl_CurrentLineBuffer;

    while ((c = input()) != '\n' && c != EOF)
    {
        *Gbl_LineBufPtr = c;
        Gbl_LineBufPtr++;
    }
    *Gbl_LineBufPtr = 0;

    /* First argument is the actual line number */

    Token = strtok (Gbl_CurrentLineBuffer, " ");
    if (!Token)
    {
        goto ResetAndExit;
    }

    /* First argument is the line number */

    LineNumber = (UINT32) UtDoConstant (Token);

    /* Emit the appropriate number of newlines */

    Gbl_CurrentColumn = 0;
    if (LineNumber > Gbl_CurrentLineNumber)
    {
        for (i = 0; i < (LineNumber - Gbl_CurrentLineNumber); i++)
        {
            FlWriteFile (ASL_FILE_SOURCE_OUTPUT, "\n", 1);
            Gbl_CurrentColumn++;
        }
    }

    FlSetLineNumber (LineNumber);

    /* Second argument is the optional filename (in double quotes) */

    Token = strtok (NULL, " \"");
    if (Token)
    {
        Filename = ACPI_ALLOCATE_ZEROED (strlen (Token) + 1);
        strcpy (Filename, Token);
        FlSetFilename (Filename);
    }

    /* Third argument is not supported at this time */

ResetAndExit:

    /* Reset globals for a new line */

    Gbl_CurrentLineOffset += Gbl_CurrentColumn;
    Gbl_CurrentColumn = 0;
    Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
}


/*******************************************************************************
 *
 * FUNCTION:    AslPopInputFileStack
 *
 * PARAMETERS:  None
 *
 * RETURN:      0 if a node was popped, -1 otherwise
 *
 * DESCRIPTION: Pop the top of the input file stack and point the parser to
 *              the saved parse buffer contained in the fnode. Also, set the
 *              global line counters to the saved values. This function is
 *              called when an include file reaches EOF.
 *
 ******************************************************************************/

int
AslPopInputFileStack (
    void)
{
    ASL_FILE_NODE           *Fnode;


    Gbl_PreviousIncludeFilename = Gbl_Files[ASL_FILE_INPUT].Filename;
    Fnode = Gbl_IncludeFileStack;
    DbgPrint (ASL_PARSE_OUTPUT,
        "\nPop InputFile Stack, Fnode %p\n", Fnode);

    DbgPrint (ASL_PARSE_OUTPUT,
        "Include: Closing \"%s\"\n\n", Gbl_Files[ASL_FILE_INPUT].Filename);

    if (!Fnode)
    {
        return (-1);
    }

    /* Close the current include file */

    fclose (yyin);

    /* Update the top-of-stack */

    Gbl_IncludeFileStack = Fnode->Next;

    /* Reset global line counter and filename */

    Gbl_Files[ASL_FILE_INPUT].Filename = Fnode->Filename;
    Gbl_CurrentLineNumber = Fnode->CurrentLineNumber;

    /* Point the parser to the popped file */

    yy_delete_buffer (YY_CURRENT_BUFFER);
    yy_switch_to_buffer (Fnode->State);

    /* All done with this node */

    ACPI_FREE (Fnode);
    return (0);
}


/*******************************************************************************
 *
 * FUNCTION:    AslPushInputFileStack
 *
 * PARAMETERS:  InputFile           - Open file pointer
 *              Filename            - Name of the file
 *
 * RETURN:      None
 *
 * DESCRIPTION: Push the InputFile onto the file stack, and point the parser
 *              to this file. Called when an include file is successfully
 *              opened.
 *
 ******************************************************************************/

void
AslPushInputFileStack (
    FILE                    *InputFile,
    char                    *Filename)
{
    ASL_FILE_NODE           *Fnode;
    YY_BUFFER_STATE         State;


    /* Save the current state in an Fnode */

    Fnode = UtLocalCalloc (sizeof (ASL_FILE_NODE));

    Fnode->File = yyin;
    Fnode->Next = Gbl_IncludeFileStack;
    Fnode->State = YY_CURRENT_BUFFER;
    Fnode->Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
    Fnode->CurrentLineNumber = Gbl_CurrentLineNumber;

    /* Push it on the stack */

    Gbl_IncludeFileStack = Fnode;

    /* Point the parser to this file */

    State = yy_create_buffer (InputFile, YY_BUF_SIZE);
    yy_switch_to_buffer (State);

    DbgPrint (ASL_PARSE_OUTPUT,
        "\nPush InputFile Stack, returning %p\n\n", InputFile);

    /* Reset the global line count and filename */

    Gbl_Files[ASL_FILE_INPUT].Filename =
        UtStringCacheCalloc (strlen (Filename) + 1);

    strcpy (Gbl_Files[ASL_FILE_INPUT].Filename, Filename);

    Gbl_CurrentLineNumber = 1;
    yyin = InputFile;
}


/*******************************************************************************
 *
 * FUNCTION:    AslResetCurrentLineBuffer
 *
 * PARAMETERS:  None
 *
 * RETURN:      None
 *
 * DESCRIPTION: Reset the Line Buffer to zero, increment global line numbers.
 *
 ******************************************************************************/

void
AslResetCurrentLineBuffer (
    void)
{

    if (Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle)
    {
        FlWriteFile (ASL_FILE_SOURCE_OUTPUT, Gbl_CurrentLineBuffer,
            Gbl_LineBufPtr - Gbl_CurrentLineBuffer);
    }

    Gbl_CurrentLineOffset += Gbl_CurrentColumn;
    Gbl_CurrentColumn = 0;

    Gbl_CurrentLineNumber++;
    Gbl_LogicalLineNumber++;
    Gbl_LineBufPtr = Gbl_CurrentLineBuffer;
}


/*******************************************************************************
 *
 * FUNCTION:    AslInsertLineBuffer
 *
 * PARAMETERS:  SourceChar          - One char from the input ASL source file
 *
 * RETURN:      None
 *
 * DESCRIPTION: Put one character of the source file into the temp line buffer
 *
 ******************************************************************************/

void
AslInsertLineBuffer (
    int                     SourceChar)
{
    UINT32                  i;
    UINT32                  Count = 1;


    if (SourceChar == EOF)
    {
        return;
    }

    Gbl_InputByteCount++;

    /* Handle tabs. Convert to spaces */

    if (SourceChar == '\t')
    {
        SourceChar = ' ';
        Count = ASL_SPACES_PER_TAB -
                    (Gbl_CurrentColumn & (ASL_SPACES_PER_TAB-1));
    }

    for (i = 0; i < Count; i++)
    {
        Gbl_CurrentColumn++;

        /* Insert the character into the line buffer */

        *Gbl_LineBufPtr = (UINT8) SourceChar;
        Gbl_LineBufPtr++;

        if (Gbl_LineBufPtr >
            (Gbl_CurrentLineBuffer + (Gbl_LineBufferSize - 1)))
        {
#if 0
            /*
             * Warning if we have split a long source line.
             * <Probably overkill>
             */
            sprintf (MsgBuffer, "Max %u", Gbl_LineBufferSize);
            AslCommonError (ASL_WARNING, ASL_MSG_LONG_LINE,
                Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
                Gbl_CurrentLineOffset, Gbl_CurrentColumn,
                Gbl_Files[ASL_FILE_INPUT].Filename, MsgBuffer);
#endif

            AslResetCurrentLineBuffer ();
        }
        else if (SourceChar == '\n')
        {
            /* End of line */

            AslResetCurrentLineBuffer ();
        }
    }
}


/*******************************************************************************
 *
 * FUNCTION:    count
 *
 * PARAMETERS:  yytext              - Contains the matched keyword.
 *              Type                - Keyword/Character type:
 *                                      0 = anything except a keyword
 *                                      1 = pseudo-keywords
 *                                      2 = non-executable ASL keywords
 *                                      3 = executable ASL keywords
 *
 * RETURN:      None
 *
 * DESCRIPTION: Count keywords and put them into the line buffer
 *
 ******************************************************************************/

static void
count (
    int                 Type)
{
    int                 i;


    switch (Type)
    {
    case 2:

        TotalKeywords++;
        TotalNamedObjects++;
        break;

    case 3:

        TotalKeywords++;
        TotalExecutableOpcodes++;
        break;

    default:

        break;
    }

    for (i = 0; (yytext[i] != 0) && (yytext[i] != EOF); i++)
    {
        AslInsertLineBuffer (yytext[i]);
        *Gbl_LineBufPtr = 0;
    }
}


/*******************************************************************************
 *
 * FUNCTION:    AslDoComment
 *
 * PARAMETERS:  none
 *
 * RETURN:      none
 *
 * DESCRIPTION: Process a standard comment.
 *
 ******************************************************************************/

static char
AslDoComment (
    void)
{
    int                 c;
    int                 c1 = 0;


    AslInsertLineBuffer ('/');
    AslInsertLineBuffer ('*');

loop:

    /* Eat chars until end-of-comment */

    while (((c = input ()) != '*') && (c != EOF))
    {
        AslInsertLineBuffer (c);
        c1 = c;
    }

    if (c == EOF)
    {
        goto EarlyEOF;
    }

    /*
     * Check for nested comment -- can help catch cases where a previous
     * comment was accidently left unterminated
     */
    if ((c1 == '/') && (c == '*'))
    {
        AslCommonError (ASL_WARNING, ASL_MSG_NESTED_COMMENT,
            Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
            Gbl_InputByteCount, Gbl_CurrentColumn,
            Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
    }

    /* Comment is closed only if the NEXT character is a slash */

    AslInsertLineBuffer (c);

    if (((c1 = input ()) != '/') && (c1 != EOF))
    {
        unput(c1);
        goto loop;
    }

    if (c1 == EOF)
    {
        goto EarlyEOF;
    }

    AslInsertLineBuffer (c1);
    return (TRUE);


EarlyEOF:
    /*
     * Premature End-Of-File
     */
    AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
        Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
        Gbl_CurrentLineOffset, Gbl_CurrentColumn,
        Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
    return (FALSE);
}


/*******************************************************************************
 *
 * FUNCTION:    AslDoCommentType2
 *
 * PARAMETERS:  none
 *
 * RETURN:      none
 *
 * DESCRIPTION: Process a new "//" comment.
 *
 ******************************************************************************/

static char
AslDoCommentType2 (
    void)
{
    int                 c;


    AslInsertLineBuffer ('/');
    AslInsertLineBuffer ('/');

    while (((c = input ()) != '\n') && (c != EOF))
    {
        AslInsertLineBuffer (c);
    }

    if (c == EOF)
    {
        /* End of file is OK, change to newline. Let parser detect EOF later */

        c = '\n';
    }

    AslInsertLineBuffer (c);
    return (TRUE);
}


/*******************************************************************************
 *
 * FUNCTION:    AslDoStringLiteral
 *
 * PARAMETERS:  none
 *
 * RETURN:      none
 *
 * DESCRIPTION: Process a string literal (surrounded by quotes)
 *
 ******************************************************************************/

static char
AslDoStringLiteral (
    void)
{
    char                *StringBuffer = MsgBuffer;
    char                *EndBuffer = MsgBuffer + ASL_MSG_BUFFER_SIZE;
    char                *CleanString;
    int                 StringChar;
    UINT32              State = ASL_NORMAL_CHAR;
    UINT32              i = 0;
    UINT8               Digit;
    char                ConvertBuffer[4];


    /*
     * Eat chars until end-of-literal.
     * NOTE:  Put back the original surrounding quotes into the
     * source line buffer.
     */
    AslInsertLineBuffer ('\"');
    while ((StringChar = input()) != EOF)
    {
        AslInsertLineBuffer (StringChar);

DoCharacter:
        switch (State)
        {
        case ASL_NORMAL_CHAR:

            switch (StringChar)
            {
            case '\\':
                /*
                 * Special handling for backslash-escape sequence. We will
                 * toss the backslash and translate the escape char(s).
                 */
                State = ASL_ESCAPE_SEQUENCE;
                continue;

            case '\"':

                /* String terminator */

                goto CompletedString;

            default:

                break;
            }
            break;


        case ASL_ESCAPE_SEQUENCE:

            State = ASL_NORMAL_CHAR;
            switch (StringChar)
            {
            case 'a':

                StringChar = 0x07;      /* BELL */
                break;

            case 'b':

                StringChar = 0x08;      /* BACKSPACE */
                break;

            case 'f':

                StringChar = 0x0C;      /* FORMFEED */
                break;

            case 'n':

                StringChar = 0x0A;      /* LINEFEED */
                break;

            case 'r':

                StringChar = 0x0D;      /* CARRIAGE RETURN*/
                break;

            case 't':

                StringChar = 0x09;      /* HORIZONTAL TAB */
                break;

            case 'v':

                StringChar = 0x0B;      /* VERTICAL TAB */
                break;

            case 'x':

                State = ASL_HEX_CONSTANT;
                i = 0;
                continue;

            case '\'':                  /* Single Quote */
            case '\"':                  /* Double Quote */
            case '\\':                  /* Backslash */

                break;

            default:

                /* Check for an octal digit (0-7) */

                if (ACPI_IS_OCTAL_DIGIT (StringChar))
                {
                    State = ASL_OCTAL_CONSTANT;
                    ConvertBuffer[0] = StringChar;
                    i = 1;
                    continue;
                }

                /* Unknown escape sequence issue warning, but use the character */

                AslCommonError (ASL_WARNING, ASL_MSG_INVALID_ESCAPE,
                    Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
                    Gbl_CurrentLineOffset, Gbl_CurrentColumn,
                    Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
                break;
            }
            break;


        case ASL_OCTAL_CONSTANT:

            /* Up to three octal digits allowed */

            if (!ACPI_IS_OCTAL_DIGIT (StringChar) ||
                (i > 2))
            {
                /*
                 * Reached end of the constant. Convert the assembled ASCII
                 * string and resume processing of the next character
                 */
                ConvertBuffer[i] = 0;
                Digit = (UINT8) strtoul (ConvertBuffer, NULL, 8);

                /* Check for NULL or non-ascii character (ignore if so) */

                if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
                {
                    AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
                        Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
                        Gbl_CurrentLineOffset, Gbl_CurrentColumn,
                        Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
                }
                else
                {
                    *StringBuffer = (char) Digit;
                    StringBuffer++;
                    if (StringBuffer >= EndBuffer)
                    {
                        goto BufferOverflow;
                    }
                }

                State = ASL_NORMAL_CHAR;
                goto DoCharacter;
                break;
            }

            /* Append another digit of the constant */

            ConvertBuffer[i] = StringChar;
            i++;
            continue;

        case ASL_HEX_CONSTANT:

            /* Up to two hex digits allowed */

            if (!isxdigit (StringChar) ||
                (i > 1))
            {
                /*
                 * Reached end of the constant. Convert the assembled ASCII
                 * string and resume processing of the next character
                 */
                ConvertBuffer[i] = 0;
                Digit = (UINT8) strtoul (ConvertBuffer, NULL, 16);

                /* Check for NULL or non-ascii character (ignore if so) */

                if ((Digit == 0) || (Digit > ACPI_ASCII_MAX))
                {
                    AslCommonError (ASL_WARNING, ASL_MSG_INVALID_STRING,
                        Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
                        Gbl_CurrentLineOffset, Gbl_CurrentColumn,
                        Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
                }
                else
                {
                    *StringBuffer = (char) Digit;
                    StringBuffer++;
                    if (StringBuffer >= EndBuffer)
                    {
                        goto BufferOverflow;
                    }
                }

                State = ASL_NORMAL_CHAR;
                goto DoCharacter;
                break;
            }

            /* Append another digit of the constant */

            ConvertBuffer[i] = StringChar;
            i++;
            continue;

        default:

            break;
        }

        /* Save the finished character */

        *StringBuffer = StringChar;
        StringBuffer++;
        if (StringBuffer >= EndBuffer)
        {
            goto BufferOverflow;
        }
    }

    /*
     * Premature End-Of-File
     */
    AslCommonError (ASL_ERROR, ASL_MSG_EARLY_EOF,
        Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
        Gbl_CurrentLineOffset, Gbl_CurrentColumn,
        Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
    return (FALSE);


CompletedString:
    /*
     * Null terminate the input string and copy string to a new buffer
     */
    *StringBuffer = 0;

    CleanString = UtStringCacheCalloc (strlen (MsgBuffer) + 1);
    if (!CleanString)
    {
        AslCommonError (ASL_ERROR, ASL_MSG_MEMORY_ALLOCATION,
            Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
            Gbl_CurrentLineOffset, Gbl_CurrentColumn,
            Gbl_Files[ASL_FILE_INPUT].Filename, NULL);
        return (FALSE);
    }

    strcpy (CleanString, MsgBuffer);
    AslCompilerlval.s = CleanString;
    return (TRUE);


BufferOverflow:

    /* Literal was too long */

    AslCommonError (ASL_ERROR, ASL_MSG_STRING_LENGTH,
        Gbl_CurrentLineNumber, Gbl_LogicalLineNumber,
        Gbl_CurrentLineOffset, Gbl_CurrentColumn,
        Gbl_Files[ASL_FILE_INPUT].Filename, "Max length 4096");
    return (FALSE);
}
