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.

444 lines
12 KiB

  1. /** Microsoft LAN Manager **/
  2. /** Copyright(c) Microsoft Corp., 1987-1999 **/
  3. /*****************************************************************************/
  4. /*****************************************************************************
  5. File : main.cxx
  6. Title : compiler controller object management routines
  7. History :
  8. 05-Aug-1991 VibhasC Created
  9. *****************************************************************************/
  10. #if 0
  11. Notes
  12. -----
  13. This file provides the entry point for the MIDL compiler. The main routine
  14. creates the compiler controller object, which in turn fans out control to
  15. the various passes of the compiler.
  16. #endif // 0
  17. #pragma warning ( disable : 4514 )
  18. /****************************************************************************
  19. includes
  20. ****************************************************************************/
  21. #include "nulldefs.h"
  22. extern "C" {
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <malloc.h>
  26. #include <excpt.h>
  27. #include <process.h>
  28. #include <io.h>
  29. #include <fcntl.h>
  30. #include <sys/types.h>
  31. #include <sys/stat.h>
  32. }
  33. #include "allnodes.hxx"
  34. #include "cmdana.hxx"
  35. #include "filehndl.hxx"
  36. #include "lextable.hxx"
  37. #include "control.hxx"
  38. #include "idict.hxx"
  39. #include "Pragma.hxx"
  40. #include "midlvers.h"
  41. extern unsigned long BackAllocation;
  42. extern unsigned long Skl_Bytes;
  43. #define MAX_LEX_STRINGS (1000)
  44. #define MIDL_LEX_TABLE_SIZE (unsigned long)(1 * MAX_LEX_STRINGS)
  45. #ifdef MIDL_INTERNAL
  46. #define MIDL_FREE_BUILD 0
  47. #define MIDL_INTERNAL_PRINTF(x) printf(x)
  48. #else
  49. #define MIDL_FREE_BUILD 1
  50. #define MIDL_INTERNAL_PRINTF(x)
  51. #endif
  52. /****************************************************************************
  53. extern procedures
  54. ****************************************************************************/
  55. extern void Test();
  56. extern STATUS_T MIDL_4();
  57. extern void CGMain( node_skl * pNode );
  58. extern void Ndr64CGMain( node_skl * pNode );
  59. /****************************************************************************
  60. extern data
  61. ****************************************************************************/
  62. extern unsigned long TotalAllocation;
  63. extern CCONTROL * pCompiler;
  64. extern NFA_INFO * pImportCntrl;
  65. extern LexTable * pMidlLexTable;
  66. extern PASS_1 * pPass1;
  67. extern PASS_2 * pPass2;
  68. extern PASS_3 * pPass3;
  69. extern CMD_ARG * pCommand;
  70. extern node_source * pSourceNode;
  71. extern BOOL fNoLogo;
  72. extern CMessageNumberList GlobalMainMessageNumberList;
  73. /****************************************************************************
  74. extern functions
  75. ****************************************************************************/
  76. extern void print_memstats();
  77. extern void print_typegraph();
  78. /****************************************************************************
  79. local data
  80. ****************************************************************************/
  81. #define szVerName ""
  82. const char *pSignon1 = "Microsoft (R) 32b/64b MIDL Compiler Engine Version %s " szVerName " " "\n";
  83. const char *pSignon2 = "Copyright (c) Microsoft Corp 1991-1999. All rights reserved.\n";
  84. /****************************************************************************/
  85. void
  86. DumpArgs(
  87. int argc,
  88. char * argv[],
  89. char * Comment )
  90. {
  91. printf("Dumping args %s\n", Comment );
  92. for (int i = 0; i < argc && argv[i]; i++ )
  93. printf(" %s\n", argv[i] );
  94. }
  95. /****************************************************************************
  96. Read the command file into a in-memory buffer.
  97. The pointer returned is a pointer to the contents of the command file.
  98. To aid debugging the size of the file is tucked away just in front of it.
  99. ****************************************************************************/
  100. char * ReadCommandFile(const char *pszFilename)
  101. {
  102. int fileCmd = -1;
  103. struct _stat filestat = {0};
  104. char *Buffer = NULL;
  105. int bytesread;
  106. fileCmd = _open( pszFilename, _O_BINARY | _O_RDONLY | _O_SEQUENTIAL );
  107. if ( -1 == fileCmd )
  108. goto Error;
  109. if ( -1 == _fstat( fileCmd, &filestat ) )
  110. goto Error;
  111. Buffer = new char[filestat.st_size + sizeof(filestat.st_size)];
  112. // Tuck away the size of the buffer to make debugging easier
  113. * (_off_t *) Buffer = filestat.st_size;
  114. Buffer += sizeof( _off_t );
  115. bytesread = _read( fileCmd, Buffer, filestat.st_size );
  116. if ( bytesread != filestat.st_size )
  117. goto Error;
  118. _close(fileCmd);
  119. return Buffer;
  120. Error:
  121. if (NULL != Buffer)
  122. delete [] (Buffer - sizeof(_off_t));
  123. if (-1 != fileCmd )
  124. _close( fileCmd );
  125. char message[1024];
  126. sprintf(message, ": %s (%s)", _strerror(NULL), pszFilename);
  127. // _strerror embeds a newline in the error string, get rid of it
  128. * ( strchr( message, '\n') ) = ' ';
  129. RpcError( 0, 0, UNABLE_TO_OPEN_CMD_FILE, message );
  130. return NULL;
  131. }
  132. /****************************************************************************
  133. If the command file is corrupt do a hex dump of (up to) the first
  134. 256 bytes of the file to aid in finding out what whacked it.
  135. REVIEW: This was intended to be a temporary feature. It may be useful
  136. to just leave it in.
  137. ****************************************************************************/
  138. void HexDumpCommandFile(char *buffer)
  139. {
  140. _off_t length = * (_off_t *) (buffer - sizeof(_off_t));
  141. _off_t bytes = 0;
  142. for (int i = 0; i < 16 && bytes < length; i++)
  143. {
  144. printf("%02x: ", i * 16);
  145. for ( int j = 0; j < 16 && bytes < length; j++)
  146. {
  147. printf( "%02x ", buffer[i*16+j] );
  148. ++bytes;
  149. }
  150. for ( int k = j; k < 16; k++ )
  151. printf(" ");
  152. for ( int l = 0; l < j; l++ )
  153. if ( iscntrl( buffer[i*16+l] ) )
  154. putchar( '.' );
  155. else
  156. putchar( buffer[i*16+l] );
  157. printf("\n");
  158. }
  159. }
  160. /****************************************************************************
  161. If this is a fre build and the -debugexc switch is *not* present then
  162. catch any exceptions and shutdown MIDL at least semi-gracefully. Otherwise
  163. allow the system to throw up a popup / enter a debugger / etc to make
  164. debugging easier.
  165. In any case print a message saying that something bad happened.
  166. ****************************************************************************/
  167. int FilterException()
  168. {
  169. printf( "\nmidl : error MIDL%d : internal compiler problem -",
  170. I_ERR_UNEXPECTED_INTERNAL_PROBLEM );
  171. printf( " See documentation for suggestions on how to find a workaround.\n" );
  172. #if MIDL_FREE_BUILD
  173. if ( ! pCommand->IsSwitchDefined( SWITCH_DEBUGEXC ) )
  174. return EXCEPTION_EXECUTE_HANDLER;
  175. #endif
  176. return EXCEPTION_CONTINUE_SEARCH;
  177. }
  178. int
  179. main (
  180. int argc,
  181. char* argv[]
  182. )
  183. {
  184. STATUS_T Status = UNABLE_TO_OPEN_CMD_FILE;
  185. pCommand = new CMD_ARG;
  186. __try
  187. {
  188. if ( argc != 2 )
  189. {
  190. char szCompilerVersion[32];
  191. Status = NO_INTERMEDIATE_FILE;
  192. sprintf( szCompilerVersion, "%d.%02d.%04d", rmj, rmm, rup );
  193. fprintf( stderr, pSignon1, szCompilerVersion );
  194. fprintf( stderr, pSignon2 );
  195. fflush( stderr );
  196. RpcError( 0, 0, Status, 0 );
  197. }
  198. else
  199. {
  200. char *Buffer;
  201. Buffer = ReadCommandFile( argv[1] );
  202. if ( NULL != Buffer )
  203. Status = pCommand->StreamIn( Buffer );
  204. switch (Status)
  205. {
  206. case STATUS_OK:
  207. pCompiler = new ccontrol( pCommand );
  208. Status = pCompiler->Go();
  209. break;
  210. case BAD_CMD_FILE:
  211. RpcError( 0, 0, Status, argv[1] );
  212. HexDumpCommandFile( Buffer );
  213. break;
  214. case UNABLE_TO_OPEN_CMD_FILE:
  215. // This should have been reported in ReadCommandFile
  216. break;
  217. default:
  218. RpcError( 0, 0, Status, NULL );
  219. }
  220. if ( NULL != Buffer )
  221. {
  222. // The buffer was biased by it's size to make debugging easier.
  223. delete [] (Buffer - sizeof(_off_t));
  224. }
  225. }
  226. }
  227. __except( FilterException() )
  228. {
  229. // The real work is done in FilterException
  230. Status = (STATUS_T) GetExceptionCode();
  231. }
  232. return Status;
  233. }
  234. /****************************************************************************
  235. ccontrol:
  236. the constructor
  237. ****************************************************************************/
  238. ccontrol::ccontrol( CMD_ARG* pCommand )
  239. {
  240. // initialize
  241. ErrorCount = 0;
  242. pCompiler = this;
  243. // set up the command processor
  244. SetCommandProcessor( pCommand );
  245. // set up the lexeme table
  246. pMidlLexTable = new LexTable( (size_t )MIDL_LEX_TABLE_SIZE );
  247. }
  248. _inline void
  249. DumpStatsTypeGraph()
  250. {
  251. #ifdef MIDL_INTERNAL
  252. if((pCompiler->GetCommandProcessor())->IsSwitchDefined( SWITCH_DUMP ) )
  253. {
  254. print_memstats();
  255. print_typegraph();
  256. };
  257. #endif
  258. }
  259. /****************************************************************************
  260. go:
  261. the actual compiler execution
  262. ****************************************************************************/
  263. STATUS_T
  264. ccontrol::Go()
  265. {
  266. STATUS_T Status = STATUS_OK;
  267. pPass1 = new PASS_1;
  268. if( (Status = pPass1->Go() ) == STATUS_OK )
  269. {
  270. MIDL_INTERNAL_PRINTF( "starting ACF pass\n" );
  271. pPass2 = new PASS_2;
  272. if( (Status = pPass2->Go() ) == STATUS_OK )
  273. {
  274. // DumpStatsTypeGraph();
  275. MIDL_INTERNAL_PRINTF( "starting Semantic pass\n" );
  276. GlobalMainMessageNumberList.SetAll();
  277. pPass3 = new PASS_3;
  278. if ( ( (Status = pPass3->Go() ) == STATUS_OK )
  279. #ifdef MIDL_INTERNAL
  280. || pCommand->IsSwitchDefined( SWITCH_OVERRIDE )
  281. #endif // MIDL_INTERNAL
  282. )
  283. {
  284. DumpStatsTypeGraph();
  285. // Complain if the user used -wire_compat. Put it here so
  286. // that they can turn it off with midl_pragma if they want to.
  287. if ( pCommand->IsSwitchDefined( SWITCH_WIRE_COMPAT ) )
  288. RpcError( NULL, 0, WIRE_COMPAT_WARNING, NULL );
  289. //UseBackEndHeap();
  290. #ifndef NOBACKEND
  291. if( !pCommand->IsSwitchDefined( SWITCH_SYNTAX_CHECK ) &&
  292. !pCommand->IsSwitchDefined( SWITCH_ZS ) &&
  293. pCommand->NeedsNDRRun() )
  294. {
  295. MIDL_INTERNAL_PRINTF( "starting codegen pass\n");
  296. pCommand->SetIsNDRRun();
  297. GlobalMainMessageNumberList.SetAll();
  298. CGMain( pSourceNode );
  299. pCommand->ResetIsNDRRun();
  300. #endif // NOBACKEND
  301. }
  302. //DestroyBackEndHeap();
  303. // BUGBUG: for now assume NDR is always the first, unless in ndr64 only case.
  304. if (pCommand->NeedsNDR64Run() )
  305. {
  306. //UseBackEndHeap();
  307. pCommand->SetIsNDR64Run();
  308. if ( pCommand->NeedsNDRRun() )
  309. pCommand->SetIs2ndCodegenRun();
  310. GlobalMainMessageNumberList.SetAll();
  311. Ndr64CGMain( pSourceNode );
  312. //DestroyBackEndHeap();
  313. }
  314. }
  315. }
  316. }
  317. #ifdef DEBUG
  318. printf("front end %d , back end %d, other %d \n",Skl_Bytes,BackAllocation,TotalAllocation);
  319. #endif
  320. if((pCompiler->GetCommandProcessor())->IsSwitchDefined( SWITCH_DUMP ) )
  321. {
  322. print_memstats();
  323. // print_typegraph();
  324. }
  325. return Status;
  326. }
  327. void
  328. IncrementErrorCount()
  329. {
  330. if ( pCompiler )
  331. pCompiler->IncrementErrorCount();
  332. }