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.

442 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. lexer.hxx
  5. Abstract:
  6. This module implements functions to recognize the tokens in the string
  7. repressentation of the search filter. The format of the search filter
  8. according to the RFC 1960.
  9. Author:
  10. Shankara Shastry [ShankSh] 08-Jul-1996
  11. ++*/
  12. #include "nds.hxx"
  13. #pragma hdrstop
  14. DFA_STATE CQryLexer::_pStateTable[MAX_STATES][MAX_CHAR_CLASSES] = gStateTable;
  15. DWORD CQryLexer::_pCharClassTable[] = gCharClassTable;
  16. //+---------------------------------------------------------------------------
  17. // Function: CQryLexer
  18. //
  19. // Synopsis: Constructor: Allocate memory for the pattern and initialize
  20. //
  21. // Arguments: szBuffer: pattern
  22. //
  23. // Returns:
  24. //
  25. // Modifies:
  26. //
  27. // History: 07-09-96 ShankSh Created.
  28. //
  29. //----------------------------------------------------------------------------
  30. CQryLexer::CQryLexer(
  31. LPWSTR szBuffer
  32. ):
  33. _ptr(NULL),
  34. _Buffer(NULL),
  35. _dwEndofString(0),
  36. _dwState(ATTRTYPE_START_STATE),
  37. _lexeme()
  38. {
  39. _bInitialized = FALSE;
  40. if (!szBuffer || !*szBuffer) {
  41. return;
  42. }
  43. _Buffer = (LPWSTR) AllocADsMem(
  44. (wcslen(szBuffer)+1) * sizeof(WCHAR)
  45. );
  46. if(_Buffer)
  47. wcscpy(_Buffer,
  48. szBuffer
  49. );
  50. _ptr = _Buffer;
  51. }
  52. //+---------------------------------------------------------------------------
  53. // Function: GetNextToken
  54. //
  55. // Synopsis: Give the next valid token
  56. //
  57. // Arguments:
  58. //
  59. // Returns:
  60. //
  61. // Modifies:
  62. //
  63. // History: 07-09-96 ShankSh Created.
  64. //
  65. //----------------------------------------------------------------------------
  66. HRESULT
  67. CQryLexer::GetNextToken(
  68. LPWSTR *ppszToken,
  69. LPDWORD pdwToken
  70. )
  71. {
  72. WCHAR wcNextChar;
  73. DWORD dwActionId;
  74. DFA_STATE dfaState;
  75. DWORD dwStartState = _dwState;
  76. // If there is no pattern
  77. if(!_ptr) {
  78. *pdwToken = TOKEN_ENDINPUT;
  79. RRETURN (S_OK);
  80. }
  81. // Start forming the lexeme.
  82. _lexeme.ResetLexeme();
  83. *ppszToken = NULL;
  84. *pdwToken = TOKEN_ERROR;
  85. while (_dwState != ERROR_STATE && _dwState < FINAL_STATES_BEGIN) {
  86. // Get the character class from the character and then index the
  87. // state table
  88. wcNextChar = NextChar();
  89. DWORD now = GetCharClass(wcNextChar);
  90. dwActionId = _pStateTable[_dwState][GetCharClass(wcNextChar)].
  91. dwActionId;
  92. _dwState = _pStateTable[_dwState][GetCharClass(wcNextChar)].
  93. dwNextState;
  94. if(_dwState == ERROR_STATE) {
  95. BAIL_ON_FAILURE (E_FAIL);
  96. }
  97. PerformAction(_dwState,
  98. wcNextChar,
  99. dwActionId
  100. );
  101. }
  102. _bInitialized = TRUE;
  103. if(*pdwToken == TOKEN_ENDINPUT)
  104. RRETURN (S_OK);
  105. *ppszToken = _lexeme.GetLexeme();
  106. *pdwToken = GetTokenFromState(_dwState);
  107. _dwStateSave = _dwState;
  108. // This is to set the start state for the next token to be recognized
  109. if(*pdwToken == TOKEN_ATTRTYPE) {
  110. _dwState = ATTRVAL_START_STATE;
  111. }
  112. else if (*pdwToken == TOKEN_ATTRVAL) {
  113. _dwState = ATTRTYPE_START_STATE;
  114. }
  115. else if (*pdwToken == TOKEN_PRESENT) {
  116. _dwState = ATTRTYPE_START_STATE;
  117. } else {
  118. _dwState = dwStartState;
  119. }
  120. RRETURN (S_OK);
  121. error:
  122. RRETURN (E_FAIL);
  123. }
  124. //+---------------------------------------------------------------------------
  125. // Function: GetCurrentToken
  126. //
  127. // Synopsis: Give the current valid token, and do not advance unless
  128. // it is the first token
  129. //
  130. // Arguments:
  131. //
  132. // Returns:
  133. //
  134. // Modifies:
  135. //
  136. // History: 07-09-96 ShankSh Created.
  137. //
  138. //----------------------------------------------------------------------------
  139. HRESULT
  140. CQryLexer::GetCurrentToken(
  141. LPWSTR *ppszToken,
  142. LPDWORD pdwToken
  143. )
  144. {
  145. if (!_bInitialized) {
  146. HRESULT hr;
  147. hr = GetNextToken(
  148. ppszToken,
  149. pdwToken
  150. );
  151. return hr;
  152. } else {
  153. *ppszToken = _lexeme.GetLexeme();
  154. *pdwToken = GetTokenFromState(_dwStateSave);
  155. return (S_OK);
  156. }
  157. }
  158. //+---------------------------------------------------------------------------
  159. // Function: NextChar
  160. //
  161. // Synopsis: Returns the next chaarcter in the pattern
  162. //
  163. // Arguments:
  164. //
  165. // Returns:
  166. //
  167. // Modifies:
  168. //
  169. // History: 07-09-96 ShankSh Created.
  170. //
  171. //----------------------------------------------------------------------------
  172. WCHAR
  173. CQryLexer::NextChar()
  174. {
  175. if (_ptr == NULL || *_ptr == L'\0') {
  176. _dwEndofString = TRUE;
  177. return(L'\0');
  178. }
  179. return(*_ptr++);
  180. }
  181. //+---------------------------------------------------------------------------
  182. // Function: PushbackChar
  183. //
  184. // Synopsis: Puts back a character to the unrecognised pattern
  185. //
  186. // Arguments:
  187. //
  188. // Returns:
  189. //
  190. // Modifies:
  191. //
  192. // History: 07-09-96 ShankSh Created.
  193. //
  194. //----------------------------------------------------------------------------
  195. void
  196. CQryLexer::PushbackChar()
  197. {
  198. if (_dwEndofString) {
  199. return;
  200. }
  201. _ptr--;
  202. }
  203. HRESULT
  204. CQryLexer::PerformAction(
  205. DWORD dwCurrState,
  206. WCHAR wcCurrChar,
  207. DWORD dwActionId
  208. )
  209. {
  210. switch(dwActionId) {
  211. case ACTION_PUSHBACK_CHAR:
  212. PushbackChar();
  213. break;
  214. case ACTION_PUSHBACK_2CHAR:
  215. PushbackChar();
  216. PushbackChar();
  217. _lexeme.PushBackChar();
  218. break;
  219. case ACTION_IGNORE_ESCAPECHAR:
  220. break;
  221. case ACTION_DEFAULT:
  222. _lexeme.PushNextChar(wcCurrChar);
  223. break;
  224. }
  225. if(_dwState >= FINAL_STATES_BEGIN)
  226. _lexeme.PushNextChar(L'\0');
  227. RRETURN (S_OK);
  228. }
  229. //+---------------------------------------------------------------------------
  230. // Function: CQryLexer::GetTokenFromState
  231. //
  232. // Synopsis:
  233. //
  234. // Arguments:
  235. //
  236. // Returns:
  237. //
  238. // Modifies:
  239. //
  240. // History: 07-09-96 ShankSh Created.
  241. //
  242. //----------------------------------------------------------------------------
  243. inline DWORD
  244. CQryLexer::GetTokenFromState(
  245. DWORD dwCurrState
  246. )
  247. {
  248. return (dwCurrState - FINAL_STATES_BEGIN);
  249. }
  250. //+---------------------------------------------------------------------------
  251. // Function: ~CQryLexer
  252. //
  253. // Synopsis:
  254. //
  255. // Arguments:
  256. //
  257. // Returns:
  258. //
  259. // Modifies:
  260. //
  261. // History: 07-09-96 ShankSh Created.
  262. //
  263. //----------------------------------------------------------------------------
  264. CQryLexer::~CQryLexer()
  265. {
  266. if( _Buffer )
  267. FreeADsMem (_Buffer);
  268. }
  269. //+---------------------------------------------------------------------------
  270. // Function: CLexeme
  271. //
  272. // Synopsis: Constructor: Allocate memory for the pattern and initialize
  273. //
  274. // Arguments:
  275. //
  276. // Returns:
  277. //
  278. // Modifies:
  279. //
  280. // History: 07-09-96 ShankSh Created.
  281. //
  282. //----------------------------------------------------------------------------
  283. CLexeme::CLexeme(
  284. ):
  285. _dwMaxLength(0),
  286. _dwIndex(0)
  287. {
  288. _pszLexeme = (LPWSTR) AllocADsMem(LEXEME_UNIT_LENGTH * sizeof(WCHAR));
  289. if(_pszLexeme)
  290. _dwMaxLength = LEXEME_UNIT_LENGTH;
  291. }
  292. //+---------------------------------------------------------------------------
  293. // Function: ~CLexeme
  294. //
  295. // Synopsis: Destructor
  296. //
  297. // Arguments:
  298. //
  299. // Returns:
  300. //
  301. // Modifies:
  302. //
  303. // History: 07-09-96 ShankSh Created.
  304. //
  305. //----------------------------------------------------------------------------
  306. inline CLexeme::~CLexeme(
  307. )
  308. {
  309. if(_pszLexeme)
  310. FreeADsMem(_pszLexeme);
  311. }
  312. //+---------------------------------------------------------------------------
  313. // Function: PushNextChar
  314. //
  315. // Synopsis: Add the next character after making sure there is enough memory
  316. //
  317. // Arguments:
  318. //
  319. // Returns:
  320. //
  321. // Modifies:
  322. //
  323. // History: 07-09-96 ShankSh Created.
  324. //
  325. //----------------------------------------------------------------------------
  326. HRESULT
  327. CLexeme::PushNextChar(
  328. WCHAR wcNextChar
  329. )
  330. {
  331. if(_dwIndex >= _dwMaxLength)
  332. {
  333. _pszLexeme = (LPWSTR) ReallocADsMem(
  334. _pszLexeme,
  335. _dwMaxLength * sizeof(WCHAR),
  336. (_dwMaxLength + LEXEME_UNIT_LENGTH) * sizeof(WCHAR)
  337. );
  338. BAIL_ON_NULL(_pszLexeme);
  339. _dwMaxLength += LEXEME_UNIT_LENGTH;
  340. }
  341. _pszLexeme[_dwIndex++] = wcNextChar;
  342. RRETURN (S_OK);
  343. error:
  344. RRETURN (E_FAIL);
  345. }
  346. HRESULT
  347. CLexeme::PushBackChar()
  348. {
  349. _pszLexeme[--_dwIndex] = '\0';
  350. RRETURN (S_OK);
  351. }
  352. //+---------------------------------------------------------------------------
  353. //
  354. // Function: RemoveWhiteSpaces
  355. //
  356. // Synopsis: Removes the leading and trailing white spaces
  357. //
  358. // Arguments: pszText Text strings from which the leading
  359. // and trailing white spaces are to be
  360. // removed
  361. //
  362. // Returns: LPWSTR Pointer to the modified string
  363. //
  364. // Modifies:
  365. //
  366. // History: 08-15-96 ShankSh Created.
  367. //
  368. //----------------------------------------------------------------------------
  369. LPWSTR
  370. RemoveWhiteSpaces(
  371. LPWSTR pszText)
  372. {
  373. LPWSTR pChar;
  374. if(!pszText)
  375. return (pszText);
  376. while(*pszText && iswspace(*pszText))
  377. pszText++;
  378. for(pChar = pszText + wcslen(pszText) - 1; pChar >= pszText; pChar--) {
  379. if(!iswspace(*pChar))
  380. break;
  381. else
  382. *pChar = L'\0';
  383. }
  384. return pszText;
  385. }