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.

364 lines
12 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. mc.c
  5. Abstract:
  6. This is the main source file for the Win32 Message Compiler (MC)
  7. Author:
  8. Steve Wood (stevewo) 21-Aug-1991
  9. Revision History:
  10. --*/
  11. #include "mc.h"
  12. #include "version.h"
  13. #include <ntverp.h>
  14. #include <common.ver>
  15. NAME_INFO DefaultLanguageName;
  16. int UnicodeOutput=TRUE;
  17. BOOL fUniqueBinName = FALSE;
  18. void
  19. ConvertAppToOem( unsigned argc, char* argv[] )
  20. /*++
  21. Routine Description:
  22. Converts the command line from ANSI to OEM, and force the app
  23. to use OEM APIs
  24. Arguments:
  25. argc - Standard C argument count.
  26. argv - Standard C argument strings.
  27. Return Value:
  28. None.
  29. --*/
  30. {
  31. unsigned i;
  32. for (i = 0; i < argc; i++ ) {
  33. CharToOem( argv[i], argv[i] );
  34. }
  35. SetFileApisToOEM();
  36. }
  37. void
  38. InitializeMCNls( void );
  39. void
  40. McPrintUsage( void )
  41. {
  42. fprintf(stderr,
  43. "Microsoft (R) Message Compiler Version 1.12.%04d\n"
  44. VER_LEGALCOPYRIGHT_STR
  45. "\n\n",
  46. VER_PRODUCTBUILD);
  47. fputs("usage: MC [-?aAcdnosuUvw] [-m maxmsglen] [-h dirspec] [-e extension] [-r dirspec] [-x dbgFileSpec] filename.mc\n"
  48. " -? - displays this message\n"
  49. " -a - input file is ANSI (default).\n"
  50. " -A - messages in .BIN file should be ANSI.\n"
  51. " -b - .BIN filename should have .mc filename_ included for uniqueness.\n"
  52. " -c - sets the Customer bit in all the message Ids.\n"
  53. " -d - FACILTY and SEVERITY values in header file in decimal.\n"
  54. " Sets message values in header to decimal initially.\n"
  55. " -e extension - Specify the extension for the header file.\n"
  56. " From 1 - 3 chars.\n"
  57. " -h pathspec - gives the path of where to create the C include file\n"
  58. " Default is .\\\n"
  59. " -m maxmsglen - generate a warning if the size of any message exceeds\n"
  60. " maxmsglen characters.\n"
  61. " -n - terminates all strings with null's in the message tables.\n"
  62. " -o - generate OLE2 header file (use HRESULT definition instead of\n"
  63. " status code definition)\n"
  64. " -r pathspec - gives the path of where to create the RC include file\n"
  65. " and the binary message resource files it includes.\n"
  66. " Default is .\\\n"
  67. " -s - insert symbolic name as first line of each message.\n"
  68. " -u - input file is Unicode.\n"
  69. " -U - messages in .BIN file should be Unicode (default).\n"
  70. " -v - gives verbose output.\n"
  71. " -w - warns if message text contains non-OS/2 compatible inserts.\n"
  72. " -x pathspec - gives the path of where to create the .dbg C include\n"
  73. " file that maps message Ids to their symbolic name.\n"
  74. " filename.mc - gives the names of a message text file\n"
  75. " to compile.\n"
  76. " Generated files have the Archive bit cleared.\n",
  77. stderr);
  78. }
  79. int
  80. __cdecl main(
  81. int argc,
  82. char *argv[]
  83. )
  84. {
  85. char c, *s, *s1;
  86. int i;
  87. int ShowUsage;
  88. setlocale(LC_ALL, "");
  89. if (argc == 1) {
  90. McPrintUsage();
  91. exit(1);
  92. }
  93. ConvertAppToOem( argc, argv );
  94. // Initialize CurrentLanguageName
  95. DefaultLanguageName.CodePage = GetOEMCP();
  96. CurrentLanguageName = &DefaultLanguageName;
  97. CurrentFacilityName =
  98. McAddName( &FacilityNames, L"Application", 0x0, NULL );
  99. CurrentSeverityName =
  100. McAddName( &SeverityNames, L"Success", 0x0, NULL );
  101. McAddName( &SeverityNames, L"Informational", 0x1, NULL );
  102. McAddName( &SeverityNames, L"Warning", 0x2, NULL );
  103. McAddName( &SeverityNames, L"Error", 0x3, NULL );
  104. McAddName( &LanguageNames,
  105. L"English",
  106. MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  107. L"MSG00001"
  108. );
  109. strcpy( DebugFileName, ".\\" );
  110. strcpy( HeaderFileName, ".\\" );
  111. strcpy( HeaderFileExt, "h" );
  112. strcpy( RcInclFileName, ".\\" );
  113. strcpy( BinaryMessageFileName, ".\\" );
  114. MessageFileName[ 0 ] = '\0';
  115. McInitLexer();
  116. NULLTerminate = FALSE;
  117. VerboseOutput = FALSE;
  118. WarnOs2Compatible = FALSE;
  119. GenerateDecimalSevAndFacValues = FALSE;
  120. GenerateDecimalMessageValues = FALSE;
  121. GenerateDebugFile = FALSE;
  122. MaxMessageLength = 0; // No limit
  123. ShowUsage = FALSE;
  124. while (--argc) {
  125. s = *++argv;
  126. if (*s == '-' || *s == '/') {
  127. while (c = *++s) {
  128. switch( tolower( c ) ) {
  129. case '?':
  130. McPrintUsage();
  131. exit( 0 );
  132. break;
  133. case 'a':
  134. if (c == 'a') {
  135. UnicodeInput = FALSE;
  136. } else {
  137. UnicodeOutput = FALSE;
  138. }
  139. break;
  140. case 'b':
  141. fUniqueBinName = TRUE;
  142. break;
  143. case 'c':
  144. CustomerMsgIdBit = 0x1 << 29;
  145. break;
  146. case 'd':
  147. GenerateDecimalSevAndFacValues = TRUE;
  148. GenerateDecimalMessageValues = TRUE;
  149. break;
  150. case 'e':
  151. if (--argc) {
  152. strcpy( HeaderFileExt, *++argv );
  153. i = strlen( HeaderFileExt );
  154. if ((i < 1) || (i > 3) || (*HeaderFileExt == '.')) {
  155. fprintf( stderr, "MC: invalid argument for -%c switch\n", (USHORT)c );
  156. ShowUsage = TRUE;
  157. }
  158. } else {
  159. argc++;
  160. fprintf( stderr, "MC: missing argument for -%c switch\n", (USHORT)c );
  161. ShowUsage = TRUE;
  162. }
  163. break;
  164. case 'h':
  165. if (--argc) {
  166. strcpy( s1 = HeaderFileName, *++argv );
  167. // s1 += strlen( s1 ) - 1;
  168. s1 += strlen(s1);
  169. s1 = CharPrev( HeaderFileName, s1 );
  170. if (*s1 != '\\' && *s1 != '/') {
  171. // *++s1 = '\\';
  172. s1 = CharNext( s1 );
  173. *s1 = '\\';
  174. *++s1 = '\0';
  175. }
  176. } else {
  177. argc++;
  178. fprintf( stderr, "MC: missing argument for -%c switch\n", (USHORT)c );
  179. ShowUsage = TRUE;
  180. }
  181. break;
  182. case 'm':
  183. if (--argc) {
  184. MaxMessageLength = atoi(*++argv);
  185. if (MaxMessageLength <= 0) {
  186. fprintf( stderr, "MC: invalid argument (%s) for -%c switch\n", *argv, (USHORT)c );
  187. ShowUsage = TRUE;
  188. }
  189. } else {
  190. argc++;
  191. fprintf( stderr, "MC: missing argument for -%c switch\n", (USHORT)c );
  192. ShowUsage = TRUE;
  193. }
  194. break;
  195. case 'n':
  196. NULLTerminate = TRUE;
  197. break;
  198. case 'o':
  199. OleOutput = TRUE;
  200. break;
  201. case 'r':
  202. if (--argc) {
  203. strcpy( s1 = RcInclFileName, *++argv );
  204. // s1 += strlen( s1 ) - 1;
  205. s1 += strlen( s1 );
  206. s1 = CharPrev( HeaderFileName, s1 );
  207. if (*s1 != '\\' && *s1 != '/') {
  208. // *++s1 = '\\';
  209. s1 = CharNext( s1 );
  210. *s1 = '\\';
  211. *++s1 = '\0';
  212. }
  213. strcpy( BinaryMessageFileName, RcInclFileName );
  214. } else {
  215. argc++;
  216. fprintf( stderr, "MC: missing argument for -%c switch\n", (USHORT)c );
  217. ShowUsage = TRUE;
  218. }
  219. break;
  220. case 's':
  221. InsertSymbolicName = TRUE;
  222. break;
  223. case 'u':
  224. if (c == 'u') {
  225. UnicodeInput = TRUE;
  226. } else {
  227. UnicodeOutput = TRUE;
  228. }
  229. break;
  230. case 'v':
  231. VerboseOutput = TRUE;
  232. break;
  233. case 'w':
  234. WarnOs2Compatible = TRUE;
  235. break;
  236. case 'x':
  237. if (--argc) {
  238. strcpy( s1 = DebugFileName, *++argv );
  239. // s1 += strlen( s1 ) - 1;
  240. s1 += strlen( s1 );
  241. s1 = CharPrev( HeaderFileName, s1 );
  242. if (*s1 != '\\' && *s1 != '/') {
  243. // *++s1 = '\\';
  244. s1 = CharNext( s1 );
  245. *s1 = '\\';
  246. *++s1 = '\0';
  247. }
  248. GenerateDebugFile = TRUE;
  249. } else {
  250. argc++;
  251. fprintf( stderr, "MC: missing argument for -%c switch\n", (USHORT)c );
  252. ShowUsage = TRUE;
  253. }
  254. break;
  255. default:
  256. fprintf( stderr, "MC: Invalid switch: %c\n", (USHORT)c );
  257. ShowUsage = TRUE;
  258. break;
  259. }
  260. }
  261. } else if (strlen( MessageFileName )) {
  262. fprintf( stderr, "MC: may only specify one message file to compile.\n" );
  263. ShowUsage = TRUE;
  264. } else {
  265. strcpy( MessageFileName, s );
  266. }
  267. }
  268. if (ShowUsage) {
  269. McPrintUsage();
  270. exit( 1 );
  271. }
  272. if (fUniqueBinName) {
  273. _splitpath(MessageFileName, NULL, NULL, FNameMsgFileName, NULL);
  274. strcat(BinaryMessageFileName, FNameMsgFileName);
  275. strcat(BinaryMessageFileName, "_");
  276. }
  277. if (UnicodeInput) {
  278. if (!IsFileUnicode( MessageFileName )) {
  279. fprintf( stderr, "MC: -u switch cannot be used with non-Unicode message file!\n" );
  280. exit( 1 );
  281. }
  282. } else {
  283. if (IsFileUnicode( MessageFileName )) {
  284. fprintf( stderr, "MC: -u switch must be used with Unicode message file!\n" );
  285. exit( 1 );
  286. }
  287. }
  288. InputErrorCount = 0;
  289. ResultCode = 1;
  290. if (McParseFile() && McBlockMessages() &&
  291. (UnicodeOutput ? McWriteBinaryFilesW() : McWriteBinaryFilesA())) {
  292. if (InputErrorCount == 0) {
  293. ResultCode = 0;
  294. }
  295. }
  296. McCloseInputFile();
  297. McCloseOutputFiles((BOOL)(ResultCode == 0));
  298. return( ResultCode );
  299. }