Source code of Windows XP (NT5)
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.

2354 lines
74 KiB

  1. /*** parseasl.c - Parse ASL source file
  2. *
  3. * Copyright (c) 1996,1997 Microsoft Corporation
  4. * Author: Michael Tsang (MikeTs)
  5. * Created: 09/07/96
  6. *
  7. * This module implements a recursive decent parser for the ASL language.
  8. *
  9. * MODIFICATION HISTORY
  10. */
  11. #include "aslp.h"
  12. /***LP ParseASLFile - Parse the ASL source file
  13. *
  14. * ENTRY
  15. * pszFile -> file name string
  16. *
  17. * EXIT-SUCCESS
  18. * returns ASLERR_NONE
  19. * EXIT-FAILURE
  20. * returns negative error code
  21. */
  22. int LOCAL ParseASLFile(PSZ pszFile)
  23. {
  24. int rc = ASLERR_NONE;
  25. FILE *pfileSrc;
  26. PTOKEN ptoken;
  27. PSZ pszOldFile;
  28. ENTER((1, "ParseASLFile(File=%s)\n", pszFile));
  29. if ((pfileSrc = fopen(pszFile, "r")) == NULL)
  30. {
  31. ERROR(("ParseASLFile: failed to open source file - %s", pszFile));
  32. rc = ASLERR_OPEN_FILE;
  33. }
  34. else
  35. {
  36. if ((ptoken = OpenScan(pfileSrc)) == NULL)
  37. {
  38. ERROR(("ParseASLFile: failed to initialize scanner"));
  39. rc = ASLERR_INIT_SCANNER;
  40. }
  41. else
  42. {
  43. pszOldFile = gpszASLFile;
  44. gpszASLFile = pszFile;
  45. printf("%s:\n", pszFile);
  46. if ((rc = ParseASLTerms(ptoken, 0)) == TOKERR_EOF)
  47. rc = ASLERR_NONE;
  48. else if (rc == ASLERR_EXPECT_EOF)
  49. {
  50. PrintTokenErr(ptoken, "Expecting end-of-file", TRUE);
  51. }
  52. gpszASLFile = pszOldFile;
  53. CloseScan(ptoken);
  54. }
  55. fclose(pfileSrc);
  56. }
  57. EXIT((1, "ParseASLFile=%d\n", rc));
  58. return rc;
  59. } //ParseASLFile
  60. /***LP ParseASLTerms - Parse all ASL statements
  61. *
  62. * ENTRY
  63. * ptoken - token stream
  64. * iNestLevel - nesting level of current file
  65. *
  66. * EXIT-SUCCESS
  67. * returns ASLERR_NONE
  68. * EXIT-FAILURE
  69. * returns negative error code
  70. */
  71. int LOCAL ParseASLTerms(PTOKEN ptoken, int iNestLevel)
  72. {
  73. int rc = ASLERR_NONE;
  74. PCODEOBJ pcode;
  75. ENTER((1, "ParseASLTerms(ptoken=%p,Level=%d)\n", ptoken, iNestLevel));
  76. do
  77. {
  78. if ((pcode = (PCODEOBJ)MEMALLOC(sizeof(CODEOBJ))) == NULL)
  79. {
  80. ERROR(("ParseASLTerms: failed to allocate code object"));
  81. rc = ASLERR_OUT_OF_MEM;
  82. }
  83. else
  84. {
  85. memset(pcode, 0, sizeof(CODEOBJ));
  86. if (gpcodeRoot == NULL)
  87. gpcodeRoot = pcode;
  88. else if (gpcodeScope != NULL)
  89. {
  90. pcode->pcParent = gpcodeScope;
  91. ListInsertTail(&pcode->list,
  92. (PPLIST)&gpcodeScope->pcFirstChild);
  93. }
  94. gpcodeScope = pcode;
  95. rc = ParseASLTerm(ptoken, iNestLevel);
  96. gpcodeScope = pcode->pcParent;
  97. if (rc != ASLERR_NONE)
  98. {
  99. if (gpcodeRoot == pcode)
  100. gpcodeRoot = NULL;
  101. else if (gpcodeScope != NULL)
  102. {
  103. ListRemoveEntry(&pcode->list,
  104. (PPLIST)&gpcodeScope->pcFirstChild);
  105. }
  106. MEMFREE(pcode);
  107. }
  108. }
  109. } while (rc == ASLERR_NONE);
  110. EXIT((1, "ParseASLTerms=%d\n", rc));
  111. return rc;
  112. } //ParseASLTerms
  113. /***LP ValidateTermClass - Validate term class with parent
  114. *
  115. * ENTRY
  116. * dwTermClass - term class of child
  117. * pcParent -> parent
  118. *
  119. * EXIT-SUCCESS
  120. * returns TRUE
  121. * EXIT-FAILURE
  122. * returns FALSE
  123. */
  124. BOOL LOCAL ValidateTermClass(DWORD dwTermClass, PCODEOBJ pcParent)
  125. {
  126. BOOL rc = TRUE;
  127. ENTER((2, "ValidateTermClass(TermClass=%x,Parent=%p)\n",
  128. dwTermClass, pcParent));
  129. if ((dwTermClass & TC_COMPILER_DIRECTIVE) == 0)
  130. {
  131. while (pcParent != NULL)
  132. {
  133. //
  134. // Go upward to find a parent that is not "Include".
  135. //
  136. if (TermTable[pcParent->dwTermIndex].lID == ID_INCLUDE)
  137. {
  138. pcParent = pcParent->pcParent;
  139. }
  140. else
  141. {
  142. break;
  143. }
  144. }
  145. if ((pcParent != NULL) && (pcParent->dwfCode & CF_PARSING_VARLIST))
  146. {
  147. rc = (dwTermClass & TermTable[pcParent->dwTermIndex].dwfTerm) != 0;
  148. }
  149. }
  150. EXIT((2, "ValidateTermClass=%d\n", rc));
  151. return rc;
  152. } //ValidateTermClass
  153. /***LP ParseASLTerm - Parse an ASL statement
  154. *
  155. * ENTRY
  156. * ptoken - token stream
  157. * iNestLevel - nesting level of current file
  158. *
  159. * EXIT-SUCCESS
  160. * returns ASLERR_NONE
  161. * EXIT-FAILURE
  162. * returns negative error code
  163. */
  164. int LOCAL ParseASLTerm(PTOKEN ptoken, int iNestLevel)
  165. {
  166. int rc;
  167. ENTER((1, "ParseASLTerm(ptoken=%p,Level=%d)\n", ptoken, iNestLevel));
  168. if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_RBRACE, MTF_NOT_ERR,
  169. NULL)) == TOKERR_NONE)
  170. {
  171. if (iNestLevel == 0)
  172. rc = ASLERR_EXPECT_EOF;
  173. else
  174. {
  175. //
  176. // We have no more terms in the current scope
  177. //
  178. UnGetToken(ptoken);
  179. rc = TOKERR_NO_MATCH;
  180. }
  181. }
  182. else if ((rc != TOKERR_EOF) &&
  183. ((rc = MatchToken(ptoken, TOKTYPE_ID, 0, MTF_ANY_VALUE, NULL)) ==
  184. TOKERR_NONE))
  185. {
  186. if ((gpcodeRoot == NULL) &&
  187. ((ptoken->llTokenValue < 0) ||
  188. (TermTable[ptoken->llTokenValue].lID != ID_DEFBLK)))
  189. {
  190. //
  191. // outside of definition block
  192. //
  193. rc = ASLERR_EXPECT_EOF;
  194. }
  195. else if (ptoken->llTokenValue == ID_USER) //user term
  196. {
  197. if ((rc = ParseUserTerm(ptoken, FALSE)) == TOKERR_NO_MATCH)
  198. {
  199. PrintTokenErr(ptoken, "User ID is not a method", TRUE);
  200. rc = ASLERR_SYNTAX;
  201. }
  202. }
  203. else if (ptoken->llTokenValue >= 0) //ASL term
  204. {
  205. PNSOBJ pnsScopeSave = gpnsCurrentScope;
  206. PNSOBJ pnsOwnerSave = gpnsCurrentOwner;
  207. PASLTERM pterm;
  208. int iNumArgs;
  209. pterm = &TermTable[ptoken->llTokenValue];
  210. iNumArgs = pterm->pszArgTypes? strlen(pterm->pszArgTypes): 0;
  211. gpcodeScope->dwCodeType = CODETYPE_ASLTERM;
  212. gpcodeScope->dwTermIndex = (DWORD)ptoken->llTokenValue;
  213. gpcodeScope->dwCodeValue = pterm->dwOpcode;
  214. gpcodeScope->dwDataLen = (DWORD)iNumArgs;
  215. if (!ValidateTermClass(pterm->dwfTermClass, gpcodeScope->pcParent))
  216. {
  217. PrintTokenErr(ptoken, "unexpected ASL term type", TRUE);
  218. rc = ASLERR_SYNTAX;
  219. }
  220. else if (pterm->pszArgTypes != NULL) //there is a fixed list
  221. rc = ParseArgs(ptoken, pterm, iNumArgs);
  222. if ((rc == ASLERR_NONE) && (pterm->dwfTerm & TF_ACTION_FLIST))
  223. {
  224. ASSERT(pterm->pfnTerm != NULL);
  225. rc = pterm->pfnTerm(ptoken, TRUE);
  226. }
  227. if (rc == ASLERR_NONE)
  228. {
  229. if (pterm->dwfTerm & TF_ALL_LISTS)
  230. {
  231. if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_LBRACE, 0,
  232. NULL)) == TOKERR_NONE)
  233. {
  234. if (pterm->dwfTerm & TF_CHANGE_CHILDSCOPE)
  235. {
  236. ASSERT(gpcodeScope->pnsObj != NULL);
  237. gpnsCurrentScope = gpcodeScope->pnsObj;
  238. }
  239. if (pterm->lID == ID_METHOD)
  240. {
  241. gpnsCurrentOwner = gpcodeScope->pnsObj;
  242. }
  243. gpcodeScope->dwfCode |= CF_PARSING_VARLIST;
  244. if (pterm->dwfTerm & TF_FIELD_LIST)
  245. rc = ParseFieldList(ptoken);
  246. else if (pterm->dwfTerm & TF_PACKAGE_LIST)
  247. rc = ParsePackageList(ptoken);
  248. else if (pterm->dwfTerm & TF_DATA_LIST)
  249. rc = ParseBuffList(ptoken);
  250. else if (pterm->dwfTerm & TF_BYTE_LIST)
  251. rc = ParseDataList(ptoken, sizeof(BYTE));
  252. else if (pterm->dwfTerm & TF_DWORD_LIST)
  253. rc = ParseDataList(ptoken, sizeof(DWORD));
  254. else
  255. rc = ParseASLTerms(ptoken, iNestLevel + 1);
  256. gpcodeScope->dwfCode &= ~CF_PARSING_VARLIST;
  257. if (((rc == TOKERR_NO_MATCH) || (rc == TOKERR_EOF)) &&
  258. ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL,
  259. SYM_RBRACE, 0, NULL)) ==
  260. TOKERR_NONE))
  261. {
  262. ComputeChkSumLen(gpcodeScope);
  263. if (pterm->dwfTerm & TF_ACTION_VLIST)
  264. {
  265. ASSERT(pterm->pfnTerm != NULL);
  266. rc = pterm->pfnTerm(ptoken, FALSE);
  267. }
  268. }
  269. }
  270. }
  271. else
  272. {
  273. ComputeChkSumLen(gpcodeScope);
  274. }
  275. }
  276. gpnsCurrentScope = pnsScopeSave;
  277. gpnsCurrentOwner = pnsOwnerSave;
  278. }
  279. else
  280. {
  281. PrintTokenErr(ptoken, "unexpected term type", TRUE);
  282. rc = ASLERR_SYNTAX;
  283. }
  284. }
  285. EXIT((1, "ParseASLTerm=%d\n", rc));
  286. return rc;
  287. } //ParseASLTerm
  288. /***LP ParseFieldList - Parse Field List
  289. *
  290. * ENTRY
  291. * ptoken - token stream
  292. *
  293. * EXIT-SUCCESS
  294. * returns ASLERR_NONE
  295. * EXIT-FAILURE
  296. * returns negative error code
  297. */
  298. int LOCAL ParseFieldList(PTOKEN ptoken)
  299. {
  300. int rc = ASLERR_NONE;
  301. NAMESEG NameSeg;
  302. DWORD dwcbLen;
  303. DWORD dwcBits = 0, dwcTotalBits = 0;
  304. PCODEOBJ pc;
  305. PNSOBJ pns;
  306. ENTER((1, "ParseFieldList(ptoken=%p,AccSize=%ld)\n",
  307. ptoken, gdwFieldAccSize));
  308. while ((rc == ASLERR_NONE) &&
  309. (((rc = MatchToken(ptoken, TOKTYPE_ID, 0,
  310. MTF_ANY_VALUE | MTF_NOT_ERR, NULL)) ==
  311. TOKERR_NONE) ||
  312. ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_COMMA, MTF_NOT_ERR,
  313. NULL)) == TOKERR_NONE)))
  314. {
  315. pns = NULL;
  316. if (ptoken->iTokenType == TOKTYPE_SYMBOL)
  317. {
  318. NameSeg = 0;
  319. rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0, MTF_ANY_VALUE, NULL);
  320. dwcBits = (DWORD)ptoken->llTokenValue;
  321. }
  322. else if (ptoken->llTokenValue >= 0)
  323. {
  324. if (TermTable[ptoken->llTokenValue].lID == ID_OFFSET)
  325. {
  326. if (((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_LPARAN, 0,
  327. NULL)) == TOKERR_NONE) &&
  328. ((rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0, MTF_ANY_VALUE,
  329. NULL)) == TOKERR_NONE))
  330. {
  331. NameSeg = 0;
  332. if ((DWORD)ptoken->llTokenValue*8 >= dwcTotalBits)
  333. {
  334. dwcBits = (DWORD)ptoken->llTokenValue*8 - dwcTotalBits;
  335. rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_RPARAN, 0,
  336. NULL);
  337. }
  338. else
  339. {
  340. PrintTokenErr(ptoken, "backward offset is not allowed",
  341. TRUE);
  342. rc = ASLERR_SYNTAX;
  343. }
  344. }
  345. }
  346. else if (TermTable[ptoken->llTokenValue].lID == ID_ACCESSAS)
  347. {
  348. PCODEOBJ pcode;
  349. UnGetToken(ptoken);
  350. if ((pcode = (PCODEOBJ)MEMALLOC(sizeof(CODEOBJ))) == NULL)
  351. {
  352. ERROR(("ParseFieldList: failed to allocate code object"));
  353. rc = ASLERR_OUT_OF_MEM;
  354. }
  355. else
  356. {
  357. ASSERT(gpcodeScope != NULL);
  358. memset(pcode, 0, sizeof(CODEOBJ));
  359. pcode->pcParent = gpcodeScope;
  360. ListInsertTail(&pcode->list,
  361. (PPLIST)&gpcodeScope->pcFirstChild);
  362. gpcodeScope = pcode;
  363. rc = ParseASLTerm(ptoken, 0);
  364. gpcodeScope = pcode->pcParent;
  365. if (rc != ASLERR_NONE)
  366. {
  367. ListRemoveEntry(&pcode->list,
  368. (PPLIST)&gpcodeScope->pcFirstChild);
  369. MEMFREE(pcode);
  370. }
  371. else if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_COMMA,
  372. MTF_NOT_ERR, NULL)) ==
  373. TOKERR_NONE)
  374. {
  375. continue;
  376. }
  377. }
  378. }
  379. else
  380. {
  381. PrintTokenErr(ptoken, "unexpected ASL term in field list",
  382. TRUE);
  383. rc = ASLERR_SYNTAX;
  384. }
  385. }
  386. else
  387. {
  388. //
  389. // expecting a NameSeg and an integer
  390. //
  391. dwcbLen = sizeof(NAMESEG);
  392. if ((ptoken->llTokenValue >= 0) || //an ASL term?
  393. !ValidASLNameSeg(ptoken, ptoken->szToken, strlen(ptoken->szToken)) ||
  394. ((rc = EncodeName(ptoken->szToken, (PBYTE)&NameSeg, &dwcbLen)) !=
  395. ASLERR_NONE) ||
  396. (dwcbLen != sizeof(NAMESEG)))
  397. {
  398. PrintTokenErr(ptoken, "not a valid NameSeg", TRUE);
  399. rc = ASLERR_SYNTAX;
  400. }
  401. else if ((rc = CreateNameSpaceObj(ptoken, ptoken->szToken,
  402. gpnsCurrentScope,
  403. gpnsCurrentOwner,
  404. &pns, NSF_EXIST_ERR)) ==
  405. ASLERR_NONE)
  406. {
  407. pns->ObjData.dwDataType = OBJTYPE_FIELDUNIT;
  408. if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_COMMA, 0,
  409. NULL)) == TOKERR_NONE)
  410. {
  411. rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0, MTF_ANY_VALUE, NULL);
  412. dwcBits = (DWORD)ptoken->llTokenValue;
  413. }
  414. }
  415. }
  416. if (rc == ASLERR_NONE)
  417. {
  418. if ((NameSeg == 0) && (dwcBits == 0))
  419. {
  420. rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_COMMA, MTF_NOT_ERR,
  421. NULL);
  422. }
  423. else if ((pc = MEMALLOC(sizeof(CODEOBJ))) == NULL)
  424. {
  425. ERROR(("ParseFieldList: failed to allocate field code object"));
  426. rc = ASLERR_OUT_OF_MEM;
  427. }
  428. else
  429. {
  430. int icb;
  431. memset(pc, 0, sizeof(CODEOBJ));
  432. if ((rc = EncodePktLen(dwcBits, &pc->dwDataLen, &icb)) ==
  433. ASLERR_NONE)
  434. {
  435. dwcTotalBits += dwcBits;
  436. if (gpcodeScope->pnsObj != NULL)
  437. {
  438. ASSERT(gpcodeScope->pnsObj->ObjData.dwDataType ==
  439. OBJTYPE_OPREGION);
  440. if ((gpcodeScope->pnsObj->ObjData.uipDataValue !=
  441. 0xffffffff) &&
  442. ((dwcTotalBits + 7)/8 >
  443. gpcodeScope->pnsObj->ObjData.uipDataValue))
  444. {
  445. char szMsg[MAX_MSG_LEN + 1];
  446. sprintf(szMsg,
  447. "field offset is exceeding operation region range (offset=0x%x)",
  448. (dwcTotalBits + 7)/8);
  449. PrintTokenErr(ptoken, szMsg, TRUE);
  450. rc = ASLERR_SYNTAX;
  451. break;
  452. }
  453. }
  454. pc->pcParent = gpcodeScope;
  455. ListInsertTail(&pc->list,
  456. (PPLIST)&gpcodeScope->pcFirstChild);
  457. pc->dwCodeType = CODETYPE_FIELDOBJ;
  458. if (pns != NULL)
  459. {
  460. pc->dwfCode |= CF_CREATED_NSOBJ;
  461. pc->pnsObj = pns;
  462. pns->Context = pc;
  463. }
  464. pc->dwCodeValue = NameSeg;
  465. pc->dwCodeLen = (NameSeg == 0)? sizeof(BYTE):
  466. sizeof(NAMESEG);
  467. pc->dwCodeLen += icb;
  468. pc->bCodeChkSum = ComputeDataChkSum((PBYTE)&NameSeg,
  469. sizeof(NAMESEG));
  470. pc->bCodeChkSum = (BYTE)
  471. (pc->bCodeChkSum +
  472. ComputeDataChkSum((PBYTE)&pc->dwDataLen, icb));
  473. rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_COMMA,
  474. MTF_NOT_ERR, NULL);
  475. }
  476. else
  477. {
  478. MEMFREE(pc);
  479. PrintTokenErr(ptoken, "exceeding maximum encoding limit",
  480. TRUE);
  481. }
  482. }
  483. }
  484. }
  485. EXIT((1, "ParseFieldList=%d\n", rc));
  486. return rc;
  487. } //ParseFieldList
  488. /***LP ParsePackageList - Parse Package List
  489. *
  490. * ENTRY
  491. * ptoken - token stream
  492. *
  493. * EXIT-SUCCESS
  494. * returns ASLERR_NONE
  495. * EXIT-FAILURE
  496. * returns negative error code
  497. */
  498. int LOCAL ParsePackageList(PTOKEN ptoken)
  499. {
  500. int rc;
  501. PCODEOBJ pc;
  502. int icElements = 0;
  503. PCODEOBJ pArgs;
  504. ENTER((1, "ParsePackageList(ptoken=%p)\n", ptoken));
  505. do
  506. {
  507. if ((pc = MEMALLOC(sizeof(CODEOBJ))) == NULL)
  508. {
  509. ERROR(("ParsePackageList: failed to allocate package object"));
  510. rc = ASLERR_OUT_OF_MEM;
  511. }
  512. else
  513. {
  514. memset(pc, 0, sizeof(CODEOBJ));
  515. pc->pcParent = gpcodeScope;
  516. ListInsertTail(&pc->list, (PPLIST)&gpcodeScope->pcFirstChild);
  517. gpcodeScope = pc;
  518. if ((rc = ParseData(ptoken)) == TOKERR_NO_MATCH)
  519. {
  520. UnGetToken(ptoken);
  521. rc = ParseName(ptoken, TRUE);
  522. }
  523. gpcodeScope = pc->pcParent;
  524. if (rc != ASLERR_NONE)
  525. {
  526. ListRemoveEntry(&pc->list, (PPLIST)&gpcodeScope->pcFirstChild);
  527. MEMFREE(pc);
  528. }
  529. else if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, 0, MTF_ANY_VALUE,
  530. NULL)) == TOKERR_NONE)
  531. {
  532. icElements++;
  533. if (ptoken->llTokenValue == SYM_RBRACE)
  534. {
  535. UnGetToken(ptoken);
  536. rc = TOKERR_NO_MATCH;
  537. }
  538. else if (ptoken->llTokenValue != SYM_COMMA)
  539. {
  540. PrintTokenErr(ptoken, "expecting ',' or '}'", TRUE);
  541. rc = ASLERR_SYNTAX;
  542. }
  543. }
  544. }
  545. } while (rc == ASLERR_NONE);
  546. if (rc == TOKERR_NO_MATCH)
  547. {
  548. pArgs = (PCODEOBJ)gpcodeScope->pbDataBuff;
  549. if (pArgs[0].dwfCode & CF_MISSING_ARG)
  550. {
  551. pArgs[0].dwfCode &= ~CF_MISSING_ARG;
  552. SetIntObject(&pArgs[0], (DWORD)icElements, sizeof(BYTE));
  553. }
  554. else if (pArgs[0].dwCodeValue < (DWORD)icElements)
  555. {
  556. PrintTokenErr(ptoken, "Package has too many elements", TRUE);
  557. rc = ASLERR_SYNTAX;
  558. }
  559. }
  560. EXIT((1, "ParsePackageList=%d\n", rc));
  561. return rc;
  562. } //ParsePackageList
  563. /***LP ParseBuffList - Parse Buffer List
  564. *
  565. * ENTRY
  566. * ptoken - token stream
  567. *
  568. * EXIT-SUCCESS
  569. * returns ASLERR_NONE
  570. * EXIT-FAILURE
  571. * returns negative error code
  572. */
  573. int LOCAL ParseBuffList(PTOKEN ptoken)
  574. {
  575. int rc = ASLERR_NONE;
  576. PCODEOBJ pc;
  577. ENTER((1, "ParseBuffList(ptoken=%p)\n", ptoken));
  578. if ((pc = (PCODEOBJ)MEMALLOC(sizeof(CODEOBJ))) == NULL)
  579. {
  580. ERROR(("ParseBuffList: failed to allocate buffer code object"))
  581. rc = ASLERR_OUT_OF_MEM;
  582. }
  583. else
  584. {
  585. #define MAX_TEMP_BUFF 256
  586. PCODEOBJ pArgs;
  587. DWORD dwReservedLen;
  588. PBYTE pbBuff;
  589. DWORD dwBuffSize = MAX_TEMP_BUFF;
  590. memset(pc, 0, sizeof(CODEOBJ));
  591. pc->pcParent = gpcodeScope;
  592. ListInsertTail(&pc->list, (PPLIST)&gpcodeScope->pcFirstChild);
  593. pArgs = (PCODEOBJ)gpcodeScope->pbDataBuff;
  594. pc->dwCodeType = CODETYPE_DATAOBJ;
  595. if ((rc = MatchToken(ptoken, TOKTYPE_STRING, 0,
  596. MTF_ANY_VALUE | MTF_NOT_ERR, NULL)) == TOKERR_NONE)
  597. {
  598. pc->dwDataLen = strlen(ptoken->szToken) + 1;
  599. if (!(pArgs[0].dwfCode & CF_MISSING_ARG) &&
  600. (pArgs[0].dwCodeType == CODETYPE_DATAOBJ) &&
  601. ((rc = GetIntData(&pArgs[0], &dwReservedLen)) == ASLERR_NONE) &&
  602. (pc->dwDataLen > dwReservedLen))
  603. {
  604. PrintTokenErr(ptoken, "Buffer has too many initializers", TRUE);
  605. rc = ASLERR_SYNTAX;
  606. }
  607. else
  608. {
  609. if ((pc->pbDataBuff = MEMALLOC((size_t)pc->dwDataLen)) == NULL)
  610. {
  611. ERROR(("ParseBuffList: failed to allocate string object - %s",
  612. ptoken->szToken));
  613. rc = ASLERR_OUT_OF_MEM;
  614. }
  615. else
  616. {
  617. memset(pc->pbDataBuff, 0, pc->dwDataLen);
  618. memcpy(pc->pbDataBuff, ptoken->szToken, pc->dwDataLen);
  619. pc->dwCodeLen = pc->dwDataLen;
  620. pc->bCodeChkSum =
  621. ComputeDataChkSum(pc->pbDataBuff, pc->dwDataLen);
  622. }
  623. }
  624. }
  625. else if ((pbBuff = MEMALLOC(dwBuffSize)) == NULL)
  626. {
  627. ERROR(("ParseBuffList: failed to allocate temp. buffer"))
  628. rc = ASLERR_OUT_OF_MEM;
  629. }
  630. else
  631. {
  632. DWORD dwLen = 0;
  633. while ((rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0,
  634. MTF_ANY_VALUE | MTF_NOT_ERR, NULL)) ==
  635. TOKERR_NONE)
  636. {
  637. if (ptoken->llTokenValue > MAX_BYTE)
  638. {
  639. PrintTokenErr(ptoken, "expecting byte value", TRUE);
  640. rc = ASLERR_SYNTAX;
  641. break;
  642. }
  643. else if (dwLen >= MAX_PACKAGE_LEN)
  644. {
  645. PrintTokenErr(ptoken, "data exceeding Buffer limit", TRUE);
  646. rc = ASLERR_SYNTAX;
  647. break;
  648. }
  649. else
  650. {
  651. if (dwLen >= dwBuffSize)
  652. {
  653. PBYTE pb;
  654. dwBuffSize += MAX_TEMP_BUFF;
  655. if ((pb = MEMALLOC(dwBuffSize)) == NULL)
  656. {
  657. ERROR(("ParseBuffList: failed to resize temp. buffer (size=%ld)",
  658. dwBuffSize))
  659. rc = ASLERR_OUT_OF_MEM;
  660. break;
  661. }
  662. else
  663. {
  664. memcpy(pb, pbBuff, dwLen);
  665. MEMFREE(pbBuff);
  666. pbBuff = pb;
  667. }
  668. }
  669. pbBuff[dwLen++] = (BYTE)ptoken->llTokenValue;
  670. if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, 0,
  671. MTF_ANY_VALUE, NULL)) == TOKERR_NONE)
  672. {
  673. if (ptoken->llTokenValue == SYM_RBRACE)
  674. {
  675. UnGetToken(ptoken);
  676. break;
  677. }
  678. else if (ptoken->llTokenValue != SYM_COMMA)
  679. {
  680. PrintTokenErr(ptoken, "expecting ',' or '}'", TRUE);
  681. rc = ASLERR_SYNTAX;
  682. break;
  683. }
  684. }
  685. else
  686. break;
  687. }
  688. }
  689. if (rc == TOKERR_NO_MATCH)
  690. rc = ASLERR_NONE;
  691. if (rc == ASLERR_NONE)
  692. {
  693. pc->dwDataLen = dwLen;
  694. if (!(pArgs[0].dwfCode & CF_MISSING_ARG) &&
  695. (pArgs[0].dwCodeType == CODETYPE_DATAOBJ) &&
  696. ((rc = GetIntData(&pArgs[0], &dwReservedLen)) ==
  697. ASLERR_NONE) &&
  698. (pc->dwDataLen > dwReservedLen))
  699. {
  700. PrintTokenErr(ptoken, "Buffer has too many initializers",
  701. TRUE);
  702. rc = ASLERR_SYNTAX;
  703. }
  704. else
  705. {
  706. if ((pc->pbDataBuff = MEMALLOC((size_t)pc->dwDataLen)) ==
  707. NULL)
  708. {
  709. ERROR(("ParseBuffList: failed to allocate data object"));
  710. rc = ASLERR_OUT_OF_MEM;
  711. }
  712. else
  713. {
  714. memset(pc->pbDataBuff, 0, pc->dwDataLen);
  715. memcpy(pc->pbDataBuff, pbBuff, pc->dwDataLen);
  716. pc->dwCodeLen = pc->dwDataLen;
  717. pc->bCodeChkSum =
  718. ComputeDataChkSum(pc->pbDataBuff, pc->dwDataLen);
  719. }
  720. }
  721. }
  722. MEMFREE(pbBuff);
  723. }
  724. if ((rc == ASLERR_NONE) && (pArgs[0].dwfCode & CF_MISSING_ARG))
  725. {
  726. pArgs[0].dwfCode &= ~CF_MISSING_ARG;
  727. rc = MakeIntData(pc->dwDataLen, &pArgs[0]);
  728. }
  729. if (rc == ASLERR_NONE)
  730. rc = TOKERR_NO_MATCH;
  731. }
  732. EXIT((1, "ParseBuffList=%d\n", rc));
  733. return rc;
  734. } //ParseBuffList
  735. /***LP ParseDataList - Parse Data List
  736. *
  737. * ENTRY
  738. * ptoken - token stream
  739. * icbDataSize - data size in bytes
  740. *
  741. * EXIT-SUCCESS
  742. * returns ASLERR_NONE
  743. * EXIT-FAILURE
  744. * returns negative error code
  745. */
  746. int LOCAL ParseDataList(PTOKEN ptoken, int icbDataSize)
  747. {
  748. int rc = ASLERR_NONE;
  749. PCODEOBJ pc;
  750. ENTER((1, "ParseDataList(ptoken=%p,DataSize=%d)\n", ptoken, icbDataSize));
  751. if ((pc = (PCODEOBJ)MEMALLOC(sizeof(CODEOBJ))) == NULL)
  752. {
  753. ERROR(("ParseDataList: failed to allocate buffer code object"))
  754. rc = ASLERR_OUT_OF_MEM;
  755. }
  756. else
  757. {
  758. #define MAX_TEMP_BUFF 256
  759. PBYTE pbBuff;
  760. DWORD dwBuffSize = MAX_TEMP_BUFF*icbDataSize;
  761. memset(pc, 0, sizeof(CODEOBJ));
  762. pc->pcParent = gpcodeScope;
  763. ListInsertTail(&pc->list, (PPLIST)&gpcodeScope->pcFirstChild);
  764. pc->dwCodeType = CODETYPE_DATAOBJ;
  765. if ((pbBuff = MEMALLOC(dwBuffSize)) == NULL)
  766. {
  767. ERROR(("ParseDataList: failed to allocate temp. buffer"))
  768. rc = ASLERR_OUT_OF_MEM;
  769. }
  770. else
  771. {
  772. DWORD dwLen = 0;
  773. while ((rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0,
  774. MTF_ANY_VALUE | MTF_NOT_ERR, NULL)) ==
  775. TOKERR_NONE)
  776. {
  777. switch (icbDataSize)
  778. {
  779. case sizeof(BYTE):
  780. if (ptoken->llTokenValue > MAX_BYTE)
  781. {
  782. PrintTokenErr(ptoken, "expecting byte value", TRUE);
  783. rc = ASLERR_SYNTAX;
  784. }
  785. break;
  786. case sizeof(WORD):
  787. if (ptoken->llTokenValue > MAX_WORD)
  788. {
  789. PrintTokenErr(ptoken, "expecting word value", TRUE);
  790. rc = ASLERR_SYNTAX;
  791. }
  792. break;
  793. case sizeof(DWORD):
  794. if (ptoken->llTokenValue > MAX_DWORD)
  795. {
  796. PrintTokenErr(ptoken, "expecting dword value", TRUE);
  797. rc = ASLERR_SYNTAX;
  798. }
  799. break;
  800. default:
  801. ERROR(("ParseDataList: unexpected data size - %d",
  802. icbDataSize));
  803. rc = ASLERR_INTERNAL_ERROR;
  804. }
  805. if (rc != ASLERR_NONE)
  806. break;
  807. if (dwLen + icbDataSize > MAX_PACKAGE_LEN)
  808. {
  809. PrintTokenErr(ptoken, "data exceeding Buffer limit", TRUE);
  810. rc = ASLERR_SYNTAX;
  811. break;
  812. }
  813. else
  814. {
  815. if (dwLen + icbDataSize > dwBuffSize)
  816. {
  817. PBYTE pb;
  818. dwBuffSize += MAX_TEMP_BUFF*icbDataSize;
  819. if ((pb = MEMALLOC(dwBuffSize)) == NULL)
  820. {
  821. ERROR(("ParseDataList: failed to resize temp. buffer (size=%ld)",
  822. dwBuffSize))
  823. rc = ASLERR_OUT_OF_MEM;
  824. break;
  825. }
  826. else
  827. {
  828. memcpy(pb, pbBuff, dwLen);
  829. MEMFREE(pbBuff);
  830. pbBuff = pb;
  831. }
  832. }
  833. switch (icbDataSize)
  834. {
  835. case sizeof(BYTE):
  836. pbBuff[dwLen] = (BYTE)ptoken->llTokenValue;
  837. break;
  838. case sizeof(WORD):
  839. *((PWORD)&pbBuff[dwLen]) = (WORD)
  840. ptoken->llTokenValue;
  841. break;
  842. case sizeof(DWORD):
  843. *((PDWORD)&pbBuff[dwLen]) = (DWORD)
  844. ptoken->llTokenValue;
  845. break;
  846. }
  847. dwLen += icbDataSize;
  848. if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, 0,
  849. MTF_ANY_VALUE, NULL)) == TOKERR_NONE)
  850. {
  851. if (ptoken->llTokenValue == SYM_RBRACE)
  852. {
  853. UnGetToken(ptoken);
  854. break;
  855. }
  856. else if (ptoken->llTokenValue != SYM_COMMA)
  857. {
  858. PrintTokenErr(ptoken, "expecting ',' or '}'", TRUE);
  859. rc = ASLERR_SYNTAX;
  860. break;
  861. }
  862. }
  863. else
  864. break;
  865. }
  866. }
  867. if (rc == TOKERR_NO_MATCH)
  868. rc = ASLERR_NONE;
  869. if (rc == ASLERR_NONE)
  870. {
  871. pc->dwDataLen = dwLen;
  872. if ((pc->pbDataBuff = MEMALLOC(pc->dwDataLen)) == NULL)
  873. {
  874. ERROR(("ParseDataList: failed to allocate data object"));
  875. rc = ASLERR_OUT_OF_MEM;
  876. }
  877. else
  878. {
  879. memcpy(pc->pbDataBuff, pbBuff, pc->dwDataLen);
  880. pc->dwCodeLen = pc->dwDataLen;
  881. pc->bCodeChkSum =
  882. ComputeDataChkSum(pc->pbDataBuff, pc->dwDataLen);
  883. }
  884. }
  885. MEMFREE(pbBuff);
  886. }
  887. if (rc == ASLERR_NONE)
  888. rc = TOKERR_NO_MATCH;
  889. }
  890. EXIT((1, "ParseDataList=%d\n", rc));
  891. return rc;
  892. } //ParseDataList
  893. /***LP ParseArgs - Parse ASL term arguments
  894. *
  895. * ENTRY
  896. * ptoken - token stream
  897. * pterm -> asl term
  898. * iNumArgs - number of arguments
  899. *
  900. * EXIT-SUCCESS
  901. * returns ASLERR_NONE
  902. * EXIT-FAILURE
  903. * returns negative error code
  904. */
  905. int LOCAL ParseArgs(PTOKEN ptoken, PASLTERM pterm, int iNumArgs)
  906. {
  907. int rc = ASLERR_NONE;
  908. ENTER((1, "ParseArgs(ptoken=%p,pterm=%p,NumArgs=%d)\n",
  909. ptoken, pterm, iNumArgs));
  910. if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_LPARAN, 0, NULL)) ==
  911. TOKERR_NONE)
  912. {
  913. PCODEOBJ pArgs = NULL;
  914. if ((iNumArgs != 0) &&
  915. ((pArgs = MEMALLOC(sizeof(CODEOBJ)*iNumArgs)) == NULL))
  916. {
  917. ERROR(("ParseArgs: failed to allocate argument objects"))
  918. rc = ASLERR_OUT_OF_MEM;
  919. }
  920. else
  921. {
  922. int i;
  923. char chArgType;
  924. char szNameBuff[MAX_NAME_LEN + 1];
  925. BOOL fOptional;
  926. PSZ pszArgType = "Unknown";
  927. gpcodeScope->dwfCode |= CF_PARSING_FIXEDLIST;
  928. if (pArgs != NULL)
  929. {
  930. gpcodeScope->pbDataBuff = (PBYTE)pArgs;
  931. memset(pArgs, 0, sizeof(CODEOBJ)*iNumArgs);
  932. }
  933. for (i = 0; (rc == ASLERR_NONE) && (i < iNumArgs); ++i)
  934. {
  935. chArgType = pterm->pszArgTypes[i];
  936. if (islower(chArgType))
  937. {
  938. chArgType = (char)_toupper(chArgType);
  939. fOptional = TRUE;
  940. }
  941. else
  942. fOptional = FALSE;
  943. pArgs[i].pcParent = gpcodeScope;
  944. gpcodeScope = &pArgs[i];
  945. switch (chArgType)
  946. {
  947. case 'N':
  948. case 'R':
  949. rc = ParseName(ptoken, (chArgType == 'N')? TRUE: FALSE);
  950. pszArgType = "Name";
  951. break;
  952. case 'S':
  953. if (((rc = ParseSuperName(ptoken)) ==
  954. TOKERR_NO_MATCH) && fOptional)
  955. {
  956. pArgs[i].dwCodeType = CODETYPE_ASLTERM;
  957. pArgs[i].dwCodeValue = OP_ZERO;
  958. pArgs[i].dwCodeLen = 0;
  959. pArgs[i].bCodeChkSum = OP_ZERO;
  960. rc = LookupIDIndex(ID_ZERO,
  961. &pArgs[i].dwTermIndex);
  962. }
  963. pszArgType = "SuperName";
  964. break;
  965. case 'O':
  966. rc = ParseData(ptoken);
  967. pszArgType = "DataObject";
  968. break;
  969. case 'B':
  970. case 'W':
  971. case 'D':
  972. case 'U':
  973. case 'Q':
  974. rc = ParseInteger(ptoken, chArgType);
  975. if (chArgType == 'B')
  976. pszArgType = "ByteInteger";
  977. else if (chArgType == 'W')
  978. pszArgType = "WordInteger";
  979. else if (chArgType == 'D')
  980. pszArgType = "DWordInteger";
  981. else if (chArgType == 'Q')
  982. pszArgType = "QWordInteger";
  983. else
  984. pszArgType = "Integer";
  985. break;
  986. case 'C':
  987. case 'M':
  988. case 'P':
  989. rc = ParseOpcode(ptoken, chArgType);
  990. pszArgType = "Opcode";
  991. break;
  992. case 'E':
  993. case 'K':
  994. rc = ParseKeyword(ptoken, pterm->pszArgActions[i]);
  995. pszArgType = "Keyword";
  996. if ((chArgType == 'E') && (rc == TOKERR_NO_MATCH))
  997. {
  998. if ((rc = ParseInteger(ptoken, 'B')) == ASLERR_NONE)
  999. {
  1000. if ((gpcodeScope->dwCodeValue <
  1001. (pterm->dwTermData >> 24)) ||
  1002. (gpcodeScope->dwCodeValue >
  1003. ((pterm->dwTermData >> 16) & 0xff)))
  1004. {
  1005. PrintTokenErr(ptoken,
  1006. "invalid integer range",
  1007. TRUE);
  1008. rc = ASLERR_SYNTAX;
  1009. }
  1010. }
  1011. }
  1012. break;
  1013. case 'Z':
  1014. rc = ParseString(ptoken);
  1015. pszArgType = "String";
  1016. break;
  1017. }
  1018. gpcodeScope = pArgs[i].pcParent;
  1019. if (rc == TOKERR_NO_MATCH)
  1020. {
  1021. if (fOptional)
  1022. {
  1023. pArgs[i].dwfCode |= CF_MISSING_ARG;
  1024. rc = ASLERR_NONE;
  1025. }
  1026. else
  1027. {
  1028. char szMsg[MAX_MSG_LEN + 1];
  1029. sprintf(szMsg, "expecting argument type \"%s\"",
  1030. pszArgType);
  1031. PrintTokenErr(ptoken, szMsg, TRUE);
  1032. rc = ASLERR_SYNTAX;
  1033. }
  1034. }
  1035. if ((rc == ASLERR_NONE) && (pterm->pszArgActions != NULL) &&
  1036. ((chArgType == 'N') || (chArgType == 'S') ||
  1037. (chArgType == 'C') || (chArgType == 'M') ||
  1038. (chArgType == 'P')) &&
  1039. (pArgs[i].dwCodeType == CODETYPE_NAME) &&
  1040. ((rc = DecodeName(pArgs[i].pbDataBuff, szNameBuff,
  1041. sizeof(szNameBuff))) == ASLERR_NONE))
  1042. {
  1043. char chActType = pterm->pszArgActions[i];
  1044. if (islower(chActType))
  1045. {
  1046. rc = CreateObject(ptoken, szNameBuff,
  1047. (char)_toupper(chActType), NULL);
  1048. }
  1049. else
  1050. {
  1051. rc = ValidateObject(ptoken, szNameBuff, chActType,
  1052. chArgType);
  1053. }
  1054. }
  1055. if (rc == ASLERR_NONE)
  1056. { //
  1057. // expecting either a comma or a close paran.
  1058. //
  1059. if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, 0,
  1060. MTF_ANY_VALUE, NULL)) == TOKERR_NONE)
  1061. {
  1062. if (ptoken->llTokenValue == SYM_RPARAN)
  1063. {
  1064. UnGetToken(ptoken);
  1065. }
  1066. else if (ptoken->llTokenValue != SYM_COMMA)
  1067. {
  1068. PrintTokenErr(ptoken, "expecting ',' or ')'", TRUE);
  1069. rc = ASLERR_SYNTAX;
  1070. }
  1071. else if (i == iNumArgs - 1) //last argument
  1072. {
  1073. PrintTokenErr(ptoken, "expecting ')'", TRUE);
  1074. rc = ASLERR_SYNTAX;
  1075. }
  1076. }
  1077. }
  1078. }
  1079. gpcodeScope->dwfCode &= ~CF_PARSING_FIXEDLIST;
  1080. if (rc == ASLERR_NONE)
  1081. rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_RPARAN, 0, NULL);
  1082. }
  1083. }
  1084. EXIT((1, "ParseArgs=%d\n", rc));
  1085. return rc;
  1086. } //ParseArgs
  1087. /***LP ParseUserTerm - Parse user method name
  1088. *
  1089. * ENTRY
  1090. * ptoken - token stream
  1091. * fNonMethodOK - if TRUE, user term can be a non-method
  1092. *
  1093. * EXIT-SUCCESS
  1094. * returns TOKERR_NONE
  1095. * EXIT-FAILURE
  1096. * returns negative error code
  1097. */
  1098. int LOCAL ParseUserTerm(PTOKEN ptoken, BOOL fNonMethodOK)
  1099. {
  1100. int rc;
  1101. ENTER((1, "ParseUserTerm(ptoken=%p,fNonMethodOK=%d)\n",
  1102. ptoken, fNonMethodOK));
  1103. //
  1104. // Max number of argument is 7 but we need to store the user term name too,
  1105. // we will store it in Arg0, so we will make it 8.
  1106. //
  1107. if ((gpcodeScope->pbDataBuff = MEMALLOC(sizeof(CODEOBJ)*(MAX_ARGS + 1))) ==
  1108. NULL)
  1109. {
  1110. ERROR(("ParseUserTerm: failed to allocate user term object"));
  1111. rc = ASLERR_OUT_OF_MEM;
  1112. }
  1113. else
  1114. {
  1115. PCODEOBJ pArgs = (PCODEOBJ)gpcodeScope->pbDataBuff;
  1116. int i;
  1117. gpcodeScope->dwCodeType = CODETYPE_USERTERM;
  1118. gpcodeScope->dwDataLen = MAX_ARGS + 1;
  1119. memset(pArgs, 0, sizeof(CODEOBJ)*gpcodeScope->dwDataLen);
  1120. pArgs[0].pcParent = gpcodeScope;
  1121. gpcodeScope = &pArgs[0];
  1122. UnGetToken(ptoken);
  1123. if ((rc = ParseName(ptoken, TRUE)) == TOKERR_NONE)
  1124. {
  1125. PNSOBJ pns;
  1126. char szName[MAX_NAME_LEN + 1];
  1127. strcpy(szName, ptoken->szToken);
  1128. GetNameSpaceObj(szName, gpnsCurrentScope, &pns, 0);
  1129. gpcodeScope = pArgs[0].pcParent;
  1130. if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_LPARAN,
  1131. fNonMethodOK? MTF_NOT_ERR: 0, NULL)) ==
  1132. TOKERR_NONE)
  1133. {
  1134. for (i = 1;
  1135. (rc == TOKERR_NONE) && (i < (int)gpcodeScope->dwDataLen);
  1136. ++i)
  1137. {
  1138. pArgs[i].pcParent = gpcodeScope;
  1139. gpcodeScope = &pArgs[i];
  1140. if ((rc = ParseOpcode(ptoken, 'C')) == TOKERR_NONE)
  1141. {
  1142. if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, 0,
  1143. MTF_ANY_VALUE, NULL)) ==
  1144. TOKERR_NONE)
  1145. {
  1146. if (ptoken->llTokenValue == SYM_RPARAN)
  1147. {
  1148. UnGetToken(ptoken);
  1149. gpcodeScope = pArgs[i].pcParent;
  1150. //
  1151. // Readjust the number of arguments
  1152. //
  1153. gpcodeScope->dwDataLen = i + 1;
  1154. break;
  1155. }
  1156. else if (ptoken->llTokenValue != SYM_COMMA)
  1157. {
  1158. PrintTokenErr(ptoken, "expecting ',' or ')'",
  1159. TRUE);
  1160. rc = ASLERR_SYNTAX;
  1161. }
  1162. }
  1163. }
  1164. else if (rc == TOKERR_NO_MATCH)
  1165. {
  1166. gpcodeScope = pArgs[i].pcParent;
  1167. //
  1168. // Readjust the number of arguments
  1169. //
  1170. gpcodeScope->dwDataLen = i;
  1171. rc = TOKERR_NONE;
  1172. break;
  1173. }
  1174. gpcodeScope = pArgs[i].pcParent;
  1175. }
  1176. if (rc == TOKERR_NONE)
  1177. {
  1178. ComputeArgsChkSumLen(gpcodeScope);
  1179. if ((rc = MatchToken(ptoken, TOKTYPE_SYMBOL, SYM_RPARAN, 0,
  1180. NULL)) == ASLERR_NONE)
  1181. {
  1182. char szMsg[MAX_MSG_LEN + 1];
  1183. if (pns == NULL)
  1184. {
  1185. rc = QueueNSChk(ptoken, szName, OBJTYPE_METHOD,
  1186. gpcodeScope->dwDataLen - 1);
  1187. }
  1188. else if (pns->ObjData.dwDataType != OBJTYPE_METHOD)
  1189. {
  1190. sprintf(szMsg, "%s is not a method", szName);
  1191. PrintTokenErr(ptoken, szMsg, TRUE);
  1192. rc = ASLERR_SYNTAX;
  1193. }
  1194. else if (pns->ObjData.uipDataValue <
  1195. gpcodeScope->dwDataLen - 1)
  1196. {
  1197. sprintf(szMsg, "%s has too many arguments", szName);
  1198. PrintTokenErr(ptoken, szMsg, TRUE);
  1199. rc = ASLERR_SYNTAX;
  1200. }
  1201. else if (pns->ObjData.uipDataValue >
  1202. gpcodeScope->dwDataLen - 1)
  1203. {
  1204. sprintf(szMsg, "%s has too few arguments", szName);
  1205. PrintTokenErr(ptoken, szMsg, TRUE);
  1206. rc = ASLERR_SYNTAX;
  1207. }
  1208. }
  1209. }
  1210. }
  1211. else if (rc == TOKERR_NO_MATCH)
  1212. {
  1213. gpcodeScope->dwCodeType = pArgs[0].dwCodeType;
  1214. gpcodeScope->dwDataLen = pArgs[0].dwDataLen;
  1215. gpcodeScope->pbDataBuff = pArgs[0].pbDataBuff;
  1216. gpcodeScope->dwCodeLen = pArgs[0].dwCodeLen;
  1217. gpcodeScope->bCodeChkSum = pArgs[0].bCodeChkSum;
  1218. MEMFREE(pArgs);
  1219. if (pns == NULL)
  1220. {
  1221. rc = QueueNSChk(ptoken, szName, OBJTYPE_UNKNOWN, 0);
  1222. }
  1223. else
  1224. {
  1225. rc = TOKERR_NONE;
  1226. }
  1227. }
  1228. }
  1229. }
  1230. EXIT((1, "ParseUserTerm=%d\n", rc));
  1231. return rc;
  1232. } //ParseUserTerm
  1233. /***LP ParseName - Parse ASL name
  1234. *
  1235. * ENTRY
  1236. * ptoken - token stream
  1237. * fEncode - TRUE if encode name else store it raw as string
  1238. *
  1239. * EXIT-SUCCESS
  1240. * returns TOKERR_NONE
  1241. * EXIT-FAILURE
  1242. * returns negative error code
  1243. */
  1244. int LOCAL ParseName(PTOKEN ptoken, BOOL fEncode)
  1245. {
  1246. int rc;
  1247. BYTE abBuff[MAX_NAMECODE_LEN];
  1248. DWORD dwLen = sizeof(abBuff);
  1249. ENTER((1, "ParseName(ptoken=%p,fEncode=%x)\n", ptoken, fEncode));
  1250. if ((rc = MatchToken(ptoken, TOKTYPE_ID, ID_USER, MTF_NOT_ERR, NULL)) ==
  1251. TOKERR_NONE)
  1252. {
  1253. if (!ValidASLName(ptoken, ptoken->szToken))
  1254. {
  1255. PrintTokenErr(ptoken, "expecting ASL name", TRUE);
  1256. rc = ASLERR_SYNTAX;
  1257. }
  1258. else if (fEncode)
  1259. {
  1260. if ((rc = EncodeName(ptoken->szToken, abBuff, &dwLen)) ==
  1261. ASLERR_NONE)
  1262. {
  1263. if ((gpcodeScope->pbDataBuff = MEMALLOC((size_t)dwLen)) == NULL)
  1264. {
  1265. ERROR(("ParseName: failed to allocate name string object - %s",
  1266. ptoken->szToken));
  1267. rc = ASLERR_OUT_OF_MEM;
  1268. }
  1269. else
  1270. {
  1271. memcpy(gpcodeScope->pbDataBuff, abBuff, (int)dwLen);
  1272. gpcodeScope->dwCodeType = CODETYPE_NAME;
  1273. gpcodeScope->dwDataLen = dwLen;
  1274. gpcodeScope->dwCodeLen = dwLen;
  1275. gpcodeScope->bCodeChkSum =
  1276. ComputeDataChkSum(gpcodeScope->pbDataBuff, dwLen);
  1277. }
  1278. }
  1279. else
  1280. {
  1281. PrintTokenErr(ptoken, "name too long", TRUE);
  1282. }
  1283. }
  1284. else
  1285. {
  1286. gpcodeScope->dwDataLen = strlen(ptoken->szToken) + 1;
  1287. if ((gpcodeScope->pbDataBuff = MEMALLOC(gpcodeScope->dwDataLen)) !=
  1288. NULL)
  1289. {
  1290. memcpy(gpcodeScope->pbDataBuff, ptoken->szToken,
  1291. gpcodeScope->dwDataLen);
  1292. gpcodeScope->dwCodeType = CODETYPE_STRING;
  1293. gpcodeScope->dwCodeLen = gpcodeScope->dwDataLen;
  1294. gpcodeScope->bCodeChkSum =
  1295. ComputeDataChkSum(gpcodeScope->pbDataBuff,
  1296. gpcodeScope->dwDataLen);
  1297. }
  1298. else
  1299. {
  1300. ERROR(("ParseName: failed to allocate raw name string object - %s",
  1301. ptoken->szToken));
  1302. rc = ASLERR_OUT_OF_MEM;
  1303. }
  1304. }
  1305. }
  1306. EXIT((1, "ParseName=%d (Name=%s)\n", rc, ptoken->szToken));
  1307. return rc;
  1308. } //ParseName
  1309. /***LP ParseSuperName - Parse ASL super name
  1310. *
  1311. * ENTRY
  1312. * ptoken - token stream
  1313. *
  1314. * EXIT-SUCCESS
  1315. * returns TOKERR_NONE
  1316. * EXIT-FAILURE
  1317. * returns negative error code
  1318. */
  1319. int LOCAL ParseSuperName(PTOKEN ptoken)
  1320. {
  1321. int rc;
  1322. ENTER((1, "ParseSuperName(ptoken=%p)\n", ptoken));
  1323. if ((rc = MatchToken(ptoken, TOKTYPE_ID, 0, MTF_ANY_VALUE | MTF_NOT_ERR,
  1324. NULL)) == TOKERR_NONE)
  1325. {
  1326. if (ptoken->llTokenValue == ID_USER)
  1327. {
  1328. UnGetToken(ptoken);
  1329. rc = ParseName(ptoken, TRUE);
  1330. }
  1331. else
  1332. {
  1333. if (TermTable[ptoken->llTokenValue].dwfTermClass &
  1334. TC_SHORT_NAME)
  1335. {
  1336. gpcodeScope->dwCodeType = CODETYPE_ASLTERM;
  1337. gpcodeScope->dwTermIndex = (DWORD)ptoken->llTokenValue;
  1338. gpcodeScope->dwCodeValue =
  1339. TermTable[ptoken->llTokenValue].dwOpcode;
  1340. }
  1341. else if (TermTable[ptoken->llTokenValue].dwfTermClass &
  1342. TC_REF_OBJECT)
  1343. {
  1344. UnGetToken(ptoken);
  1345. rc = ParseASLTerm(ptoken, 0);
  1346. }
  1347. else
  1348. {
  1349. UnGetToken(ptoken);
  1350. rc = TOKERR_NO_MATCH;
  1351. }
  1352. }
  1353. }
  1354. EXIT((1, "ParseSuperName=%d\n", rc));
  1355. return rc;
  1356. } //ParseSuperName
  1357. /***LP MakeIntData - make integer data object
  1358. *
  1359. * ENTRY
  1360. * dwData - integer data
  1361. * pc -> code object
  1362. *
  1363. * EXIT-SUCCESS
  1364. * returns ASLERR_NONE
  1365. * EXIT-FAILURE
  1366. * returns negative error code
  1367. */
  1368. int LOCAL MakeIntData(DWORD dwData, PCODEOBJ pc)
  1369. {
  1370. int rc = ASLERR_NONE;
  1371. DWORD dwLen;
  1372. BYTE bOp;
  1373. ENTER((1, "MakeIntData(Data=%lx,pc=%p)\n", dwData, pc));
  1374. pc->dwCodeType = CODETYPE_DATAOBJ;
  1375. if ((dwData & 0xffffff00) == 0)
  1376. {
  1377. bOp = OP_BYTE;
  1378. dwLen = 2;
  1379. }
  1380. else if ((dwData & 0xffff0000) == 0)
  1381. {
  1382. bOp = OP_WORD;
  1383. dwLen = 3;
  1384. }
  1385. else
  1386. {
  1387. bOp = OP_DWORD;
  1388. dwLen = 5;
  1389. }
  1390. if ((pc->pbDataBuff = MEMALLOC((size_t)dwLen)) == NULL)
  1391. {
  1392. ERROR(("MakeIntData: failed to allocate data object - %lx", dwData));
  1393. rc = ASLERR_OUT_OF_MEM;
  1394. }
  1395. else
  1396. {
  1397. pc->dwDataLen = dwLen;
  1398. pc->dwCodeLen = dwLen;
  1399. pc->pbDataBuff[0] = bOp;
  1400. memcpy(&pc->pbDataBuff[1], &dwData, (int)(dwLen - 1));
  1401. pc->bCodeChkSum = ComputeDataChkSum(pc->pbDataBuff, dwLen);
  1402. }
  1403. EXIT((1, "MakeIntData=%d\n", rc));
  1404. return rc;
  1405. } //MakeIntData
  1406. /***LP GetIntData - get integer from a data object
  1407. *
  1408. * ENTRY
  1409. * pc -> code object
  1410. * pdwData -> to hold integer data
  1411. *
  1412. * EXIT-SUCCESS
  1413. * returns ASLERR_NONE
  1414. * EXIT-FAILURE
  1415. * returns negative error code
  1416. */
  1417. int LOCAL GetIntData(PCODEOBJ pc, PDWORD pdwData)
  1418. {
  1419. int rc = ASLERR_NONE;
  1420. ENTER((1, "GetIntData(pc=%p,pdwData=%p)\n", pc, pdwData));
  1421. ASSERT(pc->dwCodeType == CODETYPE_DATAOBJ);
  1422. switch (pc->pbDataBuff[0])
  1423. {
  1424. case OP_BYTE:
  1425. *pdwData = (DWORD)(*((PBYTE)&pc->pbDataBuff[1]));
  1426. break;
  1427. case OP_WORD:
  1428. *pdwData = (DWORD)(*((PWORD)&pc->pbDataBuff[1]));
  1429. break;
  1430. case OP_DWORD:
  1431. *pdwData = *((PDWORD)&pc->pbDataBuff[1]);
  1432. break;
  1433. default:
  1434. ERROR(("GetIntData: data object is not integer type"));
  1435. rc = ASLERR_INVALID_OBJTYPE;
  1436. }
  1437. EXIT((1, "GetIntData=%d (Data=%lx)\n", rc, *pdwData));
  1438. return rc;
  1439. } //GetIntData
  1440. /***LP ParseData - Parse ASL data object
  1441. *
  1442. * ENTRY
  1443. * ptoken - token stream
  1444. *
  1445. * EXIT-SUCCESS
  1446. * returns TOKERR_NONE
  1447. * EXIT-FAILURE
  1448. * returns negative error code
  1449. */
  1450. int LOCAL ParseData(PTOKEN ptoken)
  1451. {
  1452. int rc;
  1453. ENTER((1, "ParseData(ptoken=%p)\n", ptoken));
  1454. if ((rc = GetToken(ptoken)) == TOKERR_NONE)
  1455. {
  1456. if (ptoken->iTokenType == TOKTYPE_NUMBER)
  1457. {
  1458. if (ptoken->llTokenValue <= MAX_DWORD)
  1459. {
  1460. rc = MakeIntData((DWORD)ptoken->llTokenValue, gpcodeScope);
  1461. }
  1462. else
  1463. {
  1464. PrintTokenErr(ptoken, "data value exceeding DWORD maximum",
  1465. TRUE);
  1466. rc = ASLERR_SYNTAX;
  1467. }
  1468. }
  1469. else if (ptoken->iTokenType == TOKTYPE_STRING)
  1470. {
  1471. DWORD dwLen;
  1472. gpcodeScope->dwCodeType = CODETYPE_DATAOBJ;
  1473. dwLen = strlen(ptoken->szToken) + 2;
  1474. if ((gpcodeScope->pbDataBuff = MEMALLOC((size_t)dwLen)) == NULL)
  1475. {
  1476. ERROR(("ParseData: failed to allocate string object - %s",
  1477. ptoken->szToken));
  1478. rc = ASLERR_OUT_OF_MEM;
  1479. }
  1480. else
  1481. {
  1482. gpcodeScope->dwDataLen = dwLen;
  1483. gpcodeScope->dwCodeLen = dwLen;
  1484. gpcodeScope->pbDataBuff[0] = OP_STRING;
  1485. memcpy(&gpcodeScope->pbDataBuff[1], ptoken->szToken,
  1486. (int)(dwLen - 1));
  1487. gpcodeScope->bCodeChkSum =
  1488. ComputeDataChkSum(gpcodeScope->pbDataBuff, dwLen);
  1489. }
  1490. }
  1491. else if ((ptoken->iTokenType != TOKTYPE_ID) ||
  1492. (ptoken->llTokenValue < 0) ||
  1493. ((TermTable[ptoken->llTokenValue].dwfTermClass &
  1494. (TC_DATA_OBJECT | TC_CONST_NAME)) == 0))
  1495. {
  1496. UnGetToken(ptoken);
  1497. rc = TOKERR_NO_MATCH;
  1498. }
  1499. else
  1500. {
  1501. UnGetToken(ptoken);
  1502. rc = ParseASLTerm(ptoken, 0);
  1503. }
  1504. }
  1505. EXIT((1, "ParseData=%d\n", rc));
  1506. return rc;
  1507. } //ParseData
  1508. /***LP ParseInteger - Parse integer data
  1509. *
  1510. * ENTRY
  1511. * ptoken - token stream
  1512. * c - integer type
  1513. *
  1514. * EXIT-SUCCESS
  1515. * returns TOKERR_NONE
  1516. * EXIT-FAILURE
  1517. * returns negative error code
  1518. */
  1519. int LOCAL ParseInteger(PTOKEN ptoken, char c)
  1520. {
  1521. int rc;
  1522. ENTER((1, "ParseInteger(ptoken=%p,ch=%c)\n", ptoken, c));
  1523. if ((rc = MatchToken(ptoken, TOKTYPE_NUMBER, 0, MTF_ANY_VALUE | MTF_NOT_ERR,
  1524. NULL)) == TOKERR_NONE)
  1525. {
  1526. gpcodeScope->dwCodeValue = 0;
  1527. if ((c == 'B') && ((ptoken->llTokenValue & 0xffffffffffffff00) != 0) ||
  1528. (c == 'W') && ((ptoken->llTokenValue & 0xffffffffffff0000) != 0) ||
  1529. (c == 'D') && ((ptoken->llTokenValue & 0xffffffff00000000) != 0))
  1530. {
  1531. char szMsg[MAX_MSG_LEN + 1];
  1532. sprintf(szMsg, "expecting %s value",
  1533. (c == 'B')? "byte":
  1534. (c == 'W')? "word": "dword");
  1535. PrintTokenErr(ptoken, szMsg, TRUE);
  1536. rc = ASLERR_SYNTAX;
  1537. }
  1538. else if (c == 'U')
  1539. {
  1540. if (ptoken->llTokenValue <= MAX_DWORD)
  1541. {
  1542. rc = MakeIntData((DWORD)ptoken->llTokenValue, gpcodeScope);
  1543. }
  1544. else
  1545. {
  1546. PrintTokenErr(ptoken, "data value exceeding DWORD maximum",
  1547. TRUE);
  1548. rc = ASLERR_SYNTAX;
  1549. }
  1550. }
  1551. else if (c != 'Q')
  1552. {
  1553. gpcodeScope->dwCodeType = CODETYPE_INTEGER;
  1554. gpcodeScope->dwDataLen = (c == 'B')? sizeof(BYTE):
  1555. (c == 'W')? sizeof(WORD):
  1556. (c == 'D')? sizeof(DWORD):
  1557. ((ptoken->llTokenValue &
  1558. 0xffffffffffffff00) == 0)? sizeof(BYTE):
  1559. ((ptoken->llTokenValue &
  1560. 0xffffffffffff0000) == 0)? sizeof(WORD):
  1561. sizeof(DWORD);
  1562. gpcodeScope->dwCodeLen = gpcodeScope->dwDataLen;
  1563. gpcodeScope->dwCodeValue = (DWORD)ptoken->llTokenValue;
  1564. gpcodeScope->bCodeChkSum =
  1565. ComputeDataChkSum((PBYTE)&ptoken->llTokenValue,
  1566. gpcodeScope->dwDataLen);
  1567. }
  1568. else if ((gpcodeScope->pbDataBuff =
  1569. MEMALLOC(gpcodeScope->dwDataLen = sizeof(QWORD))) != NULL)
  1570. {
  1571. gpcodeScope->dwCodeType = CODETYPE_QWORD;
  1572. memcpy(gpcodeScope->pbDataBuff, &ptoken->llTokenValue,
  1573. gpcodeScope->dwDataLen);
  1574. gpcodeScope->dwCodeLen = gpcodeScope->dwDataLen;
  1575. gpcodeScope->bCodeChkSum =
  1576. ComputeDataChkSum(gpcodeScope->pbDataBuff,
  1577. gpcodeScope->dwDataLen);
  1578. }
  1579. else
  1580. {
  1581. ERROR(("ParseInteger: failed to allocate QWord object - %s",
  1582. ptoken->szToken));
  1583. rc = ASLERR_OUT_OF_MEM;
  1584. }
  1585. }
  1586. EXIT((1, "ParseInteger=%d\n", rc));
  1587. return rc;
  1588. } //ParseInteger
  1589. /***LP ParseOpcode - Parse ASL opcode: MachineCode, FunctionCode, SuperName
  1590. *
  1591. * ENTRY
  1592. * ptoken - token stream
  1593. * c - opcode type
  1594. *
  1595. * EXIT-SUCCESS
  1596. * returns TOKERR_NONE
  1597. * EXIT-FAILURE
  1598. * returns negative error code
  1599. */
  1600. int LOCAL ParseOpcode(PTOKEN ptoken, char c)
  1601. {
  1602. int rc;
  1603. ENTER((1, "ParseOpcode(ptoken=%p,ch=%c)\n", ptoken, c));
  1604. if ((rc = MatchToken(ptoken, TOKTYPE_ID, 0, MTF_ANY_VALUE | MTF_NOT_ERR,
  1605. NULL)) == TOKERR_NONE)
  1606. {
  1607. if (ptoken->llTokenValue == ID_USER)
  1608. {
  1609. PNSOBJ pns;
  1610. if ((GetNameSpaceObj(ptoken->szToken, gpnsCurrentScope, &pns, 0) ==
  1611. ASLERR_NONE) &&
  1612. (pns->ObjData.dwDataType == OBJTYPE_RES_FIELD) &&
  1613. ((c == 'M') || (c == 'P')))
  1614. {
  1615. DWORD dwValue = 0;
  1616. if (c == 'P')
  1617. {
  1618. dwValue = pns->ObjData.uipDataValue;
  1619. }
  1620. else if (pns->ObjData.uipDataValue%8 == 0)
  1621. {
  1622. dwValue = pns->ObjData.uipDataValue/8;
  1623. }
  1624. else
  1625. {
  1626. PrintTokenErr(ptoken,
  1627. "object can only be used in CreateField "
  1628. "or CreateBitField statements",
  1629. TRUE);
  1630. rc = ASLERR_SYNTAX;
  1631. }
  1632. if (rc == ASLERR_NONE)
  1633. {
  1634. rc = MakeIntData(dwValue, gpcodeScope);
  1635. }
  1636. }
  1637. else
  1638. {
  1639. rc = ParseUserTerm(ptoken, TRUE);
  1640. }
  1641. }
  1642. else
  1643. {
  1644. UnGetToken(ptoken);
  1645. if (TermTable[ptoken->llTokenValue].dwfTermClass & TC_OPCODE)
  1646. {
  1647. rc = ParseASLTerm(ptoken, 0);
  1648. }
  1649. else
  1650. {
  1651. rc = TOKERR_NO_MATCH;
  1652. }
  1653. }
  1654. }
  1655. else
  1656. rc = ParseData(ptoken);
  1657. EXIT((1, "ParseOpcode=%d\n", rc));
  1658. return rc;
  1659. } //ParseOpcode
  1660. /***LP ParseKeyword - Parse ASL keyword
  1661. *
  1662. * ENTRY
  1663. * ptoken - token stream
  1664. * chExpectType - expected keyword type
  1665. *
  1666. * EXIT-SUCCESS
  1667. * returns TOKERR_NONE
  1668. * EXIT-FAILURE
  1669. * returns negative error code
  1670. *
  1671. * NOTE
  1672. * DATATYPE_KEYWORD is a transient type. It will be lumped together with
  1673. * other keyword type arguments and be converted into one DATATYPE_INTEGER.
  1674. */
  1675. int LOCAL ParseKeyword(PTOKEN ptoken, char chExpectType)
  1676. {
  1677. int rc;
  1678. ENTER((1, "ParseKeyword(ptoken=%p,ExpectedType=%c)\n",
  1679. ptoken, chExpectType));
  1680. if ((rc = MatchToken(ptoken, TOKTYPE_ID, 0, MTF_ANY_VALUE | MTF_NOT_ERR,
  1681. NULL)) == TOKERR_NONE)
  1682. {
  1683. if ((ptoken->llTokenValue == ID_USER) ||
  1684. !(TermTable[ptoken->llTokenValue].dwfTermClass & TC_KEYWORD))
  1685. {
  1686. UnGetToken(ptoken);
  1687. rc = TOKERR_NO_MATCH;
  1688. }
  1689. else if (TermTable[ptoken->llTokenValue].pszArgActions[0] !=
  1690. chExpectType)
  1691. {
  1692. PrintTokenErr(ptoken, "incorrect keyword type", TRUE);
  1693. rc = ASLERR_SYNTAX;
  1694. }
  1695. else
  1696. {
  1697. gpcodeScope->dwCodeType = CODETYPE_KEYWORD;
  1698. gpcodeScope->dwTermIndex = (DWORD)ptoken->llTokenValue;
  1699. gpcodeScope->dwCodeValue = TOKID(ptoken->llTokenValue);
  1700. }
  1701. }
  1702. EXIT((1, "ParseKeyword=%d\n", rc));
  1703. return rc;
  1704. } //ParseKeyword
  1705. /***LP ParseString - Parse string object
  1706. *
  1707. * ENTRY
  1708. * ptoken - token stream
  1709. *
  1710. * EXIT-SUCCESS
  1711. * returns TOKERR_NONE
  1712. * EXIT-FAILURE
  1713. * returns negative error code
  1714. */
  1715. int LOCAL ParseString(PTOKEN ptoken)
  1716. {
  1717. int rc;
  1718. ENTER((1, "ParseString(ptoken=%p)\n", ptoken));
  1719. if ((rc = MatchToken(ptoken, TOKTYPE_STRING, 0, MTF_ANY_VALUE | MTF_NOT_ERR,
  1720. NULL)) == TOKERR_NONE)
  1721. {
  1722. gpcodeScope->dwDataLen = strlen(ptoken->szToken) + 1;
  1723. if (gpcodeScope->dwDataLen > MAX_STRING_LEN + 1)
  1724. {
  1725. ERROR(("ParseString: string too big - %s", ptoken->szToken));
  1726. rc = ASLERR_SYNTAX;
  1727. }
  1728. else if ((gpcodeScope->pbDataBuff =
  1729. MEMALLOC((size_t)gpcodeScope->dwDataLen)) == NULL)
  1730. {
  1731. ERROR(("ParseString: failed to allocate string object - %s",
  1732. ptoken->szToken));
  1733. rc = ASLERR_OUT_OF_MEM;
  1734. }
  1735. else
  1736. {
  1737. gpcodeScope->dwCodeType = CODETYPE_STRING;
  1738. memcpy(gpcodeScope->pbDataBuff, ptoken->szToken,
  1739. (int)gpcodeScope->dwDataLen);
  1740. gpcodeScope->dwCodeLen = gpcodeScope->dwDataLen;
  1741. gpcodeScope->bCodeChkSum =
  1742. ComputeDataChkSum(gpcodeScope->pbDataBuff,
  1743. gpcodeScope->dwDataLen);
  1744. }
  1745. }
  1746. EXIT((1, "ParseString=%d\n", rc));
  1747. return rc;
  1748. } //ParseString
  1749. /***LP CreateObject - Create NameSpace object for the term
  1750. *
  1751. * ENTRY
  1752. * ptoken -> TOKEN
  1753. * pszName -> object name
  1754. * c - object type to be created
  1755. * ppns -> to hold object created
  1756. *
  1757. * EXIT-SUCCESS
  1758. * returns ASLERR_NONE
  1759. * EXIT-FAILURE
  1760. * returns negative error code
  1761. */
  1762. int LOCAL CreateObject(PTOKEN ptoken, PSZ pszName, char c, PNSOBJ *ppns)
  1763. {
  1764. int rc = ASLERR_NONE;
  1765. PNSOBJ pns;
  1766. ENTER((2, "CreateObject(ptoken=%p,Name=%s,Type=%c)\n",
  1767. ptoken, pszName, c));
  1768. if (((rc = GetNameSpaceObj(pszName, gpnsCurrentScope, &pns, 0)) ==
  1769. ASLERR_NONE) &&
  1770. (pns->ObjData.dwDataType == OBJTYPE_EXTERNAL) ||
  1771. ((rc = CreateNameSpaceObj(ptoken, pszName, gpnsCurrentScope,
  1772. gpnsCurrentOwner, &pns, NSF_EXIST_ERR)) ==
  1773. ASLERR_NONE))
  1774. {
  1775. if (!(gdwfASL & ASLF_UNASM))
  1776. {
  1777. ASSERT(gpcodeScope->pnsObj == NULL);
  1778. gpcodeScope->dwfCode |= CF_CREATED_NSOBJ;
  1779. gpcodeScope->pnsObj = pns;
  1780. pns->Context = gpcodeScope;
  1781. }
  1782. switch (c)
  1783. {
  1784. case NSTYPE_UNKNOWN:
  1785. break;
  1786. case NSTYPE_FIELDUNIT:
  1787. pns->ObjData.dwDataType = OBJTYPE_FIELDUNIT;
  1788. break;
  1789. case NSTYPE_DEVICE:
  1790. pns->ObjData.dwDataType = OBJTYPE_DEVICE;
  1791. break;
  1792. case NSTYPE_EVENT:
  1793. pns->ObjData.dwDataType = OBJTYPE_EVENT;
  1794. break;
  1795. case NSTYPE_METHOD:
  1796. pns->ObjData.dwDataType = OBJTYPE_METHOD;
  1797. break;
  1798. case NSTYPE_MUTEX:
  1799. pns->ObjData.dwDataType = OBJTYPE_MUTEX;
  1800. break;
  1801. case NSTYPE_OPREGION:
  1802. pns->ObjData.dwDataType = OBJTYPE_OPREGION;
  1803. break;
  1804. case NSTYPE_POWERRES:
  1805. pns->ObjData.dwDataType = OBJTYPE_POWERRES;
  1806. break;
  1807. case NSTYPE_PROCESSOR:
  1808. pns->ObjData.dwDataType = OBJTYPE_PROCESSOR;
  1809. break;
  1810. case NSTYPE_THERMALZONE:
  1811. pns->ObjData.dwDataType = OBJTYPE_THERMALZONE;
  1812. break;
  1813. case NSTYPE_OBJALIAS:
  1814. pns->ObjData.dwDataType = OBJTYPE_OBJALIAS;
  1815. break;
  1816. case NSTYPE_BUFFFIELD:
  1817. pns->ObjData.dwDataType = OBJTYPE_BUFFFIELD;
  1818. break;
  1819. default:
  1820. ERROR(("CreateObject: invalid object type %c", c));
  1821. rc = ASLERR_INVALID_OBJTYPE;
  1822. }
  1823. if (ppns != NULL)
  1824. {
  1825. *ppns = pns;
  1826. }
  1827. }
  1828. EXIT((2, "CreateObject=%d\n", rc));
  1829. return rc;
  1830. } //CreateObject
  1831. #ifdef __UNASM
  1832. /***LP CreateScopeObj - Create Scope object
  1833. *
  1834. * ENTRY
  1835. * pszName -> object name
  1836. * ppns -> to hold object created
  1837. *
  1838. * EXIT-SUCCESS
  1839. * returns ASLERR_NONE
  1840. * EXIT-FAILURE
  1841. * returns negative error code
  1842. */
  1843. int LOCAL CreateScopeObj(PSZ pszName, PNSOBJ *ppns)
  1844. {
  1845. int rc = ASLERR_NONE;
  1846. PNSOBJ pnsScope;
  1847. PSZ psz;
  1848. ENTER((2, "CreateScopeObj(Name=%s)\n", pszName));
  1849. ASSERT(ppns != NULL);
  1850. if ((psz = strrchr(pszName, '.')) != NULL)
  1851. {
  1852. *psz = '\0';
  1853. if ((rc = GetNameSpaceObj(pszName, gpnsCurrentScope, &pnsScope, 0)) ==
  1854. ASLERR_NSOBJ_NOT_FOUND)
  1855. {
  1856. rc = CreateScopeObj(pszName, &pnsScope);
  1857. }
  1858. *psz = '.';
  1859. psz++;
  1860. }
  1861. else if (pszName[0] == '\\')
  1862. {
  1863. pnsScope = gpnsNameSpaceRoot;
  1864. psz = &pszName[1];
  1865. }
  1866. else
  1867. {
  1868. pnsScope = gpnsCurrentScope;
  1869. psz = pszName;
  1870. }
  1871. if ((rc == ASLERR_NONE) &&
  1872. ((rc = CreateNameSpaceObj(NULL, psz, pnsScope, NULL, ppns,
  1873. NSF_EXIST_OK)) == ASLERR_NONE))
  1874. {
  1875. (*ppns)->ObjData.dwDataType = OBJTYPE_EXTERNAL;
  1876. }
  1877. EXIT((2, "CreateScopeObj=%d (pns=%p)\n", rc, *ppns));
  1878. return rc;
  1879. } //CreateScopeObj
  1880. #endif //ifdef __UNASM
  1881. /***LP ValidateObject - Validate the existence and type of the object
  1882. *
  1883. * ENTRY
  1884. * ptoken -> TOKEN
  1885. * pszName -> object name
  1886. * chActType - action type
  1887. * chArgType - argument type
  1888. *
  1889. * EXIT-SUCCESS
  1890. * returns ASLERR_NONE
  1891. * EXIT-FAILURE
  1892. * returns negative error code
  1893. */
  1894. int LOCAL ValidateObject(PTOKEN ptoken, PSZ pszName, char chActType,
  1895. char chArgType)
  1896. {
  1897. int rc = ASLERR_NONE;
  1898. ULONG dwDataType = OBJTYPE_UNKNOWN;
  1899. ENTER((2, "ValidateObject(ptoken=%p,Name=%s,ActType=%c,ArgType=%c)\n",
  1900. ptoken, pszName, chActType, chArgType));
  1901. switch (chActType)
  1902. {
  1903. case NSTYPE_UNKNOWN:
  1904. case NSTYPE_SCOPE:
  1905. break;
  1906. case NSTYPE_FIELDUNIT:
  1907. dwDataType = OBJTYPE_FIELDUNIT;
  1908. break;
  1909. case NSTYPE_DEVICE:
  1910. dwDataType = OBJTYPE_DEVICE;
  1911. break;
  1912. case NSTYPE_EVENT:
  1913. dwDataType = OBJTYPE_EVENT;
  1914. break;
  1915. case NSTYPE_METHOD:
  1916. dwDataType = OBJTYPE_METHOD;
  1917. break;
  1918. case NSTYPE_MUTEX:
  1919. dwDataType = OBJTYPE_MUTEX;
  1920. break;
  1921. case NSTYPE_OPREGION:
  1922. dwDataType = OBJTYPE_OPREGION;
  1923. break;
  1924. case NSTYPE_POWERRES:
  1925. dwDataType = OBJTYPE_POWERRES;
  1926. break;
  1927. case NSTYPE_PROCESSOR:
  1928. dwDataType = OBJTYPE_PROCESSOR;
  1929. break;
  1930. case NSTYPE_THERMALZONE:
  1931. dwDataType = OBJTYPE_THERMALZONE;
  1932. break;
  1933. case NSTYPE_OBJALIAS:
  1934. dwDataType = OBJTYPE_OBJALIAS;
  1935. break;
  1936. case NSTYPE_BUFFFIELD:
  1937. dwDataType = OBJTYPE_BUFFFIELD;
  1938. break;
  1939. default:
  1940. ERROR(("ValidateObject: invalid object type %c", chActType));
  1941. rc = ASLERR_INVALID_OBJTYPE;
  1942. }
  1943. if (rc == ASLERR_NONE)
  1944. {
  1945. PNSOBJ pns;
  1946. char szMsg[MAX_MSG_LEN + 1];
  1947. if (((rc = GetNameSpaceObj(pszName, gpnsCurrentScope, &pns, 0)) ==
  1948. ASLERR_NONE) &&
  1949. ((pns->hOwner == NULL) ||
  1950. ((PNSOBJ)pns->hOwner == gpnsCurrentOwner)))
  1951. {
  1952. if ((pns->ObjData.dwDataType == OBJTYPE_RES_FIELD) &&
  1953. (chArgType != 'M') && (chArgType != 'P'))
  1954. {
  1955. PrintTokenErr(ptoken,
  1956. "object can only be used in the index argument "
  1957. "of CreateXField or Index statements",
  1958. TRUE);
  1959. rc = ASLERR_SYNTAX;
  1960. }
  1961. else if ((dwDataType != OBJTYPE_UNKNOWN) &&
  1962. (pns->ObjData.dwDataType != dwDataType))
  1963. {
  1964. sprintf(szMsg,
  1965. "%s has an incorrect type (ObjType=%s, ExpectedType=%s)",
  1966. pszName, GetObjectTypeName(pns->ObjData.dwDataType),
  1967. GetObjectTypeName(dwDataType));
  1968. PrintTokenErr(ptoken, szMsg, TRUE);
  1969. rc = ASLERR_SYNTAX;
  1970. }
  1971. else if ((chActType == NSTYPE_SCOPE) ||
  1972. (chActType == NSTYPE_OPREGION))
  1973. {
  1974. ASSERT(gpcodeScope->pnsObj == NULL);
  1975. gpcodeScope->pnsObj = pns;
  1976. }
  1977. }
  1978. else if ((rc == ASLERR_NSOBJ_NOT_FOUND) && (gpnsCurrentOwner != NULL))
  1979. {
  1980. //
  1981. // We are in a method referring to something not yet defined.
  1982. // Let's queue it and check it after we are done.
  1983. //
  1984. rc = QueueNSChk(ptoken, pszName, dwDataType, 0);
  1985. }
  1986. else
  1987. {
  1988. sprintf(szMsg, "%s does not exist or not in accessible scope",
  1989. pszName);
  1990. PrintTokenErr(ptoken, szMsg, FALSE);
  1991. rc = ASLERR_NONE;
  1992. }
  1993. }
  1994. EXIT((2, "ValidateObject=%d\n", rc));
  1995. return rc;
  1996. } //ValidateObject
  1997. /***LP ValidateNSChkList - Validate objects in NSCHK list
  1998. *
  1999. * ENTRY
  2000. * pnschkHead -> NSCHK list
  2001. *
  2002. * EXIT-SUCCESS
  2003. * returns ASLERR_NONE
  2004. * EXIT-FAILURE
  2005. * returns negative error code
  2006. */
  2007. int LOCAL ValidateNSChkList(PNSCHK pnschkHead)
  2008. {
  2009. int rc = ASLERR_NONE;
  2010. PNSOBJ pns;
  2011. ENTER((2, "ValidateNSChkList(Head=%p)\n", pnschkHead));
  2012. while ((rc == ASLERR_NONE) && (pnschkHead != NULL))
  2013. {
  2014. if ((GetNameSpaceObj(pnschkHead->szObjName, pnschkHead->pnsScope, &pns,
  2015. 0) == ASLERR_NONE) &&
  2016. ((pns->hOwner == NULL) ||
  2017. ((PNSOBJ)pns->hOwner == pnschkHead->pnsMethod)))
  2018. {
  2019. if (pns->ObjData.dwDataType == OBJTYPE_RES_FIELD)
  2020. {
  2021. ErrPrintf("%s(%d): error: cannot make forward reference to PNP resource object %s\n",
  2022. pnschkHead->pszFile, pnschkHead->wLineNum,
  2023. pnschkHead->szObjName);
  2024. rc = ASLERR_SYNTAX;
  2025. }
  2026. else if ((pnschkHead->dwExpectedType != OBJTYPE_UNKNOWN) &&
  2027. (pns->ObjData.dwDataType != pnschkHead->dwExpectedType))
  2028. {
  2029. ErrPrintf("%s(%d): warning: %s has incorrect type (ObjType=%s, ExpectedType=%s)\n",
  2030. pnschkHead->pszFile,
  2031. pnschkHead->wLineNum,
  2032. pnschkHead->szObjName,
  2033. GetObjectTypeName(pns->ObjData.dwDataType),
  2034. GetObjectTypeName(pnschkHead->dwExpectedType));
  2035. }
  2036. else if (pnschkHead->dwExpectedType == OBJTYPE_METHOD)
  2037. {
  2038. if (pns->ObjData.uipDataValue < pnschkHead->dwChkData)
  2039. {
  2040. ErrPrintf("%s(%d): error: %s has too many arguments\n",
  2041. pnschkHead->pszFile,
  2042. pnschkHead->wLineNum,
  2043. pnschkHead->szObjName);
  2044. rc = ASLERR_SYNTAX;
  2045. }
  2046. else if (pns->ObjData.uipDataValue > pnschkHead->dwChkData)
  2047. {
  2048. ErrPrintf("%s(%d): error: %s has too few arguments\n",
  2049. pnschkHead->pszFile,
  2050. pnschkHead->wLineNum,
  2051. pnschkHead->szObjName);
  2052. rc = ASLERR_SYNTAX;
  2053. }
  2054. }
  2055. }
  2056. else
  2057. {
  2058. ErrPrintf("%s(%d): warning: %s does not exist or not in accessible scope\n",
  2059. pnschkHead->pszFile,
  2060. pnschkHead->wLineNum,
  2061. pnschkHead->szObjName);
  2062. }
  2063. pnschkHead = pnschkHead->pnschkNext;
  2064. }
  2065. EXIT((2, "ValidateNSChkList=%d\n", rc));
  2066. return rc;
  2067. } //ValidateNSChkList
  2068. /***LP QueueNSChk - Queue a NSChk request
  2069. *
  2070. * ENTRY
  2071. * ptoken -> TOKEN
  2072. * pszObjName -> object name
  2073. * dwExpectedType - expected object type
  2074. * dwChkData - object specific check data
  2075. *
  2076. * EXIT-SUCCESS
  2077. * returns ASLERR_NONE
  2078. * EXIT-FAILURE
  2079. * returns negative error code
  2080. */
  2081. int LOCAL QueueNSChk(PTOKEN ptoken, PSZ pszObjName, ULONG dwExpectedType,
  2082. ULONG dwChkData)
  2083. {
  2084. int rc = ASLERR_NONE;
  2085. PNSCHK pnschk;
  2086. ENTER((2, "QueueNSChk(ptoken=%p,Obj=%s,ExpectedType=%s,ChkData=%x)\n",
  2087. ptoken, pszObjName, GetObjectTypeName(dwExpectedType), dwChkData));
  2088. if ((pnschk = MEMALLOC(sizeof(NSCHK))) == NULL)
  2089. {
  2090. ERROR(("QueueNSChk: failed to allocate NSCHK object"));
  2091. rc = ASLERR_OUT_OF_MEM;
  2092. }
  2093. else
  2094. {
  2095. memset(pnschk, 0, sizeof(NSCHK));
  2096. strcpy(pnschk->szObjName, pszObjName);
  2097. pnschk->pszFile = gpszASLFile;
  2098. pnschk->pnsScope = gpnsCurrentScope;
  2099. pnschk->pnsMethod = gpnsCurrentOwner;
  2100. pnschk->dwExpectedType = dwExpectedType;
  2101. pnschk->dwChkData = dwChkData;
  2102. pnschk->wLineNum = ptoken->pline->wLineNum;
  2103. if (gpnschkTail != NULL)
  2104. {
  2105. gpnschkTail->pnschkNext = pnschk;
  2106. gpnschkTail = pnschk;
  2107. }
  2108. else
  2109. {
  2110. gpnschkHead = gpnschkTail = pnschk;
  2111. }
  2112. }
  2113. EXIT((2, "QueueNSChk=%d\n"));
  2114. return rc;
  2115. } //QueueNSChk