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.

817 lines
21 KiB

  1. /*** scanasl.c - ASL scanner
  2. *
  3. * Copyright (c) 1996,1997 Microsoft Corporation
  4. * Author: Michael Tsang (MikeTs)
  5. * Created: 09/05/96
  6. *
  7. * This module provides the token scanning functions for the ASL language.
  8. *
  9. * MODIFICATION HISTORY
  10. */
  11. #include "pch.h"
  12. /*** Local function prototypes
  13. */
  14. int LOCAL ScanSym(int c, PTOKEN ptoken);
  15. int LOCAL ScanSpace(int c, PTOKEN ptoken);
  16. int LOCAL ScanID(int c, PTOKEN ptoken);
  17. int LOCAL ScanNum(int c, PTOKEN ptoken);
  18. int LOCAL ScanString(int c, PTOKEN ptoken);
  19. int LOCAL ScanChar(int c, PTOKEN ptoken);
  20. int LOCAL ProcessInLineComment(PTOKEN ptoken);
  21. int LOCAL ProcessComment(PTOKEN ptoken);
  22. int LOCAL LookupSym(PTOKEN ptoken, int iTable);
  23. LONG LOCAL LookupID(PTOKEN ptoken);
  24. int LOCAL GetEscapedChar(PLINE pline);
  25. BOOL EXPORT StrToQWord(PSZ psz, DWORD dwBase, QWORD *pqw);
  26. /*** Local data
  27. */
  28. PFNTOKEN apfnToken[] =
  29. {
  30. ScanSym,
  31. ScanSpace,
  32. ScanID,
  33. ScanNum,
  34. ScanString,
  35. ScanChar,
  36. (PFNTOKEN)NULL
  37. };
  38. #ifdef TUNE
  39. WORD awcTokenType[] =
  40. {
  41. 0, //TOKTYPE_SYMBOL
  42. 0, //TOKTYPE_SPACE
  43. 0, //TOKTYPE_ID
  44. 0, //TOKTYPE_NUM
  45. 0, //TOKTYPE_STRING
  46. 0 //TOKTYPE_CHAR
  47. };
  48. #endif
  49. //
  50. // The string positions of the symbol characters in SymCharTable
  51. // is used as an index into the SymTokTable. Therefore, if anything
  52. // is changed in either SymCharTable or SymTokTable, the other
  53. // table has to be changed correspondingly.
  54. //
  55. typedef struct symtok_s
  56. {
  57. char chSym;
  58. int iSymType;
  59. int iLink;
  60. } SYMTOK;
  61. //
  62. // Note that the symbol position in the following array must be the same
  63. // position as in the SymCharTable array.
  64. //
  65. SYMTOK SymTokTable[] =
  66. {
  67. '{', SYM_LBRACE, 0, //0
  68. '}', SYM_RBRACE, 0, //1
  69. '(', SYM_LPARAN, 0, //2
  70. ')', SYM_RPARAN, 0, //3
  71. ',', SYM_COMMA, 0, //4
  72. '/', SYM_SLASH, 7, //5
  73. '*', SYM_ASTERISK, 9, //6
  74. '/', SYM_INLINECOMMENT, 8, //7
  75. '*', SYM_OPENCOMMENT, 0, //8
  76. '/', SYM_CLOSECOMMENT, 0, //9
  77. };
  78. #define SYMTOK_TABLE_SIZE (sizeof(SymTokTable)/sizeof(SYMTOK))
  79. /***EP OpenScan - scanner initialization
  80. *
  81. * ENTRY
  82. * pfileSrc -> source file
  83. *
  84. * EXIT-SUCCESS
  85. * returns the pointer to the allocated token structure;
  86. * EXIT-FAILURE
  87. * returns NULL
  88. */
  89. PTOKEN EXPORT OpenScan(FILE *pfileSrc)
  90. {
  91. PTOKEN ptoken;
  92. ENTER((4, "OpenScan(pfileSrc=%p)\n", pfileSrc));
  93. #ifdef TUNE
  94. ptoken = OpenToken(pfileSrc, apfnToken, awcTokenType);
  95. #else
  96. ptoken = OpenToken(pfileSrc, apfnToken);
  97. #endif
  98. EXIT((4, "OpenScan=%p\n", ptoken));
  99. return ptoken;
  100. } //OpenScan
  101. /***EP CloseScan - scanner cleanup
  102. *
  103. * ENTRY
  104. * ptoken->token structure
  105. * EXIT
  106. * None
  107. */
  108. VOID EXPORT CloseScan(PTOKEN ptoken)
  109. {
  110. ENTER((4, "CloseScan(ptoken=%p)\n", ptoken));
  111. CloseToken(ptoken);
  112. EXIT((4, "CloseScan!\n"));
  113. } //CloseScan
  114. /***LP ScanSym - scan symbols token
  115. *
  116. * ENTRY
  117. * c - first character of the token
  118. * ptoken -> token structure
  119. *
  120. * EXIT-SUCCESS
  121. * returns TOKERR_NONE
  122. * EXIT-FAILURE
  123. * returns TOKERR_NO_MATCH - not a symbol token
  124. */
  125. int LOCAL ScanSym(int c, PTOKEN ptoken)
  126. {
  127. int rc = TOKERR_NO_MATCH;
  128. char *pch;
  129. ENTER((4, "ScanSym(c=%c,ptoken=%p)\n", c, ptoken));
  130. if ((pch = strchr(SymCharTable, c)) != NULL)
  131. {
  132. int i, j;
  133. i = (int)(pch - SymCharTable);
  134. if (i != (j = LookupSym(ptoken, i)))
  135. {
  136. i = j;
  137. ptoken->szToken[ptoken->wTokenLen++] = SymTokTable[i].chSym;
  138. }
  139. ptoken->iTokenType = TOKTYPE_SYMBOL;
  140. ptoken->llTokenValue = SymTokTable[i].iSymType;
  141. ptoken->szToken[ptoken->wTokenLen] = '\0';
  142. if (ptoken->llTokenValue == SYM_INLINECOMMENT)
  143. rc = ProcessInLineComment(ptoken);
  144. else if (ptoken->llTokenValue == SYM_OPENCOMMENT)
  145. rc = ProcessComment(ptoken);
  146. else
  147. rc = TOKERR_NONE;
  148. }
  149. EXIT((4, "ScanSym=%d (SymType=%I64d,Symbol=%s)\n",
  150. rc, ptoken->llTokenValue, ptoken->szToken));
  151. return rc;
  152. } //ScanSym
  153. /***LP ScanSpace - scans and skips all white spaces
  154. *
  155. * ENTRY
  156. * c - first character of the token
  157. * ptoken -> token structure
  158. *
  159. * EXIT-SUCCESS
  160. * returns TOKERR_NONE
  161. * EXIT-FAILURE
  162. * returns TOKTYPE_NO_MATCH - not a space token
  163. */
  164. int LOCAL ScanSpace(int c, PTOKEN ptoken)
  165. {
  166. int rc = TOKERR_NO_MATCH;
  167. ENTER((4, "ScanSpace(c=%c,ptoken=%p)\n", c, ptoken));
  168. if (isspace(c))
  169. {
  170. rc = TOKERR_NONE;
  171. while (((c = LineGetC(ptoken->pline)) != EOF) && isspace(c))
  172. ;
  173. LineUnGetC(c, ptoken->pline);
  174. if (ptoken->wfToken & TOKF_NOIGNORESPACE)
  175. {
  176. strcpy(ptoken->szToken, " ");
  177. ptoken->wTokenLen = 1;
  178. ptoken->iTokenType = TOKTYPE_SPACE;
  179. }
  180. else
  181. ptoken->iTokenType = TOKTYPE_NULL;
  182. }
  183. EXIT((4, "ScanSpace=%d\n", rc));
  184. return rc;
  185. } //ScanSpace
  186. /***LP ScanID - scan ID token
  187. *
  188. * ENTRY
  189. * c - first character of the token
  190. * ptoken -> token structure
  191. *
  192. * EXIT-SUCCESS
  193. * returns TOKERR_NONE
  194. * EXIT-FAILURE
  195. * returns TOKTYPE_NO_MATCH - not an ID token
  196. * TOKERR_TOKEN_TOO_LONG - ID too long
  197. */
  198. int LOCAL ScanID(int c, PTOKEN ptoken)
  199. {
  200. int rc = TOKERR_NO_MATCH;
  201. ENTER((4, "ScanID(c=%c,ptoken=%p)\n", c, ptoken));
  202. if (isalpha(c) || (c == '_') ||
  203. (c == CH_ROOT_PREFIX) || (c == CH_PARENT_PREFIX))
  204. {
  205. BOOL fParentPrefix = (c == CH_PARENT_PREFIX);
  206. rc = TOKERR_NONE;
  207. ptoken->iTokenType = TOKTYPE_ID;
  208. while (((c = LineGetC(ptoken->pline)) != EOF) &&
  209. (fParentPrefix && (c == CH_PARENT_PREFIX) ||
  210. isalnum(c) || (c == '_') || (c == CH_NAMESEG_SEP)))
  211. {
  212. fParentPrefix = (c == CH_PARENT_PREFIX);
  213. if (rc == TOKERR_TOKEN_TOO_LONG)
  214. continue;
  215. else if (ptoken->wTokenLen < MAX_TOKEN_LEN)
  216. ptoken->szToken[ptoken->wTokenLen++] = (char)c;
  217. else
  218. {
  219. ptoken->wErrLine = ptoken->pline->wLineNum;
  220. ptoken->wErrPos = ptoken->pline->wLinePos;
  221. rc = TOKERR_TOKEN_TOO_LONG;
  222. }
  223. }
  224. ptoken->szToken[ptoken->wTokenLen] = '\0';
  225. LineUnGetC(c, ptoken->pline);
  226. if (rc == TOKERR_NONE)
  227. {
  228. ptoken->llTokenValue = LookupID(ptoken);
  229. }
  230. }
  231. EXIT((4, "ScanID=%d (IDType=%I64d,ID=%s)\n",
  232. rc, ptoken->llTokenValue, ptoken->szToken));
  233. return rc;
  234. } //ScanID
  235. /***LP ScanNum - scan number token
  236. *
  237. * ENTRY
  238. * c - first character of the token
  239. * ptoken -> token structure
  240. *
  241. * EXIT-SUCCESS
  242. * returns TOKERR_NONE
  243. * EXIT-FAILURE
  244. * returns TOKTYPE_NO_MATCH - not a number token
  245. * TOKERR_TOKEN_TOO_LONG - number too long
  246. */
  247. int LOCAL ScanNum(int c, PTOKEN ptoken)
  248. {
  249. int rc = TOKERR_NO_MATCH;
  250. ENTER((4, "ScanNum(c=%c,ptoken=%p)\n", c, ptoken));
  251. if (isdigit(c))
  252. {
  253. BOOL fHex = FALSE;
  254. rc = TOKERR_NONE;
  255. ptoken->iTokenType = TOKTYPE_NUMBER;
  256. if ((c == '0') && ((c = LineGetC(ptoken->pline)) != EOF))
  257. {
  258. if (c != 'x')
  259. LineUnGetC(c, ptoken->pline);
  260. else
  261. {
  262. ptoken->szToken[ptoken->wTokenLen++] = (char)c;
  263. fHex = TRUE;
  264. }
  265. }
  266. while (((c = LineGetC(ptoken->pline)) != EOF) &&
  267. ((!fHex && isdigit(c)) || fHex && isxdigit(c)))
  268. {
  269. if (rc == TOKERR_TOKEN_TOO_LONG)
  270. continue;
  271. else if (ptoken->wTokenLen < MAX_TOKEN_LEN)
  272. ptoken->szToken[ptoken->wTokenLen++] = (char)c;
  273. else
  274. {
  275. ptoken->wErrLine = ptoken->pline->wLineNum;
  276. ptoken->wErrPos = ptoken->pline->wLinePos;
  277. rc = TOKERR_TOKEN_TOO_LONG;
  278. }
  279. }
  280. ptoken->szToken[ptoken->wTokenLen] = '\0';
  281. LineUnGetC(c, ptoken->pline);
  282. if (rc == TOKERR_NONE)
  283. {
  284. if (!StrToQWord(ptoken->szToken, 0, (QWORD *)&ptoken->llTokenValue))
  285. {
  286. ptoken->wErrLine = ptoken->pline->wLineNum;
  287. ptoken->wErrPos = ptoken->pline->wLinePos;
  288. rc = TOKERR_TOKEN_TOO_LONG;
  289. }
  290. }
  291. }
  292. EXIT((4, "ScanNum=%d (Num=%I64d,Token=%s)\n",
  293. rc, ptoken->llTokenValue, ptoken->szToken));
  294. return rc;
  295. } //ScanNum
  296. /***LP ScanString - scan string token
  297. *
  298. * ENTRY
  299. * c - first character of the token
  300. * ptoken -> token structure
  301. *
  302. * EXIT-SUCCESS
  303. * returns TOKERR_NONE
  304. * EXIT-FAILURE
  305. * returns TOKTYPE_NO_MATCH - not a string token
  306. * TOKERR_TOKEN_TOO_LONG - string too long
  307. * TOKERR_UNCLOSED_STRING - EOF before string close
  308. */
  309. int LOCAL ScanString(int c, PTOKEN ptoken)
  310. {
  311. int rc = TOKERR_NO_MATCH;
  312. ENTER((4, "ScanString(c=%c,ptoken=%p)\n", c, ptoken));
  313. if (c == '"')
  314. {
  315. rc = TOKERR_NONE;
  316. ptoken->iTokenType = TOKTYPE_STRING;
  317. ptoken->wTokenLen--;
  318. while (((c = LineGetC(ptoken->pline)) != EOF) && (c != '"'))
  319. {
  320. if (rc == TOKERR_TOKEN_TOO_LONG)
  321. continue;
  322. else if (ptoken->wTokenLen >= MAX_TOKEN_LEN)
  323. {
  324. ptoken->wErrLine = ptoken->pline->wLineNum;
  325. ptoken->wErrPos = ptoken->pline->wLinePos;
  326. rc = TOKERR_TOKEN_TOO_LONG;
  327. }
  328. else
  329. {
  330. if (c == '\\')
  331. c = GetEscapedChar(ptoken->pline);
  332. ptoken->szToken[ptoken->wTokenLen++] = (char)c;
  333. }
  334. }
  335. ptoken->szToken[ptoken->wTokenLen] = '\0';
  336. if (c == EOF)
  337. {
  338. ptoken->wErrLine = ptoken->pline->wLineNum;
  339. if ((ptoken->wErrPos = ptoken->pline->wLinePos) != 0)
  340. ptoken->wErrPos--;
  341. rc = TOKERR_UNCLOSED_STRING;
  342. }
  343. }
  344. EXIT((4, "ScanString=%d (string=%s)\n", rc, ptoken->szToken));
  345. return rc;
  346. } //ScanString
  347. /***LP ScanChar - scan character token
  348. *
  349. * ENTRY
  350. * c - first character of the token
  351. * ptoken -> token structure
  352. *
  353. * EXIT-SUCCESS
  354. * returns TOKERR_NONE
  355. * EXIT-FAILURE
  356. * returns TOKERR_NO_MATCH - not a character token
  357. * TOKERR_TOKEN_TOO_LONG - token too long
  358. * TOKERR_UNCLOSED_CHAR - cannot find character close
  359. */
  360. int LOCAL ScanChar(int c, PTOKEN ptoken)
  361. {
  362. int rc = TOKERR_NO_MATCH;
  363. ENTER((4, "ScanChar(c=%c,ptoken=%p)\n", c, ptoken));
  364. if (c == '\'')
  365. {
  366. rc = TOKERR_NONE;
  367. ptoken->iTokenType = TOKTYPE_CHAR;
  368. ptoken->wTokenLen--;
  369. if (((c = LineGetC(ptoken->pline)) == EOF) ||
  370. (c == '\\') && ((c = GetEscapedChar(ptoken->pline)) == EOF))
  371. {
  372. rc = TOKERR_UNCLOSED_CHAR;
  373. }
  374. else
  375. {
  376. ptoken->szToken[ptoken->wTokenLen++] = (char)c;
  377. ptoken->szToken[ptoken->wTokenLen] = '\0';
  378. ptoken->llTokenValue = c;
  379. if ((c = LineGetC(ptoken->pline)) == EOF)
  380. rc = TOKERR_UNCLOSED_CHAR;
  381. else if (c != '\'')
  382. rc = TOKERR_TOKEN_TOO_LONG;
  383. }
  384. if (rc != TOKERR_NONE)
  385. {
  386. ptoken->wErrLine = ptoken->pline->wLineNum;
  387. if ((ptoken->wErrPos = ptoken->pline->wLinePos) != 0)
  388. ptoken->wErrPos--;
  389. if (rc == TOKERR_TOKEN_TOO_LONG)
  390. {
  391. while (((c = LineGetC(ptoken->pline)) != EOF) && (c != '\''))
  392. ;
  393. if (c == EOF)
  394. rc = TOKERR_UNCLOSED_CHAR;
  395. }
  396. }
  397. }
  398. EXIT((4, "ScanChar=%d (Value=%I64d,Char=%s)\n",
  399. rc, ptoken->llTokenValue, ptoken->szToken));
  400. return rc;
  401. } //ScanChar
  402. /***LP ProcessInLineComment - handle inline comment
  403. *
  404. * ENTRY
  405. * ptoken -> token structure
  406. *
  407. * EXIT
  408. * always returns TOKERR_NONE
  409. */
  410. int LOCAL ProcessInLineComment(PTOKEN ptoken)
  411. {
  412. ENTER((4, "ProcessInLineComment(ptoken=%p,Token=%s,Comment=%s)\n",
  413. ptoken, ptoken->szToken,
  414. &ptoken->pline->szLineBuff[ptoken->pline->wLinePos]));
  415. LineFlush(ptoken->pline);
  416. ptoken->iTokenType = TOKTYPE_NULL;
  417. EXIT((4, "ProcessInLineComment=%d\n", TOKERR_NONE));
  418. return TOKERR_NONE;
  419. } //ProcessInLineComment
  420. /***LP ProcessComment - handle comment
  421. *
  422. * ENTRY
  423. * ptoken -> token structure
  424. *
  425. * EXIT
  426. * always returns TOKERR_NONE
  427. */
  428. int LOCAL ProcessComment(PTOKEN ptoken)
  429. {
  430. int rc = TOKERR_UNCLOSED_COMMENT;
  431. int c;
  432. char *pch;
  433. ENTER((4, "ProcessComment(ptoken=%p,Token=%s,Comment=%s)\n",
  434. ptoken, ptoken->szToken,
  435. &ptoken->pline->szLineBuff[ptoken->pline->wLinePos]));
  436. while ((c = LineGetC(ptoken->pline)) != EOF)
  437. {
  438. if ((pch = strchr(SymCharTable, c)) != NULL)
  439. {
  440. int i;
  441. i = LookupSym(ptoken, (int)(pch - SymCharTable));
  442. if (SymTokTable[i].iSymType == SYM_CLOSECOMMENT)
  443. {
  444. ptoken->iTokenType = TOKTYPE_NULL;
  445. rc = TOKERR_NONE;
  446. break;
  447. }
  448. }
  449. }
  450. if (rc != TOKERR_NONE)
  451. {
  452. ptoken->wErrLine = ptoken->pline->wLineNum;
  453. if ((ptoken->wErrPos = ptoken->pline->wLinePos) != 0)
  454. ptoken->wErrPos--;
  455. }
  456. EXIT((4, "ProcessComment=%d\n", rc));
  457. return rc;
  458. } //ProcessComment
  459. /***LP LookupSym - match for 2-char. symbols
  460. *
  461. * ENTRY
  462. * ptoken -> token structure
  463. * iTable = SymCharTable index
  464. *
  465. * EXIT-SUCCESS
  466. * returns a different index than iTable;
  467. * EXIT-FAILURE
  468. * returns iTable;
  469. */
  470. int LOCAL LookupSym(PTOKEN ptoken, int iTable)
  471. {
  472. int i = iTable;
  473. int c;
  474. ENTER((4, "LookupSym(ptoken=%p,iTable=%d)\n", ptoken, iTable));
  475. if ((SymTokTable[iTable].iLink != 0) &&
  476. ((c = LineGetC(ptoken->pline)) != EOF))
  477. {
  478. i = SymTokTable[iTable].iLink;
  479. while ((c != SymTokTable[i].chSym) && (SymTokTable[i].iLink != 0))
  480. i = SymTokTable[i].iLink;
  481. if (c != SymTokTable[i].chSym)
  482. {
  483. LineUnGetC(c, ptoken->pline);
  484. i = iTable;
  485. }
  486. }
  487. EXIT((4, "LookupSym=%d\n", i));
  488. return i;
  489. } //LookupSym
  490. /***LP LookupID - lookup the token in our reserved ID list
  491. *
  492. * ENTRY
  493. * ptoken -> token structure
  494. *
  495. * EXIT-SUCCESS
  496. * returns index of TermTable
  497. * EXIT-FAILURE
  498. * returns ID_USER
  499. */
  500. LONG LOCAL LookupID(PTOKEN ptoken)
  501. {
  502. LONG lID = ID_USER;
  503. LONG i;
  504. ENTER((4, "LookupID(ptoken=%p)\n", ptoken));
  505. for (i = 0; TermTable[i].pszID != NULL; ++i)
  506. {
  507. if (_stricmp(TermTable[i].pszID, ptoken->szToken) == 0)
  508. {
  509. lID = i;
  510. break;
  511. }
  512. }
  513. EXIT((4, "LookupID=%ld\n", lID));
  514. return lID;
  515. } //LookupID
  516. /***LP GetEscapedChar - read and translate escape character
  517. *
  518. * ENTRY
  519. * pline -> line structure
  520. *
  521. * EXIT-SUCCESS
  522. * returns the escape character
  523. * EXIT-FAILURE
  524. * returns EOF - eof encountered
  525. */
  526. int LOCAL GetEscapedChar(PLINE pline)
  527. {
  528. int c;
  529. #define ESCAPE_BUFF_SIZE 5
  530. char achEscapedBuff[ESCAPE_BUFF_SIZE];
  531. int i;
  532. ENTER((4, "GetEscapedChar(pline=%p)\n", pline));
  533. if ((c = LineGetC(pline)) != EOF)
  534. {
  535. switch(c)
  536. {
  537. case '0':
  538. achEscapedBuff[0] = (char)c;
  539. for (i = 1; i < 4; i++) //maximum 3 digits
  540. {
  541. if (((c = LineGetC(pline)) != EOF) &&
  542. (c >= '0') && (c <= '7'))
  543. {
  544. achEscapedBuff[i] = (char)c;
  545. }
  546. else
  547. {
  548. LineUnGetC(c, pline);
  549. break;
  550. }
  551. }
  552. achEscapedBuff[i] = '\0';
  553. c = (int)strtoul(achEscapedBuff, NULL, 8);
  554. break;
  555. case 'a':
  556. c = '\a'; //alert (bell)
  557. break;
  558. case 'b':
  559. c = '\b'; //backspace
  560. break;
  561. case 'f':
  562. c = '\f'; //form feed
  563. break;
  564. case 'n':
  565. c = '\n'; //newline
  566. break;
  567. case 'r':
  568. c = '\r'; //carriage return
  569. break;
  570. case 't':
  571. c = '\t'; //horizontal tab
  572. break;
  573. case 'v':
  574. c = '\v'; //vertical tab
  575. break;
  576. case 'x':
  577. for (i = 0; i < 2; i++) //maximum 2 digits
  578. {
  579. if (((c = LineGetC(pline)) != EOF) && isxdigit(c))
  580. achEscapedBuff[i] = (char)c;
  581. else
  582. {
  583. LineUnGetC(c, pline);
  584. break;
  585. }
  586. }
  587. achEscapedBuff[i] = '\0';
  588. c = (int)strtoul(achEscapedBuff, NULL, 16);
  589. }
  590. }
  591. EXIT((4, "GetEscapedChar=%x\n", c));
  592. return c;
  593. } //GetEscapedChar
  594. /***EP PrintScanErr - print scan error
  595. *
  596. * ENTRY
  597. * ptoken -> token structure
  598. * rcErr - error code
  599. *
  600. * EXIT
  601. * None
  602. */
  603. VOID EXPORT PrintScanErr(PTOKEN ptoken, int rcErr)
  604. {
  605. WORD i;
  606. ENTER((4, "PrintScanErr(ptoken=%p,Err=%d)\n", ptoken, rcErr));
  607. ASSERT(ptoken->wTokenLine == ptoken->wErrLine);
  608. ErrPrintf("%5u: %s\n ",
  609. ptoken->wTokenLine, ptoken->pline->szLineBuff);
  610. for (i = 0; i < ptoken->wErrPos; ++i)
  611. {
  612. if (ptoken->pline->szLineBuff[i] == '\t')
  613. {
  614. ErrPrintf("\t");
  615. }
  616. else
  617. {
  618. ErrPrintf(" ");
  619. }
  620. }
  621. ErrPrintf("^***\n");
  622. switch (rcErr)
  623. {
  624. case TOKERR_TOKEN_TOO_LONG:
  625. ErrPrintf("ScanErr: Token too long\n");
  626. break;
  627. case TOKERR_UNCLOSED_STRING:
  628. ErrPrintf("ScanErr: Unclosed string\n");
  629. break;
  630. case TOKERR_UNCLOSED_CHAR:
  631. ErrPrintf("ScanErr: Unclosed character quote\n");
  632. break;
  633. default:
  634. ErrPrintf("ScanErr: Syntax error\n");
  635. break;
  636. }
  637. EXIT((4, "PrintScanErr!\n"));
  638. } //PrintScanErr
  639. /***EP StrToQWord - convert the number in a string to a QWord
  640. *
  641. * ENTRY
  642. * psz -> string
  643. * dwBase - the base of the number (if 0, auto-detect base)
  644. * pqw -> to hold the resulting QWord
  645. *
  646. * EXIT-SUCCESS
  647. * returns TRUE
  648. * EXIT-FAILURE
  649. * returns FALSE
  650. */
  651. BOOL EXPORT StrToQWord(PSZ psz, DWORD dwBase, QWORD *pqw)
  652. {
  653. BOOL rc = TRUE;
  654. ULONG m;
  655. ENTER((4, "StrToQWord(Str=%s,Base=%x,pqw=%p)\n", psz, dwBase, pqw));
  656. *pqw = 0;
  657. if (dwBase == 0)
  658. {
  659. if (psz[0] == '0')
  660. {
  661. if ((psz[1] == 'x') || (psz[1] == 'X'))
  662. {
  663. dwBase = 16;
  664. psz += 2;
  665. }
  666. else
  667. {
  668. dwBase = 8;
  669. psz++;
  670. }
  671. }
  672. else
  673. dwBase = 10;
  674. }
  675. while (*psz != '\0')
  676. {
  677. if ((*psz >= '0') && (*psz <= '9'))
  678. m = *psz - '0';
  679. else if ((*psz >= 'A') && (*psz <= 'Z'))
  680. m = *psz - 'A' + 10;
  681. else if ((*psz >= 'a') && (*psz <= 'z'))
  682. m = *psz - 'a' + 10;
  683. else
  684. {
  685. rc = FALSE;
  686. break;
  687. }
  688. if (m < dwBase)
  689. {
  690. *pqw = (*pqw * dwBase) + m;
  691. psz++;
  692. }
  693. else
  694. {
  695. rc = FALSE;
  696. break;
  697. }
  698. }
  699. EXIT((4, "StrToQWord=%x (QWord=0x%I64x)\n", rc, *pqw));
  700. return rc;
  701. } //StrToQWord