1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** 79** NAME: 80** 81** command.c 82** 83** FACILITY: 84** 85** Interface Definition Language (IDL) Compiler 86** 87** ABSTRACT: 88** 89** IDL command line parsing. 90** 91** VERSION: DCE 1.0 92** 93*/ 94 95#include <nidl.h> /* IDL common defs */ 96#include <command.h> 97 98#include <files.h> /* File handling defs */ 99#include <getflags.h> /* Command line parsing defs */ 100#include <message.h> /* reporting functions */ 101 102#ifndef MAX_DEF_STRINGS 103# define MAX_DEF_STRINGS 10 104#endif 105 106#ifndef MAX_DUMP_STRINGS 107# define MAX_DUMP_STRINGS 10 108#endif 109 110#ifndef MAX_IMPORT_DIRECTORIES 111# define MAX_IMPORT_DIRECTORIES 50 112#endif 113 114extern boolean ERR_no_warnings; /* Global copy of -no_warn cmd option */ 115extern char *last_string; /* Last string parsed from cmd line */ 116 117static boolean cmd_opt[NUM_OPTS]; /* True/False values for command options */ 118static void *cmd_val[NUM_OPTS]; /* Values associated w/ options (if any) */ 119 120/* Global versions of the command options */ 121 boolean *CMD_opts = (boolean*)cmd_opt; 122 void **CMD_vals = (void**)cmd_val; 123 124static const char *UNSPECIFIED = ""; 125static const char *nidl_library = NULL; 126 127static int do_bug[NUM_BUGS]; 128static int do_not_do_bug[NUM_BUGS]; 129static boolean support_bug[NUM_BUGS + 1]; 130 131static const char *caux_suffix = CAUX_SUFFIX, 132 *caux_file; 133 134static const char *cc_cmd; 135static const char *cc_opt; 136 137static const char *client; 138#define client_none 0 139#define client_stub 1 140#define client_aux 2 141#define client_all 3 142static const char *client_vals[] = { "none", "stub", "aux", "all", NULL }; 143 144const char *CMD_def_cpp_cmd; 145static const char *cpp_cmd; 146static const char *cpp_opt; 147 148static const char *cstub_suffix = CSTUB_SUFFIX, 149 *cstub_file; 150 151static char *(def_strings[MAX_DEF_STRINGS + 1]); 152static char *(undef_strings[MAX_DEF_STRINGS + 1]); 153 154#ifdef DUMPERS 155static char *dump_strings[MAX_DUMP_STRINGS+1]; 156#define dump_acf 0 157#define dump_ast 1 158#define dump_ast_after 2 159#define dump_cmd 3 160#define dump_debug 4 161#define dump_flat 5 162#define dump_mnode 6 163#define dump_mool 7 164#define dump_nametbl 8 165#define dump_recs 9 166#define dump_sends 10 167#define dump_unode 11 168#define dump_uool 12 169#define dump_yy 13 170static const char *dump_vals[] = { "acf", "ast", "ast_after", "cmd", "debug", 171 "flat", "mnode", "mool", "nametbl", "recs", 172 "sends", "unode", "uool", "yy", NULL }; 173#endif 174 175static const char *header_suffix = HEADER_SUFFIX, 176 *header_file; 177 178/* List of import directories - allow two extra slots for the implicit 179 * -I CD_DIR -I DEFAULT_IDIR and one for the sentinel. 180 */ 181static const char *(import_directories[MAX_IMPORT_DIRECTORIES + 2 + 1]); 182 183static const char *keep; 184#define keep_none 0 185#define keep_c_source 1 186#define keep_object 2 187#define keep_both 3 188#define keep_all 4 189static const char *keep_vals[] = { "none", "c_source", "object", "both", 190 "all", NULL }; 191 192static const char *out_dir; 193 194static const char *saux_suffix = SAUX_SUFFIX, 195 *saux_file; 196 197static const char *server; 198#define server_none 0 199#define server_stub 1 200#define server_aux 2 201#define server_all 3 202static const char *server_vals[] = { "none", "stub", "aux", "all", NULL }; 203 204static const char *sstub_suffix = SSTUB_SUFFIX, 205 *sstub_file; 206 207boolean CMD_DCL_interface = FALSE; 208static const char *standard = "extended"; 209static int standard_opt; 210static const char *standard_vals[] = { 211 "portable", "dce_v10", "dce_v11", "extended", NULL }; 212static const int standard_ivals[] = { 213 opt_standard_dce_1_0, opt_standard_dce_1_0, 214 opt_standard_dce_1_1, opt_standard_dce_1_1 }; 215 216#define FD(x) (FLAGDEST)&x 217#define FDV(x) (FLAGDEST)x 218 219static const 220OPTIONS option_table[]={ 221 {"bug", VINTARG(NUM_BUGS), FDV(do_bug)}, 222 {"caux", STRARG, FD(caux_file)}, 223 {"cc_cmd", STRARG, FD(cc_cmd)}, 224 {"cc_opt", STRARG, FD(cc_opt)}, 225 {"cepv", ASSERTARG, FD(cmd_opt[opt_cepv])}, 226 {"client", STRARG, FD(client)}, 227 {"confirm", ASSERTARG|HIDARG, FD(cmd_opt[opt_confirm])}, 228 {"cpp_cmd", OSTRARG, FD(cpp_cmd)}, 229 {"cpp_opt", STRARG, FD(cpp_opt)}, 230 {"cstub", STRARG, FD(cstub_file)}, 231 {"D", VSTRARG(MAX_DEF_STRINGS), FDV(def_strings)}, 232#ifdef DUMPERS 233 {"dump", VSTRARG(MAX_DUMP_STRINGS)|HIDARG,FDV(dump_strings)}, 234#endif 235 {"header", OSTRARG, FD(header_file)}, 236 {"I", VSTRARG(MAX_IMPORT_DIRECTORIES),FDV(import_directories)}, 237 {"keep", STRARG, FD(keep)}, 238 {"midl", ASSERTARG|HIDARG, FD(cmd_opt[opt_midl])}, 239 {"no_bug", VINTARG(NUM_BUGS), FDV(do_not_do_bug)}, 240 {"no_cpp", DENYARG, FD(cmd_opt[opt_cpp])}, 241 {"no_def_idir", DENYARG, FD(cmd_opt[opt_def_idir])}, 242 {"no_header", DENYARG|HIDARG, FD(cmd_opt[opt_header])}, 243 {"no_mepv", DENYARG, FD(cmd_opt[opt_mepv])}, 244 {"no_warn", DENYARG, FD(cmd_opt[opt_warn])}, 245#ifdef DUMPERS 246 {"ool", ASSERTARG|HIDARG, FD(cmd_opt[opt_ool])}, 247#endif 248 {"out", STRARG, FD(out_dir)}, 249 {"saux", STRARG, FD(saux_file)}, 250 {"server", STRARG, FD(server)}, 251 {"space_opt", ASSERTARG, FD(cmd_opt[opt_space_opt])}, 252 {"sstub", STRARG, FD(sstub_file)}, 253 {"standard", STRARG, FD(standard)}, 254 {"stdin", ASSERTARG, FD(cmd_opt[opt_stdin])}, 255 {"syntax_only", ASSERTARG, FD(cmd_opt[opt_syntax_check])}, 256 {"U", VSTRARG(MAX_DEF_STRINGS), FDV(undef_strings)}, 257 {"v", ASSERTARG|HIDARG, FD(cmd_opt[opt_verbose])}, 258 {"version", ASSERTARG|HIDARG, FD(cmd_opt[opt_version])}, 259 {0, 0, 0} 260}; 261 262/* 263** C M D _ e x p l a i n _ a r g s 264** 265** Explains command line arguments. 266*/ 267 268void CMD_explain_args(void) 269{ 270 message_print(NIDL_USAGE); 271 272 /* 273 * Don't print full list of command options here unless -confirm 274 * specified, but let user know there is a way to do it. 275 */ 276 if (cmd_opt[opt_confirm]) 277 printflags(option_table); 278 else 279 message_print(NIDL_CMDERR, "-confirm"); 280} 281 282/* 283** c h e c k _ s t r _ l i s t 284** 285** Checks a string argument against a list of legal 286** values. Issues error and exits for illegal value. 287** 288** Returns: Index of match. Returns -1 for null string. 289*/ 290 291static int check_str_list 292( 293 const char *opt, /* [in] Name of command option */ 294 const char *val, /* [in] Value assigned to command option */ 295 const char **list /* [in] List of legal values for cmd option */ 296) 297{ 298 int i; /* List index */ 299 300 if (val[0] == '\0') 301 return -1; 302 303 for (i = 0 ; list[i] != NULL ; i++ ) 304 if (strcmp(val, list[i]) == 0) 305 return i; 306 307 message_print(NIDL_INVOPTION, opt, val); 308 message_print(NIDL_LEGALVALS); 309 310 for ( ; *list != NULL ; list++ ) 311 fprintf(stderr, " %s", *list); 312 313 fprintf(stderr, "\n"); 314 exit(pgm_error); 315} 316 317/* 318** c h e c k _ s t r _ i n t _ l i s t 319** 320** Checks a string argument against a list of legal 321** values. Issues error and exits for illegal value. 322** 323** Returns: Integer corresponding to matched string. Integer is 324** obtained from array using index of matched string. 325** Returns -1 for null string. 326*/ 327 328static int check_str_int_list 329( 330 const char *opt, /* [in] Name of command option */ 331 const char *val, /* [in] Value assigned to command option */ 332 const char **list, /* [in] List of legal values for cmd option */ 333 const int *ilist /* [in] List of corresponding integer values */ 334) 335{ 336 int i; /* List index */ 337 338 if (val[0] == '\0') 339 return -1; 340 341 for (i = 0 ; list[i] != NULL ; i++ ) 342 if (strcmp(val, list[i]) == 0) 343 return ilist[i]; 344 345 message_print(NIDL_INVOPTION, opt, val); 346 message_print(NIDL_LEGALVALS); 347 348 for ( ; *list != NULL ; list++ ) 349 fprintf(stderr, " %s", *list); 350 351 fprintf(stderr, "\n"); 352 exit(pgm_error); 353} 354 355/* 356** d u m p _ c m d _ d a t a 357** 358** Dump state of internal command vectors. 359*/ 360 361#ifdef DUMPERS 362typedef enum {bit, string, string_list, int_list, number} opt_kind_t; 363typedef struct 364{ 365 const char *opt_name; 366 opt_kind_t opt_kind; 367} opt_struct; 368 369/* 370 * Entries in this table must be consistent with definitions in command.h. 371 */ 372static const opt_struct opt_info[NUM_OPTS] = 373{ 374 { "caux", string }, 375 { "cc_cmd", string }, 376 { "cc_opt", string }, 377 { "cepv", bit }, 378 { "confirm", bit }, 379 { "cpp_cmd", string }, 380 { "cpp_def", string_list }, 381 { "cpp_opt", string }, 382 { "cpp_undef", string_list }, 383 { "cstub", string }, 384 { "def_idir", bit }, 385 { "do_bug", int_list }, 386 { "emit_cstub", bit }, 387 { "emit_sstub", bit }, 388 { "header", string }, 389 { "idir", string_list }, 390 { "keep_c", bit }, 391 { "keep_obj", bit }, 392 { "mepv", bit }, 393 { "out", string }, 394 { "saux", string }, 395 { "source", string }, 396 { "space_opt", bit }, 397 { "sstub", string }, 398 { "stdin", bit }, 399 { "syntax_only", bit }, 400 { "v", bit }, 401 { "version", bit }, 402 { "warn", bit }, 403 { "standard", number }, 404 { "midl", bit} 405#ifdef DUMPERS 406 , 407 { "dump_acf", bit }, 408 { "dump_ast", bit }, 409 { "dump_ast_after", bit }, 410 { "dump_cmd", bit }, 411 { "dump_debug", bit }, 412 { "dump_flat", bit }, 413 { "dump_mnode", bit }, 414 { "dump_mool", bit }, 415 { "dump_nametbl", bit }, 416 { "dump_recs", bit }, 417 { "dump_sends", bit }, 418 { "dump_unode", bit }, 419 { "dump_uool", bit }, 420 { "dump_yy", bit }, 421 { "ool", bit } 422#endif 423}; 424 425static void dump_cmd_data(void) 426{ 427 int i; /* Option index */ 428 int j; /* Table index */ 429 int tbl_size; /* Table size */ 430 char **pstr; /* Ptr to string table entry */ 431 int *pint; /* Ptr to integer table entry */ 432 433 printf("\n"); 434 435 for (i = 0 ; i < NUM_OPTS ; i++) 436 { 437 printf("%-20s", opt_info[i].opt_name); 438 439 if (cmd_opt[i]) 440 printf("true "); 441 else 442 printf("false "); 443 444 switch (opt_info[i].opt_kind) 445 { 446 case bit: 447 printf("\n"); 448 break; 449 450 case string: 451 if (cmd_val[i] != NULL) 452 printf(" %s\n", (char*)cmd_val[i]); 453 else 454 printf(" \n"); 455 break; 456 457 case string_list: 458 pstr = (char **)cmd_val[i]; 459 if (pstr != NULL) 460 while (*pstr != NULL) 461 printf(" %s", *pstr++); 462 printf("\n"); 463 break; 464 465 case int_list: 466 pint = (int *)cmd_val[i]; 467 tbl_size = flags_option_count(option_table, opt_info[i].opt_name); 468 for (j = 0 ; j < tbl_size ; j++) 469 printf(" %d", *pint++); 470 printf("\n"); 471 break; 472 473 case number: 474 pint = (int *)cmd_val[i]; 475 printf(" %d\n", *pint++); 476 break; 477 478 default: 479 printf("**Error**: Unsupported opt_kind in dump_cmd_data.\n"); 480 } 481 } 482} 483#endif 484 485/* 486** a l l o c _ a n d _ c o p y 487** 488** Allocates memory for and copies a string to a return string. 489*/ 490 491static char *alloc_and_copy /* Returns address of new string */ 492( 493 const char *orig_str /* String to copy */ 494) 495{ 496 char *new_str; /* Local ptr to new string */ 497 498 if (orig_str == NULL || orig_str[0] == '\0') 499 orig_str = UNSPECIFIED; /* Empty string */ 500 501 new_str = NEW_VEC (char, strlen(orig_str) + 1); 502 503 strlcpy(new_str, orig_str, strlen(orig_str) + 1); 504 505 return new_str; 506} 507 508/* 509** a d d _ d e f _ s t r i n g 510** 511** Adds specified string to the array of symbols defined for 512** preprocessor input. 513*/ 514 515boolean add_def_string 516( 517 const char *def_string /* [in] Additional #define string for preprocessor input */ 518) 519{ 520 char **defs = (char**) cmd_val[opt_cpp_def]; 521 char *def; 522 int len, i = 0; 523 524 len = 1; /* just to start the loop */ 525 def = defs[i]; 526 527 /* find the last def string */ 528 while (i < MAX_DEF_STRINGS && (def != NULL && len > 0)) 529 { 530 if (def != NULL) 531 { 532 /* it makes no sense to define the same thing twice */ 533 if (!strcmp(def, def_string)) return true; 534 len = strlen(def); 535 } 536 def = defs[++i]; 537 } 538 539 /* add only if there's enough space */ 540 if (i < MAX_DEF_STRINGS) 541 { 542 defs[i] = alloc_and_copy(def_string); 543 return true; 544 } 545 546 return false; 547} 548 549/* 550** g e t _ s r c _ f i l e s p e c 551** 552** Gets the source filespec from the command line, if any. When it is 553** ambiguous as to which parameter on the command line specifies the source 554** IDL file, the rightmost parameter that can sensibly specify the source 555** IDL file is chosen. 556** 557** Returns: TRUE if a source file was specified; FALSE otherwise 558*/ 559 560static boolean get_src_filespec 561( 562 char *src_filespec, /* [out] Source filespec */ 563 size_t src_filespec_len 564) 565{ 566 int other_count; /* Parameter cnt (excl. option cnt) */ 567 568 other_count = flags_other_count(); 569 570 /* Check for invalid extra arguments. */ 571 if (other_count > 1) 572 { 573 int i; 574 CMD_explain_args(); 575 576 message_print(NIDL_INVPARAMS); 577 for (i = 1; i < other_count ; i++) 578 fprintf(stderr, " %s", flags_other(i)); 579 fprintf(stderr, "\n"); 580 581 return FALSE; 582 } 583 584 /* 585 * If one argument, it must be the source filespec if -stdin was not 586 * specified. It -stdin was specified, it is an invalid extra argument. 587 */ 588 if (other_count == 1) 589 { 590 if (cmd_opt[opt_stdin]) 591 { 592 CMD_explain_args(); 593 message_print(NIDL_INVPARAMS); 594 fprintf(stderr, " %s\n", flags_other(0)); 595 return FALSE; 596 } 597 else 598 { 599 strlcpy(src_filespec, flags_other(0), src_filespec_len); 600 return TRUE; 601 } 602 } 603 604 /* No arguments. Fine if -stdin selected. */ 605 if (cmd_opt[opt_stdin]) 606 { 607 src_filespec[0] = '\0'; 608 return TRUE; 609 } 610 611 /* 612 * We do not have an obvious source filespec on the command line as parsed. 613 * However, the command line format is ambiguous. Any command option that 614 * takes an OPTIONAL string argument might have swallowed up what was 615 * really intended to be the source filespec. The getflags function saves 616 * us the last such optional string that was parsed. If we have one, that 617 * option becomes argument-less and what was parsed as its argument becomes 618 * the source filespec. 619 */ 620 if (last_string == NULL || last_string[0] == '\0') 621 { 622 if (cmd_opt[opt_version]) 623 exit(pgm_ok); 624 625 CMD_explain_args(); 626 627 message_print(NIDL_SRCFILEREQ); 628#ifdef DUMPERS 629 if (cmd_opt[opt_dump_cmd]) 630 dump_cmd_data(); 631#endif 632 return FALSE; 633 } 634 635 strlcpy(src_filespec, last_string, src_filespec_len); 636 last_string[0] = '\0'; 637 return TRUE; 638} 639 640/* 641** C M D _ p a r s e _ a r g s 642** 643** Parses command arguments. 644*/ 645 646boolean CMD_parse_args /* Returns TRUE on success */ 647( 648 int argc, /* [in] Argument count */ 649 char **argv, /* [in] Argument vector */ 650 boolean **p_cmd_opt, /*[out] Ptr to array of cmd option arguments */ 651 void ***p_cmd_val, /*[out] Ptr to array of cmd option values */ 652 STRTAB_str_t *p_idl_sid /*[out] Ptr to IDL filespec stringtable ID */ 653 /* STRTAB_NULL_STR => stdin */ 654) 655{ 656 FILE_k_t out_dir_kind; /* File kind of -out string */ 657 int i, j; 658 STRTAB_str_t src_file_str; /* Source file stringtable ID */ 659 char src_filespec[PATH_MAX]; /* Source file specification */ 660 char src_filename[PATH_MAX]; /* Source file name portion */ 661 char l_cstub_file[PATH_MAX]; /* Work buf for full cstub filespec */ 662 char l_sstub_file[PATH_MAX]; /* Work buf for full sstub filespec */ 663 char l_header_file[PATH_MAX]; /* Work buf for full header filespec */ 664 char l_caux_file[PATH_MAX]; /* Work buf for full caux filespec */ 665 char l_saux_file[PATH_MAX]; /* Work buf for full saux filespec */ 666 char filespec[PATH_MAX]; /* Work buf for any filespec */ 667 668 /* 669 * Set up default command line options. 670 */ 671 cmd_opt[opt_do_bug] = TRUE; 672 for (i = 0; i <= NUM_BUGS; i++) /* 1-based index, thus extra elem */ 673 support_bug[i] = FALSE; 674 /* 675 * By default, -bug 4 is included in the code which causes 676 * arrays of [ref] pointers contained in structures to not 677 * be represented as a hole in NDR. 678 */ 679 support_bug[bug_array_no_ref_hole] = TRUE; 680 681 cmd_opt[opt_caux] = TRUE; 682 caux_file = ""; 683 684 cmd_opt[opt_cc_cmd] = TRUE; 685 cc_cmd = CC_DEF_CMD; 686 687 cmd_opt[opt_cc_opt] = TRUE; 688#if defined(__alpha) && defined(__osf__) 689 cc_opt = "-std1"; 690#else 691 cc_opt = ""; 692#endif 693 694 cmd_opt[opt_cepv] = FALSE; 695 696 cmd_opt[opt_emit_cstub] = TRUE; 697 client = client_vals[client_all]; 698 699 cmd_opt[opt_confirm] = FALSE; 700 701 cpp_cmd = CPP; 702 cmd_opt[opt_cpp] = TRUE; 703 704 CMD_def_cpp_cmd = CPP; 705 cmd_opt[opt_cpp_opt] = TRUE; 706 cpp_opt = ""; 707 708 cmd_opt[opt_cstub] = TRUE; 709 cstub_file = ""; 710 711 cmd_opt[opt_header] = TRUE; 712 header_file = ""; 713 714 cmd_opt[opt_keep_c] = FALSE; 715 cmd_opt[opt_keep_obj] = TRUE; 716 keep = keep_vals[keep_object]; 717 718 cmd_opt[opt_idir] = TRUE; 719 cmd_opt[opt_def_idir] = TRUE; 720 721 cmd_opt[opt_mepv] = TRUE; 722 cmd_opt[opt_warn] = TRUE; 723 724 cmd_opt[opt_out] = FALSE; 725 out_dir = ""; 726 727 cmd_opt[opt_saux] = TRUE; 728 saux_file = ""; 729 730 cmd_opt[opt_emit_sstub] = TRUE; 731 server = server_vals[server_all]; 732 733 cmd_opt[opt_source] = TRUE; 734 735 cmd_opt[opt_space_opt] = FALSE; 736 737 cmd_opt[opt_sstub] = TRUE; 738 sstub_file = ""; 739 740 cmd_opt[opt_stdin] = FALSE; 741 742 cmd_opt[opt_syntax_check] = FALSE; 743 744 cmd_opt[opt_verbose] = FALSE; 745 746 cmd_opt[opt_version] = FALSE; 747 748 standard_opt = opt_standard_dce_1_1; 749 cmd_val[opt_standard] = (void*)&standard_opt; 750 751 cmd_opt[opt_midl] = FALSE; 752 753#ifdef DUMPERS 754 cmd_opt[opt_dump_acf] = FALSE; 755 cmd_opt[opt_dump_ast] = FALSE; 756 cmd_opt[opt_dump_ast_after] = FALSE; 757 cmd_opt[opt_dump_cmd] = FALSE; 758 cmd_opt[opt_dump_debug] = FALSE; 759 cmd_opt[opt_dump_flat] = FALSE; 760 cmd_opt[opt_dump_mnode] = FALSE; 761 cmd_opt[opt_dump_mool] = FALSE; 762 cmd_opt[opt_dump_nametbl] = FALSE; 763 cmd_opt[opt_dump_recs] = FALSE; 764 cmd_opt[opt_dump_sends] = FALSE; 765 cmd_opt[opt_dump_unode] = FALSE; 766 cmd_opt[opt_dump_uool] = FALSE; 767 cmd_opt[opt_dump_yy] = FALSE; 768 cmd_opt[opt_ool] = FALSE; 769#endif 770 771 /* 772 * Set up pointers to static storage and return parameters. 773 */ 774 cmd_val[opt_cpp_def] = (void *)def_strings; 775 cmd_val[opt_cpp_undef] = (void *)undef_strings; 776 cmd_val[opt_do_bug] = (void *)support_bug; 777 cmd_val[opt_idir] = (void *)import_directories; 778 *p_cmd_opt = cmd_opt; 779 *p_cmd_val = cmd_val; 780 781 /* 782 * Check for no arguments. 783 */ 784 if (argc == 0) 785 { 786 CMD_explain_args(); 787 exit(pgm_error); 788 } 789 790 /* 791 * Parse command line options. 792 */ 793 getflags(argc, argv, option_table); 794 795 if (cmd_opt[opt_version]) 796 { 797 message_print(NIDL_VERSION, IDL_VERSION_TEXT); 798 } 799 800 /* 801 * Check -bug and -no_bug options. 802 */ 803 for (i = flags_option_count(option_table, "bug") - 1; i >= 0; i--) 804 if ((do_bug[i] < 1) || (do_bug[i] > NUM_BUGS) || 805 (do_bug[i] == bug_array_no_ref_hole)) 806 { 807 message_print(NIDL_INVBUG, do_bug[i]); 808 exit(pgm_error); 809 } 810 811 for (i = flags_option_count(option_table, "no_bug") - 1; i >= 0; i--) 812 if ((do_not_do_bug[i] < 1) || (do_not_do_bug[i] > NUM_BUGS) || 813 (do_not_do_bug[i] == bug_array_no_ref_hole)) 814 { 815 message_print(NIDL_INVNOBUG, do_not_do_bug[i]); 816 exit(pgm_error); 817 } 818 819 for (i = flags_option_count(option_table, "bug") - 1; i >= 0; i--) 820 for (j = flags_option_count(option_table, "no_bug") - 1; j >= 0; j--) 821 if (do_bug[i] == do_not_do_bug[j]) 822 { 823 message_print(NIDL_BUGNOBUG, do_bug[i], do_bug[i]); 824 exit(pgm_error); 825 } 826 827 for (i = flags_option_count(option_table, "bug") - 1; i >= 0; i--) 828 { 829 cmd_opt[opt_do_bug] = TRUE; 830 support_bug[do_bug[i]] = TRUE; 831 } 832 833 for (i = flags_option_count(option_table, "no_bug") - 1; i >= 0; i--) 834 support_bug[do_not_do_bug[i]] = FALSE; 835 836 /* 837 * Check the -client option. 838 */ 839 i = check_str_list("client", client, client_vals); 840 switch (i) 841 { 842 case client_none: 843 cmd_opt[opt_emit_cstub] = FALSE; 844 cmd_opt[opt_caux] = FALSE; 845 break; 846 847 case client_stub: 848 cmd_opt[opt_emit_cstub] = TRUE; 849 cmd_opt[opt_caux] = FALSE; 850 break; 851 852 case client_aux: 853 cmd_opt[opt_emit_cstub] = FALSE; 854 cmd_opt[opt_caux] = TRUE; 855 break; 856 857 case client_all: 858 default: 859 cmd_opt[opt_emit_cstub] = TRUE; 860 cmd_opt[opt_caux] = TRUE; 861 } 862 863 /* 864 * Check the -dump options. 865 */ 866#ifdef DUMPERS 867 for (j = 0; dump_strings[j] != NULL; j++) 868 { 869 i = check_str_list("dump", dump_strings[j], dump_vals); 870 switch (i) 871 { 872 case dump_acf: 873 cmd_opt[opt_dump_acf] = TRUE; 874 break; 875 876 case dump_ast: 877 cmd_opt[opt_dump_ast] = TRUE; 878 break; 879 880 case dump_ast_after: 881 cmd_opt[opt_dump_ast_after] = TRUE; 882 break; 883 884 case dump_cmd: 885 cmd_opt[opt_dump_cmd] = TRUE; 886 break; 887 888 case dump_debug: 889 cmd_opt[opt_dump_debug] = TRUE; 890 break; 891 892 case dump_flat: 893 cmd_opt[opt_dump_flat] = TRUE; 894 break; 895 896 case dump_mnode: 897 cmd_opt[opt_dump_mnode] = TRUE; 898 break; 899 900 case dump_mool: 901 cmd_opt[opt_dump_mool] = TRUE; 902 break; 903 904 case dump_nametbl: 905 cmd_opt[opt_dump_nametbl] = TRUE; 906 break; 907 908 case dump_recs: 909 cmd_opt[opt_dump_recs] = TRUE; 910 break; 911 912 case dump_sends: 913 cmd_opt[opt_dump_sends] = TRUE; 914 break; 915 916 case dump_unode: 917 cmd_opt[opt_dump_unode] = TRUE; 918 break; 919 920 case dump_uool: 921 cmd_opt[opt_dump_uool] = TRUE; 922 break; 923 924 case dump_yy: 925 { 926 extern int nidl_yydebug; 927 extern int acf_yydebug; 928 cmd_opt[opt_dump_yy] = TRUE; 929 nidl_yydebug = acf_yydebug = (int)TRUE; 930 break; 931 } 932 } 933 } 934#endif 935 standard_opt = check_str_int_list("standard", standard, 936 standard_vals, standard_ivals); 937 if (standard_opt == -1) standard_opt = opt_standard_dce_1_1; 938 939 /* 940 * Process the -I options for import directories. 941 */ 942 if (cmd_opt[opt_def_idir]) 943 { 944 for (i = 0; import_directories[i] != NULL 945 && import_directories[i][0] != '\0' ; i++) 946 ; 947 import_directories[i+2] = NULL; 948 949#ifdef NIDL_LIBRARY_EV 950 nidl_library = getenv(NIDL_LIBRARY_EV); 951#endif 952 if (nidl_library == NULL) 953 nidl_library = DEFAULT_IDIR; 954 import_directories[i+1] = nidl_library; 955 956 for ( ; i > 0; i--) 957 import_directories[i] = import_directories[i-1]; 958 import_directories[0] = CD_IDIR; 959 flags_incr_count(option_table, "I", 2); 960 } 961 962 if (!cmd_opt[opt_def_idir] && 963 (import_directories[0] == NULL || import_directories[0][0] == '\0')) 964 { 965 import_directories[0] = CD_IDIR; 966 flags_incr_count(option_table, "I", 1); 967 } 968 969 /* 970 * Check the -keep option. 971 */ 972 i = check_str_list("keep", keep, keep_vals); 973 switch (i) 974 { 975 case keep_none: 976 cmd_opt[opt_keep_c] = FALSE; 977 cmd_opt[opt_keep_obj] = FALSE; 978 break; 979 980 case keep_c_source: 981 cmd_opt[opt_keep_c] = TRUE; 982 cmd_opt[opt_keep_obj] = FALSE; 983 break; 984 985 case keep_object: 986 default: 987 cmd_opt[opt_keep_c] = FALSE; 988 cmd_opt[opt_keep_obj] = TRUE; 989 break; 990 991 case keep_both: 992 case keep_all: 993 cmd_opt[opt_keep_c] = TRUE; 994 cmd_opt[opt_keep_obj] = TRUE; 995 break; 996 } 997 998 /* 999 * Check for -out specification of output directory. 1000 */ 1001 if (out_dir[0] != '\0') 1002 cmd_opt[opt_out] = TRUE; 1003 1004 /* 1005 * Make sure we have a source filespec before we use it to construct 1006 * other names. 1007 */ 1008 if (!get_src_filespec(src_filespec, sizeof (src_filespec))) 1009 exit(pgm_error); 1010 1011 if (src_filespec[0] == '\0') /* -stdin */ 1012 { 1013 src_file_str = STRTAB_NULL_STR; 1014 src_filename[0] = 'a'; /* output filenames a.h, a_cstub.c, etc. */ 1015 src_filename[1] = '\0'; 1016 } 1017 else /* file */ 1018 { 1019 if (!FILE_parse(src_filespec, (char *)NULL, 0, src_filename, sizeof (src_filename), (char *)NULL, 0)) 1020 { 1021 /* Not a valid filespec so probably a bogus option. */ 1022 error(NIDL_UNKFLAG, src_filespec); 1023 return FALSE; 1024 } 1025 1026 src_file_str = STRTAB_add_string(src_filespec); 1027 } 1028 1029 /* 1030 * Check the -server option. 1031 */ 1032 i = check_str_list("server", server, server_vals); 1033 switch (i) 1034 { 1035 case server_none: 1036 cmd_opt[opt_emit_sstub] = FALSE; 1037 cmd_opt[opt_saux] = FALSE; 1038 break; 1039 1040 case server_stub: 1041 cmd_opt[opt_emit_sstub] = TRUE; 1042 cmd_opt[opt_saux] = FALSE; 1043 break; 1044 1045 case server_aux: 1046 cmd_opt[opt_emit_sstub] = FALSE; 1047 cmd_opt[opt_saux] = TRUE; 1048 break; 1049 1050 case server_all: 1051 default: 1052 cmd_opt[opt_emit_sstub] = TRUE; 1053 cmd_opt[opt_saux] = TRUE; 1054 } 1055 1056 /* If -syntax_only specified, disable all output file processing. */ 1057 if (cmd_opt[opt_syntax_check]) 1058 { 1059 cmd_opt[opt_out] = FALSE; 1060 cmd_opt[opt_cstub] = FALSE; 1061 cmd_opt[opt_sstub] = FALSE; 1062 cmd_opt[opt_header] = FALSE; 1063 cmd_opt[opt_caux] = FALSE; 1064 cmd_opt[opt_saux] = FALSE; 1065 } 1066 1067 /* 1068 * If the -out option was selected, verify that the output-directory string 1069 * is a valid directory spec before prepending to any output filenames. 1070 */ 1071 if (cmd_opt[opt_out]) 1072 { 1073 if (!FILE_kind(out_dir, &out_dir_kind)) 1074 error(NIDL_FILENOTFND, out_dir); 1075 1076 if (out_dir_kind != file_dir) 1077 error(NIDL_FILENOTDIR, out_dir); 1078 } 1079 1080 /* 1081 * Process -cstub option. 1082 */ 1083 if (cmd_opt[opt_cstub]) 1084 { 1085 sprintf(filespec, "%s%s", src_filename, cstub_suffix); 1086 if (!FILE_form_filespec(cstub_file, out_dir, (char *)NULL, filespec, 1087 l_cstub_file, sizeof(l_cstub_file))) 1088 { 1089 message_print(NIDL_INVFILESPEC, cstub_file); 1090 return FALSE; 1091 } 1092 cstub_file = l_cstub_file; /* Point at local buffer */ 1093 } 1094 1095 /* 1096 * Process -sstub option. 1097 */ 1098 if (cmd_opt[opt_sstub]) 1099 { 1100 sprintf(filespec, "%s%s", src_filename, sstub_suffix); 1101 if (!FILE_form_filespec(sstub_file, out_dir, (char *)NULL, filespec, 1102 l_sstub_file, sizeof(l_sstub_file))) 1103 { 1104 message_print(NIDL_INVFILESPEC, sstub_file); 1105 return FALSE; 1106 } 1107 sstub_file = l_sstub_file; /* Point at local buffer */ 1108 } 1109 1110 /* 1111 * Process -header option. 1112 */ 1113 sprintf(filespec, "%s%s", src_filename, header_suffix); /* =tbl */ 1114 if (!FILE_form_filespec(header_file, out_dir, (char *)NULL, /* =tbl */ 1115 filespec, l_header_file, sizeof(l_header_file))) /* =tbl */ 1116 { 1117 message_print(NIDL_INVFILESPEC, header_file); 1118 return FALSE; 1119 } 1120 header_file = l_header_file; /* Point at local buffer */ 1121 1122 /* 1123 * Process -caux option. 1124 */ 1125 if (cmd_opt[opt_caux]) 1126 { 1127 sprintf(filespec, "%s%s", src_filename, caux_suffix); 1128 if (!FILE_form_filespec(caux_file, out_dir, (char *)NULL, filespec, 1129 l_caux_file, sizeof(l_caux_file))) 1130 { 1131 message_print(NIDL_INVFILESPEC, caux_file); 1132 return FALSE; 1133 } 1134 caux_file = l_caux_file; /* Point at local buffer */ 1135 } 1136 1137 /* 1138 * Process -saux option. 1139 */ 1140 if (cmd_opt[opt_saux]) 1141 { 1142 sprintf(filespec, "%s%s", src_filename, saux_suffix); 1143 if (!FILE_form_filespec(saux_file, out_dir, (char *)NULL, filespec, 1144 l_saux_file, sizeof(l_saux_file))) 1145 { 1146 message_print(NIDL_INVFILESPEC, saux_file); 1147 return FALSE; 1148 } 1149 saux_file = l_saux_file; /* Point at local buffer */ 1150 } 1151 1152 /* 1153 * All options are now loaded with default values if necessary. 1154 * Setup the cmd_val table to point to the parsed values. 1155 * Memory management assumptions: It is assumed that pointers to 1156 * unmodified command options reference memory that is valid for the 1157 * entire program. Any modified command options, however, reference 1158 * local storage. We must allocate permanent memory for those, via 1159 * the alloc_and_copy function. 1160 */ 1161 cmd_val[opt_caux] = (void *)alloc_and_copy(caux_file); 1162 cmd_val[opt_cc_cmd] = (void *)cc_cmd; 1163 cmd_val[opt_cc_opt] = (void *)cc_opt; 1164 cmd_val[opt_cpp] = (void *)cpp_cmd; 1165 cmd_val[opt_cpp_opt] = (void *)cpp_opt; 1166 cmd_val[opt_cstub] = (void *)alloc_and_copy(cstub_file); 1167 cmd_val[opt_header] = (void *)alloc_and_copy(header_file); 1168 cmd_val[opt_out] = (void *)out_dir; 1169 cmd_val[opt_saux] = (void *)alloc_and_copy(saux_file); 1170 cmd_val[opt_source] = (void *)src_filespec; 1171 cmd_val[opt_sstub] = (void *)alloc_and_copy(sstub_file); 1172 1173#ifdef DUMPERS 1174 if (cmd_opt[opt_dump_cmd]) 1175 dump_cmd_data(); 1176#endif 1177 1178 /* 1179 * Print list of options if requested. 1180 */ 1181 if (cmd_opt[opt_confirm]) 1182 { 1183 printflags(option_table); 1184 if (!cmd_opt[opt_verbose]) 1185 exit(pgm_ok); 1186 } 1187 1188 ERR_no_warnings = !cmd_opt[opt_warn]; 1189 1190 *p_idl_sid = src_file_str; 1191 return(TRUE); 1192} 1193