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.

331 lines
7.9 KiB

  1. #include <stdafx.h>
  2. #include "Parser.h"
  3. #include "EventCmd.h"
  4. #include "Errors.h"
  5. CParser gParser;
  6. CParser::CParser()
  7. {
  8. m_pOperList = NULL;
  9. m_fdInput = -1;
  10. m_nLineNo = 1;
  11. m_nTokenNo = 0;
  12. m_pInput = m_szInput;
  13. }
  14. CParser::~CParser()
  15. {
  16. if (m_fdInput != -1)
  17. _close(m_fdInput);
  18. if (m_pOperList != NULL)
  19. delete m_pOperList;
  20. }
  21. DWORD CParser::OpenInputFile()
  22. {
  23. DWORD retCode;
  24. m_fdInput = _open(gCommandLine.m_szFileName, _O_RDONLY | _O_BINARY);
  25. retCode = GetLastError();
  26. if (retCode != ERROR_SUCCESS)
  27. _E(retCode, IDS_ERR08, gCommandLine.m_szFileName);
  28. else
  29. retCode = ReloadInputBuffer();
  30. return retCode;
  31. }
  32. DWORD CParser::ReloadInputBuffer()
  33. {
  34. DWORD retCode;
  35. int nBuf;
  36. m_pInput = m_szInput;
  37. nBuf = _read(m_fdInput, m_szInput, INPUT_BUFFER_SZ);
  38. retCode = GetLastError();
  39. if (retCode != ERROR_SUCCESS)
  40. _E(retCode, IDS_ERR09, m_nLineNo);
  41. else if (nBuf < INPUT_BUFFER_SZ)
  42. m_szInput[nBuf] = '\0';
  43. return retCode;
  44. }
  45. DWORD CParser::AdvanceInputPointer()
  46. {
  47. DWORD retCode = ERROR_SUCCESS;
  48. if (*m_pInput == '\0')
  49. {
  50. _W(WARN_TRACK, IDS_TRCK_WRN27, m_nLineNo, m_nTokenNo);
  51. return ERROR_END_OF_MEDIA;
  52. }
  53. if (*m_pInput == TOKEN_CH_NL)
  54. {
  55. m_nLineNo++;
  56. m_nTokenNo;
  57. m_nTokenNo = 0;
  58. }
  59. if (m_pInput < m_szInput + INPUT_BUFFER_SZ - 1)
  60. m_pInput++;
  61. else
  62. retCode = ReloadInputBuffer();
  63. if (retCode == ERROR_SUCCESS && *m_pInput == '\0')
  64. {
  65. _W(WARN_TRACK, IDS_TRCK_WRN28, m_nLineNo, m_nTokenNo);
  66. retCode = ERROR_END_OF_MEDIA;
  67. }
  68. return retCode;
  69. }
  70. DWORD CParser::GetNextToken(char * pToken, int nSizeToken)
  71. {
  72. int i;
  73. DWORD nLineStrDelim;
  74. DWORD nTokenStrDelim;
  75. enum
  76. {
  77. STATE_BLANKS,
  78. STATE_COMMENT,
  79. STATE_TOKEN
  80. } state = STATE_BLANKS;
  81. DWORD retCode = ERROR_SUCCESS;
  82. while (retCode == ERROR_SUCCESS)
  83. {
  84. if (state == STATE_BLANKS)
  85. {
  86. if (*m_pInput == TOKEN_CH_COM_DELIM)
  87. state = STATE_COMMENT;
  88. else if (strchr(TOKEN_SZ_BLANKS, *m_pInput) == NULL)
  89. break;
  90. }
  91. else if (state == STATE_COMMENT)
  92. {
  93. if (*m_pInput == TOKEN_CH_NL)
  94. state = STATE_BLANKS;
  95. }
  96. retCode = AdvanceInputPointer();
  97. }
  98. i = 0;
  99. state = STATE_BLANKS;
  100. m_nTokenNo++;
  101. while (retCode == ERROR_SUCCESS &&
  102. *m_pInput != TOKEN_CH_COM_DELIM)
  103. {
  104. if (state == STATE_BLANKS)
  105. {
  106. if (strchr(TOKEN_SZ_BLANKS, *m_pInput) != NULL)
  107. break;
  108. if (*m_pInput == TOKEN_CH_STR_DELIM)
  109. {
  110. state = STATE_TOKEN;
  111. nLineStrDelim = m_nLineNo;
  112. nTokenStrDelim = m_nTokenNo;
  113. retCode = AdvanceInputPointer();
  114. continue;
  115. }
  116. }
  117. if (state == STATE_TOKEN)
  118. {
  119. if (*m_pInput == TOKEN_CH_STR_DELIM)
  120. {
  121. state = STATE_BLANKS;
  122. retCode = AdvanceInputPointer();
  123. break;
  124. }
  125. }
  126. pToken[i++] = *m_pInput;
  127. if (i >= nSizeToken)
  128. {
  129. return _E(ERROR_BUFFER_OVERFLOW, IDS_ERR04,
  130. m_nLineNo, m_nTokenNo, nSizeToken);
  131. }
  132. retCode = AdvanceInputPointer();
  133. }
  134. pToken[i] = '\0';
  135. if (state == STATE_TOKEN)
  136. {
  137. _W(WARN_ERROR, IDS_ERRO_WRN29,
  138. nLineStrDelim, nTokenStrDelim);
  139. }
  140. if (i > 0 && retCode == ERROR_END_OF_MEDIA)
  141. retCode = ERROR_SUCCESS;
  142. return retCode;
  143. }
  144. DWORD CParser::UnGetToken(char *szToken)
  145. {
  146. int nTokenLen;
  147. char *pInsertion;
  148. nTokenLen = strlen(szToken) + 2;
  149. if (m_pInput - m_szInput < nTokenLen)
  150. {
  151. int nDrift = nTokenLen - (int)(m_pInput - m_szInput);
  152. memmove(m_pInput + nDrift, m_pInput, INPUT_BUFFER_SZ - (size_t)(m_pInput - m_szInput) - nDrift);
  153. m_pInput += nDrift;
  154. if (_lseek(m_fdInput, -nDrift, SEEK_CUR) == -1)
  155. {
  156. return _E(GetLastError(), IDS_ERR10);
  157. }
  158. }
  159. pInsertion = m_pInput = m_pInput - nTokenLen;
  160. *pInsertion++ = '\"';
  161. strcpy(pInsertion, szToken);
  162. pInsertion += nTokenLen - 2;
  163. *pInsertion = '\"';
  164. m_nTokenNo--;
  165. return ERROR_SUCCESS;
  166. }
  167. DWORD CParser::CheckUnGetToken(char *pMatchToken, char *pToken)
  168. {
  169. DWORD retCode = ERROR_SUCCESS;
  170. if (strcmp(pMatchToken, pToken) == 0 &&
  171. (retCode = UnGetToken(pToken)) == ERROR_SUCCESS)
  172. retCode = ERROR_INVALID_PARAMETER;
  173. return retCode;
  174. }
  175. DWORD CParser::ParseInputFile()
  176. {
  177. DWORD retCode;
  178. DWORD dwSkipLine;
  179. enum
  180. {
  181. STATE_READ,
  182. STATE_SKIP
  183. } state = STATE_READ;
  184. retCode = OpenInputFile();
  185. if (retCode == ERROR_SUCCESS)
  186. {
  187. while(1)
  188. {
  189. char szToken[INPUT_TOKEN_SZ];
  190. retCode = GetNextToken(szToken, INPUT_TOKEN_SZ);
  191. if (retCode != ERROR_SUCCESS)
  192. break;
  193. if (state == STATE_SKIP)
  194. {
  195. if (m_nLineNo == dwSkipLine)
  196. continue;
  197. state = STATE_READ;
  198. }
  199. if (state == STATE_READ)
  200. {
  201. if (strcmp(szToken, KEYWORD_PRAGMA) != 0)
  202. {
  203. _W(WARN_ALERT, IDS_ALRT_WRN30, m_nLineNo, m_nTokenNo);
  204. dwSkipLine = m_nLineNo;
  205. state = STATE_SKIP;
  206. continue;
  207. }
  208. retCode = GetNextToken(szToken, INPUT_TOKEN_SZ);
  209. if (retCode != ERROR_SUCCESS)
  210. {
  211. _W(WARN_ALERT, IDS_ALRT_WRN31, m_nLineNo, m_nTokenNo);
  212. dwSkipLine = m_nLineNo;
  213. state = STATE_SKIP;
  214. continue;
  215. }
  216. if (_stricmp(szToken, KEYWORD_CMD_ADD_EVENT) == 0)
  217. retCode = ParseCommand(OP_ADD_EVENT);
  218. else if (_stricmp(szToken, KEYWORD_CMD_DEL_EVENT) == 0)
  219. retCode = ParseCommand(OP_DEL_EVENT);
  220. else if (_stricmp(szToken, KEYWORD_CMD_ADD_TRAP) == 0)
  221. retCode = ParseCommand(OP_ADD_TRAP);
  222. else if (_stricmp(szToken, KEYWORD_CMD_DEL_TRAP) == 0)
  223. retCode = ParseCommand(OP_DEL_TRAP);
  224. else
  225. {
  226. retCode = ERROR_INVALID_OPERATION;
  227. _W(WARN_ALERT, IDS_ALRT_WRN32,
  228. m_nLineNo, m_nTokenNo, szToken);
  229. }
  230. if (retCode != ERROR_SUCCESS)
  231. {
  232. dwSkipLine = m_nLineNo;
  233. state = STATE_SKIP;
  234. retCode = ERROR_SUCCESS;
  235. continue;
  236. }
  237. }
  238. }
  239. }
  240. if (retCode == ERROR_END_OF_MEDIA)
  241. retCode = ERROR_SUCCESS;
  242. return retCode;
  243. }
  244. DWORD CParser::ParseCommand(tOperation opType)
  245. {
  246. DWORD retCode = ERROR_SUCCESS;
  247. COperation *pOperation;
  248. switch(opType)
  249. {
  250. case OP_ADD_EVENT:
  251. case OP_DEL_EVENT:
  252. pOperation = new COpEvents(opType);
  253. break;
  254. case OP_ADD_TRAP:
  255. case OP_DEL_TRAP:
  256. pOperation = new COpTraps(opType);
  257. break;
  258. }
  259. if (pOperation == NULL)
  260. return _E(ERROR_OUTOFMEMORY, IDS_ERR01);
  261. retCode = pOperation->ParseCmdArgs();
  262. if (retCode == ERROR_SUCCESS)
  263. {
  264. if (m_pOperList == NULL)
  265. m_pOperList = pOperation;
  266. else
  267. m_pOperList = m_pOperList->Insert(pOperation);
  268. }
  269. else
  270. delete pOperation;
  271. return retCode;
  272. }
  273. DWORD CParser::ProcessCommands()
  274. {
  275. DWORD retCode = ERROR_SUCCESS;
  276. COperation *pOperation;
  277. for (pOperation = m_pOperList;
  278. retCode == ERROR_SUCCESS && pOperation != NULL;
  279. pOperation = pOperation->GetNextOp())
  280. retCode = pOperation->ProcessCommand();
  281. return retCode;
  282. }