This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

cpplib: Command line arguments


This is the current state of my patch to tighten up cpplib's command line handling. -ifoutput support has been removed, as for the CVS version. As the assignment stuff has now been accepted by the FSF, you can commit it if you're happy with it, Zack. With the built-in strlen workaround, gcc bootstraps with this patch. Neil. * cppinit.c (opt_comp) New function. Called by sort_options as the comparison routine. (sort_options) New function. Sorts the array of command line options at run time for non-ASCII host environments. (parse_option) New function. Parses a single command line option, possibly taking an argument. (cpp_handle_option) Rewritten to use parse_option for binary searching of options. (cpp_handle_options) Sorts the array of command line options during its first invocation. (print_help) Updated run-time help. * cpplib.h Remove prototype of cpp_handle_option; it is now local to cppinit.c Index: cppinit.c =================================================================== RCS file: /cvs/gcc/egcs/gcc/cppinit.c,v retrieving revision 1.52 diff -u -p -r1.52 cppinit.c --- cppinit.c 2000/03/06 18:03:54 1.52 +++ cppinit.c 2000/03/07 11:42:25 @@ -183,6 +183,11 @@ static void initialize_dependency_output static void initialize_standard_includes PARAMS ((cpp_reader *)); static void new_pending_define PARAMS ((struct cpp_options *, const char *)); +#ifdef HOST_EBCDIC +static int opt_comp PARAMS ((const void*, const void*)); +#endif +static int parse_option PARAMS ((const char *)); +static int cpp_handle_option PARAMS ((cpp_reader *, int, char **)); /* Fourth argument to append_include_chain: chain to use */ enum { QUOTE = 0, BRACKET, SYSTEM, AFTER }; @@ -897,11 +902,190 @@ new_pending_define (opts, text) APPEND (opts->pending, define, o); } +enum opt_code +{ + OPT_stdin_stdout = 0, OPT_dollar, OPT_plus, + OPT__help, OPT__version, + OPT_A, OPT_C, OPT_D, OPT_H, OPT_I, OPT_M, + OPT_MD, OPT_MG, OPT_MM, OPT_MMD, + OPT_P, OPT_U, OPT_W, + OPT_d, + OPT_fleading_underscore, OPT_fno_leading_underscore, + OPT_fpreprocessed, OPT_fno_preprocessed, + OPT_g, OPT_h, + OPT_idirafter, OPT_imacros, OPT_include, + OPT_iprefix, OPT_isystem, OPT_iwithprefix, OPT_iwithprefixbefore, + OPT_lang_asm, OPT_lang_c, OPT_lang_cplusplus, OPT_lang_c89, + OPT_lang_chill, OPT_lang_fortran, OPT_lang_objc, OPT_lang_objcplusplus, + OPT_nostdinc, OPT_nostdincplusplus, + OPT_o, + OPT_pedantic, OPT_pedantic_errors, OPT_remap, + OPT_std_c89, OPT_std_c99, OPT_std_c9x, OPT_std_gnu89, OPT_std_gnu99, + OPT_std_gnu9x, OPT_std_iso9899_1990, OPT_std_iso9899_199409, + OPT_std_iso9899_1999, OPT_std_iso9899_199x, + OPT_traditional, OPT_trigraphs, + OPT_v, OPT_w, + N_OPTS +}; + +struct cl_option +{ + const char* opt_text; + const char* msg; + size_t opt_len; + enum opt_code opt_code; +}; + +static const char no_arg[] = N_("Argument missing after `%s' option"); +static const char no_ass[] = N_("Assertion missing after `%s' option"); +static const char no_dir[] = N_("Directory name missing after `%s' option"); +static const char no_fil[] = N_("File name missing after `%s' option"); +static const char no_mac[] = N_("Macro name missing after `%s' option"); +static const char no_pth[] = N_("Path name missing after `%s' option"); + +/* This list must be ASCII sorted. Make enum order above match this. */ +#define DEF_OPT(text, msg, code) {text, msg, sizeof(text) - 1, code} + +#ifdef HOST_EBCDIC +static struct cl_option cl_options[] = +#else +static const struct cl_option cl_options[] = +#endif +{ + DEF_OPT("", 0, OPT_stdin_stdout), + DEF_OPT("$", 0, OPT_dollar), + DEF_OPT("+", 0, OPT_plus), + DEF_OPT("-help", 0, OPT__help), + DEF_OPT("-version", 0, OPT__version), + DEF_OPT("A", no_ass, OPT_A), + DEF_OPT("C", 0, OPT_C), + DEF_OPT("D", no_mac, OPT_D), + DEF_OPT("H", 0, OPT_H), + DEF_OPT("I", no_dir, OPT_I), + DEF_OPT("M", 0, OPT_M), + DEF_OPT("MD", no_fil, OPT_MD), + DEF_OPT("MG", 0, OPT_MG), + DEF_OPT("MM", 0, OPT_MM), + DEF_OPT("MMD", no_fil, OPT_MMD), + DEF_OPT("P", 0, OPT_P), + DEF_OPT("U", no_mac, OPT_U), + /* NB: Immed arg only, and not reqd */ + DEF_OPT("W", no_arg, OPT_W), + DEF_OPT("d", no_arg, OPT_d), + DEF_OPT("fleading-underscore", 0, OPT_fleading_underscore), + DEF_OPT("fno-leading-underscore", 0, OPT_fno_leading_underscore), + DEF_OPT("fpreprocessed", 0, OPT_fpreprocessed), + DEF_OPT("fno-preprocessed", 0, OPT_fno_preprocessed), + /* NB: Immed arg only, and not reqd */ + DEF_OPT("g", no_arg, OPT_g), + DEF_OPT("h", 0, OPT_h), + DEF_OPT("idirafter", no_dir, OPT_idirafter), + DEF_OPT("imacros", no_fil, OPT_imacros), + DEF_OPT("include", no_fil, OPT_include), + DEF_OPT("iprefix", no_pth, OPT_iprefix), + DEF_OPT("isystem", no_dir, OPT_isystem), + DEF_OPT("iwithprefix", no_dir, OPT_iwithprefix), + DEF_OPT("iwithprefixbefore", no_dir, OPT_iwithprefixbefore), + DEF_OPT("lang-asm", 0, OPT_lang_asm), + DEF_OPT("lang-c", 0, OPT_lang_c), + DEF_OPT("lang-c++", 0, OPT_lang_cplusplus), + DEF_OPT("lang-c89", 0, OPT_lang_c89), + DEF_OPT("lang-chill", 0, OPT_lang_chill), + DEF_OPT("lang-fortran", 0, OPT_lang_fortran), + DEF_OPT("lang-objc", 0, OPT_lang_objc), + DEF_OPT("lang-objc++", 0, OPT_lang_objcplusplus), + DEF_OPT("nostdinc", 0, OPT_nostdinc), + DEF_OPT("nostdinc++", 0, OPT_nostdincplusplus), + DEF_OPT("o", no_fil, OPT_o), + DEF_OPT("pedantic", 0, OPT_pedantic), + DEF_OPT("pedantic-errors", 0, OPT_pedantic_errors), + DEF_OPT("remap", 0, OPT_remap), + DEF_OPT("std=c89", 0, OPT_std_c89), + DEF_OPT("std=c99", 0, OPT_std_c99), + DEF_OPT("std=c9x", 0, OPT_std_c9x), + DEF_OPT("std=gnu89", 0, OPT_std_gnu89), + DEF_OPT("std=gnu99", 0, OPT_std_gnu99), + DEF_OPT("std=gnu9x", 0, OPT_std_gnu9x), + DEF_OPT("std=iso9899:1990", 0, OPT_std_iso9899_1990), + DEF_OPT("std=iso9899:199409", 0, OPT_std_iso9899_199409), + DEF_OPT("std=iso9899:1999", 0, OPT_std_iso9899_1999), + DEF_OPT("std=iso9899:199x", 0, OPT_std_iso9899_199x), + DEF_OPT("traditional", 0, OPT_traditional), + DEF_OPT("trigraphs", 0, OPT_trigraphs), + DEF_OPT("v", 0, OPT_v), + DEF_OPT("w", 0, OPT_w) +}; +#undef DEF_OPT + +/* Perform a binary search to find which, if any, option the given + command-line matches. Returns its index in the option array, + negative on failure. Complications arise since some options can be + suffixed with an argument, and multiple complete matches can occur, + e.g. -iwithprefix and -iwithprefixbefore. Moreover, we want to + accept options beginning with -g and -W that we do not recognise, + but not to swallow any subsequent command line argument; these are + handled as special cases in cpp_handle_option */ +static int +parse_option (input) + const char* input; +{ + unsigned int md, mn, mx; + size_t opt_len; + int comp; + + mn = 0; + mx = N_OPTS; + + while (mx > mn) + { + md = (mn + mx) / 2; + + opt_len = cl_options[md].opt_len; + comp = strncmp (input, cl_options[md].opt_text, opt_len); + + if (comp > 0) + mn = md + 1; + else if (comp < 0) + mx = md; + else + { + if (input[opt_len] == '\0') + return md; + /* We were passed more text. If the option takes an argument, + we may match a later option or we may have been passed the + argument. The longest possible option match succeeds. + If the option takes no arguments we have not matched and + continue the search (e.g. input="stdc++" match was "stdc") */ + mn = md + 1; + if (cl_options[md].msg) + { + /* Scan forwards. If we get an exact match, return it. + Otherwise, return the longest option-accepting match. + This loops no more than twice with current options */ + mx = md; + for (; mn < N_OPTS; mn++) + { + opt_len = cl_options[mn].opt_len; + if (strncmp (input, cl_options[mn].opt_text, opt_len)) + break; + if (input[opt_len] == '\0') + return mn; + if (cl_options[mn].msg) + mx = mn; + } + return mx; + } + } + } + + return -1; +} + /* Handle one command-line option in (argc, argv). Can be called multiple times, to handle multiple sets of options. Returns number of strings consumed. */ -int +static int cpp_handle_option (pfile, argc, argv) cpp_reader *pfile; int argc; @@ -923,374 +1107,213 @@ cpp_handle_option (pfile, argc, argv) opts->in_fname = argv[i]; } else - switch (argv[i][1]) - { - case 'f': - if (!strcmp (argv[i], "-fleading-underscore")) + { + enum opt_code opt_code; + int opt_index; + char* arg = 0; + + /* Skip over '-' */ + opt_index = parse_option (&argv[i][1]); + if (opt_index < 0) + return i; + + opt_code = cl_options[opt_index].opt_code; + if (cl_options[opt_index].msg) + { + arg = &argv[i][cl_options[opt_index].opt_len + 1]; + + /* Yuk. Special case for -g and -W as they must not swallow + up any following argument. If this becomes common, add + another field to the cl_options table */ + if (arg[0] == '\0' && !(opt_code == OPT_g || opt_code == OPT_W)) + { + arg = argv[++i]; + if (!arg) + { + cpp_fatal (pfile, _(cl_options[opt_index].msg), argv[i - 1]); + return argc; + } + } + } + + switch (opt_code) + { + case N_OPTS: /* shut GCC up */ + break; + case OPT_fleading_underscore: user_label_prefix = "_"; - else if (!strcmp (argv[i], "-fno-leading-underscore")) + break; + case OPT_fno_leading_underscore: user_label_prefix = ""; - else if (!strcmp (argv[i], "-fpreprocessed")) + break; + case OPT_fpreprocessed: opts->preprocessed = 1; - else if (!strcmp (argv[i], "-fno-preprocessed")) + break; + case OPT_fno_preprocessed: opts->preprocessed = 0; - else - { - return i; - } - break; - - case 'I': /* Add directory to path for includes. */ - if (!strcmp (argv[i] + 2, "-")) - { - /* -I- means: - Use the preceding -I directories for #include "..." - but not #include <...>. - Don't search the directory of the present file - for #include "...". (Note that -I. -I- is not the same as - the default setup; -I. uses the compiler's working dir.) */ - if (! opts->ignore_srcdir) - { - opts->ignore_srcdir = 1; - opts->pending->quote_head = opts->pending->brack_head; - opts->pending->quote_tail = opts->pending->brack_tail; - opts->pending->brack_head = 0; - opts->pending->brack_tail = 0; - } - else - { - cpp_fatal (pfile, "-I- specified twice"); - return argc; - } - } - else - { - char *fname; - if (argv[i][2] != 0) - fname = argv[i] + 2; - else if (i + 1 == argc) - goto missing_dirname; - else - fname = argv[++i]; - append_include_chain (pfile, opts->pending, - xstrdup (fname), BRACKET, 0); - } - break; - - case 'i': - /* Add directory to beginning of system include path, as a system - include directory. */ - if (!strcmp (argv[i], "-isystem")) - { - if (i + 1 == argc) - goto missing_filename; - append_include_chain (pfile, opts->pending, - xstrdup (argv[++i]), SYSTEM, 0); - } - else if (!strcmp (argv[i], "-include")) - { - if (i + 1 == argc) - goto missing_filename; - else - { - struct pending_option *o = (struct pending_option *) - xmalloc (sizeof (struct pending_option)); - o->arg = argv[++i]; - - /* This list has to be built in reverse order so that - when cpp_start_read pushes all the -include files onto - the buffer stack, they will be scanned in forward order. */ - o->next = opts->pending->include_head; - opts->pending->include_head = o; - } - } - else if (!strcmp (argv[i], "-imacros")) - { - if (i + 1 == argc) - goto missing_filename; - else - { - struct pending_option *o = (struct pending_option *) - xmalloc (sizeof (struct pending_option)); - o->arg = argv[++i]; - o->next = NULL; - - APPEND (opts->pending, imacros, o); - } - } - /* Add directory to end of path for includes, - with the default prefix at the front of its name. */ - else if (!strcmp (argv[i], "-iwithprefix")) - { - char *fname; - int len; - if (i + 1 == argc) - goto missing_dirname; - ++i; - len = strlen (argv[i]); - - if (opts->include_prefix != 0) - { - fname = xmalloc (opts->include_prefix_len + len + 1); - memcpy (fname, opts->include_prefix, opts->include_prefix_len); - memcpy (fname + opts->include_prefix_len, argv[i], len + 1); - } - else - { - fname = xmalloc (sizeof GCC_INCLUDE_DIR - 8 + len); - memcpy (fname, GCC_INCLUDE_DIR, sizeof GCC_INCLUDE_DIR - 9); - memcpy (fname + sizeof GCC_INCLUDE_DIR - 9, argv[i], len + 1); - } - - append_include_chain (pfile, opts->pending, fname, SYSTEM, 0); - } - /* Add directory to main path for includes, - with the default prefix at the front of its name. */ - else if (!strcmp (argv[i], "-iwithprefixbefore")) - { - char *fname; - int len; - if (i + 1 == argc) - goto missing_dirname; - ++i; - len = strlen (argv[i]); - - if (opts->include_prefix != 0) - { - fname = xmalloc (opts->include_prefix_len + len + 1); - memcpy (fname, opts->include_prefix, opts->include_prefix_len); - memcpy (fname + opts->include_prefix_len, argv[i], len + 1); - } - else - { - fname = xmalloc (sizeof GCC_INCLUDE_DIR - 8 + len); - memcpy (fname, GCC_INCLUDE_DIR, sizeof GCC_INCLUDE_DIR - 9); - memcpy (fname + sizeof GCC_INCLUDE_DIR - 9, argv[i], len + 1); - } - - append_include_chain (pfile, opts->pending, fname, BRACKET, 0); - } - /* Add directory to end of path for includes. */ - else if (!strcmp (argv[i], "-idirafter")) - { - if (i + 1 == argc) - goto missing_dirname; - append_include_chain (pfile, opts->pending, - xstrdup (argv[++i]), AFTER, 0); - } - else if (!strcmp (argv[i], "-iprefix")) - { - if (i + 1 == argc) - goto missing_filename; - else - { - opts->include_prefix = argv[++i]; - opts->include_prefix_len = strlen (argv[i]); - } - } - break; - - case 'o': - if (opts->out_fname != NULL) - { - cpp_fatal (pfile, "Output filename specified twice"); - return argc; - } - if (i + 1 == argc) - goto missing_filename; - opts->out_fname = argv[++i]; - if (!strcmp (opts->out_fname, "-")) - opts->out_fname = ""; - break; - - case 'p': - if (!strcmp (argv[i], "-pedantic")) - opts->pedantic = 1; - else if (!strcmp (argv[i], "-pedantic-errors")) - { - opts->pedantic = 1; - opts->pedantic_errors = 1; - } - break; - - case 't': - if (!strcmp (argv[i], "-traditional")) - { - opts->traditional = 1; - opts->cplusplus_comments = 0; - opts->trigraphs = 0; - opts->warn_trigraphs = 0; - } - else if (!strcmp (argv[i], "-trigraphs")) - opts->trigraphs = 1; - break; - - case 'l': - if (! strcmp (argv[i], "-lang-c")) - opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0, - opts->c99 = 1, opts->objc = 0; - if (! strcmp (argv[i], "-lang-c89")) - { - opts->cplusplus = 0, opts->cplusplus_comments = 0; - opts->c89 = 1, opts->c99 = 0, opts->objc = 0; - opts->trigraphs = 1; - new_pending_define (opts, "__STRICT_ANSI__"); - } - if (! strcmp (argv[i], "-lang-c++")) - opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0, - opts->c99 = 0, opts->objc = 0; - if (! strcmp (argv[i], "-lang-objc")) - opts->cplusplus = 0, opts->cplusplus_comments = 1, opts->c89 = 0, - opts->c99 = 0, opts->objc = 1; - if (! strcmp (argv[i], "-lang-objc++")) - opts->cplusplus = 1, opts->cplusplus_comments = 1, opts->c89 = 0, - opts->c99 = 0, opts->objc = 1; - if (! strcmp (argv[i], "-lang-asm")) - opts->lang_asm = 1; - if (! strcmp (argv[i], "-lang-fortran")) - opts->lang_fortran = 1, opts->cplusplus_comments = 0; - if (! strcmp (argv[i], "-lang-chill")) - opts->objc = 0, opts->cplusplus = 0, opts->chill = 1, - opts->traditional = 1; - break; - - case '+': - opts->cplusplus = 1, opts->cplusplus_comments = 1; - break; - - case 's': - if (!strcmp (argv[i], "-std=gnu89")) - { - opts->cplusplus = 0, opts->cplusplus_comments = 1; - opts->c89 = 1, opts->c99 = 0, opts->objc = 0; - } - else if (!strcmp (argv[i], "-std=gnu9x") - || !strcmp (argv[i], "-std=gnu99")) - { - opts->cplusplus = 0, opts->cplusplus_comments = 1; - opts->c89 = 0, opts->c99 = 1, opts->objc = 0; - new_pending_define (opts, "__STDC_VERSION__=199901L"); - } - else if (!strcmp (argv[i], "-std=iso9899:1990") - || !strcmp (argv[i], "-std=c89")) - { - opts->cplusplus = 0, opts->cplusplus_comments = 0; - opts->c89 = 1, opts->c99 = 0, opts->objc = 0; - opts->trigraphs = 1; - new_pending_define (opts, "__STRICT_ANSI__"); - } - else if (!strcmp (argv[i], "-std=iso9899:199409")) - { - opts->cplusplus = 0, opts->cplusplus_comments = 0; - opts->c89 = 1, opts->c99 = 0, opts->objc = 0; - opts->trigraphs = 1; - new_pending_define (opts, "__STRICT_ANSI__"); - new_pending_define (opts, "__STDC_VERSION__=199409L"); - } - else if (!strcmp (argv[i], "-std=iso9899:199x") - || !strcmp (argv[i], "-std=iso9899:1999") - || !strcmp (argv[i], "-std=c9x") - || !strcmp (argv[i], "-std=c99")) - { - opts->cplusplus = 0, opts->cplusplus_comments = 1; - opts->c89 = 0, opts->c99 = 1, opts->objc = 0; - opts->trigraphs = 1; - new_pending_define (opts, "__STRICT_ANSI__"); - new_pending_define (opts, "__STDC_VERSION__=199901L"); - } - break; - - case 'w': - opts->inhibit_warnings = 1; - break; - - case 'W': - if (!strcmp (argv[i], "-Wtrigraphs")) - opts->warn_trigraphs = 1; - else if (!strcmp (argv[i], "-Wno-trigraphs")) + break; + case OPT_w: + opts->inhibit_warnings = 1; + break; + case OPT_g: /* Silently ignore anything but -g3 */ + if (!strcmp(&argv[i][2], "3")) + opts->debug_output = 1; + break; + case OPT_h: + case OPT__help: + print_help (); + exit (0); /* XXX */ + break; + case OPT__version: + fprintf (stderr, _("GNU CPP version %s (cpplib)\n"), version_string); + exit (0); /* XXX */ + break; + case OPT_C: + opts->discard_comments = 0; + break; + case OPT_P: + opts->no_line_commands = 1; + break; + case OPT_dollar: /* Don't include $ in identifiers. */ + opts->dollars_in_ident = 0; + break; + case OPT_H: + opts->print_include_names = 1; + break; + case OPT_D: + new_pending_define (opts, arg); + break; + case OPT_pedantic_errors: + opts->pedantic_errors = 1; + /* fall through */ + case OPT_pedantic: + opts->pedantic = 1; + break; + case OPT_traditional: + opts->traditional = 1; + opts->cplusplus_comments = 0; + opts->trigraphs = 0; opts->warn_trigraphs = 0; - else if (!strcmp (argv[i], "-Wcomment")) - opts->warn_comments = 1; - else if (!strcmp (argv[i], "-Wno-comment")) - opts->warn_comments = 0; - else if (!strcmp (argv[i], "-Wcomments")) - opts->warn_comments = 1; - else if (!strcmp (argv[i], "-Wno-comments")) - opts->warn_comments = 0; - else if (!strcmp (argv[i], "-Wtraditional")) - opts->warn_stringify = 1; - else if (!strcmp (argv[i], "-Wno-traditional")) - opts->warn_stringify = 0; - else if (!strcmp (argv[i], "-Wundef")) - opts->warn_undef = 1; - else if (!strcmp (argv[i], "-Wno-undef")) - opts->warn_undef = 0; - else if (!strcmp (argv[i], "-Wimport")) - opts->warn_import = 1; - else if (!strcmp (argv[i], "-Wno-import")) - opts->warn_import = 0; - else if (!strcmp (argv[i], "-Werror")) - opts->warnings_are_errors = 1; - else if (!strcmp (argv[i], "-Wno-error")) - opts->warnings_are_errors = 0; - else if (!strcmp (argv[i], "-Wall")) - { - opts->warn_trigraphs = 1; - opts->warn_comments = 1; - } - break; - - case 'M': - /* The style of the choices here is a bit mixed. - The chosen scheme is a hybrid of keeping all options in one string - and specifying each option in a separate argument: - -M|-MM|-MD file|-MMD file [-MG]. An alternative is: - -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely: - -M[M][G][D file]. This is awkward to handle in specs, and is not - as extensible. */ - /* ??? -MG must be specified in addition to one of -M or -MM. - This can be relaxed in the future without breaking anything. - The converse isn't true. */ - - /* -MG isn't valid with -MD or -MMD. This is checked for later. */ - if (!strcmp (argv[i], "-MG")) - { - opts->print_deps_missing_files = 1; - break; - } - if (!strcmp (argv[i], "-M")) - opts->print_deps = 2; - else if (!strcmp (argv[i], "-MM")) - opts->print_deps = 1; - else if (!strcmp (argv[i], "-MD")) - opts->print_deps = 2; - else if (!strcmp (argv[i], "-MMD")) - opts->print_deps = 1; - /* For -MD and -MMD options, write deps on file named by next arg. */ - if (!strcmp (argv[i], "-MD") || !strcmp (argv[i], "-MMD")) - { - if (i+1 == argc) - goto missing_filename; - opts->deps_file = argv[++i]; - } - else - { - /* For -M and -MM, write deps on standard output - and suppress the usual output. */ - opts->no_output = 1; - } - break; - - case 'd': - { - char *p = argv[i] + 2; - char c; - while ((c = *p++) != 0) + break; + case OPT_trigraphs: + opts->trigraphs = 1; + break; + case OPT_plus: + opts->cplusplus = 1; + opts->cplusplus_comments = 1; + break; + case OPT_remap: + opts->remap = 1; + break; + case OPT_iprefix: + opts->include_prefix = arg; + opts->include_prefix_len = strlen (arg); + break; + case OPT_lang_c: + opts->cplusplus = 0, opts->cplusplus_comments = 1; + opts->c89 = 0, opts->c99 = 1, opts->objc = 0; + break; + case OPT_lang_c89: + opts->cplusplus = 0, opts->cplusplus_comments = 0; + opts->c89 = 1, opts->c99 = 0, opts->objc = 0; + opts->trigraphs = 1; + new_pending_define (opts, "__STRICT_ANSI__"); + break; + case OPT_lang_cplusplus: + opts->cplusplus = 1, opts->cplusplus_comments = 1; + opts->c89 = 0, opts->c99 = 0, opts->objc = 0; + break; + case OPT_lang_objc: + case OPT_lang_objcplusplus: + opts->cplusplus = opt_code == OPT_lang_objcplusplus; + opts->cplusplus_comments = 1; + opts->c89 = 0, opts->c99 = 0, opts->objc = 1; + break; + case OPT_lang_asm: + opts->lang_asm = 1; + break; + case OPT_lang_fortran: + opts->lang_fortran = 1, opts->cplusplus_comments = 0; + break; + case OPT_lang_chill: + opts->objc = 0, opts->cplusplus = 0; + opts->chill = 1, opts->traditional = 1; + break; + case OPT_nostdinc: + /* -nostdinc causes no default include directories. + You must specify all include-file directories with -I. */ + opts->no_standard_includes = 1; + break; + case OPT_nostdincplusplus: + /* -nostdinc++ causes no default C++-specific include directories. */ + opts->no_standard_cplusplus_includes = 1; + break; + case OPT_std_gnu89: + opts->cplusplus = 0, opts->cplusplus_comments = 1; + opts->c89 = 1, opts->c99 = 0, opts->objc = 0; + break; + case OPT_std_gnu9x: + case OPT_std_gnu99: + opts->cplusplus = 0, opts->cplusplus_comments = 1; + opts->c89 = 0, opts->c99 = 1, opts->objc = 0; + new_pending_define (opts, "__STDC_VERSION__=199901L"); + break; + case OPT_std_iso9899_199409: + new_pending_define (opts, "__STDC_VERSION__=199409L"); + /* Fall through */ + case OPT_std_iso9899_1990: + case OPT_std_c89: + opts->cplusplus = 0, opts->cplusplus_comments = 0; + opts->c89 = 1, opts->c99 = 0, opts->objc = 0; + opts->trigraphs = 1; + new_pending_define (opts, "__STRICT_ANSI__"); + break; + case OPT_std_iso9899_199x: + case OPT_std_iso9899_1999: + case OPT_std_c9x: + case OPT_std_c99: + opts->cplusplus = 0, opts->cplusplus_comments = 1; + opts->c89 = 0, opts->c99 = 1, opts->objc = 0; + opts->trigraphs = 1; + new_pending_define (opts, "__STRICT_ANSI__"); + new_pending_define (opts, "__STDC_VERSION__=199901L"); + break; + case OPT_o: + if (opts->out_fname != NULL) { - /* Arg to -d specifies what parts of macros to dump */ - switch (c) - { - case 'M': + cpp_fatal (pfile, "Output filename specified twice"); + return argc; + } + opts->out_fname = arg; + if (!strcmp (opts->out_fname, "-")) + opts->out_fname = ""; + break; + case OPT_v: + fprintf (stderr, _("GNU CPP version %s (cpplib)\n"), version_string); +#ifdef TARGET_VERSION + TARGET_VERSION; +#endif + fputc ('\n', stderr); + opts->verbose = 1; + break; + case OPT_stdin_stdout: + /* JF handle '-' as file name meaning stdin or stdout */ + if (opts->in_fname == NULL) + opts->in_fname = ""; + else if (opts->out_fname == NULL) + opts->out_fname = ""; + break; + case OPT_d: + /* Args to -d specify what parts of macros to dump. + Silently ignore unrecognised options; they may + be aimed at the compiler proper. */ + { + char c; + + while ((c = *arg++) != '\0') + switch (c) + { + case 'M': opts->dump_macros = dump_only; opts->no_output = 1; break; @@ -1304,75 +1327,50 @@ cpp_handle_option (pfile, argc, argv) opts->dump_includes = 1; break; } - } - } - break; - - case 'g': - if (argv[i][2] == '3') - opts->debug_output = 1; - break; - - case '-': - if (!strcmp (argv[i], "--help")) - print_help (); - else if (!strcmp (argv[i], "--version")) - fprintf (stderr, _("GNU CPP version %s (cpplib)\n"), version_string); - exit (0); /* XXX */ - break; - - case 'v': - fprintf (stderr, _("GNU CPP version %s (cpplib)\n"), version_string); -#ifdef TARGET_VERSION - TARGET_VERSION; -#endif - fputc ('\n', stderr); - opts->verbose = 1; - break; - - case 'H': - opts->print_include_names = 1; - break; - - case 'D': - { - const char *text; - if (argv[i][2] != 0) - text = argv[i] + 2; - else if (i + 1 == argc) - { - cpp_fatal (pfile, "Macro name missing after -D option"); - return argc; - } - else - text = argv[++i]; - new_pending_define (opts, text); - } - break; - - case 'A': - { - char *p; - - if (argv[i][2] != 0) - p = argv[i] + 2; - else if (i + 1 == argc) - { - cpp_fatal (pfile, "Assertion missing after -A option"); - return argc; - } - else - p = argv[++i]; - - if (strcmp (p, "-")) - { - struct pending_option *o = (struct pending_option *) - xmalloc (sizeof (struct pending_option)); + } + break; + /* The style of the choices here is a bit mixed. + The chosen scheme is a hybrid of keeping all options in one string + and specifying each option in a separate argument: + -M|-MM|-MD file|-MMD file [-MG]. An alternative is: + -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely: + -M[M][G][D file]. This is awkward to handle in specs, and is not + as extensible. */ + /* ??? -MG must be specified in addition to one of -M or -MM. + This can be relaxed in the future without breaking anything. + The converse isn't true. */ + + /* -MG isn't valid with -MD or -MMD. This is checked for later. */ + case OPT_MG: + opts->print_deps_missing_files = 1; + break; + case OPT_M: + case OPT_MD: + case OPT_MM: + case OPT_MMD: + if (opt_code == OPT_M || opt_code == OPT_MD) + opts->print_deps = 2; + else + opts->print_deps = 1; - o->arg = p; - o->next = NULL; - o->undef = 0; - APPEND (opts->pending, assert, o); + /* For -MD and -MMD options, write deps on file named by next arg */ + /* For -M and -MM, write deps on standard output + and suppress the usual output. */ + if (opt_code == OPT_MD || opt_code == OPT_MMD) + opts->deps_file = arg; + else + opts->no_output = 1; + break; + case OPT_A: + if (strcmp (arg, "-")) + { + struct pending_option *o = (struct pending_option *) + xmalloc (sizeof (struct pending_option)); + + o->arg = arg; + o->next = NULL; + o->undef = 0; + APPEND (opts->pending, assert, o); } else { @@ -1401,88 +1399,163 @@ cpp_handle_option (pfile, argc, argv) opts->pending->define_head = NULL; opts->pending->define_tail = NULL; } - } - break; - - case 'U': - { - struct pending_option *o = (struct pending_option *) - xmalloc (sizeof (struct pending_option)); - - if (argv[i][2] != 0) - o->arg = argv[i] + 2; - else if (i + 1 == argc) + break; + case OPT_U: + { + struct pending_option *o = (struct pending_option *) + xmalloc (sizeof (struct pending_option)); + + o->arg = arg; + o->next = NULL; + o->undef = 1; + APPEND (opts->pending, define, o); + } + break; + case OPT_I: /* Add directory to path for includes. */ + if (!strcmp (arg, "-")) + { + /* -I- means: + Use the preceding -I directories for #include "..." + but not #include <...>. + Don't search the directory of the present file + for #include "...". (Note that -I. -I- is not the same as + the default setup; -I. uses the compiler's working dir.) */ + if (! opts->ignore_srcdir) + { + opts->ignore_srcdir = 1; + opts->pending->quote_head = opts->pending->brack_head; + opts->pending->quote_tail = opts->pending->brack_tail; + opts->pending->brack_head = 0; + opts->pending->brack_tail = 0; + } + else + { + cpp_fatal (pfile, "-I- specified twice"); + return argc; + } + } + else + append_include_chain (pfile, opts->pending, + xstrdup (arg), BRACKET, 0); + break; + case OPT_isystem: + /* Add directory to beginning of system include path, as a system + include directory. */ + append_include_chain (pfile, opts->pending, + xstrdup (arg), SYSTEM, 0); + break; + case OPT_include: + { + struct pending_option *o = (struct pending_option *) + xmalloc (sizeof (struct pending_option)); + o->arg = arg; + + /* This list has to be built in reverse order so that + when cpp_start_read pushes all the -include files onto + the buffer stack, they will be scanned in forward order. */ + o->next = opts->pending->include_head; + opts->pending->include_head = o; + } + break; + case OPT_imacros: + { + struct pending_option *o = (struct pending_option *) + xmalloc (sizeof (struct pending_option)); + o->arg = arg; + o->next = NULL; + + APPEND (opts->pending, imacros, o); + } + break; + case OPT_iwithprefix: + /* Add directory to end of path for includes, + with the default prefix at the front of its name. */ + /* fall through */ + case OPT_iwithprefixbefore: + /* Add directory to main path for includes, + with the default prefix at the front of its name. */ + { + char *fname; + int len; + + len = strlen (arg); + + if (opts->include_prefix != 0) + { + fname = xmalloc (opts->include_prefix_len + len + 1); + memcpy (fname, opts->include_prefix, opts->include_prefix_len); + memcpy (fname + opts->include_prefix_len, arg, len + 1); + } + else + { + fname = xmalloc (sizeof GCC_INCLUDE_DIR - 8 + len); + memcpy (fname, GCC_INCLUDE_DIR, sizeof GCC_INCLUDE_DIR - 9); + memcpy (fname + sizeof GCC_INCLUDE_DIR - 9, arg, len + 1); + } + + append_include_chain (pfile, opts->pending, fname, + opt_code == OPT_iwithprefix ? SYSTEM: BRACKET, 0); + } + break; + case OPT_idirafter: + /* Add directory to end of path for includes. */ + append_include_chain (pfile, opts->pending, + xstrdup (arg), AFTER, 0); + break; + case OPT_W: + /* Silently ignore unrecognised options */ + if (!strcmp (argv[i], "-Wall")) { - cpp_fatal (pfile, "Macro name missing after -U option"); - return argc; + opts->warn_trigraphs = 1; + opts->warn_comments = 1; } - else - o->arg = argv[++i]; - - o->next = NULL; - o->undef = 1; - APPEND (opts->pending, define, o); - } - break; - - case 'C': - opts->discard_comments = 0; - break; - - case 'E': /* -E comes from cc -E; ignore it. */ - break; - - case 'P': - opts->no_line_commands = 1; - break; - - case '$': /* Don't include $ in identifiers. */ - opts->dollars_in_ident = 0; - break; - - case 'n': - if (!strcmp (argv[i], "-nostdinc")) - /* -nostdinc causes no default include directories. - You must specify all include-file directories with -I. */ - opts->no_standard_includes = 1; - else if (!strcmp (argv[i], "-nostdinc++")) - /* -nostdinc++ causes no default C++-specific include directories. */ - opts->no_standard_cplusplus_includes = 1; - break; - - case 'r': - if (!strcmp (argv[i], "-remap")) - opts->remap = 1; - break; - - case '\0': /* JF handle '-' as file name meaning stdin or stdout */ - if (opts->in_fname == NULL) - opts->in_fname = ""; - else if (opts->out_fname == NULL) - opts->out_fname = ""; - else - return i; /* error */ - break; - - default: - return i; - } - + else if (!strcmp (argv[i], "-Wtraditional")) + opts->warn_stringify = 1; + else if (!strcmp (argv[i], "-Wtrigraphs")) + opts->warn_trigraphs = 1; + else if (!strcmp (argv[i], "-Wcomment")) + opts->warn_comments = 1; + else if (!strcmp (argv[i], "-Wcomments")) + opts->warn_comments = 1; + else if (!strcmp (argv[i], "-Wundef")) + opts->warn_undef = 1; + else if (!strcmp (argv[i], "-Wimport")) + opts->warn_import = 1; + else if (!strcmp (argv[i], "-Werror")) + opts->warnings_are_errors = 1; + else if (!strcmp (argv[i], "-Wno-traditional")) + opts->warn_stringify = 0; + else if (!strcmp (argv[i], "-Wno-trigraphs")) + opts->warn_trigraphs = 0; + else if (!strcmp (argv[i], "-Wno-comment")) + opts->warn_comments = 0; + else if (!strcmp (argv[i], "-Wno-comments")) + opts->warn_comments = 0; + else if (!strcmp (argv[i], "-Wno-undef")) + opts->warn_undef = 0; + else if (!strcmp (argv[i], "-Wno-import")) + opts->warn_import = 0; + else if (!strcmp (argv[i], "-Wno-error")) + opts->warnings_are_errors = 0; + break; + } + } return i + 1; +} - missing_filename: - cpp_fatal (pfile, "Filename missing after `%s' option", argv[i]); - return argc; - missing_dirname: - cpp_fatal (pfile, "Directory name missing after `%s' option", argv[i]); - return argc; +#ifdef HOST_EBCDIC +static int +opt_comp (const void* p1, const void* p2) +{ + return strcmp (((struct cl_option*) p1)->opt_text, + ((struct cl_option*) p2)->opt_text); } +#endif /* Handle command-line options in (argc, argv). Can be called multiple times, to handle multiple sets of options. Returns if an unrecognized option is seen. Returns number of strings consumed. */ - int cpp_handle_options (pfile, argc, argv) cpp_reader *pfile; @@ -1491,6 +1564,18 @@ cpp_handle_options (pfile, argc, argv) { int i; int strings_processed; + +#ifdef HOST_EBCDIC + static int opts_sorted = 0; + + if (!opts_sorted) + { + opts_sorted = 1; + /* For non-ASCII hosts, the array needs to be sorted at runtime */ + qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp); + } +#endif + for (i = 0; i < argc; i += strings_processed) { strings_processed = cpp_handle_option (pfile, argc - i, argv + i); @@ -1514,11 +1599,13 @@ Switches:\n\ -isystem <dir> Add <dir> to the start of the system include path\n\ -idirafter <dir> Add <dir> to the end of the system include path\n\ -I <dir> Add <dir> to the end of the main include path\n\ + -I- Fine-grained include path control; see info docs\n\ -nostdinc Do not search system include directories\n\ (dirs specified with -isystem will still be used)\n\ -nostdinc++ Do not search system include directories for C++\n\ -o <file> Put output into <file>\n\ -pedantic Issue all warnings demanded by strict ANSI C\n\ + -pedantic-errors Issue -pedantic warnings as errors instead\n\ -traditional Follow K&R pre-processor behaviour\n\ -trigraphs Support ANSI C trigraphs\n\ -lang-c Assume that the input sources are in C\n\ @@ -1553,7 +1640,7 @@ Switches:\n\ -MD As -M, but put output in a .d file\n\ -MMD As -MD, but ignore system header files\n\ -MG Treat missing header file as generated files\n\ - -g Include #define and #undef directives in the output\n\ + -g3 Include #define and #undef directives in the output\n\ -D<macro> Define a <macro> with string '1' as its value\n\ -D<macro>=<val> Define a <macro> with <val> as its value\n\ -A<question> (<answer>) Assert the <answer> to <question>\n\ @@ -1568,6 +1655,7 @@ Switches:\n\ -P Do not generate #line directives\n\ -$ Do not allow '$' in identifiers\n\ -remap Remap file names when including files.\n\ + --version Display version information\n\ -h or --help Display this information\n\ "), stdout); } Index: cpplib.h =================================================================== RCS file: /cvs/gcc/egcs/gcc/cpplib.h,v retrieving revision 1.64 diff -u -p -r1.64 cpplib.h --- cpplib.h 2000/03/04 19:42:04 1.64 +++ cpplib.h 2000/03/07 11:42:26 @@ -64,7 +64,6 @@ enum cpp_token typedef enum cpp_token (*parse_underflow_t) PARAMS((cpp_reader *)); typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader *)); -extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **)); extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **)); extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *)); extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *));
Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]