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.

2838 lines
92 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. cmdana.cxx
  5. Abstract:
  6. This file handles all command (switch) processing for the MIDL compiler.
  7. Notes:
  8. Author:
  9. vibhasc
  10. Nov-12-1991 VibhasC Modified to conform to coding style gudelines
  11. Notes:
  12. The command analysis is handled by a command analyser object. The MIDL
  13. compiler registers its arguments with the command analyser and calls the
  14. ProcessArgs functions. The ProcessArgs performs syntactic analysis of the
  15. switch specification by checking for (1) proper switch syntax, (2) duplicate
  16. definition of the switch, and (3) illegal switch specification. After all
  17. the switches are analysed, the SetPostDefault function is called to set the
  18. default compiler switch values etc.
  19. Currently switches fall into these categories:
  20. (1) one-time switches : these can be specified only once, and the
  21. redefinition results in a warning and the second defintion
  22. overrides the first. Examples are -cc_cmd / -cc_opt etc.
  23. (2) multiple definition switches: such switches can be specified
  24. multiple times. These include /I, /D, /U etc.
  25. (3) filename switches : this is switch class specialises in filename
  26. argument handling.
  27. (4) ordinary switches : all other switches fall into this category.
  28. Normally a redef of such a switch is also a warning. These are
  29. different from the one-time switch category just for convenience.
  30. These switches normally set some internal flag etc and do not need
  31. the user specified argument to be stored in string form like
  32. the -cc_cmd etc.
  33. A general word about the command analyser. Switch syntax comes in various
  34. flavours. Some switches take arguments, some do not. Switches which have
  35. arguments may have spaces necesary between the arguments and switch name,
  36. others may not. The most interesting case, however is when the switch
  37. may have as its argument a switch-like specification, which should not be
  38. confused with another MIDL switch. We keep a data-base of switches in the
  39. switch descriptor, which keeps info about the switch name, switch
  40. enumeration and the switch syntax descriptor. The core switch syntax
  41. analyser is BumpThisArg which uses this descriptor.
  42. Also, some switches like -W? and -Wx must really be separate switches
  43. because -W? and -Wx can co-exist at the same time. If we treat the switch
  44. recognition as the same, then the code must detect a separate definition,
  45. and set the command analyser flags.This approach results in unnecessary code
  46. all over the place. An alternative is to recognise the Wx as a separate
  47. switch in the SearchForSwitch routine and return a different switch to
  48. the command analyser. This is a much cleaner approach. Only, the parsing
  49. becomes tricky. Since -W? and -Wx look VERY similar, and SearchForSwitch
  50. stops at the first match, we need to define -Wx BEFORE -W in the switch
  51. descriptor table. This happens also with the client client_env and -server
  52. and -server_env switches. In any case it we remember to properly keep
  53. tables such that the longer string is kept first, this problem gets isolated
  54. to a very small, manageable part of the command analyser. I therefore
  55. chose this approach.
  56. Note: MIDL_INTERNAL is specified by a C preprocessor command line -D option.
  57. This corresponds to debugging builds for internal purposes only.
  58. ----------------------------------------------------------------------------*/
  59. #pragma warning ( disable : 4514 4710 )
  60. /****************************************************************************
  61. * include files
  62. ***************************************************************************/
  63. #include "cmdline.h"
  64. #include "stream.hxx"
  65. #include "midlvers.h"
  66. #include <string.h>
  67. #include <io.h>
  68. #include <time.h>
  69. /****************************************************************************
  70. * local definitions
  71. ***************************************************************************/
  72. /**
  73. ** definitions for the type of switch arguments.
  74. ** switches may or may not expect arguments, there may be spaces
  75. ** between the switch and its argument(s). One special case is when the
  76. ** argument can be switch like, .ie have the - or / as the argument starter,
  77. ** so we need to treat such switches specially.
  78. **/
  79. #define ARG_NONE (0x01) /* no arg for this switch */
  80. #define ARG_YES (0x02) /* arg expected for this switch */
  81. #define ARG_SPACE (0x04) /* (a) space(s) may be present */
  82. #define ARG_NO_SPACE (0x08) /* no space is allowed */
  83. #define ARG_SWITCH_LIKE (0x10) /* the arg may be switch-like */
  84. #define ARG_OPTIONAL (ARG_YES + ARG_NONE + ARG_SPACE)
  85. #define ARG_SPACED (ARG_YES + ARG_SPACE)
  86. #define ARG_SPACE_NONE (ARG_YES + ARG_NO_SPACE)
  87. #define ARG_SPACE_OPTIONAL (ARG_YES + ARG_NO_SPACE + ARG_SPACE)
  88. #define ARG_CC_ETC (ARG_SPACE_OPTIONAL + ARG_SWITCH_LIKE)
  89. /***
  90. *** Preferably keep this table sorted by name.
  91. *** Also, partially matching names like -client / -client_env, -W/-Wx must
  92. *** be kept so that the longer sub-string appears first. The only
  93. *** reason to keep this sorted, is so that we can visually ensure this.
  94. ***/
  95. const struct sw_desc
  96. {
  97. const char * pSwitchName; // switch string
  98. unsigned short flag; // switch descriptor
  99. enum _swenum SwitchValue; // switch enum value
  100. } switch_desc[] = {
  101. { "", ARG_NONE , SWITCH_NOTHING }
  102. , { "?", ARG_NONE , SWITCH_HELP }
  103. , { "D", ARG_SPACE_OPTIONAL , SWITCH_D }
  104. , { "I", ARG_SPACE_OPTIONAL , SWITCH_I }
  105. , { "O", ARG_SPACE_OPTIONAL , SWITCH_O }
  106. , { "U", ARG_SPACE_OPTIONAL , SWITCH_U }
  107. , { "WX", ARG_NONE , SWITCH_WX }
  108. , { "W", ARG_SPACE_NONE , SWITCH_W }
  109. , { "Zp", ARG_SPACE_NONE , SWITCH_ZP }
  110. , { "Zs", ARG_NONE , SWITCH_ZS }
  111. , { "append64", ARG_NONE , SWITCH_APPEND64 }
  112. , { "acf", ARG_SPACE_OPTIONAL , SWITCH_ACF }
  113. , { "c_ext", ARG_NONE , SWITCH_C_EXT }
  114. , { "char", ARG_SPACED , SWITCH_CHAR }
  115. , { "client", ARG_SPACED , SWITCH_CLIENT }
  116. , { "confirm", ARG_NONE , SWITCH_CONFIRM }
  117. , { "nologo", ARG_NONE , SWITCH_NOLOGO }
  118. , { "cpp_cmd", ARG_CC_ETC , SWITCH_CPP_CMD }
  119. , { "cpp_opt", ARG_CC_ETC , SWITCH_CPP_OPT }
  120. , { "msc_ver", ARG_SPACED , SWITCH_MSC_VER }
  121. , { "cstub", ARG_CC_ETC , SWITCH_CSTUB }
  122. , { "nocstub", ARG_NONE , SWITCH_NO_CLIENT }
  123. #ifdef MIDL_INTERNAL
  124. , { "dump", ARG_NONE , SWITCH_DUMP }
  125. #endif // MIDL_INTERNAL
  126. , { "debugexc", ARG_NONE , SWITCH_DEBUGEXC }
  127. , { "debugline", ARG_NONE , SWITCH_DEBUGLINE }
  128. , { "debug64_opt", ARG_SPACED , SWITCH_DEBUG64_OPT }
  129. , { "debug64", ARG_SPACED , SWITCH_DEBUG64 }
  130. , { "dlldata", ARG_CC_ETC , SWITCH_DLLDATA }
  131. , { "env", ARG_SPACED , SWITCH_ENV }
  132. , { "error", ARG_SPACED , SWITCH_ERROR }
  133. , { "robust", ARG_NONE , SWITCH_ROBUST }
  134. , { "header", ARG_CC_ETC , SWITCH_HEADER }
  135. , { "help", ARG_NONE , SWITCH_HELP }
  136. , { "iid", ARG_CC_ETC , SWITCH_IID }
  137. , { "internal", ARG_NONE , SWITCH_INTERNAL }
  138. , { "lcid", ARG_SPACED , SWITCH_LOCALE_ID }
  139. , { "mktyplib203", ARG_NONE , SWITCH_MKTYPLIB }
  140. , { "newtlb", ARG_NONE , SWITCH_NEW_TLB }
  141. , { "no_cpp", ARG_NONE , SWITCH_NO_CPP }
  142. , { "no_def_idir", ARG_NONE , SWITCH_NO_DEF_IDIR }
  143. , { "no_warn", ARG_NONE , SWITCH_NO_WARN }
  144. , { "use_epv", ARG_NONE , SWITCH_USE_EPV }
  145. , { "no_default_epv",ARG_NONE , SWITCH_NO_DEFAULT_EPV }
  146. , { "no_robust", ARG_NONE , SWITCH_NO_ROBUST }
  147. , { "no_stamp", ARG_NONE , SWITCH_NO_STAMP }
  148. , { "oldnames", ARG_NONE , SWITCH_OLDNAMES }
  149. , { "oldtlb", ARG_NONE , SWITCH_OLD_TLB }
  150. , { "osf", ARG_NONE , SWITCH_OSF }
  151. , { "out", ARG_SPACE_OPTIONAL , SWITCH_OUT }
  152. #ifdef MIDL_INTERNAL
  153. , { "override", ARG_NONE , SWITCH_OVERRIDE }
  154. #endif // MIDL_INTERNAL
  155. , { "pack", ARG_SPACED , SWITCH_PACK }
  156. , { "prefix", ARG_SPACED , SWITCH_PREFIX }
  157. // , { "suffix", ARG_SPACED , SWITCH_SUFFIX }
  158. , { "proxy", ARG_CC_ETC , SWITCH_PROXY }
  159. , { "noproxy", ARG_NONE , SWITCH_NO_PROXY }
  160. , { "proxydef", ARG_CC_ETC , SWITCH_PROXY_DEF }
  161. , { "noproxydef", ARG_NONE , SWITCH_NO_PROXY_DEF }
  162. , { "dlldef", ARG_CC_ETC , SWITCH_DLL_SERVER_DEF }
  163. , { "nodlldef", ARG_NONE , SWITCH_NO_DLL_SERVER_DEF }
  164. , { "dllmain", ARG_CC_ETC , SWITCH_DLL_SERVER_CLASS_GEN }
  165. , { "nodllmain", ARG_NONE , SWITCH_NO_DLL_SERVER_CLASS_GEN }
  166. , { "reg", ARG_CC_ETC , SWITCH_SERVER_REG }
  167. , { "noreg", ARG_NONE , SWITCH_NO_SERVER_REG }
  168. , { "exesuppt", ARG_CC_ETC , SWITCH_EXE_SERVER }
  169. , { "noexesuppt", ARG_NONE , SWITCH_NO_EXE_SERVER }
  170. , { "exemain", ARG_CC_ETC , SWITCH_EXE_SERVER_MAIN }
  171. , { "noexemain", ARG_NONE , SWITCH_NO_EXE_SERVER_MAIN }
  172. , { "testclient", ARG_CC_ETC , SWITCH_TESTCLIENT }
  173. , { "notestclient", ARG_NONE , SWITCH_NO_TESTCLIENT }
  174. , { "methods", ARG_CC_ETC , SWITCH_CLASS_METHODS }
  175. , { "nomethods", ARG_NONE , SWITCH_NO_CLASS_METHODS }
  176. , { "iunknown", ARG_CC_ETC , SWITCH_CLASS_IUNKNOWN }
  177. , { "noiunknown", ARG_NONE , SWITCH_NO_CLASS_IUNKNOWN }
  178. , { "class_hdr", ARG_CC_ETC , SWITCH_CLASS_HEADER }
  179. , { "noclass_hdr", ARG_NONE , SWITCH_NO_CLASS_HEADER }
  180. , { "savePP", ARG_NONE , SWITCH_SAVEPP }
  181. , { "server", ARG_SPACED , SWITCH_SERVER }
  182. , { "sstub", ARG_CC_ETC , SWITCH_SSTUB }
  183. , { "nosstub", ARG_NONE , SWITCH_NO_SERVER }
  184. , { "syntax_check", ARG_NONE , SWITCH_SYNTAX_CHECK }
  185. , { "target", ARG_SPACED , SWITCH_TARGET_SYSTEM }
  186. , { "warn", ARG_SPACED , SWITCH_W }
  187. #ifdef MIDL_INTERNAL
  188. , { "x", ARG_NONE , SWITCH_X }
  189. #endif // MIDL_INTERNAL
  190. , { "ms_ext", ARG_NONE , SWITCH_MS_EXT }
  191. , { "ms_conf_struct",ARG_NONE , SWITCH_MS_CONF_STRUCT }
  192. , { "ms_union", ARG_NONE , SWITCH_MS_UNION }
  193. , { "no_format_opt", ARG_NONE , SWITCH_NO_FMT_OPT }
  194. , { "app_config", ARG_NONE , SWITCH_APP_CONFIG }
  195. , { "rpcss", ARG_NONE , SWITCH_RPCSS }
  196. , { "hookole", ARG_NONE , SWITCH_HOOKOLE }
  197. , { "netmonstub", ARG_CC_ETC , SWITCH_NETMON_STUB_OUTPUT_FILE}
  198. , { "netmonobjstub", ARG_CC_ETC , SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE}
  199. , { "netmon", ARG_NONE , SWITCH_NETMON }
  200. , { "version_stamp", ARG_NONE , SWITCH_VERSION_STAMP }
  201. // MKTYPLIB switches
  202. , { "tlb", ARG_SPACED , SWITCH_TLIB }
  203. , { "o", ARG_SPACED , SWITCH_REDIRECT_OUTPUT }
  204. , { "h", ARG_CC_ETC , SWITCH_HEADER }
  205. , { "align", ARG_SPACE_OPTIONAL , SWITCH_ZP }
  206. , { "nocpp", ARG_NONE , SWITCH_NO_CPP }
  207. , { "wire_compat" ,ARG_SPACED , SWITCH_WIRE_COMPAT }
  208. , { "wi", ARG_SPACE_NONE , SWITCH_ODL_ENV } // win16, win32, win64
  209. , { "do", ARG_SPACE_NONE , SWITCH_ODL_ENV } // dos
  210. , { "ma", ARG_SPACE_NONE , SWITCH_ODL_ENV } // mac
  211. , { "po", ARG_SPACE_NONE , SWITCH_ODL_ENV } // powermac
  212. , { "no_buffer_reuse", ARG_NONE , SWITCH_NOREUSE_BUFFER }
  213. , { "use_vt_int_ptr",ARG_NONE , SWITCH_USE_VT_INT_PTR }
  214. , { "notlb" ,ARG_NONE , SWITCH_NO_TLIB }
  215. , { "protocol" ,ARG_SPACED , SWITCH_TRANSFER_SYNTAX }
  216. , { "ms_ext64" ,ARG_NONE , SWITCH_MS_EXT64 }
  217. , { "debuginfo" ,ARG_NONE , SWITCH_DEBUGINFO }
  218. };
  219. const CHOICE CharChoice[] =
  220. {
  221. { "signed" , CHAR_SIGNED }
  222. ,{ "unsigned" , CHAR_UNSIGNED }
  223. ,{ "ascii7" , CHAR_ANSI7 }
  224. ,{ 0 , 0 }
  225. };
  226. const CHOICE ErrorChoice[] =
  227. {
  228. { "all" , ERROR_ALL }
  229. ,{ "allocation" , ERROR_ALLOCATION }
  230. ,{ "bounds_check" , ERROR_BOUNDS_CHECK }
  231. ,{ "enum" , ERROR_ENUM }
  232. ,{ "ref" , ERROR_REF }
  233. ,{ "stub_data" , ERROR_STUB_DATA }
  234. ,{ "none" , ERROR_NONE }
  235. ,{ 0 , 0 }
  236. };
  237. const CHOICE EnvChoice[] =
  238. {
  239. { "dos" , ENV_OBSOLETE }
  240. ,{ "win16" , ENV_OBSOLETE }
  241. ,{ "win32" , ENV_WIN32 }
  242. ,{ "win64" , ENV_WIN64 }
  243. ,{ "mac" , ENV_OBSOLETE }
  244. ,{ "powermac" , ENV_OBSOLETE }
  245. ,{ 0 , 0 }
  246. };
  247. const CHOICE SyntaxChoice[] =
  248. {
  249. { "dce" , SYNTAX_DCE }
  250. ,{ "ndr64" , SYNTAX_NDR64 }
  251. ,{ "all" , SYNTAX_BOTH }
  252. ,{ 0 , 0 }
  253. };
  254. const CHOICE TargetChoice[] =
  255. {
  256. { "NT40" , NT40 }
  257. ,{ "NT50" , NT50 }
  258. ,{ "NT51" , NT51 }
  259. ,{ 0 , 0 }
  260. };
  261. const CHOICE ClientChoice[] =
  262. {
  263. { "stub" , CLNT_STUB }
  264. ,{ "none" , CLNT_NONE }
  265. ,{ 0 , 0 }
  266. };
  267. const CHOICE ServerChoice[] =
  268. {
  269. { "stub" , SRVR_STUB }
  270. ,{ "none" , SRVR_NONE }
  271. ,{ 0 , 0 }
  272. };
  273. const CHOICE WireCompatChoice[] =
  274. {
  275. { "enum16unionalign", WIRE_COMPAT_ENUM16UNIONALIGN }
  276. ,{ 0 , 0 }
  277. };
  278. #define IS_NUMERIC_1( pThisArg ) ((strlen( pThisArg) == 1 ) && \
  279. (isdigit( *pThisArg )) )
  280. // this is now the same for ALL platforms
  281. #define C_COMPILER_NAME() ("cl.exe")
  282. #define C_PREPROCESSOR_NAME() ("cl.exe")
  283. #define ADDITIONAL_CPP_OPT() (" -E -nologo")
  284. #define MIDL_HELP_FILE_NAME ("midl.hlp")
  285. /****************************************************************************
  286. * local data
  287. ***************************************************************************/
  288. /****************************************************************************
  289. * externs
  290. ***************************************************************************/
  291. extern void ReportUnimplementedSwitch( short );
  292. extern char * SwitchStringForValue( unsigned short );
  293. extern _swenum SearchForSwitch( char ** );
  294. extern STATUS_T SelectChoice( const CHOICE *, char *, short *);
  295. extern bool PPCmdEngine( int argc, char *argv[], IDICT * );
  296. extern void PrintArg( enum _swenum, char *, char * );
  297. void CmdProcess( pair_switch*, CommandLine*, char* );
  298. /****************************************************************************/
  299. void
  300. CommandLine::RegisterArgs(
  301. char * pArgs[],
  302. short cArguments
  303. )
  304. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  305. Routine Description:
  306. This routine registers with the command analyser the argument vector
  307. and argument count for user supplied arguments.
  308. Arguments:
  309. pArgs - Array of pointers to arguments ( switches etc ).
  310. cArguments - count of arguments.
  311. Return Value:
  312. None.
  313. Notes:
  314. The process of registering the arguments consists of keeping a local
  315. copy of the argument vector pointer and count.
  316. The argument vector is passed such that the argv[1] is the first
  317. argument available to the command processor. Therefore , count is
  318. one less too.
  319. Why do we need registering the arguments ? In the process of parsing
  320. we might want to skip an argument back or forward. So we keep a local
  321. copy of the pointer to the arguments.
  322. ----------------------------------------------------------------------------*/
  323. {
  324. iArgV = 0;
  325. pArgDict= new IDICT( 10, 5 );
  326. fShowLogo = PPCmdEngine( cArguments, pArgs, pArgDict );
  327. cArgs = pArgDict->GetCurrentSize();
  328. }
  329. char *
  330. CommandLine::GetNextArg()
  331. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  332. Routine Description:
  333. Get the next argument in the argument vector.
  334. Arguments:
  335. None.
  336. Return Value:
  337. returns a pointer to the next argument.
  338. Notes:
  339. if no more arguments
  340. return a null.
  341. else
  342. return the next argument pointer.
  343. decrement the count, increment the pointer to point to the next arg.
  344. ----------------------------------------------------------------------------*/
  345. {
  346. if(cArgs == 0 )
  347. return (char *)NULL;
  348. cArgs--;
  349. return (char *)pArgDict->GetElement( (IDICTKEY)iArgV++);
  350. }
  351. void
  352. CommandLine::UndoGetNextArg()
  353. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  354. Routine Description:
  355. Undo the effect of the last GetNextArg call.
  356. Arguments:
  357. None.
  358. Return Value:
  359. None.
  360. Notes:
  361. if this is not the first argument already
  362. Push back the argument pointer.
  363. Increment count.
  364. else
  365. Do nothing.
  366. This prepares the argument vector to accept more GetNextArgCalls.
  367. ----------------------------------------------------------------------------*/
  368. {
  369. if(iArgV == 0)
  370. return;
  371. cArgs++;
  372. iArgV--;
  373. }
  374. STATUS_T
  375. CommandLine::ProcessArgs()
  376. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  377. Routine Description:
  378. Process command line arguments.
  379. Arguments:
  380. None.
  381. Return Value:
  382. STATUS_OK - if all is well
  383. Error Status otherwise.
  384. Notes:
  385. ----------------------------------------------------------------------------*/
  386. {
  387. char * pThisArg,
  388. * pThisArgSave;
  389. STATUS_T Status, ReturnStatus = STATUS_OK;
  390. enum _swenum iSwitch;
  391. short fSwitchDetected;
  392. unsigned short SwitchValue;
  393. // loop till all arguments have been processed.
  394. while ( ( pThisArg = GetNextArg() ) != 0 )
  395. {
  396. fSwitchDetected = 0;
  397. iSwitch = SWITCH_NOTHING;
  398. // save this pointer, it is useful for error reporting.
  399. pThisArgSave = pThisArg;
  400. // if we saw a - or a / we have detected a switch. Get the index of
  401. // the switch in the switch descriptor table. If the returned index
  402. // was zero, either the switch was not a valid one, or we saw an input
  403. // which is taken as an input filename specification. If the input
  404. // filename has already been specified, this is an error.
  405. if( *pThisArg == '-' || *pThisArg == '/' )
  406. {
  407. pThisArg++;
  408. fSwitchDetected = 1;
  409. iSwitch = SearchForSwitch( &pThisArg );
  410. }
  411. if( iSwitch == SWITCH_NOTHING )
  412. {
  413. if( fSwitchDetected || IsSwitchDefined( BASE_FILENAME ) )
  414. {
  415. char * p = new char[ strlen(pThisArg)+2+1 ];
  416. sprintf(p, "\"%s\"", pThisArg );
  417. RpcError( (char *)NULL,
  418. 0,
  419. fSwitchDetected ? UNKNOWN_SWITCH : UNKNOWN_ARGUMENT,
  420. p);
  421. delete []p;
  422. }
  423. else
  424. {
  425. // the only way we can get here is if he did not specify a
  426. // switch like input AND the input filename has not been
  427. // defined yet. Hence this must be the input filename.
  428. pInputFNSwitch = new filename_switch( pThisArg);
  429. SwitchDefined( BASE_FILENAME );
  430. }
  431. continue;
  432. }
  433. // bump the input pointer to point to the argument. Depending on
  434. // what type of argument this switch takes ( spaced, non-spaced,
  435. // switch-like etc ) bump the argument pointer to the actual argument.
  436. SwitchValue = unsigned short ( switch_desc[ iSwitch ].SwitchValue );
  437. Status = BumpThisArg( &pThisArg, switch_desc[ iSwitch ].flag );
  438. if( Status != STATUS_OK )
  439. {
  440. RpcError( (char *)NULL,
  441. 0,
  442. Status,
  443. pThisArgSave );
  444. continue;
  445. }
  446. MIDL_ASSERT(NULL != pThisArg);
  447. // Process the switch. The input pointer is pointing to the
  448. // argument to the switch, after the '-' or '/'.
  449. switch( SwitchValue )
  450. {
  451. case SWITCH_CSTUB:
  452. case SWITCH_HEADER:
  453. case SWITCH_ACF:
  454. case SWITCH_SSTUB:
  455. case SWITCH_OUT:
  456. case SWITCH_IID:
  457. case SWITCH_PROXY:
  458. case SWITCH_TESTCLIENT:
  459. case SWITCH_CLASS_METHODS:
  460. case SWITCH_CLASS_HEADER:
  461. case SWITCH_CLASS_IUNKNOWN:
  462. case SWITCH_PROXY_DEF:
  463. case SWITCH_DLL_SERVER_DEF:
  464. case SWITCH_DLL_SERVER_CLASS_GEN:
  465. case SWITCH_SERVER_REG:
  466. case SWITCH_EXE_SERVER:
  467. case SWITCH_EXE_SERVER_MAIN:
  468. case SWITCH_DLLDATA:
  469. case SWITCH_TLIB:
  470. case SWITCH_REDIRECT_OUTPUT:
  471. case SWITCH_NETMON_STUB_OUTPUT_FILE:
  472. case SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE:
  473. Status = ProcessFilenameSwitch( SwitchValue, pThisArg );
  474. break;
  475. case SWITCH_LOCALE_ID:
  476. case SWITCH_PACK:
  477. case SWITCH_ZP:
  478. case SWITCH_NO_WARN:
  479. case SWITCH_USE_EPV:
  480. case SWITCH_NO_DEFAULT_EPV:
  481. case SWITCH_DEBUGEXC:
  482. case SWITCH_DEBUGLINE:
  483. case SWITCH_SYNTAX_CHECK:
  484. case SWITCH_ZS:
  485. case SWITCH_NO_CPP:
  486. case SWITCH_CLIENT:
  487. case SWITCH_SERVER:
  488. case SWITCH_ENV:
  489. case SWITCH_TARGET_SYSTEM:
  490. case SWITCH_RPCSS:
  491. case SWITCH_NETMON:
  492. case SWITCH_VERSION_STAMP:
  493. case SWITCH_DUMP:
  494. case SWITCH_OVERRIDE:
  495. case SWITCH_SAVEPP:
  496. case SWITCH_NO_DEF_IDIR:
  497. case SWITCH_VERSION:
  498. case SWITCH_CONFIRM:
  499. case SWITCH_NOLOGO:
  500. case SWITCH_CHAR:
  501. case SWITCH_HELP:
  502. case SWITCH_W:
  503. case SWITCH_WX:
  504. case SWITCH_X:
  505. case SWITCH_O:
  506. case SWITCH_APPEND64:
  507. case SWITCH_APP_CONFIG:
  508. case SWITCH_MS_EXT:
  509. case SWITCH_MS_CONF_STRUCT:
  510. case SWITCH_MS_UNION:
  511. case SWITCH_OLDNAMES:
  512. case SWITCH_NO_FMT_OPT:
  513. case SWITCH_GUARD_DEFS:
  514. case SWITCH_INTERNAL:
  515. case SWITCH_NO_STAMP:
  516. case SWITCH_ROBUST:
  517. case SWITCH_NO_ROBUST:
  518. case SWITCH_C_EXT:
  519. case SWITCH_OSF:
  520. case SWITCH_MKTYPLIB:
  521. case SWITCH_OLD_TLB:
  522. case SWITCH_NEW_TLB:
  523. case SWITCH_NOREUSE_BUFFER:
  524. case SWITCH_USE_VT_INT_PTR:
  525. case SWITCH_NO_TLIB:
  526. case SWITCH_TRANSFER_SYNTAX:
  527. case SWITCH_MS_EXT64:
  528. case SWITCH_DEBUGINFO:
  529. Status = ProcessOrdinarySwitch( SwitchValue, pThisArg );
  530. break;
  531. case SWITCH_ODL_ENV:
  532. Status = ProcessOrdinarySwitch( SwitchValue, pThisArg );
  533. SwitchValue = SWITCH_ENV;
  534. break;
  535. case SWITCH_ERROR:
  536. case SWITCH_WIRE_COMPAT:
  537. Status = ProcessSimpleMultipleSwitch( SwitchValue, pThisArg );
  538. break;
  539. case SWITCH_D:
  540. case SWITCH_I:
  541. case SWITCH_U:
  542. // specifically for -D/-I/-U we want the two characters
  543. // -I / -D / -U inside too, so that we can pass it as such to
  544. // the c preprocessor.
  545. Status = ProcessMultipleSwitch( SwitchValue, pThisArgSave, pThisArg );
  546. break;
  547. case SWITCH_MSC_VER:
  548. case SWITCH_CPP_CMD:
  549. case SWITCH_CPP_OPT:
  550. case SWITCH_DEBUG64_OPT:
  551. case SWITCH_DEBUG64:
  552. Status = ProcessOnetimeSwitch( SwitchValue, pThisArg );
  553. break;
  554. case SWITCH_PREFIX:
  555. CmdProcess( pSwitchPrefix, this, pThisArg );
  556. break;
  557. case SWITCH_HOOKOLE:
  558. RpcError( NULL, 0, SWITCH_NOT_SUPPORTED_ANYMORE, "hookole" );
  559. break;
  560. default:
  561. ReportUnimplementedSwitch( SwitchValue );
  562. continue;
  563. }
  564. // set up the defintion vector, to indicate that the switch has been
  565. // defined.
  566. if( Status == ILLEGAL_ARGUMENT )
  567. ReturnStatus = ILLEGAL_ARGUMENT;
  568. SwitchDefined( SwitchValue );
  569. }
  570. if (!IsSwitchDefined(SWITCH_OSF))
  571. {
  572. SwitchDefined(SWITCH_C_EXT);
  573. SwitchDefined(SWITCH_MS_EXT);
  574. }
  575. // if the user has asked for output to be redirected, redirect stdout
  576. if (IsSwitchDefined(SWITCH_REDIRECT_OUTPUT))
  577. {
  578. FILE * pFH;
  579. char * newfile = pRedirectOutputSwitch->GetFileName();
  580. if ( HasAppend64() || Is2ndCodegenRun() )
  581. {
  582. pFH = freopen(newfile, "r+", stdout);
  583. if ( pFH )
  584. {
  585. if ( 0 != fseek( pFH, 0, SEEK_END ) )
  586. RpcError( NULL, 0, ERROR_OPENING_FILE, newfile );
  587. }
  588. else
  589. pFH = freopen(newfile, "a+", stdout);
  590. }
  591. else
  592. pFH = freopen(newfile, "w", stdout);
  593. if ( NULL == pFH )
  594. RpcError( NULL, 0, ERROR_OPENING_FILE, newfile );
  595. }
  596. // if he has not specified the input filename, report
  597. // error, but only if the confirm switch is not specified. If it is,
  598. // processing will not occur anyway.
  599. if(!IsSwitchDefined(BASE_FILENAME) )
  600. {
  601. if( IsSwitchDefined( SWITCH_CONFIRM ) )
  602. {
  603. pInputFNSwitch = new filename_switch( "sample.idl");
  604. SwitchDefined( BASE_FILENAME );
  605. }
  606. else if( IsSwitchDefined( SWITCH_HELP ))
  607. return STATUS_OK;
  608. else
  609. {
  610. RpcError((char *)NULL,0,NO_INPUT_FILE, (char *)NULL);
  611. return NO_INPUT_FILE;
  612. }
  613. }
  614. // set post switch processing defaults
  615. ReturnStatus = SetPostDefaults();
  616. return ReturnStatus;
  617. }
  618. STATUS_T
  619. CommandLine::BumpThisArg(
  620. char ** ppArg,
  621. unsigned short flag
  622. )
  623. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  624. Routine Description:
  625. Bump the argument pointer to the start of the argument that this switch
  626. expects.
  627. Arguments:
  628. ppArg - pointer to the argument pointer.
  629. flag - descriptor of the type of argument expected by the switch.
  630. Return Value:
  631. ILLEGAL_ARGUMENT - if the switch did not expect this argument
  632. BAD_SWITCH_SYNTAX - if the switch + arg. syntax is improper.
  633. MISSING_ARGUMENT - a mandatory arg. is missing.
  634. STATUS_OK - evrything is hunky dory.
  635. Notes:
  636. In the routine below, fHasImmediateArg is a flag which is true if the
  637. switch argument follws the switch name without any spaces in between.
  638. Optional space is indicated in the switch descriptor as ARG_SPACE +
  639. ARG_NO_SPACE, so it gets reflected in fSpaceOptional as fMustNotHaveSpace
  640. && fMustHaveSpace.
  641. Other flags have self-explanatory names.
  642. This routine forms the core syntax checker for the switches.
  643. ----------------------------------------------------------------------------*/
  644. {
  645. char * pArg = *ppArg;
  646. BOOL fMustHaveArg = (BOOL) !(flag & ARG_NONE);
  647. BOOL fOptionalArg = (flag & ARG_NONE) && (flag & ARG_YES);
  648. BOOL fMustHaveSpace = (BOOL) ((flag & ARG_SPACE) != 0 );
  649. BOOL fMustNotHaveSpace = (BOOL) ((flag & ARG_NO_SPACE) != 0 );
  650. BOOL fSpaceOptional = (BOOL) (fMustNotHaveSpace &&
  651. fMustHaveSpace );
  652. BOOL fSwitchLike = (BOOL) ((flag & ARG_SWITCH_LIKE) != 0 );
  653. BOOL fHasImmediateArg = (*pArg != 0);
  654. BOOL fMustGetNextArg = FALSE;
  655. // first deal with the case of the switch having an optional argument.
  656. // If the switch has an optional argument, then check the next argument
  657. // to see if it is switch like. If it is, then this switch was specified
  658. // without an argument. If it is not, then the next argument is taken to
  659. // be the argument for the switch.
  660. if( fOptionalArg )
  661. {
  662. pArg = GetNextArg();
  663. if(!fSwitchLike && pArg && ((*pArg == '-') || (*pArg == '/') ) )
  664. {
  665. UndoGetNextArg();
  666. pArg = (char *)0;
  667. }
  668. *ppArg = pArg;
  669. return STATUS_OK;
  670. }
  671. // if the switch must not have an immediate argument and has one,
  672. // it is an error.
  673. if( !fMustHaveArg && fHasImmediateArg )
  674. return ILLEGAL_ARGUMENT;
  675. else if ( fMustHaveArg )
  676. {
  677. // if it needs an argument, and has an immediate argument, it is bad
  678. // if the switch must have space.
  679. if( fHasImmediateArg )
  680. {
  681. if( fMustHaveSpace && !fSpaceOptional )
  682. return BAD_SWITCH_SYNTAX;
  683. }
  684. else
  685. {
  686. // This is the case when the switch must have an argument and
  687. // does not seem to have an immediate argument. This is fine only
  688. // if space was either optional or expected. In either case, we must
  689. // assume that the next argument is the argument for this switch.
  690. // If switch must not have any space then this is a case of
  691. // bad switch syntax.
  692. if( fSpaceOptional || fMustHaveSpace )
  693. fMustGetNextArg = TRUE;
  694. else
  695. return BAD_SWITCH_SYNTAX;
  696. }
  697. }
  698. if( fMustGetNextArg )
  699. {
  700. // we arrive here if the switch expects an argument and
  701. // space between the switch and the argument is optional.
  702. // Note that the flag fHasImmediateArg now specifies whether
  703. // the argument is present at all.
  704. pArg = GetNextArg();
  705. fHasImmediateArg = (BOOL) ( pArg && (*pArg != 0) );
  706. if( fHasImmediateArg )
  707. {
  708. // we got the next argument.
  709. // If we get something that looks like a switch, and this switch
  710. // does not expect switch_like arguments, then this is illegal
  711. // argument for the switch.
  712. if(!fSwitchLike && ((*pArg == '-') || (*pArg == '/') ) )
  713. {
  714. UndoGetNextArg();
  715. return ILLEGAL_ARGUMENT;
  716. }
  717. }
  718. else
  719. // well, we expect an argument, and didnt get one. He just
  720. // shot himself is all I can say.
  721. return MISSING_ARG;
  722. }
  723. // we have found the right argument.
  724. *ppArg = pArg;
  725. // finally ! out of this mess.
  726. return STATUS_OK;
  727. }
  728. STATUS_T
  729. CommandLine::ProcessOnetimeSwitch(
  730. short SwitchNo,
  731. char * pThisArg
  732. )
  733. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  734. Routine Description:
  735. Process a onetime switch.
  736. Arguments:
  737. SwitchNo - switch number being processed.
  738. pThisArg - pointer to the argument for this switch.
  739. Return Value:
  740. None.
  741. Notes:
  742. Check for duplicate definition of this switch. If there is a duplicate
  743. definition, override the previous one after warning him.
  744. ----------------------------------------------------------------------------*/
  745. {
  746. onetime_switch ** ppSSwitch;
  747. switch( SwitchNo )
  748. {
  749. case SWITCH_CPP_CMD: ppSSwitch = &pCppCmdSwitch; break;
  750. case SWITCH_CPP_OPT: ppSSwitch = &pCppOptSwitch; break;
  751. case SWITCH_MSC_VER:
  752. ppSSwitch = &pMSCVerSwitch;
  753. MSCVersion = (unsigned short) atoi( pThisArg );
  754. break;
  755. case SWITCH_DEBUG64: ppSSwitch = &pDebug64Switch; break;
  756. case SWITCH_DEBUG64_OPT:ppSSwitch = &pDebug64OptSwitch; break;
  757. default: return STATUS_OK;
  758. }
  759. if( IsSwitchDefined(SwitchNo) )
  760. {
  761. RpcError( (char *)NULL,
  762. 0,
  763. SWITCH_REDEFINED,
  764. SwitchStringForValue( SwitchNo ) );
  765. delete *ppSSwitch;
  766. }
  767. (*ppSSwitch) = new onetime_switch( pThisArg );
  768. return STATUS_OK;
  769. }
  770. STATUS_T
  771. CommandLine::ProcessMultipleSwitch(
  772. short SwitchNo,
  773. char * pThisArg,
  774. char * pActualArg
  775. )
  776. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  777. Routine Description:
  778. Process a multiple occurrence switch.
  779. Arguments:
  780. SwitchNo - switch number being processed.
  781. pThisArg - pointer to the argument for this switch.
  782. pActualArg - pointer to the actual argument to -I/-D etc
  783. Return Value:
  784. None.
  785. Notes:
  786. Multiple specifications can occur. Dont check for duplicate definitions.
  787. ----------------------------------------------------------------------------*/
  788. {
  789. char * pTemp = pThisArg;
  790. multiple_switch ** ppMSwitch;
  791. switch( SwitchNo )
  792. {
  793. case SWITCH_D: ppMSwitch = &pDSwitch; break;
  794. case SWITCH_I: ppMSwitch = &pISwitch; break;
  795. case SWITCH_U: ppMSwitch = &pUSwitch; break;
  796. default: return STATUS_OK;
  797. }
  798. // now set the switches. Space is optional
  799. // If no space exists between the -I/-D value of pActualArg will point to
  800. // the byte next to the end of -I/-D etc. If there is at least one space,
  801. // the pActualArg will point further away. This fact can be used to decide
  802. // how the argument needs to be presented to the c preprocessor.
  803. // If we need the space, then create a new buffer with the space between the
  804. // -I/-D etc.
  805. // I assume the assumptions above will hold true even for segmented
  806. // architectures.
  807. size_t ActualArgOffset = pActualArg - pThisArg;
  808. if( ( pActualArg - (pThisArg+2) ) != 0 )
  809. {
  810. // we need a space
  811. ActualArgOffset = strlen( pThisArg ) + 1; // 1 for space
  812. pTemp = new char [ ActualArgOffset +
  813. strlen( pActualArg ) +
  814. 1 // 1 for terminator.
  815. ];
  816. sprintf( pTemp, "%s %s", pThisArg, pActualArg );
  817. }
  818. if(!(*ppMSwitch) )
  819. *ppMSwitch = new multiple_switch( pTemp, ActualArgOffset );
  820. else
  821. (*ppMSwitch)->Add( pTemp, ActualArgOffset );
  822. return STATUS_OK;
  823. }
  824. STATUS_T
  825. CommandLine::ProcessFilenameSwitch(
  826. short SwitchNo,
  827. char * pThisArg
  828. )
  829. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  830. Routine Description:
  831. Process a filename switch.
  832. Arguments:
  833. SwitchNo - switch number being processed.
  834. pThisArg - pointer to the argument for this switch.
  835. Return Value:
  836. STATUS_OK if all is well, error otherwise.
  837. Notes:
  838. This is like a single occurrence switch too. Warn if duplicate definition
  839. and override the previous specification.
  840. ----------------------------------------------------------------------------*/
  841. {
  842. filename_switch ** ppFNSwitch;
  843. BOOL fCheck = TRUE;
  844. char agBaseName[ _MAX_FNAME ];
  845. switch( SwitchNo )
  846. {
  847. case SWITCH_CSTUB: ppFNSwitch = &pCStubSwitch; break;
  848. case SWITCH_HEADER: ppFNSwitch = &pHeaderSwitch; break;
  849. case SWITCH_ACF: ppFNSwitch = &pAcfSwitch; break;
  850. case SWITCH_SSTUB: ppFNSwitch = &pSStubSwitch; break;
  851. case SWITCH_OUT: ppFNSwitch = &pOutputPathSwitch; fCheck=FALSE; break;
  852. case SWITCH_IID: ppFNSwitch = &pIIDSwitch; break;
  853. case SWITCH_PROXY: ppFNSwitch = &pProxySwitch; break;
  854. case SWITCH_DLLDATA: ppFNSwitch = &pDllDataSwitch; break;
  855. case SWITCH_TLIB: ppFNSwitch = &pTlibSwitch; break;
  856. case SWITCH_REDIRECT_OUTPUT: ppFNSwitch = &pRedirectOutputSwitch; break;
  857. case SWITCH_NETMON_STUB_OUTPUT_FILE: ppFNSwitch = &pNetmonStubSwitch; break;
  858. case SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE: ppFNSwitch = &pNetmonStubObjSwitch; break;
  859. default: return STATUS_OK;
  860. }
  861. if( IsSwitchDefined(SwitchNo) )
  862. {
  863. RpcError( (char *)NULL,
  864. 0,
  865. SWITCH_REDEFINED,
  866. SwitchStringForValue( SwitchNo ) );
  867. delete *ppFNSwitch;
  868. }
  869. (*ppFNSwitch) = new filename_switch( pThisArg );
  870. // check for validity of the switch. All switches other than the
  871. // out switch must have a base name specified.
  872. if( fCheck )
  873. {
  874. (*ppFNSwitch)->GetFileNameComponents( (char *)NULL,
  875. (char *)NULL,
  876. agBaseName,
  877. (char *)NULL );
  878. if( agBaseName[ 0 ] == '\0' )
  879. {
  880. RpcError( (char *)NULL,
  881. 0,
  882. ILLEGAL_ARGUMENT,
  883. SwitchStringForValue( SwitchNo ) );
  884. }
  885. }
  886. return STATUS_OK;
  887. }
  888. STATUS_T
  889. CommandLine::ProcessOrdinarySwitch(
  890. short SWValue,
  891. char * pThisArg
  892. )
  893. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  894. Routine Description:
  895. process ordinary switch catrgory.
  896. Arguments:
  897. SWValue - switch value
  898. pThisArg - the users argument to this switch.
  899. Return Value:
  900. Notes:
  901. check and warn for redefinition of the switch. Switch Warn is a special
  902. case, the warn can be redefined. The last specified warning level is
  903. valid.
  904. Generally we let the user who redefines a switch off the hook. When the
  905. arguments to a switch are wrong, we report an error and return an illegal
  906. argument status.
  907. ----------------------------------------------------------------------------*/
  908. {
  909. short Temp;
  910. STATUS_T Status = STATUS_OK;
  911. if( IsSwitchDefined( SWValue ) && (SWValue != SWITCH_O) )
  912. {
  913. RpcError( (char *)NULL,
  914. 0,
  915. SWITCH_REDEFINED,
  916. SwitchStringForValue( SWValue ) );
  917. }
  918. switch( SWValue )
  919. {
  920. case SWITCH_PACK:
  921. SwitchDefined( SWITCH_ZP );
  922. // fall through
  923. case SWITCH_ZP:
  924. {
  925. int TempZeePee = atoi( pThisArg );
  926. if (!TempZeePee || !IsValidZeePee( TempZeePee ) )
  927. goto illarg;
  928. ZeePee = (unsigned short)TempZeePee;
  929. }
  930. break;
  931. case SWITCH_LOCALE_ID:
  932. SwitchDefined( SWITCH_LOCALE_ID );
  933. LocaleId = atoi( pThisArg );
  934. /*
  935. if ( ! CurrentCharSet.SetDbcsLeadByteTable( LocaleId ) )
  936. {
  937. char temp[20];
  938. sprintf( temp, "%d", LocaleId );
  939. RpcError( NULL, 0, INVALID_LOCALE_ID, temp );
  940. }
  941. */
  942. break;
  943. case SWITCH_W:
  944. // warning level of 0 specifies no warnings.
  945. Temp = short( *pThisArg - '0' );
  946. if( ( !IS_NUMERIC_1( pThisArg ) ) ||
  947. ( Temp > WARN_LEVEL_MAX ) )
  948. goto illarg;
  949. WLevel = Temp;
  950. break;
  951. case SWITCH_O:
  952. {
  953. if ( ! *pThisArg )
  954. goto illarg;
  955. if ( OptimFlags &
  956. (OPTIMIZE_SIZE | OPTIMIZE_ANY_INTERPRETER) )
  957. RpcError( (char *)NULL,
  958. 0,
  959. SWITCH_REDEFINED,
  960. SwitchStringForValue( SWValue ) );
  961. if ( strcmp( pThisArg, "s" ) == 0 )
  962. {
  963. SetOptimizationFlags( OPTIMIZE_SIZE );
  964. OptimLevel = OPT_LEVEL_OS;
  965. }
  966. else if ( strcmp( pThisArg, "i" ) == 0 )
  967. {
  968. SetOptimizationFlags( OPTIMIZE_INTERPRETER );
  969. OptimLevel = OPT_LEVEL_OI;
  970. }
  971. else if ( strcmp( pThisArg, "ic" ) == 0 )
  972. {
  973. SetOptimizationFlags( OPTIMIZE_ALL_I1_FLAGS );
  974. OptimLevel = OPT_LEVEL_OIC;
  975. RpcError( 0, 0, OIC_SUPPORT_PHASED_OUT, "Oi1");
  976. }
  977. else if ( strcmp( pThisArg, "i1" ) == 0 )
  978. {
  979. SetOptimizationFlags( OPTIMIZE_ALL_I1_FLAGS );
  980. OptimLevel = OPT_LEVEL_OIC;
  981. RpcError( NULL, 0, CMD_OI1_PHASED_OUT, "Oi1");
  982. }
  983. else if ( strcmp( pThisArg, "icf" ) == 0 ||
  984. strcmp( pThisArg, "if" ) == 0 )
  985. {
  986. SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
  987. OptimLevel = OPT_LEVEL_OICF;
  988. }
  989. else if ( strcmp( pThisArg, "i2" ) == 0 )
  990. {
  991. SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
  992. OptimLevel = OPT_LEVEL_OICF;
  993. RpcError( NULL, 0, CMD_OI2_OBSOLETE, "Oi2");
  994. }
  995. else
  996. goto illarg;
  997. }
  998. break;
  999. case SWITCH_ODL_ENV:
  1000. pThisArg -= 2; // back up past the first three characters of the switch "win"
  1001. SWValue = SWITCH_ENV; // to ensure that the right thing gets reported if an error occurs
  1002. // fall through to SWITCH_ENV
  1003. case SWITCH_ENV:
  1004. if( SelectChoice( EnvChoice,pThisArg, &Temp ) != STATUS_OK )
  1005. goto illarg;
  1006. Env = (unsigned char) Temp;
  1007. if (ENV_OBSOLETE == Env)
  1008. RpcError( NULL, 0, SWITCH_NOT_SUPPORTED_ANYMORE, pThisArg );
  1009. break;
  1010. case SWITCH_TARGET_SYSTEM:
  1011. if( SelectChoice( TargetChoice, pThisArg, &Temp ) != STATUS_OK )
  1012. goto illarg;
  1013. TargetSystem = (TARGET_ENUM) Temp;
  1014. GetNdrVersionControl().SetTargetSystem(TargetSystem);
  1015. break;
  1016. case SWITCH_TRANSFER_SYNTAX:
  1017. if ( SelectChoice( SyntaxChoice, pThisArg, &Temp ) != STATUS_OK )
  1018. goto illarg;
  1019. TargetSyntax = (SYNTAX_ENUM) Temp;
  1020. break;
  1021. case SWITCH_NO_WARN:
  1022. WLevel = 0; // was WARN_LEVEL_MAX
  1023. break;
  1024. case SWITCH_INTERNAL:
  1025. RpcError( 0, 0, INTERNAL_SWITCH_USED, NULL );
  1026. case SWITCH_NO_STAMP:
  1027. case SWITCH_NETMON:
  1028. case SWITCH_VERSION_STAMP:
  1029. case SWITCH_DEBUGEXC:
  1030. case SWITCH_DEBUGLINE:
  1031. case SWITCH_SYNTAX_CHECK:
  1032. case SWITCH_ZS:
  1033. case SWITCH_NO_CPP:
  1034. case SWITCH_SAVEPP:
  1035. case SWITCH_DUMP:
  1036. case SWITCH_OVERRIDE:
  1037. case SWITCH_NO_DEF_IDIR:
  1038. case SWITCH_USE_EPV:
  1039. case SWITCH_NO_DEFAULT_EPV:
  1040. case SWITCH_VERSION:
  1041. case SWITCH_CONFIRM:
  1042. case SWITCH_NOLOGO:
  1043. case SWITCH_HELP:
  1044. case SWITCH_WX:
  1045. case SWITCH_X:
  1046. case SWITCH_APPEND64:
  1047. case SWITCH_APP_CONFIG:
  1048. case SWITCH_MS_EXT:
  1049. case SWITCH_MS_CONF_STRUCT:
  1050. case SWITCH_MS_UNION:
  1051. case SWITCH_OLDNAMES:
  1052. case SWITCH_NO_FMT_OPT:
  1053. case SWITCH_GUARD_DEFS:
  1054. case SWITCH_C_EXT:
  1055. case SWITCH_OSF:
  1056. case SWITCH_MKTYPLIB:
  1057. case SWITCH_OLD_TLB:
  1058. case SWITCH_NEW_TLB:
  1059. case SWITCH_NO_SERVER:
  1060. case SWITCH_NO_CLIENT:
  1061. case SWITCH_NO_HEADER:
  1062. case SWITCH_NO_IID:
  1063. case SWITCH_NO_DLLDATA:
  1064. case SWITCH_NO_PROXY:
  1065. case SWITCH_NO_CLASS_METHODS:
  1066. case SWITCH_NO_CLASS_IUNKNOWN:
  1067. case SWITCH_NO_CLASS_HEADER:
  1068. case SWITCH_NO_PROXY_DEF:
  1069. case SWITCH_NO_DLL_SERVER_DEF:
  1070. case SWITCH_NO_DLL_SERVER_CLASS_GEN:
  1071. case SWITCH_NO_SERVER_REG:
  1072. case SWITCH_NO_EXE_SERVER:
  1073. case SWITCH_NO_EXE_SERVER_MAIN:
  1074. case SWITCH_NO_TESTCLIENT:
  1075. case SWITCH_RPCSS:
  1076. case SWITCH_ROBUST:
  1077. case SWITCH_NO_ROBUST:
  1078. case SWITCH_NOREUSE_BUFFER:
  1079. case SWITCH_USE_VT_INT_PTR:
  1080. case SWITCH_NO_TLIB:
  1081. case SWITCH_MS_EXT64:
  1082. case SWITCH_DEBUGINFO:
  1083. SwitchDefined( SWValue );
  1084. break;
  1085. case SWITCH_CPP_CMD:
  1086. case SWITCH_CPP_OPT:
  1087. case SWITCH_MSC_VER:
  1088. case SWITCH_DEBUG64:
  1089. case SWITCH_DEBUG64_OPT:
  1090. ProcessOnetimeSwitch( SWValue, pThisArg );
  1091. break;
  1092. case SWITCH_CLIENT:
  1093. if( SelectChoice( ClientChoice, pThisArg ,&Temp ) != STATUS_OK )
  1094. goto illarg;
  1095. fClient = (unsigned char) Temp;
  1096. break;
  1097. case SWITCH_SERVER:
  1098. if( SelectChoice( ServerChoice, pThisArg ,&Temp ) != STATUS_OK )
  1099. goto illarg;
  1100. fServer = (unsigned char) Temp;
  1101. break;
  1102. case SWITCH_CHAR:
  1103. if( SelectChoice( CharChoice, pThisArg ,&Temp ) != STATUS_OK )
  1104. goto illarg;
  1105. CharOption = (unsigned char) Temp;
  1106. break;
  1107. default:
  1108. break;
  1109. }
  1110. return Status;
  1111. illarg:
  1112. RpcError( (char *)NULL,
  1113. 0,
  1114. Status = ILLEGAL_ARGUMENT,
  1115. SwitchStringForValue( SWValue ) );
  1116. return Status;
  1117. }
  1118. STATUS_T
  1119. CommandLine::ProcessSimpleMultipleSwitch(
  1120. short SWValue,
  1121. char * pThisArg
  1122. )
  1123. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1124. Routine Description:
  1125. process simple switches which can be multiply defined.
  1126. Arguments:
  1127. SWValue - switch value
  1128. pThisArg - the users argument to this switch.
  1129. Return Value:
  1130. Notes:
  1131. check and warn for redefinition of the switch. Switch Warn is a special
  1132. case, the warn can be redefined. The last specified warning level is
  1133. valid.
  1134. Generally we let the user who redefines a switch off the hook. When the
  1135. arguments to a switch are wrong, we report an error and return an illegal
  1136. argument status.
  1137. ----------------------------------------------------------------------------*/
  1138. {
  1139. short Temp;
  1140. STATUS_T Status = STATUS_OK;
  1141. switch( SWValue )
  1142. {
  1143. case SWITCH_ERROR:
  1144. Temp = ERROR_NONE;
  1145. if( pThisArg && SelectChoice( ErrorChoice, pThisArg ,&Temp ) != STATUS_OK )
  1146. {
  1147. Status = ILLEGAL_ARGUMENT;
  1148. RpcError( (char *)0,
  1149. 0,
  1150. Status,
  1151. SwitchStringForValue( SWValue )
  1152. );
  1153. }
  1154. if( Temp == ERROR_NONE)
  1155. ErrorOption = ERROR_NONE;
  1156. else
  1157. ErrorOption |= Temp;
  1158. break;
  1159. case SWITCH_WIRE_COMPAT:
  1160. if( !pThisArg || ( SelectChoice( WireCompatChoice, pThisArg ,&Temp ) != STATUS_OK ) )
  1161. {
  1162. Status = ILLEGAL_ARGUMENT;
  1163. RpcError( (char *)0,
  1164. 0,
  1165. Status,
  1166. SwitchStringForValue( SWValue )
  1167. );
  1168. }
  1169. else
  1170. WireCompatOption |= Temp;
  1171. break;
  1172. default:
  1173. break;
  1174. }
  1175. return Status;
  1176. }
  1177. STATUS_T
  1178. CommandLine::SetPostDefaults()
  1179. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1180. Routine Description:
  1181. Set compiler switch defaults for switches not specified.
  1182. Arguments:
  1183. None.
  1184. Return Value:
  1185. None.
  1186. Notes:
  1187. ----------------------------------------------------------------------------*/
  1188. {
  1189. char agDrive[ _MAX_DRIVE ];
  1190. char agPath[ _MAX_PATH ];
  1191. char agBaseName[ _MAX_FNAME ];
  1192. char agExt[ _MAX_EXT ];
  1193. char agBuffer[ _MAX_DRIVE + _MAX_PATH + _MAX_FNAME + _MAX_EXT + 1 ];
  1194. if( !IsSwitchDefined( SWITCH_OUT ) )
  1195. {
  1196. strcpy( agDrive, "");
  1197. strcpy( agPath, ".\\");
  1198. }
  1199. else
  1200. {
  1201. _splitpath( pOutputPathSwitch->GetFileName(),
  1202. agDrive,
  1203. agPath,
  1204. agBaseName,
  1205. agExt );
  1206. strcat( agPath, agBaseName );
  1207. strcat( agPath, agExt );
  1208. delete pOutputPathSwitch;
  1209. }
  1210. agBaseName[0] = '\0';
  1211. agExt[0] = '\0';
  1212. _makepath( agBuffer, agDrive, agPath, agBaseName, agExt );
  1213. pOutputPathSwitch = new filename_switch( agBuffer );
  1214. _splitpath( agBuffer, agDrive, agPath, agBaseName, agExt );
  1215. // we have all the components but the base filename must be the
  1216. // filename of the input file. So we get this component of the base
  1217. // filename
  1218. pInputFNSwitch->GetFileNameComponents( (char *)NULL,
  1219. (char *)NULL,
  1220. agBaseName,
  1221. (char *)NULL );
  1222. // if the cstub switch is not set, set the default.
  1223. if(!IsSwitchDefined( SWITCH_CSTUB ) )
  1224. {
  1225. pCStubSwitch = new filename_switch( agDrive,
  1226. agPath,
  1227. agBaseName,
  1228. ".c",
  1229. "_c" );
  1230. }
  1231. else
  1232. pCStubSwitch->TransformFileNameForOut( agDrive, agPath );
  1233. // if the sstub switch is not set, set the default
  1234. if(!IsSwitchDefined( SWITCH_SSTUB ) )
  1235. {
  1236. pSStubSwitch = new filename_switch( agDrive,
  1237. agPath,
  1238. agBaseName,
  1239. ".c",
  1240. "_s" );
  1241. }
  1242. else
  1243. pSStubSwitch->TransformFileNameForOut( agDrive, agPath );
  1244. // if the IID switch is not set, set it
  1245. if(!IsSwitchDefined( SWITCH_IID ) )
  1246. {
  1247. pIIDSwitch = new filename_switch( agDrive,
  1248. agPath,
  1249. agBaseName,
  1250. ".c",
  1251. "_i" );
  1252. }
  1253. else
  1254. pIIDSwitch->TransformFileNameForOut( agDrive, agPath );
  1255. // if the Proxy switch is not set, set it
  1256. if(!IsSwitchDefined( SWITCH_PROXY ) )
  1257. {
  1258. pProxySwitch = new filename_switch( agDrive,
  1259. agPath,
  1260. agBaseName,
  1261. ".c",
  1262. "_p" );
  1263. }
  1264. else
  1265. pProxySwitch->TransformFileNameForOut( agDrive, agPath );
  1266. if (!IsSwitchDefined( SWITCH_TLIB ) )
  1267. {
  1268. pTlibSwitch = new filename_switch( agDrive,
  1269. agPath,
  1270. agBaseName,
  1271. ".tlb",
  1272. "" );
  1273. }
  1274. else
  1275. pTlibSwitch->TransformFileNameForOut(agDrive, agPath);
  1276. // if the DllData switch is not set, set it
  1277. if(!IsSwitchDefined( SWITCH_DLLDATA ) )
  1278. {
  1279. pDllDataSwitch = new filename_switch( agDrive,
  1280. agPath,
  1281. "dlldata",
  1282. ".c",
  1283. "" );
  1284. }
  1285. else
  1286. pDllDataSwitch->TransformFileNameForOut( agDrive, agPath );
  1287. // if the acf switch is not set, set it
  1288. if(!IsSwitchDefined( SWITCH_ACF ) )
  1289. {
  1290. pAcfSwitch = new filename_switch( agDrive,
  1291. agPath,
  1292. agBaseName,
  1293. ".acf",
  1294. (char *)NULL );
  1295. }
  1296. // if the header switch is not set, set it
  1297. if(!IsSwitchDefined( SWITCH_HEADER ) )
  1298. {
  1299. pHeaderSwitch = new filename_switch( agDrive,
  1300. agPath,
  1301. agBaseName,
  1302. ".h",
  1303. (char *)NULL );
  1304. }
  1305. else
  1306. pHeaderSwitch->TransformFileNameForOut( agDrive, agPath );
  1307. // set up the cpp options.
  1308. if( !IsSwitchDefined( SWITCH_CPP_CMD ) )
  1309. {
  1310. pCppCmdSwitch = new onetime_switch( C_PREPROCESSOR_NAME() );
  1311. }
  1312. if( !IsSwitchDefined( SWITCH_MSC_VER ) )
  1313. {
  1314. pMSCVerSwitch = new onetime_switch( "1100" );
  1315. MSCVersion = 1100;
  1316. }
  1317. // set up the cpp_opt and cc_opt. If he did not specify a cpp_opt
  1318. // then we will pass onto the preprocessor the /I , /D and /U options.
  1319. // if he did specify a cpp_opt, then he knows best, take his options
  1320. // and dont make your own assumptions.
  1321. if ( ! IsSwitchDefined( SWITCH_CPP_OPT ) )
  1322. {
  1323. int Len = 0;
  1324. char * pTemp,
  1325. * pTemp1;
  1326. Len += (int) strlen( ADDITIONAL_CPP_OPT() );
  1327. if( !pISwitch && IsSwitchDefined( SWITCH_NO_DEF_IDIR ) )
  1328. Len += (int) strlen( "-I." ) + 1;
  1329. if( pISwitch ) Len += pISwitch->GetConsolidatedLength( true ); // Room for quotes
  1330. if( pDSwitch ) Len += pDSwitch->GetConsolidatedLength();
  1331. if( pUSwitch ) Len += pUSwitch->GetConsolidatedLength();
  1332. pTemp = new char[ Len + 1 ]; pTemp[0] = '\0';
  1333. if( !pISwitch && IsSwitchDefined( SWITCH_NO_DEF_IDIR ) )
  1334. {
  1335. strcat( pTemp, "-I." );
  1336. }
  1337. if( pISwitch )
  1338. {
  1339. strcat( pTemp, pTemp1 = pISwitch->GetConsolidatedOptions( true ) ); // Get quotes
  1340. delete pTemp1;
  1341. }
  1342. if( pDSwitch )
  1343. {
  1344. strcat( pTemp, pTemp1 = pDSwitch->GetConsolidatedOptions() );
  1345. delete pTemp1;
  1346. }
  1347. if( pUSwitch )
  1348. {
  1349. strcat( pTemp, pTemp1 = pUSwitch->GetConsolidatedOptions() );
  1350. delete pTemp1;
  1351. }
  1352. strcat( pTemp, ADDITIONAL_CPP_OPT() );
  1353. pCppOptSwitch = new onetime_switch( pTemp );
  1354. delete []pTemp;
  1355. }
  1356. // if he specified the cpp_cmd or cpp_opt switches, then no_cpp
  1357. // overrides them if specified.
  1358. if( IsSwitchDefined( SWITCH_NO_CPP ) )
  1359. {
  1360. if( IsSwitchDefined( SWITCH_CPP_CMD) ||
  1361. IsSwitchDefined( SWITCH_CPP_OPT) )
  1362. {
  1363. RpcError( (char *)NULL,
  1364. 0,
  1365. NO_CPP_OVERRIDES,
  1366. (char *)NULL );
  1367. }
  1368. }
  1369. // if the client switch is not defined, define it
  1370. if( !IsSwitchDefined( SWITCH_CLIENT ) )
  1371. {
  1372. fClient = CLNT_STUB;
  1373. }
  1374. // if warnlevel and no_warn is defined, then errors
  1375. if( IsSwitchDefined( SWITCH_W ) &&
  1376. (IsSwitchDefined( SWITCH_NO_WARN ) || (WLevel == 0) ) )
  1377. {
  1378. //
  1379. // if we set the no_warn switch already then this warning will itself
  1380. // not be emitted. Make the current warning level 1 so that this warning
  1381. // will be spit out. WLevel is made 0 anyways after that.
  1382. //
  1383. WLevel = 1;
  1384. RpcError( (char *)NULL,
  1385. 0,
  1386. NO_WARN_OVERRIDES,
  1387. (char *)NULL );
  1388. WLevel = 0;
  1389. }
  1390. // if the error switch is not defined, define it.
  1391. if( !IsSwitchDefined( SWITCH_ERROR ) )
  1392. {
  1393. ErrorOption = ERROR_ALL;
  1394. }
  1395. else if ( GetNdrVersionControl().TargetIsNT40OrLater() )
  1396. {
  1397. if ( ERROR_ALL != ErrorOption )
  1398. {
  1399. RpcError(
  1400. NULL,
  1401. 0,
  1402. CONTRADICTORY_SWITCHES,
  1403. "-error vs. -target" );
  1404. }
  1405. }
  1406. /////////////////////////////////////////////////////////////////////
  1407. // if he defined env, then he may want to compile for a platform different
  1408. // from what he is building for. Take care of platform dependent switches
  1409. // for the proper platforms.
  1410. // 64 bit additions:
  1411. // -append64 means forcing the appending on the current run
  1412. // .. it should be the second run, but it always forces with win32 or 64
  1413. // -win32 or -win64 means 32 or 64 bit run only, respectively.
  1414. //
  1415. if ( !IsSwitchDefined( SWITCH_ENV )
  1416. && NT40 == GetNdrVersionControl().GetTargetSystem() )
  1417. {
  1418. SetEnv( ENV_WIN32 );
  1419. SwitchDefined( SWITCH_ENV );
  1420. }
  1421. if( IsSwitchDefined( SWITCH_ENV ) )
  1422. {
  1423. if( !IsSwitchDefined( SWITCH_ZP ) )
  1424. {
  1425. switch( GetEnv() )
  1426. {
  1427. case ENV_WIN32: ZeePee = DEFAULT_ZEEPEE; break;
  1428. case ENV_WIN64: ZeePee = DEFAULT_ZEEPEE; break;
  1429. default: ZeePee = DEFAULT_ZEEPEE; break;
  1430. }
  1431. }
  1432. // EnumSize is set to 4 by default
  1433. }
  1434. if ( NT40 == GetNdrVersionControl().GetTargetSystem()
  1435. && ENV_WIN32 != GetEnv()
  1436. )
  1437. {
  1438. RpcError(
  1439. NULL,
  1440. 0,
  1441. CONTRADICTORY_SWITCHES,
  1442. "-win64 vs. -target NT40" );
  1443. }
  1444. if ( !IsSwitchDefined ( SWITCH_TRANSFER_SYNTAX ) )
  1445. {
  1446. if ( GetNdrVersionControl().TargetIsNT51OrLater() )
  1447. TargetSyntax = SYNTAX_BOTH;
  1448. else
  1449. TargetSyntax = SYNTAX_DCE;
  1450. }
  1451. if ( GetNdrVersionControl().TargetIsNT51OrLater() )
  1452. {
  1453. if ( SYNTAX_BOTH != TargetSyntax )
  1454. {
  1455. RpcError(
  1456. NULL,
  1457. 0,
  1458. CONTRADICTORY_SWITCHES,
  1459. "-protocol vs. -target NT51" );
  1460. }
  1461. }
  1462. if ( GetNdrVersionControl().TargetIsLessThanNT51() &&
  1463. (TargetSyntax != SYNTAX_DCE ) )
  1464. {
  1465. RpcError(
  1466. NULL,
  1467. 0,
  1468. CONTRADICTORY_SWITCHES,
  1469. "-protocol ndr(all) vs. -target NT40/NT50, use -target NT51 with -protocol ndr64(all)" );
  1470. }
  1471. // we support ndr64 on 32bit platform only when -internal is specified.
  1472. if ( ( TargetSyntax == SYNTAX_NDR64 ) &&
  1473. ( GetEnv() == ENV_WIN32 ) &&
  1474. !IsSwitchDefined( SWITCH_INTERNAL ) )
  1475. {
  1476. RpcError( NULL, 0, UNSUPPORT_NDR64_FEATURE, 0 );
  1477. }
  1478. // ndr64 is not supported in /Osf mode
  1479. if ( IsSwitchDefined(SWITCH_OSF) && TargetSyntax != SYNTAX_DCE )
  1480. {
  1481. RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-osf vs. -protocol ndr64 or -protocol all" );
  1482. }
  1483. if ( GetEnv() == ENV_WIN64 || GetEnv() == ENV_WIN32 )
  1484. {
  1485. if ( IsSwitchDefined( SWITCH_APPEND64 ) )
  1486. {
  1487. SetHasAppend64( TRUE );
  1488. SetEnv( ENV_WIN64 );
  1489. }
  1490. }
  1491. if ( GetEnv() == ENV_WIN64 )
  1492. {
  1493. // -ms_ext64 is set by default in 64bit.
  1494. SwitchDefined( SWITCH_MS_EXT64 );
  1495. }
  1496. if ( IsSwitchDefined( SWITCH_MS_EXT64 ) )
  1497. GetNdrVersionControl().SetHasMsExt64();
  1498. if ( IsSwitchDefined(SWITCH_OSF) && IsSwitchDefined(SWITCH_C_EXT) ||
  1499. IsSwitchDefined(SWITCH_OSF) && IsSwitchDefined(SWITCH_MS_EXT) )
  1500. {
  1501. RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-osf vs. -ms_ext or -c_ext" );
  1502. }
  1503. // BIG CHANGE! default becomes -Oicf
  1504. if ( !IsSwitchDefined( SWITCH_O ) )
  1505. {
  1506. SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
  1507. OptimLevel = OPT_LEVEL_OICF;
  1508. SwitchDefined( SWITCH_O );
  1509. }
  1510. else if ( GetNdrVersionControl().TargetIsNT40OrLater() )
  1511. {
  1512. if ( OptimLevel != OPT_LEVEL_OICF )
  1513. {
  1514. RpcError(
  1515. NULL,
  1516. 0,
  1517. CONTRADICTORY_SWITCHES,
  1518. "-Os/Oi/Oic vs. -target" );
  1519. }
  1520. }
  1521. //robust is on unless specified otherwise.
  1522. // robust is not supported in NT4 variaties.
  1523. if ( ( OptimLevel == OPT_LEVEL_OICF ) &&
  1524. !IsSwitchDefined( SWITCH_NO_ROBUST ) &&
  1525. ( GetNdrVersionControl().GetTargetSystem() != NT40 ) )
  1526. SwitchDefined( SWITCH_ROBUST );
  1527. if ( GetEnv() == ENV_WIN64 )
  1528. {
  1529. SetPostDefaults64();
  1530. }
  1531. if ( ( GetOptimizationFlags() != OPTIMIZE_ALL_I2_FLAGS ) &&
  1532. ( TargetSyntax != SYNTAX_DCE ) )
  1533. {
  1534. RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-Os/Oi/Oic vs. -protocol ndr64 or -protocol all" );
  1535. }
  1536. // Force /Oicf when ( /Oi or /Os ) are used with /robust
  1537. if ( GetNdrVersionControl().TargetIsNT50OrLater() )
  1538. {
  1539. if ( IsSwitchDefined( SWITCH_NO_ROBUST ) )
  1540. RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-no_robust vs. -target" );
  1541. else
  1542. SwitchDefined( SWITCH_ROBUST );
  1543. }
  1544. if ( IsSwitchDefined( SWITCH_ROBUST ) )
  1545. {
  1546. if ( IsSwitchDefined( SWITCH_NO_ROBUST ) )
  1547. RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-robust vs. -no_robust" );
  1548. if ( NT40 == GetNdrVersionControl().GetTargetSystem() )
  1549. RpcError( NULL, 0, CONTRADICTORY_SWITCHES, "-robust vs. -target NT40" );
  1550. GetNdrVersionControl().SetHasDOA();
  1551. if ( ( GetOptimizationFlags() & OPTIMIZE_ALL_I2_FLAGS ) != OPTIMIZE_ALL_I2_FLAGS )
  1552. {
  1553. RpcError( 0, 0, ROBUST_REQUIRES_OICF, 0 );
  1554. }
  1555. SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
  1556. }
  1557. if ( !IsSwitchDefined( SWITCH_INTERNAL ) )
  1558. {
  1559. // Make sure netmon switches also use -internal
  1560. if ( IsSwitchDefined( SWITCH_NETMON ) )
  1561. {
  1562. ReportUnimplementedSwitch( SWITCH_NETMON );
  1563. }
  1564. else if ( IsSwitchDefined( SWITCH_NETMON_STUB_OUTPUT_FILE ) )
  1565. {
  1566. ReportUnimplementedSwitch( SWITCH_NETMON_STUB_OUTPUT_FILE );
  1567. }
  1568. else if ( IsSwitchDefined( SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE ) )
  1569. {
  1570. ReportUnimplementedSwitch( SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE );
  1571. }
  1572. }
  1573. // Make sure -netmon is only used with -Oicf and setup output files
  1574. if ( IsSwitchDefined( SWITCH_NETMON ))
  1575. {
  1576. if ( ! ( ( GetOptimizationFlags() & OPTIMIZE_ALL_I2_FLAGS ) &&
  1577. OptimLevel == OPT_LEVEL_OICF ) )
  1578. {
  1579. RpcError( 0, 0, NETMON_REQUIRES_OICF, 0 );
  1580. }
  1581. if (!IsSwitchDefined (SWITCH_NETMON_STUB_OUTPUT_FILE))
  1582. {
  1583. pNetmonStubSwitch = new filename_switch( agDrive,
  1584. agPath,
  1585. agBaseName,
  1586. ".c",
  1587. "_netmon_stub" );
  1588. }
  1589. else
  1590. {
  1591. pNetmonStubSwitch->TransformFileNameForOut( agDrive, agPath );
  1592. }
  1593. if (!IsSwitchDefined (SWITCH_NETMON_STUB_OBJ_OUTPUT_FILE))
  1594. {
  1595. pNetmonStubObjSwitch = new filename_switch( agDrive,
  1596. agPath,
  1597. agBaseName,
  1598. ".c",
  1599. "_netmon_stub_obj" );
  1600. }
  1601. else
  1602. {
  1603. pNetmonStubObjSwitch->TransformFileNameForOut( agDrive, agPath );
  1604. }
  1605. }
  1606. // Check if the target system is consistent with other switches.
  1607. if ( TargetSystem < NT40 && IsSwitchDefined( SWITCH_NETMON) )
  1608. RpcError( NULL, 0, CMD_REQUIRES_NT40, "netmon" );
  1609. // If the -no_default_epv switch is specified then -epv switch is auto
  1610. // enabled.
  1611. if( IsSwitchDefined( SWITCH_NO_DEFAULT_EPV ) )
  1612. SwitchDefined( SWITCH_USE_EPV );
  1613. // if he specified all, set them all
  1614. if ( IsSwitchDefined( SWITCH_PREFIX ) )
  1615. {
  1616. char * pAll = pSwitchPrefix->GetUserDefinedEquivalent( PREFIX_ALL );
  1617. if ( pAll )
  1618. {
  1619. for ( short j = 0; j < PREFIX_ALL; j++ )
  1620. {
  1621. if ( !pSwitchPrefix->GetUserDefinedEquivalent( j ) )
  1622. pSwitchPrefix->AddPair( j, pAll );
  1623. }
  1624. }
  1625. }
  1626. SetModeSwitchConfigMask();
  1627. return STATUS_OK;
  1628. }
  1629. void
  1630. CommandLine::SetPostDefaults64()
  1631. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1632. Routine Description:
  1633. Set switch defaults for 64 bit runs
  1634. Arguments:
  1635. None.
  1636. Return Value:
  1637. None.
  1638. Notes:
  1639. ----------------------------------------------------------------------------*/
  1640. {
  1641. GetNdrVersionControl().SetHas64BitSupport();
  1642. if ( IsSwitchDefined( SWITCH_O ) )
  1643. {
  1644. // For 64b force any interpreter mode to be -Oicf.
  1645. //
  1646. if ( OptimFlags == OPTIMIZE_SIZE )
  1647. {
  1648. // RpcError( NULL, 0, WIN64_INTERPRETED, "-Oicf" );
  1649. }
  1650. else if ( OptimLevel != OPT_LEVEL_OICF )
  1651. {
  1652. RpcError( NULL, 0, WIN64_INTERPRETED, ": -Oicf" );
  1653. SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
  1654. OptimLevel = OPT_LEVEL_OICF;
  1655. }
  1656. }
  1657. else
  1658. {
  1659. // Default for the -O switch is -Oicf on 64b
  1660. SetOptimizationFlags( OPTIMIZE_ALL_I2_FLAGS );
  1661. OptimLevel = OPT_LEVEL_OICF;
  1662. }
  1663. // Disable -no_robust switch for 277.
  1664. // if ( ! IsSwitchDefined( SWITCH_NO_ROBUST ) &&
  1665. if ( GetOptimizationFlags() & OPTIMIZE_ALL_I2_FLAGS )
  1666. {
  1667. // Default 64b processing to robust, when -Oicf, unless -no_robust
  1668. GetNdrVersionControl().SetHasDOA();
  1669. SwitchDefined( SWITCH_ROBUST );
  1670. }
  1671. }
  1672. /*****************************************************************************
  1673. * utility functions
  1674. *****************************************************************************/
  1675. void
  1676. ReportUnimplementedSwitch(
  1677. short SWValue
  1678. )
  1679. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1680. Routine Description:
  1681. report an unimplemented switch error.
  1682. Arguments:
  1683. SWValue - switch value.
  1684. Return Value:
  1685. None.
  1686. Notes:
  1687. ----------------------------------------------------------------------------*/
  1688. {
  1689. char buf[ 50 ];
  1690. strcpy(buf, SwitchStringForValue( SWValue ) );
  1691. RpcError((char *)NULL,0,UNIMPLEMENTED_SWITCH, buf);
  1692. }
  1693. STATUS_T
  1694. SelectChoice(
  1695. const CHOICE * pCh,
  1696. char * pUserInput,
  1697. short * pChoice)
  1698. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1699. Routine Description:
  1700. Search for the given multiple choice table for the given choice.
  1701. Arguments:
  1702. pCh - pointer to multiple choice table.
  1703. pUserInput - user input string.
  1704. pChoice - return the choice value.
  1705. Return Value:
  1706. ILLEGAL_ARGUMENT if the user input did not represent a valid choice
  1707. for the switch.
  1708. STATUS_OK if everything is hunky dory.
  1709. Notes:
  1710. ----------------------------------------------------------------------------*/
  1711. {
  1712. char * pChStr;
  1713. while ( pCh && ( pChStr = (char *) pCh->pChoice ) != 0 )
  1714. {
  1715. if( strcmp( pChStr, pUserInput ) == 0 )
  1716. {
  1717. *pChoice = pCh->Choice;
  1718. return STATUS_OK;
  1719. }
  1720. pCh++;
  1721. }
  1722. return ILLEGAL_ARGUMENT;
  1723. }
  1724. enum _swenum
  1725. SearchForSwitch(
  1726. char ** ppArg )
  1727. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1728. Routine Description:
  1729. Search for the switch, given the users input as switch name.
  1730. Arguments:
  1731. ppArg - pointer to users input pointer.
  1732. Return Value:
  1733. the switch value, if found, SWITCH_NOTHING otherwise.
  1734. Notes:
  1735. search for exact switch name match, and if found, bump the pointer to
  1736. point to the character after the switch name, so that any input to the
  1737. switch can be looked at after the switch string is out of the way.
  1738. Checking the exact length may be a problem, because some switches like
  1739. -I can take no space between the arg. In these cases, ignore the length
  1740. match.
  1741. ----------------------------------------------------------------------------*/
  1742. {
  1743. short Len , LenArg, iIndex = 0;
  1744. BOOL fLengthIsOk;
  1745. char * pSrc;
  1746. struct sw_desc * pSwDesc = (struct sw_desc*) &switch_desc[0];
  1747. LenArg = (short)strlen( *ppArg );
  1748. while( iIndex < (sizeof(switch_desc) / sizeof( struct sw_desc ) ) )
  1749. {
  1750. pSrc = (char *) pSwDesc->pSwitchName;
  1751. Len = (short)strlen( pSrc );
  1752. fLengthIsOk =
  1753. ((pSwDesc->flag & ARG_SPACE_OPTIONAL) || (Len==LenArg));
  1754. if(fLengthIsOk && strncmp( pSrc, *ppArg, Len ) == 0 )
  1755. {
  1756. *ppArg += Len;
  1757. return (_swenum) iIndex;
  1758. }
  1759. iIndex++;
  1760. pSwDesc++;
  1761. }
  1762. return SWITCH_NOTHING;
  1763. }
  1764. char*
  1765. SwitchStringForValue(
  1766. unsigned short SWValue
  1767. )
  1768. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1769. Routine Description:
  1770. return the switch string given the value of the switch.
  1771. Arguments:
  1772. SWValue - switch value.
  1773. Return Value:
  1774. pointer to the switch string. pointer to a null string if not found.
  1775. Notes:
  1776. ----------------------------------------------------------------------------*/
  1777. {
  1778. #define SWITCH_DESC_SIZE (sizeof(switch_desc) / sizeof(struct sw_desc))
  1779. struct sw_desc * pDesc = (struct sw_desc*) &switch_desc[0],
  1780. * pDescEnd = (struct sw_desc*) &switch_desc[0] + SWITCH_DESC_SIZE;
  1781. while( pDesc < pDescEnd )
  1782. {
  1783. if( pDesc->SwitchValue == (enum _swenum ) SWValue)
  1784. return (char *) pDesc->pSwitchName;
  1785. pDesc++;
  1786. }
  1787. return "";
  1788. }
  1789. inline
  1790. char *
  1791. YesOrNoString( BOOL Yes )
  1792. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1793. Routine Description:
  1794. return "Yes" for true, "No" for false
  1795. Arguments:
  1796. None.
  1797. Return Value:
  1798. None.
  1799. Notes:
  1800. ----------------------------------------------------------------------------*/
  1801. {
  1802. return Yes ? "Yes" : "No";
  1803. }
  1804. void
  1805. CommandLine::Confirm()
  1806. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1807. Routine Description:
  1808. confirm the arguments by dumping onto the screen
  1809. Arguments:
  1810. None.
  1811. Return Value:
  1812. None.
  1813. Notes:
  1814. ----------------------------------------------------------------------------*/
  1815. {
  1816. short Option;
  1817. char * p;
  1818. char Buffer[100];
  1819. fprintf( stdout, "%s bit arguments",
  1820. (Is64BitEnv() ? "64" : "32" )
  1821. );
  1822. PrintArg( BASE_FILENAME, GetInputFileName() , 0 );
  1823. if( IsSwitchDefined( SWITCH_ACF ) )
  1824. PrintArg( SWITCH_ACF , GetAcfFileName(), 0);
  1825. PrintArg( SWITCH_APP_CONFIG,
  1826. YesOrNoString(IsSwitchDefined( SWITCH_APP_CONFIG)), 0);
  1827. PrintArg( SWITCH_C_EXT,
  1828. YesOrNoString(IsSwitchDefined( SWITCH_C_EXT)), 0);
  1829. Option = GetClientSwitchValue();
  1830. PrintArg( SWITCH_CLIENT,
  1831. (Option == CLNT_STUB) ? "stub" : "none", 0);
  1832. Option = GetCharOption();
  1833. PrintArg( SWITCH_CHAR, (Option == CHAR_SIGNED ) ? "signed" :
  1834. (Option == CHAR_UNSIGNED ) ? "unsigned" : "ascii7",0);
  1835. if( IsSwitchDefined(SWITCH_CONFIRM) )
  1836. PrintArg( SWITCH_CONFIRM, "Yes" , 0);
  1837. PrintArg( SWITCH_CPP_CMD, GetCPPCmd() , 0);
  1838. PrintArg( SWITCH_CPP_OPT, GetCPPOpt() , 0);
  1839. _itoa( GetMSCVer(), Buffer, 10 );
  1840. PrintArg( SWITCH_MSC_VER, Buffer , 0);
  1841. if ( ( p = GetCstubFName() ) != 0 )
  1842. PrintArg( SWITCH_CSTUB, p , 0);
  1843. if( IsSwitchDefined( SWITCH_D ) )
  1844. PrintArg( SWITCH_D, pDSwitch->GetConsolidatedOptions(), 0 );
  1845. Option = GetEnv();
  1846. PrintArg( SWITCH_ENV,
  1847. (Option == ENV_WIN64) ? "win64"
  1848. : "win32",
  1849. 0 );
  1850. PrintArg( SWITCH_APPEND64,
  1851. YesOrNoString(IsSwitchDefined( SWITCH_APPEND64)), 0);
  1852. Option = GetErrorOption();
  1853. Option = (short)IsRpcSSAllocateEnabled();
  1854. PrintArg( SWITCH_RPCSS,
  1855. YesOrNoString(IsSwitchDefined( SWITCH_RPCSS)), 0);
  1856. #ifdef MIDL_INTERNAL
  1857. PrintArg( SWITCH_NETMON,
  1858. YesOrNoString(IsSwitchDefined( SWITCH_NETMON)), 0);
  1859. #endif
  1860. PrintArg( SWITCH_USE_EPV, YesOrNoString(IsSwitchDefined( SWITCH_USE_EPV )), 0);
  1861. PrintArg( SWITCH_NO_DEFAULT_EPV, YesOrNoString(IsSwitchDefined( SWITCH_NO_DEFAULT_EPV )), 0);
  1862. //
  1863. // error options.
  1864. //
  1865. Buffer[0] = '\0';
  1866. if( ErrorOption != ERROR_NONE )
  1867. {
  1868. if( ErrorOption & ERROR_ALLOCATION )
  1869. strcat( Buffer, "allocation ");
  1870. if( ErrorOption & ERROR_REF )
  1871. strcat( Buffer, "ref ");
  1872. if( ErrorOption & ERROR_BOUNDS_CHECK )
  1873. strcat( Buffer, "bounds_check ");
  1874. if( ErrorOption & ERROR_ENUM )
  1875. strcat( Buffer, "enum ");
  1876. if( ErrorOption & ERROR_STUB_DATA )
  1877. strcat( Buffer, "stub_data ");
  1878. }
  1879. else
  1880. strcat( Buffer, "none" );
  1881. PrintArg( SWITCH_ERROR, Buffer, 0 );
  1882. if ( ( p = GetHeader() ) != 0 )
  1883. PrintArg( SWITCH_HEADER, p , 0);
  1884. if( IsSwitchDefined( SWITCH_I ) )
  1885. PrintArg( SWITCH_I, pISwitch->GetConsolidatedOptions(), 0 );
  1886. PrintArg( SWITCH_NOLOGO,
  1887. YesOrNoString(IsSwitchDefined( SWITCH_NOLOGO)), 0);
  1888. PrintArg( SWITCH_MS_EXT,
  1889. YesOrNoString(IsSwitchDefined( SWITCH_MS_EXT)), 0);
  1890. PrintArg( SWITCH_MS_UNION,
  1891. YesOrNoString(IsSwitchDefined( SWITCH_MS_UNION)), 0);
  1892. PrintArg( SWITCH_NO_FMT_OPT,
  1893. YesOrNoString(IsSwitchDefined( SWITCH_NO_FMT_OPT)), 0);
  1894. #ifdef MIDL_INTERNAL
  1895. PrintArg( SWITCH_GUARD_DEFS,
  1896. YesOrNoString(IsSwitchDefined( SWITCH_GUARD_DEFS)), 0);
  1897. #endif
  1898. PrintArg( SWITCH_OLDNAMES,
  1899. YesOrNoString(IsSwitchDefined( SWITCH_OLDNAMES)), 0);
  1900. if ( 0 != WireCompatOption)
  1901. {
  1902. Buffer[0] = '\0';
  1903. if( ErrorOption & WIRE_COMPAT_ENUM16UNIONALIGN )
  1904. strcat( Buffer, "enum16unionalign ");
  1905. PrintArg( SWITCH_WIRE_COMPAT, Buffer, 0 );
  1906. }
  1907. if( IsSwitchDefined( SWITCH_NO_CPP ) )
  1908. PrintArg( SWITCH_NO_CPP, "Yes" , 0);
  1909. if( IsSwitchDefined( SWITCH_NO_DEF_IDIR ) )
  1910. PrintArg( SWITCH_NO_DEF_IDIR, "Yes", 0 );
  1911. if( IsSwitchDefined( SWITCH_NO_WARN ) )
  1912. PrintArg( SWITCH_NO_WARN, "Yes" , 0);
  1913. if( IsSwitchDefined( SWITCH_USE_EPV ) )
  1914. PrintArg( SWITCH_USE_EPV, "Yes" , 0);
  1915. if( IsSwitchDefined( SWITCH_NO_DEFAULT_EPV ) )
  1916. PrintArg( SWITCH_NO_DEFAULT_EPV, "Yes" , 0);
  1917. if ( ( p = GetOutputPath() ) != 0 )
  1918. PrintArg( SWITCH_OUT, GetOutputPath(), 0 );
  1919. Option = GetZeePee();
  1920. if( IsSwitchDefined( SWITCH_PACK ) )
  1921. PrintArg( SWITCH_PACK,
  1922. (Option == 1) ? "1" :
  1923. (Option == 2) ? "2" :
  1924. (Option == 4) ? "4" : "8" , 0);
  1925. if( IsSwitchDefined( SWITCH_PREFIX ) )
  1926. {
  1927. char * pSys;
  1928. char * pUser;
  1929. char * pAll = pSwitchPrefix->GetUserDefinedEquivalent( PREFIX_ALL );
  1930. short Cur;
  1931. while( (Cur = pSwitchPrefix->GetNext( &pSys, &pUser ) ) >= 0 )
  1932. {
  1933. // if he specified all, don't report others that are the same
  1934. if ( ( Cur == PREFIX_ALL ) ||
  1935. !pAll ||
  1936. strcmp( pAll, pUser ) )
  1937. {
  1938. PrintArg( SWITCH_PREFIX,
  1939. pSys,
  1940. pUser );
  1941. }
  1942. }
  1943. }
  1944. Option = GetServerSwitchValue();
  1945. PrintArg( SWITCH_SERVER,
  1946. (Option == SRVR_STUB) ? "stub" : "none" , 0 );
  1947. if ( ( p = GetSstubFName() ) != 0 )
  1948. PrintArg( SWITCH_SSTUB, p , 0);
  1949. if ( IsSwitchDefined( SWITCH_SYNTAX_CHECK ) )
  1950. PrintArg( SWITCH_SYNTAX_CHECK, "Yes", 0 );
  1951. if ( IsSwitchDefined( SWITCH_U ) )
  1952. PrintArg( SWITCH_U, pUSwitch->GetConsolidatedOptions(), 0 );
  1953. PrintArg( SWITCH_O,
  1954. GetOptimizationFlags() == OPTIMIZE_SIZE
  1955. ? "inline stubs"
  1956. : "interpreted stubs",
  1957. 0 );
  1958. Option = GetWarningLevel();
  1959. PrintArg( SWITCH_W,
  1960. (Option == 0 ) ? "0" :
  1961. (Option == 1 ) ? "1" :
  1962. (Option == 2 ) ? "2" :
  1963. (Option == 3 ) ? "3" :
  1964. (Option == 4 ) ? "4" :
  1965. (Option == 5 ) ? "5" : "6" , 0);
  1966. if( IsSwitchDefined( SWITCH_WX ) )
  1967. PrintArg( SWITCH_WX, "Yes", 0 );
  1968. Option = GetZeePee();
  1969. PrintArg( SWITCH_ZP,
  1970. (Option == 1) ? "1" :
  1971. (Option == 2) ? "2" :
  1972. (Option == 4) ? "4" : "8" , 0);
  1973. if( IsSwitchDefined( SWITCH_ZS ) )
  1974. PrintArg( SWITCH_ZS, "Yes", 0 );
  1975. if( IsSwitchDefined( SWITCH_MS_CONF_STRUCT ) )
  1976. PrintArg( SWITCH_MS_CONF_STRUCT, "Yes", 0 );
  1977. fprintf(stdout, "\n" );
  1978. }
  1979. char *
  1980. CommandLine::GetCompilerVersion()
  1981. {
  1982. if ( !szCompilerVersion[0] )
  1983. {
  1984. sprintf( szCompilerVersion, "%d.%02d.%04d", rmj, rmm, rup );
  1985. }
  1986. return szCompilerVersion;
  1987. }
  1988. // note that this string ends with a newline.
  1989. char *
  1990. CommandLine::GetCompileTime()
  1991. {
  1992. if ( !szCompileTime[0] )
  1993. {
  1994. time_t LocalTime;
  1995. // fetch the time
  1996. time( &LocalTime );
  1997. // convert to a string
  1998. strcpy( szCompileTime, ctime( &LocalTime ) );
  1999. }
  2000. return szCompileTime;
  2001. }
  2002. // ----------------------------------------------------------------------------
  2003. // The help screen(s)
  2004. //
  2005. const char *HelpArray[] = {
  2006. " -MIDL COMPILER OPTIONS-"
  2007. ," -MODE-"
  2008. ,"/ms_ext Microsoft extensions to the IDL language (default)"
  2009. ,"/c_ext Allow Microsoft C extensions in the IDL file (default)"
  2010. ,"/osf OSF mode - disables /ms_ext and /c_ext options"
  2011. ,"/app_config Allow selected ACF attributes in the IDL file"
  2012. ,"/mktyplib203 MKTYPLIB Version 2.03 compatiblity mode"
  2013. ,""
  2014. ," -INPUT-"
  2015. ,"/acf filename Specify the attribute configuration file"
  2016. ,"/I directory-list Specify one or more directories for include path"
  2017. ,"/no_def_idir Ignore the current and the INCLUDE directories"
  2018. ,""
  2019. ," -OUTPUT FILE GENERATION-"
  2020. ,"/client none Do not generate client files"
  2021. ,"/client stub Generate client stub file only"
  2022. ,"/out directory Specify destination directory for output files"
  2023. ,"/server none Generate no server files"
  2024. ,"/server stub Generate server stub file only"
  2025. ,"/syntax_check Check syntax only; do not generate output files"
  2026. ,"/Zs Check syntax only; do not generate output files"
  2027. ,"/oldtlb Generate old format type libraries"
  2028. ,"/newtlb Generate new format type libraries (default)"
  2029. ,"/notlb Don't generate the tlb file"
  2030. ,""
  2031. ," -OUTPUT FILE NAMES-"
  2032. ,"/cstub filename Specify client stub file name"
  2033. ,"/dlldata filename Specify dlldata file name"
  2034. ,"/h filename Specify header file name"
  2035. ,"/header filename Specify header file name"
  2036. ,"/iid filename Specify interface UUID file name"
  2037. ,"/proxy filename Specify proxy file name"
  2038. ,"/sstub filename Specify server stub file name"
  2039. ,"/tlb filename Specify type library file name"
  2040. #ifdef MIDL_INTERNAL
  2041. ,"/netmonstub filename Specify Netmon classic interface stub file name"
  2042. ,"/netmonobjstub filename Specify Netmon object interface stub file name"
  2043. #endif // MIDL_INTERNAL
  2044. ,""
  2045. ," -C COMPILER AND PREPROCESSOR OPTIONS-"
  2046. ,"/cpp_cmd cmd_line Specify name of C preprocessor (default: cl.exe)"
  2047. ,"/cpp_opt options Specify additional C preprocessor options"
  2048. ,"/D name[=def] Pass #define name, optional value to C preprocessor"
  2049. ,"/no_cpp Turn off the C preprocessing option"
  2050. ,"/nocpp Turn off the C preprocessing option"
  2051. ,"/U name Remove any previous definition (undefine)"
  2052. ,"/msc_ver <nnnn> Microsoft C/C++ compiler version"
  2053. ,"/savePP Save the preprocessed temporary file(s)"
  2054. ,""
  2055. ," -ENVIRONMENT-"
  2056. ,"/char signed C compiler default char type is signed"
  2057. ,"/char unsigned C compiler default char type is unsigned"
  2058. ,"/char ascii7 Char values limited to 0-127"
  2059. ,"/env win32 Target environment is Microsoft Windows 32-bit (NT)"
  2060. ,"/env win64 Target environment is Microsoft Windows 64-bit (NT)"
  2061. ,"/lcid Locale id for international locales"
  2062. ,"/ms_union Use Midl 1.0 non-DCE wire layout for non-encapsulated unions"
  2063. ,"/oldnames Do not mangle version number into names"
  2064. ,"/rpcss Automatically activate rpc_sm_enable_allocate"
  2065. ,"/use_epv Generate server side application calls via entry-pt vector"
  2066. ,"/no_default_epv Do not generate a default entry-point vector"
  2067. ,"/prefix client str Add \"str\" prefix to client-side entry points"
  2068. ,"/prefix server str Add \"str\" prefix to server-side manager routines"
  2069. ,"/prefix switch str Add \"str\" prefix to switch routine prototypes"
  2070. ,"/prefix all str Add \"str\" prefix to all routines"
  2071. ,"/win32 Target environment is Microsoft Windows 32-bit (NT)"
  2072. ,"/win64 Target environment is Microsoft Windows 64-bit (NT)"
  2073. ,"/protocol dce Use DCE NDR transfer syntax (default for 32b)"
  2074. ,"/protocol all Use all supported transfer syntaxes"
  2075. ,"/protocol ndr64 Use Microsoft extension NDR64 transfer syntax"
  2076. ,"/target {system} Set the minimum target system"
  2077. ,""
  2078. ," -RUNTIME ERROR CHECKING BY STUBS-"
  2079. ,"/error all Turn on all the error checking options, the best flavor"
  2080. ,"/error none Turn off all the error checking options"
  2081. ,"/error allocation Check for out of memory errors"
  2082. ,"/error bounds_check Check size vs transmission length specification"
  2083. ,"/error enum Check enum values to be in allowable range"
  2084. ,"/error ref Check ref pointers to be non-null"
  2085. ,"/error stub_data Emit additional check for server side stub data validity"
  2086. ,"/robust Generate additonal information to validate parameters. "
  2087. ," Requires Windows 2000 and after (default)"
  2088. ,"/no_robust turn off /robust feature"
  2089. ,""
  2090. ," -OPTIMIZATION-"
  2091. ,"/align {N} Designate packing level of structures"
  2092. ,"/pack {N} Designate packing level of structures"
  2093. ,"/Zp {N} Designate packing level of structures"
  2094. ,"/no_format_opt Skip format string reusage optimization"
  2095. ,"/Oi Generate fully interpreted stubs, old style"
  2096. ," -Oicf is usually better"
  2097. ,"/Oic Generate fully interpreted stubs for standard interfaces and"
  2098. ," stubless proxies for object interfaces as of NT 3.51 release"
  2099. ," using -Oicf instead is usually better"
  2100. ,"/Oicf Generate fully interpreted stubs with extensions and stubless"
  2101. ," proxies for object interfaces as of NT 4.0 release (default)"
  2102. ,"/Oif Same as -Oicf"
  2103. ,"/Os Generate inline stubs"
  2104. #ifdef MIDL_INTERNAL
  2105. ,"/netmon Generate stubs for Netmon debugging (requires -Oicf)"
  2106. #endif // MIDL_INTERNAL
  2107. ,""
  2108. ," -MISCELLANEOUS-"
  2109. ,"@response_file Accept input from a response file"
  2110. ,"/? Display a list of MIDL compiler switches"
  2111. ,"/confirm Display options without compiling MIDL source"
  2112. ,"/help Display a list of MIDL compiler switches"
  2113. ,"/nologo Supress displaying of the banner lines"
  2114. ,"/o filename Redirects output from screen to a file"
  2115. ,"/W{0|1|2|3|4} Specify warning level 0-4 (default = 1)"
  2116. ,"/WX Report warnings at specified /W level as errors"
  2117. ,"/no_warn Suppress compiler warning messages"
  2118. };
  2119. STATUS_T
  2120. CommandLine::Help()
  2121. {
  2122. int i,LineCount,MaxLineCount = 23;
  2123. for(i = 0; i < sizeof(HelpArray)/sizeof(char *) ;)
  2124. {
  2125. for( LineCount = 0;
  2126. (LineCount < MaxLineCount) && (i < sizeof(HelpArray)/sizeof(char *)) ;
  2127. LineCount++,++i )
  2128. {
  2129. fprintf(stdout, "%s\n", HelpArray[i] );
  2130. }
  2131. //
  2132. // if all the help strings are displayed, then no need for user input.
  2133. //
  2134. if( i < (sizeof( HelpArray ) / sizeof( char *)) )
  2135. {
  2136. if( _isatty( MIDL_FILENO( stdout ) ) )
  2137. {
  2138. fprintf( stdout, "[ Press <return> to continue ]" );
  2139. MIDL_FGETCHAR();
  2140. }
  2141. }
  2142. }
  2143. return STATUS_OK;
  2144. }
  2145. void
  2146. PrintArg(
  2147. enum _swenum Switch,
  2148. char * pFirst,
  2149. char * pSecond )
  2150. {
  2151. char * pL = "",
  2152. * pR = "",
  2153. * pComma = "";
  2154. char * pSwString = (Switch == BASE_FILENAME) ? "input file" :
  2155. SwitchStringForValue( (unsigned short)Switch );
  2156. if( pSecond )
  2157. {
  2158. pL = "(";
  2159. pR = ")";
  2160. pComma = ",";
  2161. }
  2162. else
  2163. pSecond = "";
  2164. fprintf( stdout, "\n%20s - %s %s %s %s %s"
  2165. , pSwString
  2166. , pL
  2167. , pFirst
  2168. , pComma
  2169. , pSecond
  2170. , pR );
  2171. }
  2172. void
  2173. CmdProcess(
  2174. pair_switch* pPair,
  2175. CommandLine* pCmdAna,
  2176. char* pFirstOfPair)
  2177. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2178. Routine Description:
  2179. pair_switch command analyzer
  2180. Arguments:
  2181. pCmdAna - a ptr to the command analyser object calling this.
  2182. pFirstOfPair - the first argument after the -prefix switch.
  2183. Return Value:
  2184. NA
  2185. Notes:
  2186. Use the GetNextArg and UndoGetNextArg functions as necessary.
  2187. 1. We start with the input argument, which is the first of the
  2188. arguments to the prefix switch, ie first of the first pair.
  2189. 2. If we find an argument starting with a '-' or '/' it is definitely the
  2190. end of the prefix specification. If the switch starter is seen at the end
  2191. of a pair it is a proper end of the prefix switch, else the prefix switch
  2192. pair specification is illegal.
  2193. 3. In either case, as soon as a switch starter is seen, we must
  2194. UndoGetNextArg.
  2195. This class needs a pointer to the command analyser object that is calling
  2196. it, since it has to get and undoget argument from there
  2197. ----------------------------------------------------------------------------*/
  2198. {
  2199. short PairCheck = 0;
  2200. char * pNextOfPair;
  2201. char * pTemp;
  2202. STATUS_T Status = STATUS_OK;
  2203. short i;
  2204. while( pFirstOfPair && (*pFirstOfPair != '-') && (*pFirstOfPair != '/' ) )
  2205. {
  2206. // the first of the pair is a system defined string. Is it a valid one?
  2207. if( (i = pPair->GetIndex( pFirstOfPair )) >= 0 )
  2208. {
  2209. // we know the first of the pair is valid. Check the next before
  2210. // allocating any memory.
  2211. PairCheck++;
  2212. pTemp = pCmdAna->GetNextArg();
  2213. if( pTemp && (*pTemp != '-') && (*pTemp != '/') )
  2214. {
  2215. pNextOfPair = new char [ strlen( pTemp ) + 1 ];
  2216. strcpy( pNextOfPair, pTemp );
  2217. // update the list
  2218. pPair->AddPair( i, pNextOfPair );
  2219. PairCheck++;
  2220. }
  2221. else
  2222. break;
  2223. }
  2224. else
  2225. break;
  2226. pFirstOfPair = pCmdAna->GetNextArg();
  2227. if( PairCheck == 0 )
  2228. {
  2229. Status = ILLEGAL_ARGUMENT;
  2230. }
  2231. else if( (PairCheck % 2) != 0 )
  2232. {
  2233. Status = MISMATCHED_PREFIX_PAIR;
  2234. }
  2235. if( Status != STATUS_OK )
  2236. {
  2237. RpcError( (char *)NULL,
  2238. 0,
  2239. Status,
  2240. SwitchStringForValue( SWITCH_PREFIX ) );
  2241. }
  2242. }
  2243. // if we read ahead, push the argument back
  2244. if ( pFirstOfPair )
  2245. pCmdAna->UndoGetNextArg();
  2246. }