1169689Skan/* Command line option handling. 2169689Skan Copyright (C) 2006 Free Software Foundation, Inc. 3169689Skan 4169689SkanThis file is part of GCC. 5169689Skan 6169689SkanGCC is free software; you can redistribute it and/or modify it under 7169689Skanthe terms of the GNU General Public License as published by the Free 8169689SkanSoftware Foundation; either version 2, or (at your option) any later 9169689Skanversion. 10169689Skan 11169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 12169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 13169689SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14169689Skanfor more details. 15169689Skan 16169689SkanYou should have received a copy of the GNU General Public License 17169689Skanalong with GCC; see the file COPYING. If not, write to the Free 18169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 19169689Skan02110-1301, USA. */ 20169689Skan 21169689Skan#include "config.h" 22169689Skan#include "system.h" 23169689Skan#include "intl.h" 24169689Skan#include "coretypes.h" 25169689Skan#include "opts.h" 26169689Skan 27169689Skan/* Perform a binary search to find which option the command-line INPUT 28169689Skan matches. Returns its index in the option array, and N_OPTS 29169689Skan (cl_options_count) on failure. 30169689Skan 31169689Skan This routine is quite subtle. A normal binary search is not good 32169689Skan enough because some options can be suffixed with an argument, and 33169689Skan multiple sub-matches can occur, e.g. input of "-pedantic" matching 34169689Skan the initial substring of "-pedantic-errors". 35169689Skan 36169689Skan A more complicated example is -gstabs. It should match "-g" with 37169689Skan an argument of "stabs". Suppose, however, that the number and list 38169689Skan of switches are such that the binary search tests "-gen-decls" 39169689Skan before having tested "-g". This doesn't match, and as "-gen-decls" 40169689Skan is less than "-gstabs", it will become the lower bound of the 41169689Skan binary search range, and "-g" will never be seen. To resolve this 42169689Skan issue, opts.sh makes "-gen-decls" point, via the back_chain member, 43169689Skan to "-g" so that failed searches that end between "-gen-decls" and 44169689Skan the lexicographically subsequent switch know to go back and see if 45169689Skan "-g" causes a match (which it does in this example). 46169689Skan 47169689Skan This search is done in such a way that the longest match for the 48169689Skan front end in question wins. If there is no match for the current 49169689Skan front end, the longest match for a different front end is returned 50169689Skan (or N_OPTS if none) and the caller emits an error message. */ 51169689Skansize_t 52169689Skanfind_opt (const char *input, int lang_mask) 53169689Skan{ 54169689Skan size_t mn, mx, md, opt_len; 55169689Skan size_t match_wrong_lang; 56169689Skan int comp; 57169689Skan 58169689Skan mn = 0; 59169689Skan mx = cl_options_count; 60169689Skan 61169689Skan /* Find mn such this lexicographical inequality holds: 62169689Skan cl_options[mn] <= input < cl_options[mn + 1]. */ 63169689Skan while (mx - mn > 1) 64169689Skan { 65169689Skan md = (mn + mx) / 2; 66169689Skan opt_len = cl_options[md].opt_len; 67169689Skan comp = strncmp (input, cl_options[md].opt_text + 1, opt_len); 68169689Skan 69169689Skan if (comp < 0) 70169689Skan mx = md; 71169689Skan else 72169689Skan mn = md; 73169689Skan } 74169689Skan 75169689Skan /* This is the switch that is the best match but for a different 76169689Skan front end, or cl_options_count if there is no match at all. */ 77169689Skan match_wrong_lang = cl_options_count; 78169689Skan 79169689Skan /* Backtrace the chain of possible matches, returning the longest 80169689Skan one, if any, that fits best. With current GCC switches, this 81169689Skan loop executes at most twice. */ 82169689Skan do 83169689Skan { 84169689Skan const struct cl_option *opt = &cl_options[mn]; 85169689Skan 86169689Skan /* Is the input either an exact match or a prefix that takes a 87169689Skan joined argument? */ 88169689Skan if (!strncmp (input, opt->opt_text + 1, opt->opt_len) 89169689Skan && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED))) 90169689Skan { 91169689Skan /* If language is OK, return it. */ 92169689Skan if (opt->flags & lang_mask) 93169689Skan return mn; 94169689Skan 95169689Skan /* If we haven't remembered a prior match, remember this 96169689Skan one. Any prior match is necessarily better. */ 97169689Skan if (match_wrong_lang == cl_options_count) 98169689Skan match_wrong_lang = mn; 99169689Skan } 100169689Skan 101169689Skan /* Try the next possibility. This is cl_options_count if there 102169689Skan are no more. */ 103169689Skan mn = opt->back_chain; 104169689Skan } 105169689Skan while (mn != cl_options_count); 106169689Skan 107169689Skan /* Return the best wrong match, or cl_options_count if none. */ 108169689Skan return match_wrong_lang; 109169689Skan} 110169689Skan 111169689Skan/* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the 112169689Skan next one is the same as ORIG_NEXT_OPT_IDX. */ 113169689Skan 114169689Skanstatic bool 115169689Skancancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx) 116169689Skan{ 117169689Skan /* An option can be canceled by the same option or an option with 118169689Skan Negative. */ 119169689Skan if (cl_options [next_opt_idx].neg_index == opt_idx) 120169689Skan return true; 121169689Skan 122169689Skan if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx) 123169689Skan return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index, 124169689Skan orig_next_opt_idx); 125169689Skan 126169689Skan return false; 127169689Skan} 128169689Skan 129169689Skan/* Filter out options canceled by the ones after them. */ 130169689Skan 131169689Skanvoid 132169689Skanprune_options (int *argcp, char ***argvp) 133169689Skan{ 134169689Skan int argc = *argcp; 135169689Skan int *options = xmalloc (argc * sizeof (*options)); 136169689Skan char **argv = xmalloc (argc * sizeof (char *)); 137169689Skan int i, arg_count, need_prune = 0; 138169689Skan const struct cl_option *option; 139169689Skan size_t opt_index; 140169689Skan 141169689Skan /* Scan all arguments. */ 142169689Skan for (i = 1; i < argc; i++) 143169689Skan { 144169689Skan int value = 1; 145169689Skan const char *opt = (*argvp) [i]; 146169689Skan 147169689Skan opt_index = find_opt (opt + 1, -1); 148169689Skan if (opt_index == cl_options_count 149169689Skan && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm') 150169689Skan && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-') 151169689Skan { 152169689Skan char *dup; 153169689Skan 154169689Skan /* Drop the "no-" from negative switches. */ 155169689Skan size_t len = strlen (opt) - 3; 156169689Skan 157169689Skan dup = XNEWVEC (char, len + 1); 158169689Skan dup[0] = '-'; 159169689Skan dup[1] = opt[1]; 160169689Skan memcpy (dup + 2, opt + 5, len - 2 + 1); 161169689Skan opt = dup; 162169689Skan value = 0; 163169689Skan opt_index = find_opt (opt + 1, -1); 164169689Skan free (dup); 165169689Skan } 166169689Skan 167169689Skan if (opt_index == cl_options_count) 168169689Skan { 169169689Skancont: 170169689Skan options [i] = 0; 171169689Skan continue; 172169689Skan } 173169689Skan 174169689Skan option = &cl_options[opt_index]; 175169689Skan if (option->neg_index < 0) 176169689Skan goto cont; 177169689Skan 178169689Skan /* Skip joined switches. */ 179169689Skan if ((option->flags & CL_JOINED)) 180169689Skan goto cont; 181169689Skan 182169689Skan /* Reject negative form of switches that don't take negatives as 183169689Skan unrecognized. */ 184169689Skan if (!value && (option->flags & CL_REJECT_NEGATIVE)) 185169689Skan goto cont; 186169689Skan 187169689Skan options [i] = (int) opt_index; 188169689Skan need_prune |= options [i]; 189169689Skan } 190169689Skan 191169689Skan if (!need_prune) 192169689Skan goto done; 193169689Skan 194169689Skan /* Remove arguments which are negated by others after them. */ 195169689Skan argv [0] = (*argvp) [0]; 196169689Skan arg_count = 1; 197169689Skan for (i = 1; i < argc; i++) 198169689Skan { 199169689Skan int j, opt_idx; 200169689Skan 201169689Skan opt_idx = options [i]; 202169689Skan if (opt_idx) 203169689Skan { 204169689Skan int next_opt_idx; 205169689Skan for (j = i + 1; j < argc; j++) 206169689Skan { 207169689Skan next_opt_idx = options [j]; 208169689Skan if (next_opt_idx 209169689Skan && cancel_option (opt_idx, next_opt_idx, 210169689Skan next_opt_idx)) 211169689Skan break; 212169689Skan } 213169689Skan } 214169689Skan else 215169689Skan goto keep; 216169689Skan 217169689Skan if (j == argc) 218169689Skan { 219169689Skankeep: 220169689Skan argv [arg_count] = (*argvp) [i]; 221169689Skan arg_count++; 222169689Skan } 223169689Skan } 224169689Skan 225169689Skan if (arg_count != argc) 226169689Skan { 227169689Skan *argcp = arg_count; 228169689Skan *argvp = argv; 229169689Skan } 230169689Skan else 231169689Skan { 232169689Skandone: 233169689Skan free (argv); 234169689Skan } 235169689Skan 236169689Skan free (options); 237169689Skan} 238