2355 lines
74 KiB
C
2355 lines
74 KiB
C
/*** parseasl.c - Parse ASL source file
|
|
*
|
|
* Copyright (c) 1996,1997 Microsoft Corporation
|
|
* Author: Michael Tsang (MikeTs)
|
|
* Created: 09/07/96
|
|
*
|
|
* This module implements a recursive decent parser for the ASL language.
|
|
*
|
|
* MODIFICATION HISTORY
|
|
*/
|
|
|
|
#include "aslp.h"
|
|
|
|
/***LP ParseASLFile - Parse the ASL source file
|
|
*
|
|
* ENTRY
|
|
* pszFile -> file name string
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseASLFile(PSZ pszFile)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
FILE *pfileSrc;
|
|
PTOKEN ptoken;
|
|
PSZ pszOldFile;
|
|
|
|
ENTER((1, "ParseASLFile(File=%s)\n", pszFile));
|
|
|
|
if ((pfileSrc = fopen(pszFile, "r")) == NULL)
|
|
{
|
|
ERROR(("ParseASLFile: failed to open source file - %s", pszFile));
|
|
rc = ASLERR_OPEN_FILE;
|
|
}
|
|
else
|
|
{
|
|
if ((ptoken = OpenScan(pfileSrc)) == NULL)
|
|
{
|
|
ERROR(("ParseASLFile: failed to initialize scanner"));
|
|
rc = ASLERR_INIT_SCANNER;
|
|
}
|
|
else
|
|
{
|
|
pszOldFile = gpszASLFile;
|
|
gpszASLFile = pszFile;
|
|
printf("%s:\n", pszFile);
|
|
if ((rc = ParseASLTerms(ptoken, 0)) == TOKERR_EOF)
|
|
rc = ASLERR_NONE;
|
|
else if (rc == ASLERR_EXPECT_EOF)
|
|
{
|
|
PrintTokenErr(ptoken, "Expecting end-of-file", TRUE);
|
|
}
|
|
|
|
gpszASLFile = pszOldFile;
|
|
CloseScan(ptoken);
|
|
}
|
|
|
|
fclose(pfileSrc);
|
|
}
|
|
|
|
EXIT((1, "ParseASLFile=%d\n", rc));
|
|
return rc;
|
|
} //ParseASLFile
|
|
|
|
/***LP ParseASLTerms - Parse all ASL statements
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
* iNestLevel - nesting level of current file
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseASLTerms(PTOKEN ptoken, int iNestLevel)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PCODEOBJ pcode;
|
|
|
|
ENTER((1, "ParseASLTerms(ptoken=%p,Level=%d)\n", ptoken, iNestLevel));
|
|
|
|
do
|
|
{
|
|
if ((pcode = (PCODEOBJ)MEMALLOC(sizeof(CODEOBJ))) == NULL)
|
|
{
|
|
ERROR(("ParseASLTerms: failed to allocate code object"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
memset(pcode, 0, sizeof(CODEOBJ));
|
|
|
|
if (gpcodeRoot == NULL)
|
|
gpcodeRoot = pcode;
|
|
else if (gpcodeScope != NULL)
|
|
{
|
|
pcode->pcParent = gpcodeScope;
|
|
ListInsertTail(&pcode->list,
|
|
(PPLIST)&gpcodeScope->pcFirstChild);
|
|
}
|
|
|
|
gpcodeScope = pcode;
|
|
rc = ParseASLTerm(ptoken, iNestLevel);
|
|
gpcodeScope = pcode->pcParent;
|
|
|
|
if (rc != ASLERR_NONE)
|
|
{
|
|
if (gpcodeRoot == pcode)
|
|
gpcodeRoot = NULL;
|
|
else if (gpcodeScope != NULL)
|
|
{
|
|
ListRemoveEntry(&pcode->list,
|
|
(PPLIST)&gpcodeScope->pcFirstChild);
|
|
}
|
|
|
|
MEMFREE(pcode);
|
|
}
|
|
}
|
|
} while (rc == ASLERR_NONE);
|
|
|
|
EXIT((1, "ParseASLTerms=%d\n", rc));
|
|
return rc;
|
|
} //ParseASLTerms
|
|
|
|
/***LP ValidateTermClass - Validate term class with parent
|
|
*
|
|
* ENTRY
|
|
* dwTermClass - term class of child
|
|
* pcParent -> parent
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns TRUE
|
|
* EXIT-FAILURE
|
|
* returns FALSE
|
|
*/
|
|
|
|
BOOL LOCAL ValidateTermClass(DWORD dwTermClass, PCODEOBJ pcParent)
|
|
{
|
|
BOOL rc = TRUE;
|
|
|
|
ENTER((2, "ValidateTermClass(TermClass=%x,Parent=%p)\n",
|
|
dwTermClass, pcParent));
|
|
|
|
if ((dwTermClass & TC_COMPILER_DIRECTIVE) == 0)
|
|
{
|
|
while (pcParent != NULL)
|
|
{
|
|
//
|
|
// Go upward to find a parent that is not "Include".
|
|
//
|
|
if (TermTable[pcParent->dwTermIndex].lID == ID_INCLUDE)
|
|
{
|
|
pcParent = pcParent->pcParent;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((pcParent != NULL) && (pcParent->dwfCode & CF_PARSING_VARLIST))
|
|
{
|
|
rc = (dwTermClass & TermTable[pcParent->dwTermIndex].dwfTerm) != 0;
|
|
}
|
|
}
|
|
|
|
EXIT((2, "ValidateTermClass=%d\n", rc));
|
|
return rc;
|
|
} //ValidateTermClass
|
|
|
|
/***LP ParseASLTerm - Parse an ASL statement
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
* iNestLevel - nesting level of current file
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseASLTerm(PTOKEN ptoken, int iNestLevel)
|
|
{
|
|
int rc;
|
|
|
|
ENTER((1, "ParseASLTerm(ptoken=%p,Level=%d)\n", ptoken, iNestLevel));
|
|
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_RBRACE, MTF_NOT_ERR,
|
|
NULL)) == TOKERR_NONE)
|
|
{
|
|
if (iNestLevel == 0)
|
|
rc = ASLERR_EXPECT_EOF;
|
|
else
|
|
{
|
|
//
|
|
// We have no more terms in the current scope
|
|
//
|
|
UnGetToken(ptoken);
|
|
rc = TOKERR_NO_MATCH;
|
|
}
|
|
}
|
|
else if ((rc != TOKERR_EOF) &&
|
|
((rc = MatchToken(ptoken, TOKTYPE_ID, 0, MTF_ANY_VALUE, NULL)) ==
|
|
TOKERR_NONE))
|
|
{
|
|
if ((gpcodeRoot == NULL) &&
|
|
((ptoken->llTokenValue < 0) ||
|
|
(TermTable[ptoken->llTokenValue].lID != ID_DEFBLK)))
|
|
{
|
|
//
|
|
// outside of definition block
|
|
//
|
|
rc = ASLERR_EXPECT_EOF;
|
|
}
|
|
else if (ptoken->llTokenValue == ID_USER) //user term
|
|
{
|
|
if ((rc = ParseUserTerm(ptoken, FALSE)) == TOKERR_NO_MATCH)
|
|
{
|
|
PrintTokenErr(ptoken, "User ID is not a method", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
else if (ptoken->llTokenValue >= 0) //ASL term
|
|
{
|
|
PNSOBJ pnsScopeSave = gpnsCurrentScope;
|
|
PNSOBJ pnsOwnerSave = gpnsCurrentOwner;
|
|
PASLTERM pterm;
|
|
int iNumArgs;
|
|
|
|
pterm = &TermTable[ptoken->llTokenValue];
|
|
iNumArgs = pterm->pszArgTypes? strlen(pterm->pszArgTypes): 0;
|
|
gpcodeScope->dwCodeType = CODETYPE_ASLTERM;
|
|
gpcodeScope->dwTermIndex = (DWORD)ptoken->llTokenValue;
|
|
gpcodeScope->dwCodeValue = pterm->dwOpcode;
|
|
gpcodeScope->dwDataLen = (DWORD)iNumArgs;
|
|
|
|
if (!ValidateTermClass(pterm->dwfTermClass, gpcodeScope->pcParent))
|
|
{
|
|
PrintTokenErr(ptoken, "unexpected ASL term type", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if (pterm->pszArgTypes != NULL) //there is a fixed list
|
|
rc = ParseArgs(ptoken, pterm, iNumArgs);
|
|
|
|
if ((rc == ASLERR_NONE) && (pterm->dwfTerm & TF_ACTION_FLIST))
|
|
{
|
|
ASSERT(pterm->pfnTerm != NULL);
|
|
rc = pterm->pfnTerm(ptoken, TRUE);
|
|
}
|
|
|
|
if (rc == ASLERR_NONE)
|
|
{
|
|
if (pterm->dwfTerm & TF_ALL_LISTS)
|
|
{
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_LBRACE, 0,
|
|
NULL)) == TOKERR_NONE)
|
|
{
|
|
if (pterm->dwfTerm & TF_CHANGE_CHILDSCOPE)
|
|
{
|
|
ASSERT(gpcodeScope->pnsObj != NULL);
|
|
gpnsCurrentScope = gpcodeScope->pnsObj;
|
|
}
|
|
|
|
if (pterm->lID == ID_METHOD)
|
|
{
|
|
gpnsCurrentOwner = gpcodeScope->pnsObj;
|
|
}
|
|
|
|
gpcodeScope->dwfCode |= CF_PARSING_VARLIST;
|
|
|
|
if (pterm->dwfTerm & TF_FIELD_LIST)
|
|
rc = ParseFieldList(ptoken);
|
|
else if (pterm->dwfTerm & TF_PACKAGE_LIST)
|
|
rc = ParsePackageList(ptoken);
|
|
else if (pterm->dwfTerm & TF_DATA_LIST)
|
|
rc = ParseBuffList(ptoken);
|
|
else if (pterm->dwfTerm & TF_BYTE_LIST)
|
|
rc = ParseDataList(ptoken, sizeof(BYTE));
|
|
else if (pterm->dwfTerm & TF_DWORD_LIST)
|
|
rc = ParseDataList(ptoken, sizeof(DWORD));
|
|
else
|
|
rc = ParseASLTerms(ptoken, iNestLevel + 1);
|
|
|
|
gpcodeScope->dwfCode &= ~CF_PARSING_VARLIST;
|
|
|
|
if (((rc == TOKERR_NO_MATCH) || (rc == TOKERR_EOF)) &&
|
|
((rc = MatchToken(ptoken, TOKTYPE_SYMBOL,
|
|
SYM_RBRACE, 0, NULL)) ==
|
|
TOKERR_NONE))
|
|
{
|
|
ComputeChkSumLen(gpcodeScope);
|
|
if (pterm->dwfTerm & TF_ACTION_VLIST)
|
|
{
|
|
ASSERT(pterm->pfnTerm != NULL);
|
|
rc = pterm->pfnTerm(ptoken, FALSE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ComputeChkSumLen(gpcodeScope);
|
|
}
|
|
}
|
|
gpnsCurrentScope = pnsScopeSave;
|
|
gpnsCurrentOwner = pnsOwnerSave;
|
|
}
|
|
else
|
|
{
|
|
PrintTokenErr(ptoken, "unexpected term type", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
|
|
EXIT((1, "ParseASLTerm=%d\n", rc));
|
|
return rc;
|
|
} //ParseASLTerm
|
|
|
|
/***LP ParseFieldList - Parse Field List
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseFieldList(PTOKEN ptoken)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
NAMESEG NameSeg;
|
|
DWORD dwcbLen;
|
|
DWORD dwcBits = 0, dwcTotalBits = 0;
|
|
PCODEOBJ pc;
|
|
PNSOBJ pns;
|
|
|
|
ENTER((1, "ParseFieldList(ptoken=%p,AccSize=%ld)\n",
|
|
ptoken, gdwFieldAccSize));
|
|
|
|
while ((rc == ASLERR_NONE) &&
|
|
(((rc = MatchToken(ptoken, TOKTYPE_ID, 0,
|
|
MTF_ANY_VALUE | MTF_NOT_ERR, NULL)) ==
|
|
TOKERR_NONE) ||
|
|
((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_COMMA, MTF_NOT_ERR,
|
|
NULL)) == TOKERR_NONE)))
|
|
{
|
|
pns = NULL;
|
|
if (ptoken->iTokenType == TOKTYPE_SYMBOL)
|
|
{
|
|
NameSeg = 0;
|
|
rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0, MTF_ANY_VALUE, NULL);
|
|
dwcBits = (DWORD)ptoken->llTokenValue;
|
|
}
|
|
else if (ptoken->llTokenValue >= 0)
|
|
{
|
|
if (TermTable[ptoken->llTokenValue].lID == ID_OFFSET)
|
|
{
|
|
if (((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_LPARAN, 0,
|
|
NULL)) == TOKERR_NONE) &&
|
|
((rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0, MTF_ANY_VALUE,
|
|
NULL)) == TOKERR_NONE))
|
|
{
|
|
NameSeg = 0;
|
|
if ((DWORD)ptoken->llTokenValue*8 >= dwcTotalBits)
|
|
{
|
|
dwcBits = (DWORD)ptoken->llTokenValue*8 - dwcTotalBits;
|
|
rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_RPARAN, 0,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
PrintTokenErr(ptoken, "backward offset is not allowed",
|
|
TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
}
|
|
else if (TermTable[ptoken->llTokenValue].lID == ID_ACCESSAS)
|
|
{
|
|
PCODEOBJ pcode;
|
|
|
|
UnGetToken(ptoken);
|
|
if ((pcode = (PCODEOBJ)MEMALLOC(sizeof(CODEOBJ))) == NULL)
|
|
{
|
|
ERROR(("ParseFieldList: failed to allocate code object"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
ASSERT(gpcodeScope != NULL);
|
|
memset(pcode, 0, sizeof(CODEOBJ));
|
|
pcode->pcParent = gpcodeScope;
|
|
ListInsertTail(&pcode->list,
|
|
(PPLIST)&gpcodeScope->pcFirstChild);
|
|
|
|
gpcodeScope = pcode;
|
|
rc = ParseASLTerm(ptoken, 0);
|
|
gpcodeScope = pcode->pcParent;
|
|
|
|
if (rc != ASLERR_NONE)
|
|
{
|
|
ListRemoveEntry(&pcode->list,
|
|
(PPLIST)&gpcodeScope->pcFirstChild);
|
|
MEMFREE(pcode);
|
|
}
|
|
else if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_COMMA,
|
|
MTF_NOT_ERR, NULL)) ==
|
|
TOKERR_NONE)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PrintTokenErr(ptoken, "unexpected ASL term in field list",
|
|
TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// expecting a NameSeg and an integer
|
|
//
|
|
dwcbLen = sizeof(NAMESEG);
|
|
if ((ptoken->llTokenValue >= 0) || //an ASL term?
|
|
!ValidASLNameSeg(ptoken, ptoken->szToken, strlen(ptoken->szToken)) ||
|
|
((rc = EncodeName(ptoken->szToken, (PBYTE)&NameSeg, &dwcbLen)) !=
|
|
ASLERR_NONE) ||
|
|
(dwcbLen != sizeof(NAMESEG)))
|
|
{
|
|
PrintTokenErr(ptoken, "not a valid NameSeg", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if ((rc = CreateNameSpaceObj(ptoken, ptoken->szToken,
|
|
gpnsCurrentScope,
|
|
gpnsCurrentOwner,
|
|
&pns, NSF_EXIST_ERR)) ==
|
|
ASLERR_NONE)
|
|
{
|
|
pns->ObjData.dwDataType = OBJTYPE_FIELDUNIT;
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_COMMA, 0,
|
|
NULL)) == TOKERR_NONE)
|
|
{
|
|
rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0, MTF_ANY_VALUE, NULL);
|
|
dwcBits = (DWORD)ptoken->llTokenValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (rc == ASLERR_NONE)
|
|
{
|
|
if ((NameSeg == 0) && (dwcBits == 0))
|
|
{
|
|
rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_COMMA, MTF_NOT_ERR,
|
|
NULL);
|
|
}
|
|
else if ((pc = MEMALLOC(sizeof(CODEOBJ))) == NULL)
|
|
{
|
|
ERROR(("ParseFieldList: failed to allocate field code object"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
int icb;
|
|
|
|
memset(pc, 0, sizeof(CODEOBJ));
|
|
if ((rc = EncodePktLen(dwcBits, &pc->dwDataLen, &icb)) ==
|
|
ASLERR_NONE)
|
|
{
|
|
dwcTotalBits += dwcBits;
|
|
if (gpcodeScope->pnsObj != NULL)
|
|
{
|
|
ASSERT(gpcodeScope->pnsObj->ObjData.dwDataType ==
|
|
OBJTYPE_OPREGION);
|
|
if ((gpcodeScope->pnsObj->ObjData.uipDataValue !=
|
|
0xffffffff) &&
|
|
((dwcTotalBits + 7)/8 >
|
|
gpcodeScope->pnsObj->ObjData.uipDataValue))
|
|
{
|
|
char szMsg[MAX_MSG_LEN + 1];
|
|
|
|
sprintf(szMsg,
|
|
"field offset is exceeding operation region range (offset=0x%x)",
|
|
(dwcTotalBits + 7)/8);
|
|
PrintTokenErr(ptoken, szMsg, TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
break;
|
|
}
|
|
}
|
|
|
|
pc->pcParent = gpcodeScope;
|
|
ListInsertTail(&pc->list,
|
|
(PPLIST)&gpcodeScope->pcFirstChild);
|
|
pc->dwCodeType = CODETYPE_FIELDOBJ;
|
|
if (pns != NULL)
|
|
{
|
|
pc->dwfCode |= CF_CREATED_NSOBJ;
|
|
pc->pnsObj = pns;
|
|
pns->Context = pc;
|
|
}
|
|
pc->dwCodeValue = NameSeg;
|
|
pc->dwCodeLen = (NameSeg == 0)? sizeof(BYTE):
|
|
sizeof(NAMESEG);
|
|
pc->dwCodeLen += icb;
|
|
pc->bCodeChkSum = ComputeDataChkSum((PBYTE)&NameSeg,
|
|
sizeof(NAMESEG));
|
|
pc->bCodeChkSum = (BYTE)
|
|
(pc->bCodeChkSum +
|
|
ComputeDataChkSum((PBYTE)&pc->dwDataLen, icb));
|
|
|
|
rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_COMMA,
|
|
MTF_NOT_ERR, NULL);
|
|
}
|
|
else
|
|
{
|
|
MEMFREE(pc);
|
|
PrintTokenErr(ptoken, "exceeding maximum encoding limit",
|
|
TRUE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
EXIT((1, "ParseFieldList=%d\n", rc));
|
|
return rc;
|
|
} //ParseFieldList
|
|
|
|
/***LP ParsePackageList - Parse Package List
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParsePackageList(PTOKEN ptoken)
|
|
{
|
|
int rc;
|
|
PCODEOBJ pc;
|
|
int icElements = 0;
|
|
PCODEOBJ pArgs;
|
|
|
|
ENTER((1, "ParsePackageList(ptoken=%p)\n", ptoken));
|
|
|
|
do
|
|
{
|
|
if ((pc = MEMALLOC(sizeof(CODEOBJ))) == NULL)
|
|
{
|
|
ERROR(("ParsePackageList: failed to allocate package object"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
memset(pc, 0, sizeof(CODEOBJ));
|
|
pc->pcParent = gpcodeScope;
|
|
ListInsertTail(&pc->list, (PPLIST)&gpcodeScope->pcFirstChild);
|
|
|
|
gpcodeScope = pc;
|
|
if ((rc = ParseData(ptoken)) == TOKERR_NO_MATCH)
|
|
{
|
|
UnGetToken(ptoken);
|
|
rc = ParseName(ptoken, TRUE);
|
|
}
|
|
gpcodeScope = pc->pcParent;
|
|
|
|
if (rc != ASLERR_NONE)
|
|
{
|
|
ListRemoveEntry(&pc->list, (PPLIST)&gpcodeScope->pcFirstChild);
|
|
MEMFREE(pc);
|
|
}
|
|
else if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, 0, MTF_ANY_VALUE,
|
|
NULL)) == TOKERR_NONE)
|
|
{
|
|
icElements++;
|
|
if (ptoken->llTokenValue == SYM_RBRACE)
|
|
{
|
|
UnGetToken(ptoken);
|
|
rc = TOKERR_NO_MATCH;
|
|
}
|
|
else if (ptoken->llTokenValue != SYM_COMMA)
|
|
{
|
|
PrintTokenErr(ptoken, "expecting ',' or '}'", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
}
|
|
} while (rc == ASLERR_NONE);
|
|
|
|
if (rc == TOKERR_NO_MATCH)
|
|
{
|
|
pArgs = (PCODEOBJ)gpcodeScope->pbDataBuff;
|
|
if (pArgs[0].dwfCode & CF_MISSING_ARG)
|
|
{
|
|
pArgs[0].dwfCode &= ~CF_MISSING_ARG;
|
|
SetIntObject(&pArgs[0], (DWORD)icElements, sizeof(BYTE));
|
|
}
|
|
else if (pArgs[0].dwCodeValue < (DWORD)icElements)
|
|
{
|
|
PrintTokenErr(ptoken, "Package has too many elements", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
|
|
EXIT((1, "ParsePackageList=%d\n", rc));
|
|
return rc;
|
|
} //ParsePackageList
|
|
|
|
/***LP ParseBuffList - Parse Buffer List
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseBuffList(PTOKEN ptoken)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PCODEOBJ pc;
|
|
|
|
ENTER((1, "ParseBuffList(ptoken=%p)\n", ptoken));
|
|
|
|
if ((pc = (PCODEOBJ)MEMALLOC(sizeof(CODEOBJ))) == NULL)
|
|
{
|
|
ERROR(("ParseBuffList: failed to allocate buffer code object"))
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
#define MAX_TEMP_BUFF 256
|
|
PCODEOBJ pArgs;
|
|
DWORD dwReservedLen;
|
|
PBYTE pbBuff;
|
|
DWORD dwBuffSize = MAX_TEMP_BUFF;
|
|
|
|
memset(pc, 0, sizeof(CODEOBJ));
|
|
pc->pcParent = gpcodeScope;
|
|
ListInsertTail(&pc->list, (PPLIST)&gpcodeScope->pcFirstChild);
|
|
pArgs = (PCODEOBJ)gpcodeScope->pbDataBuff;
|
|
pc->dwCodeType = CODETYPE_DATAOBJ;
|
|
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_STRING, 0,
|
|
MTF_ANY_VALUE | MTF_NOT_ERR, NULL)) == TOKERR_NONE)
|
|
{
|
|
pc->dwDataLen = strlen(ptoken->szToken) + 1;
|
|
|
|
if (!(pArgs[0].dwfCode & CF_MISSING_ARG) &&
|
|
(pArgs[0].dwCodeType == CODETYPE_DATAOBJ) &&
|
|
((rc = GetIntData(&pArgs[0], &dwReservedLen)) == ASLERR_NONE) &&
|
|
(pc->dwDataLen > dwReservedLen))
|
|
{
|
|
PrintTokenErr(ptoken, "Buffer has too many initializers", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else
|
|
{
|
|
if ((pc->pbDataBuff = MEMALLOC((size_t)pc->dwDataLen)) == NULL)
|
|
{
|
|
ERROR(("ParseBuffList: failed to allocate string object - %s",
|
|
ptoken->szToken));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
memset(pc->pbDataBuff, 0, pc->dwDataLen);
|
|
memcpy(pc->pbDataBuff, ptoken->szToken, pc->dwDataLen);
|
|
pc->dwCodeLen = pc->dwDataLen;
|
|
pc->bCodeChkSum =
|
|
ComputeDataChkSum(pc->pbDataBuff, pc->dwDataLen);
|
|
}
|
|
}
|
|
}
|
|
else if ((pbBuff = MEMALLOC(dwBuffSize)) == NULL)
|
|
{
|
|
ERROR(("ParseBuffList: failed to allocate temp. buffer"))
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwLen = 0;
|
|
|
|
while ((rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0,
|
|
MTF_ANY_VALUE | MTF_NOT_ERR, NULL)) ==
|
|
TOKERR_NONE)
|
|
{
|
|
if (ptoken->llTokenValue > MAX_BYTE)
|
|
{
|
|
PrintTokenErr(ptoken, "expecting byte value", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
break;
|
|
}
|
|
else if (dwLen >= MAX_PACKAGE_LEN)
|
|
{
|
|
PrintTokenErr(ptoken, "data exceeding Buffer limit", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (dwLen >= dwBuffSize)
|
|
{
|
|
PBYTE pb;
|
|
|
|
dwBuffSize += MAX_TEMP_BUFF;
|
|
if ((pb = MEMALLOC(dwBuffSize)) == NULL)
|
|
{
|
|
ERROR(("ParseBuffList: failed to resize temp. buffer (size=%ld)",
|
|
dwBuffSize))
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
memcpy(pb, pbBuff, dwLen);
|
|
MEMFREE(pbBuff);
|
|
pbBuff = pb;
|
|
}
|
|
}
|
|
|
|
pbBuff[dwLen++] = (BYTE)ptoken->llTokenValue;
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, 0,
|
|
MTF_ANY_VALUE, NULL)) == TOKERR_NONE)
|
|
{
|
|
if (ptoken->llTokenValue == SYM_RBRACE)
|
|
{
|
|
UnGetToken(ptoken);
|
|
break;
|
|
}
|
|
else if (ptoken->llTokenValue != SYM_COMMA)
|
|
{
|
|
PrintTokenErr(ptoken, "expecting ',' or '}'", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (rc == TOKERR_NO_MATCH)
|
|
rc = ASLERR_NONE;
|
|
|
|
if (rc == ASLERR_NONE)
|
|
{
|
|
pc->dwDataLen = dwLen;
|
|
if (!(pArgs[0].dwfCode & CF_MISSING_ARG) &&
|
|
(pArgs[0].dwCodeType == CODETYPE_DATAOBJ) &&
|
|
((rc = GetIntData(&pArgs[0], &dwReservedLen)) ==
|
|
ASLERR_NONE) &&
|
|
(pc->dwDataLen > dwReservedLen))
|
|
{
|
|
PrintTokenErr(ptoken, "Buffer has too many initializers",
|
|
TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else
|
|
{
|
|
if ((pc->pbDataBuff = MEMALLOC((size_t)pc->dwDataLen)) ==
|
|
NULL)
|
|
{
|
|
ERROR(("ParseBuffList: failed to allocate data object"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
memset(pc->pbDataBuff, 0, pc->dwDataLen);
|
|
memcpy(pc->pbDataBuff, pbBuff, pc->dwDataLen);
|
|
pc->dwCodeLen = pc->dwDataLen;
|
|
pc->bCodeChkSum =
|
|
ComputeDataChkSum(pc->pbDataBuff, pc->dwDataLen);
|
|
}
|
|
}
|
|
}
|
|
MEMFREE(pbBuff);
|
|
}
|
|
|
|
if ((rc == ASLERR_NONE) && (pArgs[0].dwfCode & CF_MISSING_ARG))
|
|
{
|
|
pArgs[0].dwfCode &= ~CF_MISSING_ARG;
|
|
rc = MakeIntData(pc->dwDataLen, &pArgs[0]);
|
|
}
|
|
|
|
if (rc == ASLERR_NONE)
|
|
rc = TOKERR_NO_MATCH;
|
|
}
|
|
|
|
EXIT((1, "ParseBuffList=%d\n", rc));
|
|
return rc;
|
|
} //ParseBuffList
|
|
|
|
/***LP ParseDataList - Parse Data List
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
* icbDataSize - data size in bytes
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseDataList(PTOKEN ptoken, int icbDataSize)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PCODEOBJ pc;
|
|
|
|
ENTER((1, "ParseDataList(ptoken=%p,DataSize=%d)\n", ptoken, icbDataSize));
|
|
|
|
if ((pc = (PCODEOBJ)MEMALLOC(sizeof(CODEOBJ))) == NULL)
|
|
{
|
|
ERROR(("ParseDataList: failed to allocate buffer code object"))
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
#define MAX_TEMP_BUFF 256
|
|
PBYTE pbBuff;
|
|
DWORD dwBuffSize = MAX_TEMP_BUFF*icbDataSize;
|
|
|
|
memset(pc, 0, sizeof(CODEOBJ));
|
|
pc->pcParent = gpcodeScope;
|
|
ListInsertTail(&pc->list, (PPLIST)&gpcodeScope->pcFirstChild);
|
|
pc->dwCodeType = CODETYPE_DATAOBJ;
|
|
|
|
if ((pbBuff = MEMALLOC(dwBuffSize)) == NULL)
|
|
{
|
|
ERROR(("ParseDataList: failed to allocate temp. buffer"))
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwLen = 0;
|
|
|
|
while ((rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0,
|
|
MTF_ANY_VALUE | MTF_NOT_ERR, NULL)) ==
|
|
TOKERR_NONE)
|
|
{
|
|
switch (icbDataSize)
|
|
{
|
|
case sizeof(BYTE):
|
|
if (ptoken->llTokenValue > MAX_BYTE)
|
|
{
|
|
PrintTokenErr(ptoken, "expecting byte value", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
break;
|
|
|
|
case sizeof(WORD):
|
|
if (ptoken->llTokenValue > MAX_WORD)
|
|
{
|
|
PrintTokenErr(ptoken, "expecting word value", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
break;
|
|
|
|
case sizeof(DWORD):
|
|
if (ptoken->llTokenValue > MAX_DWORD)
|
|
{
|
|
PrintTokenErr(ptoken, "expecting dword value", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ERROR(("ParseDataList: unexpected data size - %d",
|
|
icbDataSize));
|
|
rc = ASLERR_INTERNAL_ERROR;
|
|
}
|
|
|
|
if (rc != ASLERR_NONE)
|
|
break;
|
|
|
|
if (dwLen + icbDataSize > MAX_PACKAGE_LEN)
|
|
{
|
|
PrintTokenErr(ptoken, "data exceeding Buffer limit", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (dwLen + icbDataSize > dwBuffSize)
|
|
{
|
|
PBYTE pb;
|
|
|
|
dwBuffSize += MAX_TEMP_BUFF*icbDataSize;
|
|
if ((pb = MEMALLOC(dwBuffSize)) == NULL)
|
|
{
|
|
ERROR(("ParseDataList: failed to resize temp. buffer (size=%ld)",
|
|
dwBuffSize))
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
memcpy(pb, pbBuff, dwLen);
|
|
MEMFREE(pbBuff);
|
|
pbBuff = pb;
|
|
}
|
|
}
|
|
|
|
switch (icbDataSize)
|
|
{
|
|
case sizeof(BYTE):
|
|
pbBuff[dwLen] = (BYTE)ptoken->llTokenValue;
|
|
break;
|
|
|
|
case sizeof(WORD):
|
|
*((PWORD)&pbBuff[dwLen]) = (WORD)
|
|
ptoken->llTokenValue;
|
|
break;
|
|
|
|
case sizeof(DWORD):
|
|
*((PDWORD)&pbBuff[dwLen]) = (DWORD)
|
|
ptoken->llTokenValue;
|
|
break;
|
|
}
|
|
dwLen += icbDataSize;
|
|
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, 0,
|
|
MTF_ANY_VALUE, NULL)) == TOKERR_NONE)
|
|
{
|
|
if (ptoken->llTokenValue == SYM_RBRACE)
|
|
{
|
|
UnGetToken(ptoken);
|
|
break;
|
|
}
|
|
else if (ptoken->llTokenValue != SYM_COMMA)
|
|
{
|
|
PrintTokenErr(ptoken, "expecting ',' or '}'", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (rc == TOKERR_NO_MATCH)
|
|
rc = ASLERR_NONE;
|
|
|
|
if (rc == ASLERR_NONE)
|
|
{
|
|
pc->dwDataLen = dwLen;
|
|
if ((pc->pbDataBuff = MEMALLOC(pc->dwDataLen)) == NULL)
|
|
{
|
|
ERROR(("ParseDataList: failed to allocate data object"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
memcpy(pc->pbDataBuff, pbBuff, pc->dwDataLen);
|
|
pc->dwCodeLen = pc->dwDataLen;
|
|
pc->bCodeChkSum =
|
|
ComputeDataChkSum(pc->pbDataBuff, pc->dwDataLen);
|
|
}
|
|
}
|
|
MEMFREE(pbBuff);
|
|
}
|
|
|
|
if (rc == ASLERR_NONE)
|
|
rc = TOKERR_NO_MATCH;
|
|
}
|
|
|
|
EXIT((1, "ParseDataList=%d\n", rc));
|
|
return rc;
|
|
} //ParseDataList
|
|
|
|
/***LP ParseArgs - Parse ASL term arguments
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
* pterm -> asl term
|
|
* iNumArgs - number of arguments
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseArgs(PTOKEN ptoken, PASLTERM pterm, int iNumArgs)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
|
|
ENTER((1, "ParseArgs(ptoken=%p,pterm=%p,NumArgs=%d)\n",
|
|
ptoken, pterm, iNumArgs));
|
|
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_LPARAN, 0, NULL)) ==
|
|
TOKERR_NONE)
|
|
{
|
|
PCODEOBJ pArgs = NULL;
|
|
|
|
if ((iNumArgs != 0) &&
|
|
((pArgs = MEMALLOC(sizeof(CODEOBJ)*iNumArgs)) == NULL))
|
|
{
|
|
ERROR(("ParseArgs: failed to allocate argument objects"))
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
char chArgType;
|
|
char szNameBuff[MAX_NAME_LEN + 1];
|
|
BOOL fOptional;
|
|
PSZ pszArgType = "Unknown";
|
|
|
|
gpcodeScope->dwfCode |= CF_PARSING_FIXEDLIST;
|
|
if (pArgs != NULL)
|
|
{
|
|
gpcodeScope->pbDataBuff = (PBYTE)pArgs;
|
|
memset(pArgs, 0, sizeof(CODEOBJ)*iNumArgs);
|
|
}
|
|
|
|
for (i = 0; (rc == ASLERR_NONE) && (i < iNumArgs); ++i)
|
|
{
|
|
chArgType = pterm->pszArgTypes[i];
|
|
if (islower(chArgType))
|
|
{
|
|
chArgType = (char)_toupper(chArgType);
|
|
fOptional = TRUE;
|
|
}
|
|
else
|
|
fOptional = FALSE;
|
|
|
|
pArgs[i].pcParent = gpcodeScope;
|
|
|
|
gpcodeScope = &pArgs[i];
|
|
switch (chArgType)
|
|
{
|
|
case 'N':
|
|
case 'R':
|
|
rc = ParseName(ptoken, (chArgType == 'N')? TRUE: FALSE);
|
|
pszArgType = "Name";
|
|
break;
|
|
|
|
case 'S':
|
|
if (((rc = ParseSuperName(ptoken)) ==
|
|
TOKERR_NO_MATCH) && fOptional)
|
|
{
|
|
pArgs[i].dwCodeType = CODETYPE_ASLTERM;
|
|
pArgs[i].dwCodeValue = OP_ZERO;
|
|
pArgs[i].dwCodeLen = 0;
|
|
pArgs[i].bCodeChkSum = OP_ZERO;
|
|
rc = LookupIDIndex(ID_ZERO,
|
|
&pArgs[i].dwTermIndex);
|
|
}
|
|
pszArgType = "SuperName";
|
|
break;
|
|
|
|
case 'O':
|
|
rc = ParseData(ptoken);
|
|
pszArgType = "DataObject";
|
|
break;
|
|
|
|
case 'B':
|
|
case 'W':
|
|
case 'D':
|
|
case 'U':
|
|
case 'Q':
|
|
rc = ParseInteger(ptoken, chArgType);
|
|
if (chArgType == 'B')
|
|
pszArgType = "ByteInteger";
|
|
else if (chArgType == 'W')
|
|
pszArgType = "WordInteger";
|
|
else if (chArgType == 'D')
|
|
pszArgType = "DWordInteger";
|
|
else if (chArgType == 'Q')
|
|
pszArgType = "QWordInteger";
|
|
else
|
|
pszArgType = "Integer";
|
|
break;
|
|
|
|
case 'C':
|
|
case 'M':
|
|
case 'P':
|
|
rc = ParseOpcode(ptoken, chArgType);
|
|
pszArgType = "Opcode";
|
|
break;
|
|
|
|
case 'E':
|
|
case 'K':
|
|
rc = ParseKeyword(ptoken, pterm->pszArgActions[i]);
|
|
pszArgType = "Keyword";
|
|
if ((chArgType == 'E') && (rc == TOKERR_NO_MATCH))
|
|
{
|
|
if ((rc = ParseInteger(ptoken, 'B')) == ASLERR_NONE)
|
|
{
|
|
if ((gpcodeScope->dwCodeValue <
|
|
(pterm->dwTermData >> 24)) ||
|
|
(gpcodeScope->dwCodeValue >
|
|
((pterm->dwTermData >> 16) & 0xff)))
|
|
{
|
|
PrintTokenErr(ptoken,
|
|
"invalid integer range",
|
|
TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'Z':
|
|
rc = ParseString(ptoken);
|
|
pszArgType = "String";
|
|
break;
|
|
}
|
|
gpcodeScope = pArgs[i].pcParent;
|
|
|
|
if (rc == TOKERR_NO_MATCH)
|
|
{
|
|
if (fOptional)
|
|
{
|
|
pArgs[i].dwfCode |= CF_MISSING_ARG;
|
|
rc = ASLERR_NONE;
|
|
}
|
|
else
|
|
{
|
|
char szMsg[MAX_MSG_LEN + 1];
|
|
|
|
sprintf(szMsg, "expecting argument type \"%s\"",
|
|
pszArgType);
|
|
PrintTokenErr(ptoken, szMsg, TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
|
|
if ((rc == ASLERR_NONE) && (pterm->pszArgActions != NULL) &&
|
|
((chArgType == 'N') || (chArgType == 'S') ||
|
|
(chArgType == 'C') || (chArgType == 'M') ||
|
|
(chArgType == 'P')) &&
|
|
(pArgs[i].dwCodeType == CODETYPE_NAME) &&
|
|
((rc = DecodeName(pArgs[i].pbDataBuff, szNameBuff,
|
|
sizeof(szNameBuff))) == ASLERR_NONE))
|
|
{
|
|
char chActType = pterm->pszArgActions[i];
|
|
|
|
if (islower(chActType))
|
|
{
|
|
rc = CreateObject(ptoken, szNameBuff,
|
|
(char)_toupper(chActType), NULL);
|
|
}
|
|
else
|
|
{
|
|
rc = ValidateObject(ptoken, szNameBuff, chActType,
|
|
chArgType);
|
|
}
|
|
}
|
|
|
|
if (rc == ASLERR_NONE)
|
|
{ //
|
|
// expecting either a comma or a close paran.
|
|
//
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, 0,
|
|
MTF_ANY_VALUE, NULL)) == TOKERR_NONE)
|
|
{
|
|
if (ptoken->llTokenValue == SYM_RPARAN)
|
|
{
|
|
UnGetToken(ptoken);
|
|
}
|
|
else if (ptoken->llTokenValue != SYM_COMMA)
|
|
{
|
|
PrintTokenErr(ptoken, "expecting ',' or ')'", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if (i == iNumArgs - 1) //last argument
|
|
{
|
|
PrintTokenErr(ptoken, "expecting ')'", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
gpcodeScope->dwfCode &= ~CF_PARSING_FIXEDLIST;
|
|
|
|
if (rc == ASLERR_NONE)
|
|
rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_RPARAN, 0, NULL);
|
|
}
|
|
|
|
}
|
|
|
|
EXIT((1, "ParseArgs=%d\n", rc));
|
|
return rc;
|
|
} //ParseArgs
|
|
|
|
/***LP ParseUserTerm - Parse user method name
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
* fNonMethodOK - if TRUE, user term can be a non-method
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns TOKERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseUserTerm(PTOKEN ptoken, BOOL fNonMethodOK)
|
|
{
|
|
int rc;
|
|
|
|
ENTER((1, "ParseUserTerm(ptoken=%p,fNonMethodOK=%d)\n",
|
|
ptoken, fNonMethodOK));
|
|
|
|
//
|
|
// Max number of argument is 7 but we need to store the user term name too,
|
|
// we will store it in Arg0, so we will make it 8.
|
|
//
|
|
if ((gpcodeScope->pbDataBuff = MEMALLOC(sizeof(CODEOBJ)*(MAX_ARGS + 1))) ==
|
|
NULL)
|
|
{
|
|
ERROR(("ParseUserTerm: failed to allocate user term object"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
PCODEOBJ pArgs = (PCODEOBJ)gpcodeScope->pbDataBuff;
|
|
int i;
|
|
|
|
gpcodeScope->dwCodeType = CODETYPE_USERTERM;
|
|
gpcodeScope->dwDataLen = MAX_ARGS + 1;
|
|
memset(pArgs, 0, sizeof(CODEOBJ)*gpcodeScope->dwDataLen);
|
|
|
|
pArgs[0].pcParent = gpcodeScope;
|
|
gpcodeScope = &pArgs[0];
|
|
UnGetToken(ptoken);
|
|
if ((rc = ParseName(ptoken, TRUE)) == TOKERR_NONE)
|
|
{
|
|
PNSOBJ pns;
|
|
char szName[MAX_NAME_LEN + 1];
|
|
|
|
strcpy(szName, ptoken->szToken);
|
|
GetNameSpaceObj(szName, gpnsCurrentScope, &pns, 0);
|
|
|
|
gpcodeScope = pArgs[0].pcParent;
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_LPARAN,
|
|
fNonMethodOK? MTF_NOT_ERR: 0, NULL)) ==
|
|
TOKERR_NONE)
|
|
{
|
|
for (i = 1;
|
|
(rc == TOKERR_NONE) && (i < (int)gpcodeScope->dwDataLen);
|
|
++i)
|
|
{
|
|
pArgs[i].pcParent = gpcodeScope;
|
|
gpcodeScope = &pArgs[i];
|
|
if ((rc = ParseOpcode(ptoken, 'C')) == TOKERR_NONE)
|
|
{
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, 0,
|
|
MTF_ANY_VALUE, NULL)) ==
|
|
TOKERR_NONE)
|
|
{
|
|
if (ptoken->llTokenValue == SYM_RPARAN)
|
|
{
|
|
UnGetToken(ptoken);
|
|
gpcodeScope = pArgs[i].pcParent;
|
|
//
|
|
// Readjust the number of arguments
|
|
//
|
|
gpcodeScope->dwDataLen = i + 1;
|
|
break;
|
|
}
|
|
else if (ptoken->llTokenValue != SYM_COMMA)
|
|
{
|
|
PrintTokenErr(ptoken, "expecting ',' or ')'",
|
|
TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
}
|
|
else if (rc == TOKERR_NO_MATCH)
|
|
{
|
|
gpcodeScope = pArgs[i].pcParent;
|
|
//
|
|
// Readjust the number of arguments
|
|
//
|
|
gpcodeScope->dwDataLen = i;
|
|
rc = TOKERR_NONE;
|
|
break;
|
|
}
|
|
|
|
gpcodeScope = pArgs[i].pcParent;
|
|
}
|
|
|
|
if (rc == TOKERR_NONE)
|
|
{
|
|
ComputeArgsChkSumLen(gpcodeScope);
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_RPARAN, 0,
|
|
NULL)) == ASLERR_NONE)
|
|
{
|
|
char szMsg[MAX_MSG_LEN + 1];
|
|
|
|
if (pns == NULL)
|
|
{
|
|
rc = QueueNSChk(ptoken, szName, OBJTYPE_METHOD,
|
|
gpcodeScope->dwDataLen - 1);
|
|
}
|
|
else if (pns->ObjData.dwDataType != OBJTYPE_METHOD)
|
|
{
|
|
sprintf(szMsg, "%s is not a method", szName);
|
|
PrintTokenErr(ptoken, szMsg, TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if (pns->ObjData.uipDataValue <
|
|
gpcodeScope->dwDataLen - 1)
|
|
{
|
|
sprintf(szMsg, "%s has too many arguments", szName);
|
|
PrintTokenErr(ptoken, szMsg, TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if (pns->ObjData.uipDataValue >
|
|
gpcodeScope->dwDataLen - 1)
|
|
{
|
|
sprintf(szMsg, "%s has too few arguments", szName);
|
|
PrintTokenErr(ptoken, szMsg, TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (rc == TOKERR_NO_MATCH)
|
|
{
|
|
gpcodeScope->dwCodeType = pArgs[0].dwCodeType;
|
|
gpcodeScope->dwDataLen = pArgs[0].dwDataLen;
|
|
gpcodeScope->pbDataBuff = pArgs[0].pbDataBuff;
|
|
gpcodeScope->dwCodeLen = pArgs[0].dwCodeLen;
|
|
gpcodeScope->bCodeChkSum = pArgs[0].bCodeChkSum;
|
|
MEMFREE(pArgs);
|
|
if (pns == NULL)
|
|
{
|
|
rc = QueueNSChk(ptoken, szName, OBJTYPE_UNKNOWN, 0);
|
|
}
|
|
else
|
|
{
|
|
rc = TOKERR_NONE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
EXIT((1, "ParseUserTerm=%d\n", rc));
|
|
return rc;
|
|
} //ParseUserTerm
|
|
|
|
/***LP ParseName - Parse ASL name
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
* fEncode - TRUE if encode name else store it raw as string
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns TOKERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseName(PTOKEN ptoken, BOOL fEncode)
|
|
{
|
|
int rc;
|
|
BYTE abBuff[MAX_NAMECODE_LEN];
|
|
DWORD dwLen = sizeof(abBuff);
|
|
|
|
ENTER((1, "ParseName(ptoken=%p,fEncode=%x)\n", ptoken, fEncode));
|
|
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_ID, ID_USER, MTF_NOT_ERR, NULL)) ==
|
|
TOKERR_NONE)
|
|
{
|
|
if (!ValidASLName(ptoken, ptoken->szToken))
|
|
{
|
|
PrintTokenErr(ptoken, "expecting ASL name", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if (fEncode)
|
|
{
|
|
if ((rc = EncodeName(ptoken->szToken, abBuff, &dwLen)) ==
|
|
ASLERR_NONE)
|
|
{
|
|
if ((gpcodeScope->pbDataBuff = MEMALLOC((size_t)dwLen)) == NULL)
|
|
{
|
|
ERROR(("ParseName: failed to allocate name string object - %s",
|
|
ptoken->szToken));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
memcpy(gpcodeScope->pbDataBuff, abBuff, (int)dwLen);
|
|
gpcodeScope->dwCodeType = CODETYPE_NAME;
|
|
gpcodeScope->dwDataLen = dwLen;
|
|
gpcodeScope->dwCodeLen = dwLen;
|
|
gpcodeScope->bCodeChkSum =
|
|
ComputeDataChkSum(gpcodeScope->pbDataBuff, dwLen);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PrintTokenErr(ptoken, "name too long", TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gpcodeScope->dwDataLen = strlen(ptoken->szToken) + 1;
|
|
if ((gpcodeScope->pbDataBuff = MEMALLOC(gpcodeScope->dwDataLen)) !=
|
|
NULL)
|
|
{
|
|
memcpy(gpcodeScope->pbDataBuff, ptoken->szToken,
|
|
gpcodeScope->dwDataLen);
|
|
gpcodeScope->dwCodeType = CODETYPE_STRING;
|
|
gpcodeScope->dwCodeLen = gpcodeScope->dwDataLen;
|
|
gpcodeScope->bCodeChkSum =
|
|
ComputeDataChkSum(gpcodeScope->pbDataBuff,
|
|
gpcodeScope->dwDataLen);
|
|
}
|
|
else
|
|
{
|
|
ERROR(("ParseName: failed to allocate raw name string object - %s",
|
|
ptoken->szToken));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
}
|
|
}
|
|
|
|
EXIT((1, "ParseName=%d (Name=%s)\n", rc, ptoken->szToken));
|
|
return rc;
|
|
} //ParseName
|
|
|
|
/***LP ParseSuperName - Parse ASL super name
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns TOKERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseSuperName(PTOKEN ptoken)
|
|
{
|
|
int rc;
|
|
|
|
ENTER((1, "ParseSuperName(ptoken=%p)\n", ptoken));
|
|
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_ID, 0, MTF_ANY_VALUE | MTF_NOT_ERR,
|
|
NULL)) == TOKERR_NONE)
|
|
{
|
|
if (ptoken->llTokenValue == ID_USER)
|
|
{
|
|
UnGetToken(ptoken);
|
|
rc = ParseName(ptoken, TRUE);
|
|
}
|
|
else
|
|
{
|
|
if (TermTable[ptoken->llTokenValue].dwfTermClass &
|
|
TC_SHORT_NAME)
|
|
{
|
|
gpcodeScope->dwCodeType = CODETYPE_ASLTERM;
|
|
gpcodeScope->dwTermIndex = (DWORD)ptoken->llTokenValue;
|
|
gpcodeScope->dwCodeValue =
|
|
TermTable[ptoken->llTokenValue].dwOpcode;
|
|
}
|
|
else if (TermTable[ptoken->llTokenValue].dwfTermClass &
|
|
TC_REF_OBJECT)
|
|
{
|
|
UnGetToken(ptoken);
|
|
rc = ParseASLTerm(ptoken, 0);
|
|
}
|
|
else
|
|
{
|
|
UnGetToken(ptoken);
|
|
rc = TOKERR_NO_MATCH;
|
|
}
|
|
}
|
|
}
|
|
|
|
EXIT((1, "ParseSuperName=%d\n", rc));
|
|
return rc;
|
|
} //ParseSuperName
|
|
|
|
/***LP MakeIntData - make integer data object
|
|
*
|
|
* ENTRY
|
|
* dwData - integer data
|
|
* pc -> code object
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL MakeIntData(DWORD dwData, PCODEOBJ pc)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
DWORD dwLen;
|
|
BYTE bOp;
|
|
|
|
ENTER((1, "MakeIntData(Data=%lx,pc=%p)\n", dwData, pc));
|
|
|
|
pc->dwCodeType = CODETYPE_DATAOBJ;
|
|
if ((dwData & 0xffffff00) == 0)
|
|
{
|
|
bOp = OP_BYTE;
|
|
dwLen = 2;
|
|
}
|
|
else if ((dwData & 0xffff0000) == 0)
|
|
{
|
|
bOp = OP_WORD;
|
|
dwLen = 3;
|
|
}
|
|
else
|
|
{
|
|
bOp = OP_DWORD;
|
|
dwLen = 5;
|
|
}
|
|
|
|
if ((pc->pbDataBuff = MEMALLOC((size_t)dwLen)) == NULL)
|
|
{
|
|
ERROR(("MakeIntData: failed to allocate data object - %lx", dwData));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
pc->dwDataLen = dwLen;
|
|
pc->dwCodeLen = dwLen;
|
|
pc->pbDataBuff[0] = bOp;
|
|
memcpy(&pc->pbDataBuff[1], &dwData, (int)(dwLen - 1));
|
|
pc->bCodeChkSum = ComputeDataChkSum(pc->pbDataBuff, dwLen);
|
|
}
|
|
|
|
EXIT((1, "MakeIntData=%d\n", rc));
|
|
return rc;
|
|
} //MakeIntData
|
|
|
|
/***LP GetIntData - get integer from a data object
|
|
*
|
|
* ENTRY
|
|
* pc -> code object
|
|
* pdwData -> to hold integer data
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL GetIntData(PCODEOBJ pc, PDWORD pdwData)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
|
|
ENTER((1, "GetIntData(pc=%p,pdwData=%p)\n", pc, pdwData));
|
|
|
|
ASSERT(pc->dwCodeType == CODETYPE_DATAOBJ);
|
|
switch (pc->pbDataBuff[0])
|
|
{
|
|
case OP_BYTE:
|
|
*pdwData = (DWORD)(*((PBYTE)&pc->pbDataBuff[1]));
|
|
break;
|
|
|
|
case OP_WORD:
|
|
*pdwData = (DWORD)(*((PWORD)&pc->pbDataBuff[1]));
|
|
break;
|
|
|
|
case OP_DWORD:
|
|
*pdwData = *((PDWORD)&pc->pbDataBuff[1]);
|
|
break;
|
|
|
|
default:
|
|
ERROR(("GetIntData: data object is not integer type"));
|
|
rc = ASLERR_INVALID_OBJTYPE;
|
|
}
|
|
|
|
EXIT((1, "GetIntData=%d (Data=%lx)\n", rc, *pdwData));
|
|
return rc;
|
|
} //GetIntData
|
|
|
|
/***LP ParseData - Parse ASL data object
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns TOKERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseData(PTOKEN ptoken)
|
|
{
|
|
int rc;
|
|
|
|
ENTER((1, "ParseData(ptoken=%p)\n", ptoken));
|
|
|
|
if ((rc = GetToken(ptoken)) == TOKERR_NONE)
|
|
{
|
|
if (ptoken->iTokenType == TOKTYPE_NUMBER)
|
|
{
|
|
if (ptoken->llTokenValue <= MAX_DWORD)
|
|
{
|
|
rc = MakeIntData((DWORD)ptoken->llTokenValue, gpcodeScope);
|
|
}
|
|
else
|
|
{
|
|
PrintTokenErr(ptoken, "data value exceeding DWORD maximum",
|
|
TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
else if (ptoken->iTokenType == TOKTYPE_STRING)
|
|
{
|
|
DWORD dwLen;
|
|
|
|
gpcodeScope->dwCodeType = CODETYPE_DATAOBJ;
|
|
dwLen = strlen(ptoken->szToken) + 2;
|
|
if ((gpcodeScope->pbDataBuff = MEMALLOC((size_t)dwLen)) == NULL)
|
|
{
|
|
ERROR(("ParseData: failed to allocate string object - %s",
|
|
ptoken->szToken));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
gpcodeScope->dwDataLen = dwLen;
|
|
gpcodeScope->dwCodeLen = dwLen;
|
|
gpcodeScope->pbDataBuff[0] = OP_STRING;
|
|
memcpy(&gpcodeScope->pbDataBuff[1], ptoken->szToken,
|
|
(int)(dwLen - 1));
|
|
gpcodeScope->bCodeChkSum =
|
|
ComputeDataChkSum(gpcodeScope->pbDataBuff, dwLen);
|
|
}
|
|
}
|
|
else if ((ptoken->iTokenType != TOKTYPE_ID) ||
|
|
(ptoken->llTokenValue < 0) ||
|
|
((TermTable[ptoken->llTokenValue].dwfTermClass &
|
|
(TC_DATA_OBJECT | TC_CONST_NAME)) == 0))
|
|
{
|
|
UnGetToken(ptoken);
|
|
rc = TOKERR_NO_MATCH;
|
|
}
|
|
else
|
|
{
|
|
UnGetToken(ptoken);
|
|
rc = ParseASLTerm(ptoken, 0);
|
|
}
|
|
}
|
|
|
|
EXIT((1, "ParseData=%d\n", rc));
|
|
return rc;
|
|
} //ParseData
|
|
|
|
/***LP ParseInteger - Parse integer data
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
* c - integer type
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns TOKERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseInteger(PTOKEN ptoken, char c)
|
|
{
|
|
int rc;
|
|
|
|
ENTER((1, "ParseInteger(ptoken=%p,ch=%c)\n", ptoken, c));
|
|
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0, MTF_ANY_VALUE | MTF_NOT_ERR,
|
|
NULL)) == TOKERR_NONE)
|
|
{
|
|
gpcodeScope->dwCodeValue = 0;
|
|
if ((c == 'B') && ((ptoken->llTokenValue & 0xffffffffffffff00) != 0) ||
|
|
(c == 'W') && ((ptoken->llTokenValue & 0xffffffffffff0000) != 0) ||
|
|
(c == 'D') && ((ptoken->llTokenValue & 0xffffffff00000000) != 0))
|
|
{
|
|
char szMsg[MAX_MSG_LEN + 1];
|
|
|
|
sprintf(szMsg, "expecting %s value",
|
|
(c == 'B')? "byte":
|
|
(c == 'W')? "word": "dword");
|
|
PrintTokenErr(ptoken, szMsg, TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if (c == 'U')
|
|
{
|
|
if (ptoken->llTokenValue <= MAX_DWORD)
|
|
{
|
|
rc = MakeIntData((DWORD)ptoken->llTokenValue, gpcodeScope);
|
|
}
|
|
else
|
|
{
|
|
PrintTokenErr(ptoken, "data value exceeding DWORD maximum",
|
|
TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
else if (c != 'Q')
|
|
{
|
|
gpcodeScope->dwCodeType = CODETYPE_INTEGER;
|
|
gpcodeScope->dwDataLen = (c == 'B')? sizeof(BYTE):
|
|
(c == 'W')? sizeof(WORD):
|
|
(c == 'D')? sizeof(DWORD):
|
|
((ptoken->llTokenValue &
|
|
0xffffffffffffff00) == 0)? sizeof(BYTE):
|
|
((ptoken->llTokenValue &
|
|
0xffffffffffff0000) == 0)? sizeof(WORD):
|
|
sizeof(DWORD);
|
|
gpcodeScope->dwCodeLen = gpcodeScope->dwDataLen;
|
|
gpcodeScope->dwCodeValue = (DWORD)ptoken->llTokenValue;
|
|
gpcodeScope->bCodeChkSum =
|
|
ComputeDataChkSum((PBYTE)&ptoken->llTokenValue,
|
|
gpcodeScope->dwDataLen);
|
|
}
|
|
else if ((gpcodeScope->pbDataBuff =
|
|
MEMALLOC(gpcodeScope->dwDataLen = sizeof(QWORD))) != NULL)
|
|
{
|
|
gpcodeScope->dwCodeType = CODETYPE_QWORD;
|
|
memcpy(gpcodeScope->pbDataBuff, &ptoken->llTokenValue,
|
|
gpcodeScope->dwDataLen);
|
|
gpcodeScope->dwCodeLen = gpcodeScope->dwDataLen;
|
|
gpcodeScope->bCodeChkSum =
|
|
ComputeDataChkSum(gpcodeScope->pbDataBuff,
|
|
gpcodeScope->dwDataLen);
|
|
}
|
|
else
|
|
{
|
|
ERROR(("ParseInteger: failed to allocate QWord object - %s",
|
|
ptoken->szToken));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
}
|
|
|
|
EXIT((1, "ParseInteger=%d\n", rc));
|
|
return rc;
|
|
} //ParseInteger
|
|
|
|
/***LP ParseOpcode - Parse ASL opcode: MachineCode, FunctionCode, SuperName
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
* c - opcode type
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns TOKERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseOpcode(PTOKEN ptoken, char c)
|
|
{
|
|
int rc;
|
|
|
|
ENTER((1, "ParseOpcode(ptoken=%p,ch=%c)\n", ptoken, c));
|
|
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_ID, 0, MTF_ANY_VALUE | MTF_NOT_ERR,
|
|
NULL)) == TOKERR_NONE)
|
|
{
|
|
if (ptoken->llTokenValue == ID_USER)
|
|
{
|
|
PNSOBJ pns;
|
|
|
|
if ((GetNameSpaceObj(ptoken->szToken, gpnsCurrentScope, &pns, 0) ==
|
|
ASLERR_NONE) &&
|
|
(pns->ObjData.dwDataType == OBJTYPE_RES_FIELD) &&
|
|
((c == 'M') || (c == 'P')))
|
|
{
|
|
DWORD dwValue = 0;
|
|
|
|
if (c == 'P')
|
|
{
|
|
dwValue = pns->ObjData.uipDataValue;
|
|
}
|
|
else if (pns->ObjData.uipDataValue%8 == 0)
|
|
{
|
|
dwValue = pns->ObjData.uipDataValue/8;
|
|
}
|
|
else
|
|
{
|
|
PrintTokenErr(ptoken,
|
|
"object can only be used in CreateField "
|
|
"or CreateBitField statements",
|
|
TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
|
|
if (rc == ASLERR_NONE)
|
|
{
|
|
rc = MakeIntData(dwValue, gpcodeScope);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = ParseUserTerm(ptoken, TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UnGetToken(ptoken);
|
|
if (TermTable[ptoken->llTokenValue].dwfTermClass & TC_OPCODE)
|
|
{
|
|
rc = ParseASLTerm(ptoken, 0);
|
|
}
|
|
else
|
|
{
|
|
rc = TOKERR_NO_MATCH;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
rc = ParseData(ptoken);
|
|
|
|
EXIT((1, "ParseOpcode=%d\n", rc));
|
|
return rc;
|
|
} //ParseOpcode
|
|
|
|
/***LP ParseKeyword - Parse ASL keyword
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
* chExpectType - expected keyword type
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns TOKERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*
|
|
* NOTE
|
|
* DATATYPE_KEYWORD is a transient type. It will be lumped together with
|
|
* other keyword type arguments and be converted into one DATATYPE_INTEGER.
|
|
*/
|
|
|
|
int LOCAL ParseKeyword(PTOKEN ptoken, char chExpectType)
|
|
{
|
|
int rc;
|
|
|
|
ENTER((1, "ParseKeyword(ptoken=%p,ExpectedType=%c)\n",
|
|
ptoken, chExpectType));
|
|
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_ID, 0, MTF_ANY_VALUE | MTF_NOT_ERR,
|
|
NULL)) == TOKERR_NONE)
|
|
{
|
|
if ((ptoken->llTokenValue == ID_USER) ||
|
|
!(TermTable[ptoken->llTokenValue].dwfTermClass & TC_KEYWORD))
|
|
{
|
|
UnGetToken(ptoken);
|
|
rc = TOKERR_NO_MATCH;
|
|
}
|
|
else if (TermTable[ptoken->llTokenValue].pszArgActions[0] !=
|
|
chExpectType)
|
|
{
|
|
PrintTokenErr(ptoken, "incorrect keyword type", TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else
|
|
{
|
|
gpcodeScope->dwCodeType = CODETYPE_KEYWORD;
|
|
gpcodeScope->dwTermIndex = (DWORD)ptoken->llTokenValue;
|
|
gpcodeScope->dwCodeValue = TOKID(ptoken->llTokenValue);
|
|
}
|
|
}
|
|
|
|
EXIT((1, "ParseKeyword=%d\n", rc));
|
|
return rc;
|
|
} //ParseKeyword
|
|
|
|
/***LP ParseString - Parse string object
|
|
*
|
|
* ENTRY
|
|
* ptoken - token stream
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns TOKERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ParseString(PTOKEN ptoken)
|
|
{
|
|
int rc;
|
|
|
|
ENTER((1, "ParseString(ptoken=%p)\n", ptoken));
|
|
|
|
if ((rc = MatchToken(ptoken, TOKTYPE_STRING, 0, MTF_ANY_VALUE | MTF_NOT_ERR,
|
|
NULL)) == TOKERR_NONE)
|
|
{
|
|
gpcodeScope->dwDataLen = strlen(ptoken->szToken) + 1;
|
|
if (gpcodeScope->dwDataLen > MAX_STRING_LEN + 1)
|
|
{
|
|
ERROR(("ParseString: string too big - %s", ptoken->szToken));
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if ((gpcodeScope->pbDataBuff =
|
|
MEMALLOC((size_t)gpcodeScope->dwDataLen)) == NULL)
|
|
{
|
|
ERROR(("ParseString: failed to allocate string object - %s",
|
|
ptoken->szToken));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
gpcodeScope->dwCodeType = CODETYPE_STRING;
|
|
memcpy(gpcodeScope->pbDataBuff, ptoken->szToken,
|
|
(int)gpcodeScope->dwDataLen);
|
|
gpcodeScope->dwCodeLen = gpcodeScope->dwDataLen;
|
|
gpcodeScope->bCodeChkSum =
|
|
ComputeDataChkSum(gpcodeScope->pbDataBuff,
|
|
gpcodeScope->dwDataLen);
|
|
}
|
|
}
|
|
|
|
EXIT((1, "ParseString=%d\n", rc));
|
|
return rc;
|
|
} //ParseString
|
|
|
|
/***LP CreateObject - Create NameSpace object for the term
|
|
*
|
|
* ENTRY
|
|
* ptoken -> TOKEN
|
|
* pszName -> object name
|
|
* c - object type to be created
|
|
* ppns -> to hold object created
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL CreateObject(PTOKEN ptoken, PSZ pszName, char c, PNSOBJ *ppns)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PNSOBJ pns;
|
|
|
|
ENTER((2, "CreateObject(ptoken=%p,Name=%s,Type=%c)\n",
|
|
ptoken, pszName, c));
|
|
|
|
if (((rc = GetNameSpaceObj(pszName, gpnsCurrentScope, &pns, 0)) ==
|
|
ASLERR_NONE) &&
|
|
(pns->ObjData.dwDataType == OBJTYPE_EXTERNAL) ||
|
|
((rc = CreateNameSpaceObj(ptoken, pszName, gpnsCurrentScope,
|
|
gpnsCurrentOwner, &pns, NSF_EXIST_ERR)) ==
|
|
ASLERR_NONE))
|
|
{
|
|
if (!(gdwfASL & ASLF_UNASM))
|
|
{
|
|
ASSERT(gpcodeScope->pnsObj == NULL);
|
|
gpcodeScope->dwfCode |= CF_CREATED_NSOBJ;
|
|
gpcodeScope->pnsObj = pns;
|
|
pns->Context = gpcodeScope;
|
|
}
|
|
|
|
switch (c)
|
|
{
|
|
case NSTYPE_UNKNOWN:
|
|
break;
|
|
|
|
case NSTYPE_FIELDUNIT:
|
|
pns->ObjData.dwDataType = OBJTYPE_FIELDUNIT;
|
|
break;
|
|
|
|
case NSTYPE_DEVICE:
|
|
pns->ObjData.dwDataType = OBJTYPE_DEVICE;
|
|
break;
|
|
|
|
case NSTYPE_EVENT:
|
|
pns->ObjData.dwDataType = OBJTYPE_EVENT;
|
|
break;
|
|
|
|
case NSTYPE_METHOD:
|
|
pns->ObjData.dwDataType = OBJTYPE_METHOD;
|
|
break;
|
|
|
|
case NSTYPE_MUTEX:
|
|
pns->ObjData.dwDataType = OBJTYPE_MUTEX;
|
|
break;
|
|
|
|
case NSTYPE_OPREGION:
|
|
pns->ObjData.dwDataType = OBJTYPE_OPREGION;
|
|
break;
|
|
|
|
case NSTYPE_POWERRES:
|
|
pns->ObjData.dwDataType = OBJTYPE_POWERRES;
|
|
break;
|
|
|
|
case NSTYPE_PROCESSOR:
|
|
pns->ObjData.dwDataType = OBJTYPE_PROCESSOR;
|
|
break;
|
|
|
|
case NSTYPE_THERMALZONE:
|
|
pns->ObjData.dwDataType = OBJTYPE_THERMALZONE;
|
|
break;
|
|
|
|
case NSTYPE_OBJALIAS:
|
|
pns->ObjData.dwDataType = OBJTYPE_OBJALIAS;
|
|
break;
|
|
|
|
case NSTYPE_BUFFFIELD:
|
|
pns->ObjData.dwDataType = OBJTYPE_BUFFFIELD;
|
|
break;
|
|
|
|
default:
|
|
ERROR(("CreateObject: invalid object type %c", c));
|
|
rc = ASLERR_INVALID_OBJTYPE;
|
|
}
|
|
|
|
if (ppns != NULL)
|
|
{
|
|
*ppns = pns;
|
|
}
|
|
}
|
|
|
|
EXIT((2, "CreateObject=%d\n", rc));
|
|
return rc;
|
|
} //CreateObject
|
|
|
|
#ifdef __UNASM
|
|
/***LP CreateScopeObj - Create Scope object
|
|
*
|
|
* ENTRY
|
|
* pszName -> object name
|
|
* ppns -> to hold object created
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL CreateScopeObj(PSZ pszName, PNSOBJ *ppns)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PNSOBJ pnsScope;
|
|
PSZ psz;
|
|
|
|
ENTER((2, "CreateScopeObj(Name=%s)\n", pszName));
|
|
ASSERT(ppns != NULL);
|
|
|
|
if ((psz = strrchr(pszName, '.')) != NULL)
|
|
{
|
|
*psz = '\0';
|
|
if ((rc = GetNameSpaceObj(pszName, gpnsCurrentScope, &pnsScope, 0)) ==
|
|
ASLERR_NSOBJ_NOT_FOUND)
|
|
{
|
|
rc = CreateScopeObj(pszName, &pnsScope);
|
|
}
|
|
*psz = '.';
|
|
psz++;
|
|
}
|
|
else if (pszName[0] == '\\')
|
|
{
|
|
pnsScope = gpnsNameSpaceRoot;
|
|
psz = &pszName[1];
|
|
}
|
|
else
|
|
{
|
|
pnsScope = gpnsCurrentScope;
|
|
psz = pszName;
|
|
}
|
|
|
|
if ((rc == ASLERR_NONE) &&
|
|
((rc = CreateNameSpaceObj(NULL, psz, pnsScope, NULL, ppns,
|
|
NSF_EXIST_OK)) == ASLERR_NONE))
|
|
{
|
|
(*ppns)->ObjData.dwDataType = OBJTYPE_EXTERNAL;
|
|
}
|
|
|
|
EXIT((2, "CreateScopeObj=%d (pns=%p)\n", rc, *ppns));
|
|
return rc;
|
|
} //CreateScopeObj
|
|
#endif //ifdef __UNASM
|
|
|
|
/***LP ValidateObject - Validate the existence and type of the object
|
|
*
|
|
* ENTRY
|
|
* ptoken -> TOKEN
|
|
* pszName -> object name
|
|
* chActType - action type
|
|
* chArgType - argument type
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ValidateObject(PTOKEN ptoken, PSZ pszName, char chActType,
|
|
char chArgType)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
ULONG dwDataType = OBJTYPE_UNKNOWN;
|
|
|
|
ENTER((2, "ValidateObject(ptoken=%p,Name=%s,ActType=%c,ArgType=%c)\n",
|
|
ptoken, pszName, chActType, chArgType));
|
|
|
|
switch (chActType)
|
|
{
|
|
case NSTYPE_UNKNOWN:
|
|
case NSTYPE_SCOPE:
|
|
break;
|
|
|
|
case NSTYPE_FIELDUNIT:
|
|
dwDataType = OBJTYPE_FIELDUNIT;
|
|
break;
|
|
|
|
case NSTYPE_DEVICE:
|
|
dwDataType = OBJTYPE_DEVICE;
|
|
break;
|
|
|
|
case NSTYPE_EVENT:
|
|
dwDataType = OBJTYPE_EVENT;
|
|
break;
|
|
|
|
case NSTYPE_METHOD:
|
|
dwDataType = OBJTYPE_METHOD;
|
|
break;
|
|
|
|
case NSTYPE_MUTEX:
|
|
dwDataType = OBJTYPE_MUTEX;
|
|
break;
|
|
|
|
case NSTYPE_OPREGION:
|
|
dwDataType = OBJTYPE_OPREGION;
|
|
break;
|
|
|
|
case NSTYPE_POWERRES:
|
|
dwDataType = OBJTYPE_POWERRES;
|
|
break;
|
|
|
|
case NSTYPE_PROCESSOR:
|
|
dwDataType = OBJTYPE_PROCESSOR;
|
|
break;
|
|
|
|
case NSTYPE_THERMALZONE:
|
|
dwDataType = OBJTYPE_THERMALZONE;
|
|
break;
|
|
|
|
case NSTYPE_OBJALIAS:
|
|
dwDataType = OBJTYPE_OBJALIAS;
|
|
break;
|
|
|
|
case NSTYPE_BUFFFIELD:
|
|
dwDataType = OBJTYPE_BUFFFIELD;
|
|
break;
|
|
|
|
default:
|
|
ERROR(("ValidateObject: invalid object type %c", chActType));
|
|
rc = ASLERR_INVALID_OBJTYPE;
|
|
}
|
|
|
|
if (rc == ASLERR_NONE)
|
|
{
|
|
PNSOBJ pns;
|
|
char szMsg[MAX_MSG_LEN + 1];
|
|
|
|
if (((rc = GetNameSpaceObj(pszName, gpnsCurrentScope, &pns, 0)) ==
|
|
ASLERR_NONE) &&
|
|
((pns->hOwner == NULL) ||
|
|
((PNSOBJ)pns->hOwner == gpnsCurrentOwner)))
|
|
{
|
|
if ((pns->ObjData.dwDataType == OBJTYPE_RES_FIELD) &&
|
|
(chArgType != 'M') && (chArgType != 'P'))
|
|
{
|
|
PrintTokenErr(ptoken,
|
|
"object can only be used in the index argument "
|
|
"of CreateXField or Index statements",
|
|
TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if ((dwDataType != OBJTYPE_UNKNOWN) &&
|
|
(pns->ObjData.dwDataType != dwDataType))
|
|
{
|
|
sprintf(szMsg,
|
|
"%s has an incorrect type (ObjType=%s, ExpectedType=%s)",
|
|
pszName, GetObjectTypeName(pns->ObjData.dwDataType),
|
|
GetObjectTypeName(dwDataType));
|
|
PrintTokenErr(ptoken, szMsg, TRUE);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if ((chActType == NSTYPE_SCOPE) ||
|
|
(chActType == NSTYPE_OPREGION))
|
|
{
|
|
ASSERT(gpcodeScope->pnsObj == NULL);
|
|
gpcodeScope->pnsObj = pns;
|
|
}
|
|
}
|
|
else if ((rc == ASLERR_NSOBJ_NOT_FOUND) && (gpnsCurrentOwner != NULL))
|
|
{
|
|
//
|
|
// We are in a method referring to something not yet defined.
|
|
// Let's queue it and check it after we are done.
|
|
//
|
|
rc = QueueNSChk(ptoken, pszName, dwDataType, 0);
|
|
}
|
|
else
|
|
{
|
|
sprintf(szMsg, "%s does not exist or not in accessible scope",
|
|
pszName);
|
|
PrintTokenErr(ptoken, szMsg, FALSE);
|
|
rc = ASLERR_NONE;
|
|
}
|
|
}
|
|
|
|
EXIT((2, "ValidateObject=%d\n", rc));
|
|
return rc;
|
|
} //ValidateObject
|
|
|
|
/***LP ValidateNSChkList - Validate objects in NSCHK list
|
|
*
|
|
* ENTRY
|
|
* pnschkHead -> NSCHK list
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL ValidateNSChkList(PNSCHK pnschkHead)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PNSOBJ pns;
|
|
ENTER((2, "ValidateNSChkList(Head=%p)\n", pnschkHead));
|
|
|
|
while ((rc == ASLERR_NONE) && (pnschkHead != NULL))
|
|
{
|
|
if ((GetNameSpaceObj(pnschkHead->szObjName, pnschkHead->pnsScope, &pns,
|
|
0) == ASLERR_NONE) &&
|
|
((pns->hOwner == NULL) ||
|
|
((PNSOBJ)pns->hOwner == pnschkHead->pnsMethod)))
|
|
{
|
|
if (pns->ObjData.dwDataType == OBJTYPE_RES_FIELD)
|
|
{
|
|
ErrPrintf("%s(%d): error: cannot make forward reference to PNP resource object %s\n",
|
|
pnschkHead->pszFile, pnschkHead->wLineNum,
|
|
pnschkHead->szObjName);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if ((pnschkHead->dwExpectedType != OBJTYPE_UNKNOWN) &&
|
|
(pns->ObjData.dwDataType != pnschkHead->dwExpectedType))
|
|
{
|
|
ErrPrintf("%s(%d): warning: %s has incorrect type (ObjType=%s, ExpectedType=%s)\n",
|
|
pnschkHead->pszFile,
|
|
pnschkHead->wLineNum,
|
|
pnschkHead->szObjName,
|
|
GetObjectTypeName(pns->ObjData.dwDataType),
|
|
GetObjectTypeName(pnschkHead->dwExpectedType));
|
|
}
|
|
else if (pnschkHead->dwExpectedType == OBJTYPE_METHOD)
|
|
|
|
{
|
|
if (pns->ObjData.uipDataValue < pnschkHead->dwChkData)
|
|
{
|
|
ErrPrintf("%s(%d): error: %s has too many arguments\n",
|
|
pnschkHead->pszFile,
|
|
pnschkHead->wLineNum,
|
|
pnschkHead->szObjName);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
else if (pns->ObjData.uipDataValue > pnschkHead->dwChkData)
|
|
{
|
|
ErrPrintf("%s(%d): error: %s has too few arguments\n",
|
|
pnschkHead->pszFile,
|
|
pnschkHead->wLineNum,
|
|
pnschkHead->szObjName);
|
|
rc = ASLERR_SYNTAX;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ErrPrintf("%s(%d): warning: %s does not exist or not in accessible scope\n",
|
|
pnschkHead->pszFile,
|
|
pnschkHead->wLineNum,
|
|
pnschkHead->szObjName);
|
|
|
|
}
|
|
|
|
pnschkHead = pnschkHead->pnschkNext;
|
|
}
|
|
|
|
EXIT((2, "ValidateNSChkList=%d\n", rc));
|
|
return rc;
|
|
} //ValidateNSChkList
|
|
|
|
/***LP QueueNSChk - Queue a NSChk request
|
|
*
|
|
* ENTRY
|
|
* ptoken -> TOKEN
|
|
* pszObjName -> object name
|
|
* dwExpectedType - expected object type
|
|
* dwChkData - object specific check data
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns ASLERR_NONE
|
|
* EXIT-FAILURE
|
|
* returns negative error code
|
|
*/
|
|
|
|
int LOCAL QueueNSChk(PTOKEN ptoken, PSZ pszObjName, ULONG dwExpectedType,
|
|
ULONG dwChkData)
|
|
{
|
|
int rc = ASLERR_NONE;
|
|
PNSCHK pnschk;
|
|
|
|
ENTER((2, "QueueNSChk(ptoken=%p,Obj=%s,ExpectedType=%s,ChkData=%x)\n",
|
|
ptoken, pszObjName, GetObjectTypeName(dwExpectedType), dwChkData));
|
|
|
|
if ((pnschk = MEMALLOC(sizeof(NSCHK))) == NULL)
|
|
{
|
|
ERROR(("QueueNSChk: failed to allocate NSCHK object"));
|
|
rc = ASLERR_OUT_OF_MEM;
|
|
}
|
|
else
|
|
{
|
|
memset(pnschk, 0, sizeof(NSCHK));
|
|
strcpy(pnschk->szObjName, pszObjName);
|
|
pnschk->pszFile = gpszASLFile;
|
|
pnschk->pnsScope = gpnsCurrentScope;
|
|
pnschk->pnsMethod = gpnsCurrentOwner;
|
|
pnschk->dwExpectedType = dwExpectedType;
|
|
pnschk->dwChkData = dwChkData;
|
|
pnschk->wLineNum = ptoken->pline->wLineNum;
|
|
if (gpnschkTail != NULL)
|
|
{
|
|
gpnschkTail->pnschkNext = pnschk;
|
|
gpnschkTail = pnschk;
|
|
}
|
|
else
|
|
{
|
|
gpnschkHead = gpnschkTail = pnschk;
|
|
}
|
|
}
|
|
|
|
EXIT((2, "QueueNSChk=%d\n"));
|
|
return rc;
|
|
} //QueueNSChk
|