Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2205 lines
72 KiB

/*** 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 "pch.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_NSPATH_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 ((pterm->pszArgActions[i] != 'Y') &&
//
// AccessAttribKeyword ( pszArgActions type 'Y' ) may be replaced
// by any integer value.
// Size checking is performed in AccessAs function.
//
((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_NSPATH_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 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) && (strcmp(pszName, "\\_OSI") != 0))
{
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
{
if(strcmp(pnschkHead->szObjName, "\\_OSI") != 0)
{
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