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.

294 lines
8.3 KiB

  1. // gc.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include "AssertWithStack.cpp"
  5. CSpUnicodeSupport g_Unicode;
  6. class CError : public ISpErrorLog
  7. {
  8. public:
  9. CError(const WCHAR * pszFileName)
  10. {
  11. m_pszFileName = pszFileName;
  12. }
  13. STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
  14. {
  15. if (riid == __uuidof(IUnknown) ||
  16. riid == __uuidof(ISpErrorLog))
  17. {
  18. *ppv = (ISpErrorLog *)this;
  19. return S_OK;
  20. }
  21. *ppv = NULL;
  22. return E_NOINTERFACE;
  23. }
  24. STDMETHODIMP_(ULONG) AddRef()
  25. {
  26. return 2;
  27. }
  28. STDMETHODIMP_(ULONG) Release()
  29. {
  30. return 1;
  31. }
  32. // -- ISpErrorLog
  33. STDMETHODIMP AddError(const long lLine, HRESULT hr, const WCHAR * pszDescription, const WCHAR * pszHelpFile, DWORD dwHelpContext);
  34. // --- data members
  35. const WCHAR * m_pszFileName;
  36. };
  37. HRESULT CError::AddError(const long lLine, HRESULT hr, const WCHAR * pszDescription, const WCHAR * pszHelpFile, DWORD dwHelpContext)
  38. {
  39. SPDBG_FUNC("CError::AddError");
  40. USES_CONVERSION;
  41. if (lLine > 0)
  42. {
  43. fprintf(stderr, "%s(%d) : %s\n", W2T(m_pszFileName), lLine, W2T(pszDescription));
  44. }
  45. else
  46. {
  47. fprintf(stderr, "%s(1) : %s\n", W2T(m_pszFileName), W2T(pszDescription));
  48. }
  49. return S_OK;
  50. }
  51. HRESULT ParseCommandLine(
  52. int argc,
  53. char * argv[],
  54. WCHAR ** pszInFileName,
  55. WCHAR ** pszOutFileName,
  56. WCHAR ** pszHeaderFileName)
  57. {
  58. SPDBG_FUNC("ParseCommandLine");
  59. HRESULT hr = S_OK;
  60. // Our job is to come up with the three filenames from the command
  61. // line arguments. We'll store them locally in cotask strings,
  62. // and return them at the end
  63. CSpDynamicString dstrInFileName;
  64. CSpDynamicString dstrOutFileName;
  65. CSpDynamicString dstrHeaderFileName;
  66. for (int i = 1; SUCCEEDED(hr) && i < argc; i++)
  67. {
  68. // If this param looks like it's an option
  69. if ((argv[i][0] == L'-') || (argv[i][0] == L'/'))
  70. {
  71. if (stricmp(&argv[i][1], "?") == 0)
  72. {
  73. // The invoker is asking for help, give it to them as if they specified an
  74. // invalid argument
  75. hr = E_INVALIDARG;
  76. }
  77. else if (i + 1 >= argc)
  78. {
  79. // The following arguments require an additional argument themsevles
  80. // so if we don't have one, we're done
  81. hr = E_INVALIDARG;
  82. }
  83. else if (stricmp(&argv[i][1], "o") == 0)
  84. {
  85. // Set the output filename if it hasn't already been set
  86. if (dstrOutFileName.Length() != 0)
  87. {
  88. hr = E_INVALIDARG;
  89. }
  90. dstrOutFileName = argv[++i];
  91. }
  92. else if (stricmp(&argv[i][1], "h") == 0)
  93. {
  94. // Set the header filename if it hasn't already been set
  95. if (dstrHeaderFileName.Length() != 0)
  96. {
  97. hr = E_INVALIDARG;
  98. }
  99. dstrHeaderFileName = argv[++i];
  100. }
  101. else
  102. {
  103. // Unknown option, we'll need to display usage
  104. hr = E_INVALIDARG;
  105. }
  106. }
  107. else
  108. {
  109. // Set the filename if it hasn't already been set
  110. if (dstrInFileName.Length() != 0)
  111. {
  112. hr = E_INVALIDARG;
  113. }
  114. dstrInFileName = argv[i];
  115. }
  116. }
  117. // If we don't have an input file name, that's an error at this point
  118. if (SUCCEEDED(hr) && dstrInFileName.Length() == 0)
  119. {
  120. hr = E_INVALIDARG;
  121. }
  122. // If we don't already have an output file name, make one up
  123. // based on the input file name (replacing the .cfg if it's there)
  124. if (SUCCEEDED(hr) && dstrOutFileName.Length() == 0)
  125. {
  126. dstrOutFileName = dstrInFileName;
  127. if (dstrOutFileName.Length() >= 4 &&
  128. wcsicmp(((const WCHAR *)dstrOutFileName) + dstrOutFileName.Length() - 4, L".xml") == 0)
  129. {
  130. wcscpy(((WCHAR *)dstrOutFileName) + dstrOutFileName.Length() - 4, L".cfg");
  131. }
  132. else
  133. {
  134. dstrOutFileName.Append(L".cfg");
  135. }
  136. }
  137. // If we failed above, we need to display usage
  138. if (FAILED(hr))
  139. {
  140. fprintf(stderr, "%s [/o cfg_filename] [/h header_filename] input_filename\n", argv[0]);
  141. }
  142. else
  143. {
  144. // Pass back our filenames based on what we saw on the command line
  145. *pszInFileName = dstrInFileName.Detach();
  146. *pszOutFileName = dstrOutFileName.Detach();
  147. *pszHeaderFileName = dstrHeaderFileName.Detach();
  148. }
  149. return hr;
  150. }
  151. HRESULT OpenFile(
  152. const WCHAR * pszFileName,
  153. DWORD dwDesiredAccess,
  154. DWORD dwCreationDisposition,
  155. const WCHAR * pszNewExtension,
  156. CSpFileStream ** ppFileStream)
  157. {
  158. SPDBG_FUNC("OpenFile");
  159. HRESULT hr = S_OK;
  160. // Try to open the file
  161. HANDLE hFile = g_Unicode.CreateFile(pszFileName, dwDesiredAccess, 0, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
  162. if (hFile == INVALID_HANDLE_VALUE)
  163. {
  164. // If that failed, try again appending the extension first
  165. if (pszNewExtension != NULL)
  166. {
  167. CSpDynamicString dstrFileNameWithExt;
  168. dstrFileNameWithExt.Append2(pszFileName, pszNewExtension);
  169. hFile = g_Unicode.CreateFile(dstrFileNameWithExt, dwDesiredAccess, 0, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
  170. }
  171. }
  172. // If we couldn't open the file, record the error
  173. if (hFile == INVALID_HANDLE_VALUE)
  174. {
  175. hr = SpHrFromLastWin32Error();
  176. }
  177. // Create a new filestream object for that file
  178. CSpFileStream * pFileStream;
  179. if (SUCCEEDED(hr))
  180. {
  181. *ppFileStream = new CSpFileStream(hFile);
  182. if (*ppFileStream == NULL)
  183. {
  184. hr = E_OUTOFMEMORY;
  185. }
  186. }
  187. // If we failed
  188. if (FAILED(hr))
  189. {
  190. // First we should let the invoker know that it failed
  191. USES_CONVERSION;
  192. fprintf(stderr, "Error: Error opening %s\n", W2T(pszFileName));
  193. if (hFile != INVALID_HANDLE_VALUE)
  194. {
  195. CloseHandle(hFile);
  196. }
  197. }
  198. return hr;
  199. }
  200. HRESULT Compile(const WCHAR * pszInFileName, const WCHAR * pszOutFileName, const WCHAR * pszHeaderFileName)
  201. {
  202. SPDBG_FUNC("Compile");
  203. HRESULT hr;
  204. CComPtr<ISpGrammarCompiler> cpCompiler;
  205. hr = cpCompiler.CoCreateInstance(CLSID_SpGrammarCompiler);
  206. CComPtr<CSpFileStream> cpInStream;
  207. if (SUCCEEDED(hr))
  208. {
  209. hr = OpenFile(pszInFileName, GENERIC_READ, OPEN_EXISTING, L".xml", &cpInStream);
  210. }
  211. CComPtr<CSpFileStream> cpOutStream;
  212. if (SUCCEEDED(hr))
  213. {
  214. hr = OpenFile(pszOutFileName, GENERIC_WRITE, CREATE_ALWAYS, NULL, &cpOutStream);
  215. }
  216. CComPtr<CSpFileStream> cpHeaderStream;
  217. if (SUCCEEDED(hr) && pszHeaderFileName != NULL)
  218. {
  219. hr = OpenFile(pszHeaderFileName, GENERIC_WRITE, CREATE_ALWAYS, NULL, &cpHeaderStream);
  220. }
  221. if (SUCCEEDED(hr))
  222. {
  223. CError errorlog(pszInFileName);
  224. hr = cpCompiler->CompileStream(cpInStream, cpOutStream, cpHeaderStream, NULL, &errorlog, 0);
  225. }
  226. return hr;
  227. }
  228. HRESULT Execute(int argc, char * argv[])
  229. {
  230. SPDBG_FUNC("Execute");
  231. HRESULT hr = S_OK;
  232. CSpDynamicString dstrInFileName, dstrOutFileName, dstrHeaderFileName;
  233. hr = ParseCommandLine(argc, argv, &dstrInFileName, &dstrOutFileName, &dstrHeaderFileName);
  234. if (SUCCEEDED(hr))
  235. {
  236. hr = Compile(dstrInFileName, dstrOutFileName, dstrHeaderFileName);
  237. }
  238. if (SUCCEEDED(hr))
  239. {
  240. fprintf(stderr, "Compilation successful!\n");
  241. }
  242. return hr;
  243. }
  244. int main(int argc, char* argv[])
  245. {
  246. SPDBG_FUNC("main");
  247. HRESULT hr;
  248. hr = CoInitialize(NULL);
  249. if (SUCCEEDED(hr))
  250. {
  251. hr = Execute(argc, argv);
  252. CoUninitialize();
  253. }
  254. return FAILED(hr) ? -1 : 0;
  255. }