Blame source/compiler/prexpress.c

Packit Service 1fb00e
/******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * Module Name: prexpress - Preprocessor #if expression support
Packit Service 1fb00e
 *
Packit Service 1fb00e
 *****************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
/*
Packit Service 1fb00e
 * Copyright (C) 2000 - 2018, Intel Corp.
Packit Service 1fb00e
 * All rights reserved.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * Redistribution and use in source and binary forms, with or without
Packit Service 1fb00e
 * modification, are permitted provided that the following conditions
Packit Service 1fb00e
 * are met:
Packit Service 1fb00e
 * 1. Redistributions of source code must retain the above copyright
Packit Service 1fb00e
 *    notice, this list of conditions, and the following disclaimer,
Packit Service 1fb00e
 *    without modification.
Packit Service 1fb00e
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
Packit Service 1fb00e
 *    substantially similar to the "NO WARRANTY" disclaimer below
Packit Service 1fb00e
 *    ("Disclaimer") and any redistribution must be conditioned upon
Packit Service 1fb00e
 *    including a substantially similar Disclaimer requirement for further
Packit Service 1fb00e
 *    binary redistribution.
Packit Service 1fb00e
 * 3. Neither the names of the above-listed copyright holders nor the names
Packit Service 1fb00e
 *    of any contributors may be used to endorse or promote products derived
Packit Service 1fb00e
 *    from this software without specific prior written permission.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * Alternatively, this software may be distributed under the terms of the
Packit Service 1fb00e
 * GNU General Public License ("GPL") version 2 as published by the Free
Packit Service 1fb00e
 * Software Foundation.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * NO WARRANTY
Packit Service 1fb00e
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit Service 1fb00e
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit Service 1fb00e
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
Packit Service 1fb00e
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit Service 1fb00e
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit Service 1fb00e
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit Service 1fb00e
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit Service 1fb00e
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
Packit Service 1fb00e
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
Packit Service 1fb00e
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Packit Service 1fb00e
 * POSSIBILITY OF SUCH DAMAGES.
Packit Service 1fb00e
 */
Packit Service 1fb00e
Packit Service 1fb00e
#include "aslcompiler.h"
Packit Service 1fb00e
Packit Service 1fb00e
#define _COMPONENT          ASL_PREPROCESSOR
Packit Service 1fb00e
        ACPI_MODULE_NAME    ("prexpress")
Packit Service 1fb00e
Packit Service 1fb00e
/* Local prototypes */
Packit Service 1fb00e
Packit Service 1fb00e
static char *
Packit Service 1fb00e
PrExpandMacros (
Packit Service 1fb00e
    char                    *Line);
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
#ifdef _UNDER_DEVELOPMENT
Packit Service 1fb00e
/******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    PrUnTokenize
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  Buffer              - Token Buffer
Packit Service 1fb00e
 *              Next                - "Next" buffer from GetNextToken
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      None
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Un-tokenized the current token buffer. The implementation is
Packit Service 1fb00e
 *              to simply set the null inserted by GetNextToken to a blank.
Packit Service 1fb00e
 *              If Next is NULL, there were no tokens found in the Buffer,
Packit Service 1fb00e
 *              so there is nothing to do.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 *****************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
static void
Packit Service 1fb00e
PrUnTokenize (
Packit Service 1fb00e
    char                    *Buffer,
Packit Service 1fb00e
    char                    *Next)
Packit Service 1fb00e
{
Packit Service 1fb00e
    UINT32                  Length = strlen (Buffer);
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
    if (!Next)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        return;
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    if (Buffer[Length] != '\n')
Packit Service 1fb00e
    {
Packit Service 1fb00e
        Buffer[strlen(Buffer)] = ' ';
Packit Service 1fb00e
    }
Packit Service 1fb00e
}
Packit Service 1fb00e
#endif
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    PrExpandMacros
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  Line                - Pointer into the current line
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      Updated pointer into the current line
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Expand any macros found in the current line buffer.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 *****************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
static char *
Packit Service 1fb00e
PrExpandMacros (
Packit Service 1fb00e
    char                    *Line)
Packit Service 1fb00e
{
Packit Service 1fb00e
    char                    *Token;
Packit Service 1fb00e
    char                    *ReplaceString;
Packit Service 1fb00e
    PR_DEFINE_INFO          *DefineInfo;
Packit Service 1fb00e
    ACPI_SIZE               TokenOffset;
Packit Service 1fb00e
    char                    *Next;
Packit Service 1fb00e
    int                     OffsetAdjust;
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
    strcpy (Gbl_ExpressionTokenBuffer, Gbl_CurrentLineBuffer);
Packit Service 1fb00e
    Token = PrGetNextToken (Gbl_ExpressionTokenBuffer, PR_EXPR_SEPARATORS, &Next);
Packit Service 1fb00e
    OffsetAdjust = 0;
Packit Service 1fb00e
Packit Service 1fb00e
    while (Token)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        DefineInfo = PrMatchDefine (Token);
Packit Service 1fb00e
        if (DefineInfo)
Packit Service 1fb00e
        {
Packit Service 1fb00e
            if (DefineInfo->Body)
Packit Service 1fb00e
            {
Packit Service 1fb00e
                /* This is a macro. TBD: Is this allowed? */
Packit Service 1fb00e
Packit Service 1fb00e
                DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
Packit Service 1fb00e
                    "Matched Macro: %s->%s\n",
Packit Service 1fb00e
                    Gbl_CurrentLineNumber, DefineInfo->Identifier,
Packit Service 1fb00e
                    DefineInfo->Replacement);
Packit Service 1fb00e
Packit Service 1fb00e
                PrDoMacroInvocation (Gbl_ExpressionTokenBuffer, Token,
Packit Service 1fb00e
                    DefineInfo, &Next);
Packit Service 1fb00e
            }
Packit Service 1fb00e
            else
Packit Service 1fb00e
            {
Packit Service 1fb00e
                ReplaceString = DefineInfo->Replacement;
Packit Service 1fb00e
Packit Service 1fb00e
                /* Replace the name in the original line buffer */
Packit Service 1fb00e
Packit Service 1fb00e
                TokenOffset = Token - Gbl_ExpressionTokenBuffer + OffsetAdjust;
Packit Service 1fb00e
                PrReplaceData (
Packit Service 1fb00e
                    &Gbl_CurrentLineBuffer[TokenOffset], strlen (Token),
Packit Service 1fb00e
                    ReplaceString, strlen (ReplaceString));
Packit Service 1fb00e
Packit Service 1fb00e
                /* Adjust for length difference between old and new name length */
Packit Service 1fb00e
Packit Service 1fb00e
                OffsetAdjust += strlen (ReplaceString) - strlen (Token);
Packit Service 1fb00e
Packit Service 1fb00e
                DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
Packit Service 1fb00e
                    "Matched #define within expression: %s->%s\n",
Packit Service 1fb00e
                    Gbl_CurrentLineNumber, Token,
Packit Service 1fb00e
                    *ReplaceString ? ReplaceString : "(NULL STRING)");
Packit Service 1fb00e
            }
Packit Service 1fb00e
        }
Packit Service 1fb00e
Packit Service 1fb00e
        Token = PrGetNextToken (NULL, PR_EXPR_SEPARATORS, &Next);
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    return (Line);
Packit Service 1fb00e
}
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    PrIsDefined
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  Identifier          - Name to be resolved
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      64-bit boolean integer value
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0).
Packit Service 1fb00e
 *
Packit Service 1fb00e
 *****************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
UINT64
Packit Service 1fb00e
PrIsDefined (
Packit Service 1fb00e
    char                    *Identifier)
Packit Service 1fb00e
{
Packit Service 1fb00e
    UINT64                  Value;
Packit Service 1fb00e
    PR_DEFINE_INFO          *DefineInfo;
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
Packit Service 1fb00e
        "**** Is defined?:  %s\n", Gbl_CurrentLineNumber, Identifier);
Packit Service 1fb00e
Packit Service 1fb00e
    Value = 0; /* Default is "Not defined" -- FALSE */
Packit Service 1fb00e
Packit Service 1fb00e
    DefineInfo = PrMatchDefine (Identifier);
Packit Service 1fb00e
    if (DefineInfo)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        Value = ACPI_UINT64_MAX; /* TRUE */
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
Packit Service 1fb00e
        "[#if defined %s] resolved to: %8.8X%8.8X\n",
Packit Service 1fb00e
        Gbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value));
Packit Service 1fb00e
Packit Service 1fb00e
    return (Value);
Packit Service 1fb00e
}
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    PrResolveDefine
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  Identifier          - Name to be resolved
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      A 64-bit boolean integer value
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Returns TRUE if the name is defined, FALSE otherwise (0).
Packit Service 1fb00e
 *
Packit Service 1fb00e
 *****************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
UINT64
Packit Service 1fb00e
PrResolveDefine (
Packit Service 1fb00e
    char                    *Identifier)
Packit Service 1fb00e
{
Packit Service 1fb00e
    UINT64                  Value;
Packit Service 1fb00e
    PR_DEFINE_INFO          *DefineInfo;
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
Packit Service 1fb00e
        "**** Resolve #define:  %s\n", Gbl_CurrentLineNumber, Identifier);
Packit Service 1fb00e
Packit Service 1fb00e
    Value = 0; /* Default is "Not defined" -- FALSE */
Packit Service 1fb00e
Packit Service 1fb00e
    DefineInfo = PrMatchDefine (Identifier);
Packit Service 1fb00e
    if (DefineInfo)
Packit Service 1fb00e
    {
Packit Service 1fb00e
        Value = ACPI_UINT64_MAX; /* TRUE */
Packit Service 1fb00e
    }
Packit Service 1fb00e
Packit Service 1fb00e
    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
Packit Service 1fb00e
        "[#if defined %s] resolved to: %8.8X%8.8X\n",
Packit Service 1fb00e
        Gbl_CurrentLineNumber, Identifier, ACPI_FORMAT_UINT64 (Value));
Packit Service 1fb00e
Packit Service 1fb00e
    return (Value);
Packit Service 1fb00e
}
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
/******************************************************************************
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * FUNCTION:    PrResolveIntegerExpression
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * PARAMETERS:  Line                - Pointer to integer expression
Packit Service 1fb00e
 *              ReturnValue         - Where the resolved 64-bit integer is
Packit Service 1fb00e
 *                                    returned.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * RETURN:      Status
Packit Service 1fb00e
 *
Packit Service 1fb00e
 * DESCRIPTION: Resolve an integer expression to a single value. Supports
Packit Service 1fb00e
 *              both integer constants and labels.
Packit Service 1fb00e
 *
Packit Service 1fb00e
 *****************************************************************************/
Packit Service 1fb00e
Packit Service 1fb00e
ACPI_STATUS
Packit Service 1fb00e
PrResolveIntegerExpression (
Packit Service 1fb00e
    char                    *Line,
Packit Service 1fb00e
    UINT64                  *ReturnValue)
Packit Service 1fb00e
{
Packit Service 1fb00e
    UINT64                  Result;
Packit Service 1fb00e
    char                    *ExpandedLine;
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
Packit Service 1fb00e
        "**** Resolve #if:  %s\n", Gbl_CurrentLineNumber, Line);
Packit Service 1fb00e
Packit Service 1fb00e
    /* Expand all macros within the expression first */
Packit Service 1fb00e
Packit Service 1fb00e
    ExpandedLine = PrExpandMacros (Line);
Packit Service 1fb00e
Packit Service 1fb00e
    /* Now we can evaluate the expression */
Packit Service 1fb00e
Packit Service 1fb00e
    Result = PrEvaluateExpression (ExpandedLine);
Packit Service 1fb00e
    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
Packit Service 1fb00e
        "**** Expression Resolved to: %8.8X%8.8X\n",
Packit Service 1fb00e
        Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Result));
Packit Service 1fb00e
Packit Service 1fb00e
    *ReturnValue = Result;
Packit Service 1fb00e
    return (AE_OK);
Packit Service 1fb00e
Packit Service 1fb00e
#if 0
Packit Service 1fb00e
InvalidExpression:
Packit Service 1fb00e
Packit Service 1fb00e
    ACPI_FREE (EvalBuffer);
Packit Service 1fb00e
    PrError (ASL_ERROR, ASL_MSG_INVALID_EXPRESSION, 0);
Packit Service 1fb00e
    return (AE_ERROR);
Packit Service 1fb00e
Packit Service 1fb00e
Packit Service 1fb00e
NormalExit:
Packit Service 1fb00e
Packit Service 1fb00e
    DbgPrint (ASL_DEBUG_OUTPUT, PR_PREFIX_ID
Packit Service 1fb00e
        "**** Expression Resolved to: %8.8X%8.8X\n",
Packit Service 1fb00e
        Gbl_CurrentLineNumber, ACPI_FORMAT_UINT64 (Value1));
Packit Service 1fb00e
Packit Service 1fb00e
    *ReturnValue = Value1;
Packit Service 1fb00e
    return (AE_OK);
Packit Service 1fb00e
#endif
Packit Service 1fb00e
}