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.

320 lines
8.1 KiB

  1. //---------------------------------------------------------------------------
  2. // Scanner.cpp - supports parsing general text files & lines with
  3. // a ";" style comment (rest of line is comment)
  4. //---------------------------------------------------------------------------
  5. #include "stdafx.h"
  6. #include "scanner.h"
  7. #include "utils.h"
  8. //---------------------------------------------------------------------------
  9. CScanner::CScanner(LPCWSTR pszTextToScan)
  10. {
  11. ResetAll(FALSE);
  12. _p = pszTextToScan;
  13. _pSymbol = NULL;
  14. }
  15. //---------------------------------------------------------------------------
  16. CScanner::~CScanner()
  17. {
  18. ResetAll(TRUE);
  19. }
  20. //---------------------------------------------------------------------------
  21. void CScanner::UseSymbol(LPCWSTR pszSymbol)
  22. {
  23. if (pszSymbol == NULL)
  24. {
  25. if (_pSymbol && *_p)
  26. {
  27. _p = _pSymbol;
  28. }
  29. _pSymbol = NULL;
  30. }
  31. else
  32. {
  33. _pSymbol = _p;
  34. _p = pszSymbol;
  35. }
  36. }
  37. //---------------------------------------------------------------------------
  38. BOOL CScanner::ReadNextLine()
  39. {
  40. if ((! _pszMultiLineBuffer) || (! *_pszMultiLineBuffer)) // end of multiple lines
  41. {
  42. _fEndOfFile = TRUE;
  43. return FALSE;
  44. }
  45. WCHAR *q = _szLineBuff;
  46. while ((*_pszMultiLineBuffer) && (*_pszMultiLineBuffer != '\r') && (*_pszMultiLineBuffer != '\n'))
  47. *q++ = *_pszMultiLineBuffer++;
  48. *q = 0;
  49. if (*_pszMultiLineBuffer == '\r')
  50. _pszMultiLineBuffer++;
  51. if (*_pszMultiLineBuffer == '\n')
  52. _pszMultiLineBuffer++;
  53. _p = _szLineBuff;
  54. _fBlankSoFar = TRUE;
  55. _iLineNum++;
  56. return TRUE;
  57. }
  58. //---------------------------------------------------------------------------
  59. BOOL CScanner::SkipSpaces()
  60. {
  61. while (1)
  62. {
  63. while (IsSpace(*_p))
  64. _p++;
  65. if ((! *_p) || (*_p == ';')) // end of line
  66. {
  67. if ((_fBlankSoFar) && (! _fEndOfFile))
  68. {
  69. ReadNextLine();
  70. continue;
  71. }
  72. if (*_p == ';') // comment
  73. _p += lstrlen(_p); // skip to end of line
  74. return FALSE;
  75. }
  76. //---- good chars on this line ----
  77. _fBlankSoFar = FALSE;
  78. break;
  79. }
  80. return (*_p != 0);
  81. }
  82. //---------------------------------------------------------------------------
  83. BOOL CScanner::GetId(LPWSTR pszIdBuff, DWORD cchIdBuff)
  84. {
  85. if (! cchIdBuff) // must have at least 1 space for NULL terminator
  86. return FALSE;
  87. SkipSpaces();
  88. WCHAR *v = pszIdBuff;
  89. while ((IsNameChar(FALSE)) && (--cchIdBuff))
  90. *v++ = *_p++;
  91. *v = 0;
  92. if (v == pszIdBuff) // no chars found
  93. return FALSE;
  94. if (IsNameChar(FALSE)) // ran out of room
  95. return FALSE;
  96. return TRUE;
  97. }
  98. //---------------------------------------------------------------------------
  99. BOOL CScanner::GetIdPair(LPWSTR pszIdBuff, LPWSTR pszValueBuff, DWORD cchValueBuff)
  100. {
  101. if (! cchValueBuff) // must have at least 1 space for NULL terminator
  102. return FALSE;
  103. if (!GetId(pszIdBuff, cchValueBuff))
  104. return FALSE;
  105. if (!GetChar('='))
  106. return FALSE;
  107. SkipSpaces();
  108. // Take everything until the end of line
  109. SafeStringCchCopyW(pszValueBuff, cchValueBuff, _p);
  110. return TRUE;
  111. }
  112. //---------------------------------------------------------------------------
  113. BOOL CScanner::GetFileName(LPWSTR pszFileNameBuff, DWORD cchFileNameBuff)
  114. {
  115. if (! cchFileNameBuff) // must have at least 1 space for NULL terminator
  116. return FALSE;
  117. SkipSpaces();
  118. WCHAR *v = pszFileNameBuff;
  119. while ((IsFileNameChar(FALSE)) && (--cchFileNameBuff))
  120. *v++ = *_p++;
  121. *v = 0;
  122. if (v == pszFileNameBuff) // no chars found
  123. return FALSE;
  124. if (IsFileNameChar(FALSE)) // ran out of room
  125. return FALSE;
  126. return TRUE;
  127. }
  128. //---------------------------------------------------------------------------
  129. BOOL CScanner::GetNumber(int *piVal)
  130. {
  131. SkipSpaces();
  132. if (! IsNumStart())
  133. return FALSE;
  134. *piVal = string2number(_p);
  135. if ((_p[0] == '0') && ((_p[1] == 'x') || (_p[1] == 'X'))) // hex num
  136. _p += 2;
  137. else
  138. _p++; // skip over digit or sign
  139. //---- skip over number ---
  140. while (IsHexDigit(*_p))
  141. _p++;
  142. return TRUE;
  143. }
  144. //---------------------------------------------------------------------------
  145. BOOL CScanner::IsNameChar(BOOL fOkToSkip)
  146. {
  147. if (fOkToSkip)
  148. SkipSpaces();
  149. return ((IsCharAlphaNumericW(*_p)) || (*_p == '_') || (*_p == '-'));
  150. }
  151. //---------------------------------------------------------------------------
  152. BOOL CScanner::IsFileNameChar(BOOL fOkToSkip)
  153. {
  154. if (fOkToSkip)
  155. SkipSpaces();
  156. return ((IsCharAlphaNumericW(*_p)) || (*_p == '_') || (*_p == '-') ||
  157. (*_p == ':') || (*_p == '\\') || (*_p == '.'));
  158. }
  159. //---------------------------------------------------------------------------
  160. BOOL CScanner::IsNumStart()
  161. {
  162. SkipSpaces();
  163. return ((IsDigit(*_p)) || (*_p == '-') || (*_p == '+'));
  164. }
  165. //---------------------------------------------------------------------------
  166. BOOL CScanner::GetChar(const WCHAR val)
  167. {
  168. SkipSpaces();
  169. if (*_p != val)
  170. return FALSE;
  171. _p++; // skip over WCHAR
  172. return TRUE;
  173. }
  174. //---------------------------------------------------------------------------
  175. BOOL CScanner::GetKeyword(LPCWSTR pszKeyword)
  176. {
  177. BOOL fRet = FALSE;
  178. SkipSpaces();
  179. if( _p )
  180. {
  181. int cch = lstrlenW(pszKeyword);
  182. LPWSTR psz = new WCHAR[cch + 1];
  183. if (psz)
  184. {
  185. StringCchCopyW(psz, cch + 1, _p);
  186. if (AsciiStrCmpI(psz, pszKeyword)==0)
  187. {
  188. _p += cch;
  189. fRet = TRUE;
  190. }
  191. delete [] psz;
  192. }
  193. }
  194. return fRet;
  195. }
  196. //---------------------------------------------------------------------------
  197. BOOL CScanner::EndOfLine()
  198. {
  199. SkipSpaces();
  200. return (*_p == 0);
  201. }
  202. //---------------------------------------------------------------------------
  203. BOOL CScanner::EndOfFile()
  204. {
  205. return _fEndOfFile;
  206. }
  207. //---------------------------------------------------------------------------
  208. BOOL CScanner::AttachLine(LPCWSTR pszLine)
  209. {
  210. ResetAll(TRUE);
  211. _p = pszLine;
  212. return TRUE;
  213. }
  214. //---------------------------------------------------------------------------
  215. BOOL CScanner::AttachMultiLineBuffer(LPCWSTR pszBuffer, LPCWSTR pszFileName)
  216. {
  217. ResetAll(TRUE);
  218. _p = _szLineBuff;
  219. _pszMultiLineBuffer = pszBuffer;
  220. SafeStringCchCopyW(_szFileName, ARRAYSIZE(_szFileName), pszFileName);
  221. return TRUE;
  222. }
  223. //---------------------------------------------------------------------------
  224. HRESULT CScanner::AttachFile(LPCWSTR pszFileName)
  225. {
  226. ResetAll(TRUE);
  227. HRESULT hr = AllocateTextFile(pszFileName, &_pszFileText, NULL);
  228. if (FAILED(hr))
  229. return hr;
  230. _pszMultiLineBuffer = _pszFileText;
  231. SafeStringCchCopyW(_szFileName, ARRAYSIZE(_szFileName), pszFileName);
  232. return S_OK;
  233. }
  234. //---------------------------------------------------------------------------
  235. void CScanner::ResetAll(BOOL fPossiblyAllocated)
  236. {
  237. _iLineNum = 0;
  238. _fEndOfFile = FALSE;
  239. _pszMultiLineBuffer = NULL;
  240. _fUnicodeInput = TRUE;
  241. _fBlankSoFar = TRUE;
  242. *_szFileName = 0;
  243. *_szLineBuff = 0;
  244. _p = _szLineBuff;
  245. if (fPossiblyAllocated)
  246. {
  247. if (_pszFileText)
  248. {
  249. LocalFree(_pszFileText);
  250. _pszFileText = NULL;
  251. }
  252. }
  253. else
  254. _pszFileText = NULL;
  255. }
  256. //---------------------------------------------------------------------------
  257. BOOL CScanner::ForceNextLine()
  258. {
  259. ReadNextLine();
  260. if (! SkipSpaces())
  261. return FALSE;
  262. return TRUE;
  263. }
  264. //---------------------------------------------------------------------------