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.

240 lines
4.2 KiB

  1. //*********************************************************************************************************************************************
  2. //
  3. // File: Parser.cpp
  4. // Author: Donald Drake
  5. // Purpose: Implements classes to support parsing tokens from a xml file
  6. #include "header.h"
  7. #include "stdio.h"
  8. #include "string.h"
  9. #include "TCHAR.h"
  10. #include "windows.h"
  11. #include "parser.h"
  12. DWORD CParseXML::Start(const CHAR *szFile)
  13. {
  14. m_fh = fopen(szFile, "r");
  15. if (m_fh == NULL)
  16. return F_NOFILE;
  17. if (SetError(Read()) != F_OK)
  18. return GetError();
  19. return F_OK;
  20. }
  21. void CParseXML::End()
  22. {
  23. if (m_fh != NULL)
  24. {
  25. fclose(m_fh);
  26. m_fh = NULL;
  27. }
  28. }
  29. DWORD CParseXML::Read()
  30. {
  31. if (fgets(m_cCurBuffer, MAX_LINE_LEN, m_fh) == NULL)
  32. {
  33. if (feof(m_fh))
  34. return F_EOF;
  35. return F_READ;
  36. }
  37. m_pCurrentIndex = m_cCurBuffer;
  38. return F_OK;
  39. }
  40. CHAR * CParseXML::GetFirstWord(CHAR *sz)
  41. {
  42. if (sz == NULL)
  43. return NULL;
  44. // ignore starting white space
  45. for (CHAR *pChar = sz; *pChar && *pChar== ' '; pChar = CharNext(pChar));
  46. memset(m_cCurWord, 0, MAX_LINE_LEN);
  47. CHAR *pWord = m_cCurWord;
  48. for (;*pChar && *pChar != ' ' && *pChar != '=' && *pChar != '\n' && *pChar != '\t' ;pChar = CharNext(pChar), pWord = CharNext(pWord))
  49. {
  50. *pWord = *pChar;
  51. if (IsDBCSLeadByte(*pChar))
  52. {
  53. *(pWord+1) = *(pChar+1);
  54. }
  55. }
  56. *pWord = NULL;
  57. return m_cCurWord;
  58. }
  59. CHAR * CParseXML::GetValue(CHAR *sz)
  60. {
  61. // get location of word value then find = sign
  62. CHAR *pChar;
  63. CHAR *p;
  64. p = sz;
  65. // BUGBUG temp hack to fix build, parser.cpp and parserhh.cpp will
  66. // soon be merged
  67. pChar = NULL;
  68. while (*p)
  69. {
  70. if ((*p == 'v' || *p == 'V') &&
  71. (*(p+1) == 'a' || *(p+1) == 'A') &&
  72. (*(p+2) == 'l' || *(p+2) == 'L') &&
  73. (*(p+3) == 'u' || *(p+3) == 'U') &&
  74. (*(p+4) == 'e' || *(p+4) == 'E'))
  75. {
  76. pChar = p;
  77. break;
  78. }
  79. p = CharNext(p);
  80. }
  81. // did not find the value tag
  82. if (pChar == NULL)
  83. return NULL;
  84. for (; *pChar && *pChar != '='; pChar = CharNext(pChar));
  85. if (*pChar == '=')
  86. {
  87. memset(m_cCurWord, 0, MAX_LINE_LEN);
  88. CHAR *pWord = m_cCurWord;
  89. // ignore white space
  90. pChar = CharNext(pChar);
  91. for (; *pChar && *pChar == ' '; pChar = CharNext(pChar));
  92. for ( ; *pChar ; pChar = CharNext(pChar))
  93. {
  94. if (*pChar == '/' && *(pChar+1) == NULL)
  95. break;
  96. if (*pChar != 34)
  97. {
  98. *pWord = *pChar;
  99. if (IsDBCSLeadByte(*pChar))
  100. {
  101. *(pWord+1) = *(pChar+1);
  102. }
  103. pWord = CharNext(pWord);
  104. }
  105. }
  106. *pWord = NULL;
  107. return m_cCurWord;
  108. }
  109. return NULL; // did not find the = sign
  110. }
  111. CHAR *CParseXML::GetToken()
  112. {
  113. // start looking for <
  114. while (TRUE)
  115. {
  116. if (*m_pCurrentIndex == NULL)
  117. {
  118. if (SetError(Read()) != F_OK)
  119. return NULL;
  120. }
  121. if (*m_pCurrentIndex != '<')
  122. {
  123. m_pCurrentIndex = CharNext(m_pCurrentIndex);
  124. continue;
  125. }
  126. // found a < skip it and start building the token
  127. memset(m_cCurToken, 0, MAX_LINE_LEN);
  128. CHAR *pWord = m_cCurToken;
  129. while (TRUE)
  130. {
  131. m_pCurrentIndex = CharNext(m_pCurrentIndex);
  132. if (*m_pCurrentIndex == NULL)
  133. if (SetError(Read()) != F_OK)
  134. return NULL;
  135. if (*m_pCurrentIndex == '>')
  136. {
  137. m_pCurrentIndex = CharNext(m_pCurrentIndex);
  138. return m_cCurToken;
  139. }
  140. *pWord = *m_pCurrentIndex;
  141. if (IsDBCSLeadByte(*m_pCurrentIndex))
  142. {
  143. *(pWord+1) = *(m_pCurrentIndex+1);
  144. }
  145. pWord = CharNext(pWord);
  146. }
  147. }
  148. }
  149. // class to support a FIFO queue of strings
  150. void CFIFOString::RemoveAll()
  151. {
  152. FIFO *prev;
  153. while (m_fifoTail)
  154. {
  155. prev = m_fifoTail->prev;
  156. delete [] m_fifoTail->string;
  157. delete m_fifoTail;
  158. m_fifoTail = prev;
  159. }
  160. }
  161. CFIFOString::~CFIFOString()
  162. {
  163. RemoveAll();
  164. }
  165. DWORD CFIFOString::AddTail(CHAR *sz)
  166. {
  167. FIFO *entry;
  168. int len;
  169. entry = new FIFO;
  170. if (entry == NULL)
  171. return F_MEMORY;
  172. len = (int)_tcslen(sz) + 1;
  173. entry->string = new CHAR[len];
  174. _tcscpy(entry->string, sz);
  175. entry->prev = NULL;
  176. if (m_fifoTail)
  177. {
  178. entry->prev = m_fifoTail;
  179. }
  180. m_fifoTail = entry;
  181. return F_OK;
  182. }
  183. DWORD CFIFOString::GetTail(CHAR **sz)
  184. {
  185. int len;
  186. FIFO *entry;
  187. if (m_fifoTail == NULL)
  188. return F_END;
  189. len = (int)_tcslen(m_fifoTail->string) + 1;
  190. *sz= new CHAR[len];
  191. if (*sz == NULL)
  192. return F_MEMORY;
  193. _tcscpy(*sz, m_fifoTail->string);
  194. entry = m_fifoTail->prev;
  195. delete [] m_fifoTail->string;
  196. delete m_fifoTail;
  197. m_fifoTail = entry;
  198. return F_OK;
  199. }