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.

443 lines
9.0 KiB

  1. /* Copyright (C) Microsoft Corporation, 1998. All rights reserved. */
  2. #include "precomp.h"
  3. #include "getsym.h"
  4. #include "utils.h"
  5. CInput::
  6. CInput
  7. (
  8. BOOL *pfRetCode,
  9. LPSTR pszPathName,
  10. UINT cbBufSize
  11. )
  12. :
  13. m_cbBufSize(cbBufSize),
  14. m_cbValidData(0),
  15. m_nCurrOffset(0),
  16. m_chCurr(INVALID_CHAR),
  17. m_fEndOfFile(TRUE)
  18. {
  19. m_pszPathName = ::My_strdup(pszPathName);
  20. m_pbDataBuf = new BYTE[m_cbBufSize];
  21. m_hFile = ::CreateFile(pszPathName,
  22. GENERIC_READ,
  23. FILE_SHARE_READ,
  24. NULL, // default security
  25. OPEN_EXISTING,
  26. FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_READONLY,
  27. NULL); // no template
  28. m_cbFileSize = (NULL != m_hFile) ? ::GetFileSize(m_hFile, NULL) : 0;
  29. *pfRetCode = (NULL != m_pszPathName) &&
  30. (NULL != m_pbDataBuf) &&
  31. (NULL != m_hFile);
  32. if (*pfRetCode)
  33. {
  34. if (CheckBuffer(1))
  35. {
  36. m_chCurr = m_pbDataBuf[0];
  37. m_fEndOfFile = FALSE;
  38. }
  39. }
  40. }
  41. CInput::
  42. ~CInput ( void )
  43. {
  44. delete m_pszPathName;
  45. delete m_pbDataBuf;
  46. if (NULL != m_hFile)
  47. {
  48. ::CloseHandle(m_hFile);
  49. }
  50. }
  51. void CInput::
  52. NextChar ( void )
  53. {
  54. if (INVALID_CHAR != m_chCurr)
  55. {
  56. // set up the next new char
  57. if (CheckBuffer(1))
  58. {
  59. m_chCurr = m_pbDataBuf[++m_nCurrOffset];
  60. }
  61. else
  62. {
  63. m_chCurr = INVALID_CHAR;
  64. m_fEndOfFile = TRUE;
  65. }
  66. }
  67. }
  68. void CInput::
  69. PeekChars ( UINT cChars, LPSTR pszChars )
  70. {
  71. if (CheckBuffer(cChars - 1))
  72. {
  73. ::CopyMemory(pszChars, &m_pbDataBuf[m_nCurrOffset], cChars);
  74. }
  75. else
  76. {
  77. ::ZeroMemory(pszChars, cChars);
  78. }
  79. }
  80. void CInput::
  81. SkipChars ( UINT cChars )
  82. {
  83. for (UINT i = 0; i < cChars; i++)
  84. {
  85. NextChar();
  86. }
  87. }
  88. BOOL CInput::
  89. CheckBuffer ( UINT cChars )
  90. {
  91. if (m_nCurrOffset + cChars >= m_cbValidData)
  92. {
  93. ASSERT(m_cbValidData >= m_nCurrOffset);
  94. UINT cbCurrValid = m_cbValidData - m_nCurrOffset;
  95. UINT cbToRead = m_cbBufSize - cbCurrValid;
  96. if (cbCurrValid > 0)
  97. {
  98. // Move the data to the front of the buffer.
  99. ::CopyMemory(&m_pbDataBuf[0], &m_pbDataBuf[m_nCurrOffset], cbCurrValid);
  100. m_nCurrOffset = 0;
  101. }
  102. ULONG cbRead = 0;
  103. if (::ReadFile(m_hFile, &m_pbDataBuf[cbCurrValid], cbToRead, &cbRead, NULL))
  104. {
  105. ASSERT(cbRead <= cbToRead);
  106. m_cbValidData = cbCurrValid + cbRead;
  107. m_nCurrOffset = 0;
  108. if (cbRead < cbToRead)
  109. {
  110. m_fEndOfFile = TRUE;
  111. }
  112. }
  113. else
  114. {
  115. m_fEndOfFile = TRUE;
  116. }
  117. return (m_nCurrOffset + cChars < m_cbValidData);
  118. }
  119. return TRUE;
  120. }
  121. BOOL CInput::
  122. Rewind ( void )
  123. {
  124. if ((DWORD) -1 != ::SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN))
  125. {
  126. // clean up members
  127. m_cbValidData = 0;
  128. m_nCurrOffset = 0;
  129. m_chCurr = INVALID_CHAR;
  130. // set up the buffer
  131. if (CheckBuffer(1))
  132. {
  133. m_chCurr = m_pbDataBuf[0];
  134. m_fEndOfFile = FALSE;
  135. }
  136. else
  137. {
  138. m_fEndOfFile = TRUE;
  139. }
  140. return TRUE;
  141. }
  142. return FALSE;
  143. }
  144. CSymbol::
  145. CSymbol ( CInput *pInput )
  146. :
  147. m_pInput(pInput),
  148. m_eSymbolID(SYMBOL_UNKNOWN),
  149. m_cchSymbolStr(0)
  150. {
  151. m_szSymbolStr[0] = '\0';
  152. }
  153. BOOL CSymbol::
  154. NextSymbol ( void )
  155. {
  156. if (SYMBOL_EOF == m_eSymbolID)
  157. {
  158. return FALSE;
  159. }
  160. char ch = m_pInput->GetChar();
  161. m_szSymbolStr[0] = ch;
  162. m_cchSymbolStr = 1;
  163. m_pInput->NextChar();
  164. if (::isdigit(ch))
  165. {
  166. // numbers
  167. while (INVALID_CHAR != (ch = m_pInput->GetChar()))
  168. {
  169. if (::isdigit(ch))
  170. {
  171. m_szSymbolStr[m_cchSymbolStr++] = ch;
  172. m_pInput->NextChar();
  173. }
  174. else
  175. {
  176. break;
  177. }
  178. }
  179. m_eSymbolID = SYMBOL_NUMBER;
  180. }
  181. else
  182. if (::isalpha(ch))
  183. {
  184. // alphanumeric
  185. while (INVALID_CHAR != (ch = m_pInput->GetChar()))
  186. {
  187. if (::isalnum(ch) || '_' == ch || '-' == ch)
  188. {
  189. m_szSymbolStr[m_cchSymbolStr++] = ch;
  190. m_pInput->NextChar();
  191. }
  192. else
  193. {
  194. m_szSymbolStr[m_cchSymbolStr] = '\0';
  195. break;
  196. }
  197. }
  198. m_eSymbolID = ::IsKeyword(&m_szSymbolStr[0]) ? SYMBOL_KEYWORD : SYMBOL_IDENTIFIER;
  199. }
  200. else
  201. if ('\n' == ch)
  202. {
  203. m_szSymbolStr[m_cchSymbolStr++] = '\n';
  204. m_eSymbolID = SYMBOL_SPACE_EOL;
  205. }
  206. else
  207. if (::isspace(ch))
  208. {
  209. // space
  210. m_eSymbolID = SYMBOL_SPACE;
  211. while (INVALID_CHAR != (ch = m_pInput->GetChar()))
  212. {
  213. if (::isspace(ch))
  214. {
  215. m_szSymbolStr[m_cchSymbolStr++] = ch;
  216. m_pInput->NextChar();
  217. if ('\n' == ch)
  218. {
  219. m_eSymbolID = SYMBOL_SPACE_EOL;
  220. }
  221. }
  222. else
  223. {
  224. break;
  225. }
  226. }
  227. }
  228. else
  229. if ('&' == ch)
  230. {
  231. m_eSymbolID = SYMBOL_FIELD;
  232. // alphanumeric
  233. while (INVALID_CHAR != (ch = m_pInput->GetChar()))
  234. {
  235. if (::isalnum(ch) || '_' == ch)
  236. {
  237. m_szSymbolStr[m_cchSymbolStr++] = ch;
  238. m_pInput->NextChar();
  239. }
  240. else
  241. {
  242. m_szSymbolStr[m_cchSymbolStr] = '\0';
  243. break;
  244. }
  245. }
  246. }
  247. else
  248. {
  249. char szTemp[4];
  250. m_eSymbolID = SYMBOL_SPECIAL;
  251. if (':' == ch)
  252. {
  253. m_pInput->PeekChars(2, &szTemp[0]);
  254. if (':' == szTemp[0] && '=' == szTemp[1])
  255. {
  256. m_pInput->SkipChars(2);
  257. m_szSymbolStr[m_cchSymbolStr++] = ':';
  258. m_szSymbolStr[m_cchSymbolStr++] = '=';
  259. m_eSymbolID = SYMBOL_DEFINITION;
  260. }
  261. }
  262. else
  263. if ('-' == ch)
  264. {
  265. m_pInput->PeekChars(1, &szTemp[0]);
  266. if ('-' == szTemp[0])
  267. {
  268. m_pInput->SkipChars(1);
  269. m_szSymbolStr[m_cchSymbolStr++] = '-';
  270. m_eSymbolID = SYMBOL_COMMENT;
  271. }
  272. }
  273. else
  274. if ('.' == ch)
  275. {
  276. m_pInput->PeekChars(2, &szTemp[0]);
  277. if ('.' == szTemp[0] && '.' == szTemp[1])
  278. {
  279. m_pInput->SkipChars(2);
  280. m_szSymbolStr[m_cchSymbolStr++] = '.';
  281. m_szSymbolStr[m_cchSymbolStr++] = '.';
  282. m_eSymbolID = SYMBOL_DOTDOTDOT;
  283. }
  284. }
  285. }
  286. // null terminate the string
  287. m_szSymbolStr[m_cchSymbolStr] = '\0';
  288. if (INVALID_CHAR != m_szSymbolStr[0])
  289. {
  290. return TRUE;
  291. }
  292. m_eSymbolID = SYMBOL_EOF;
  293. return FALSE;
  294. }
  295. BOOL CSymbol::
  296. NextUsefulSymbol ( void )
  297. {
  298. BOOL fInsideComment = FALSE;
  299. while (NextSymbol())
  300. {
  301. if (SYMBOL_SPACE_EOL == m_eSymbolID)
  302. {
  303. fInsideComment = FALSE;
  304. }
  305. else
  306. if (SYMBOL_COMMENT == m_eSymbolID)
  307. {
  308. fInsideComment = ! fInsideComment;
  309. }
  310. else
  311. if (! fInsideComment)
  312. {
  313. if (SYMBOL_SPACE != m_eSymbolID)
  314. {
  315. return TRUE;
  316. }
  317. }
  318. }
  319. return FALSE;
  320. }
  321. COutput::
  322. COutput
  323. (
  324. BOOL *pfRetCode,
  325. LPSTR pszPathName,
  326. UINT cbBufSize
  327. )
  328. :
  329. m_cbBufSize(cbBufSize),
  330. m_cbValidData(0)
  331. {
  332. m_pszPathName = ::My_strdup(pszPathName);
  333. m_pbDataBuf = new BYTE[m_cbBufSize];
  334. m_hFile = ::CreateFile(pszPathName,
  335. GENERIC_WRITE,
  336. FILE_SHARE_READ,
  337. NULL, // default security
  338. CREATE_ALWAYS,
  339. FILE_ATTRIBUTE_NORMAL,
  340. NULL); // no template
  341. *pfRetCode = (NULL != m_pszPathName) &&
  342. (NULL != m_pbDataBuf) &&
  343. (NULL != m_hFile);
  344. }
  345. COutput::
  346. ~COutput ( void )
  347. {
  348. delete m_pszPathName;
  349. delete m_pbDataBuf;
  350. if (NULL != m_hFile)
  351. {
  352. Flush();
  353. ::CloseHandle(m_hFile);
  354. }
  355. }
  356. BOOL COutput::
  357. Write
  358. (
  359. LPBYTE pbDataBuf,
  360. UINT cbToWrite
  361. )
  362. {
  363. ULONG cbWritten;
  364. while (0 != cbToWrite)
  365. {
  366. if (::WriteFile(m_hFile, pbDataBuf, cbToWrite, &cbWritten, NULL))
  367. {
  368. pbDataBuf += cbWritten;
  369. cbToWrite -= cbWritten;
  370. }
  371. else
  372. {
  373. return FALSE;
  374. }
  375. }
  376. return TRUE;
  377. }
  378. BOOL COutput::
  379. Writeln
  380. (
  381. LPBYTE pbDataBuf,
  382. UINT cbToWrite
  383. )
  384. {
  385. return Write(pbDataBuf, cbToWrite) && Write("\n", 1);
  386. }