/* Command line option handling.
   Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "intl.h"
#include "coretypes.h"
#include "opts.h"

/* Perform a binary search to find which option the command-line INPUT
   matches.  Returns its index in the option array, and N_OPTS
   (cl_options_count) on failure.

   This routine is quite subtle.  A normal binary search is not good
   enough because some options can be suffixed with an argument, and
   multiple sub-matches can occur, e.g. input of "-pedantic" matching
   the initial substring of "-pedantic-errors".

   A more complicated example is -gstabs.  It should match "-g" with
   an argument of "stabs".  Suppose, however, that the number and list
   of switches are such that the binary search tests "-gen-decls"
   before having tested "-g".  This doesn't match, and as "-gen-decls"
   is less than "-gstabs", it will become the lower bound of the
   binary search range, and "-g" will never be seen.  To resolve this
   issue, 'optc-gen.awk' makes "-gen-decls" point, via the back_chain member,
   to "-g" so that failed searches that end between "-gen-decls" and
   the lexicographically subsequent switch know to go back and see if
   "-g" causes a match (which it does in this example).

   This search is done in such a way that the longest match for the
   front end in question wins.  If there is no match for the current
   front end, the longest match for a different front end is returned
   (or N_OPTS if none) and the caller emits an error message.  */
size_t
find_opt (const char *input, int lang_mask)
{
  size_t mn, mx, md, opt_len;
  size_t match_wrong_lang;
  int comp;

  mn = 0;
  mx = cl_options_count;

  /* Find mn such this lexicographical inequality holds:
     cl_options[mn] <= input < cl_options[mn + 1].  */
  while (mx - mn > 1)
    {
      md = (mn + mx) / 2;
      opt_len = cl_options[md].opt_len;
      comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);

      if (comp < 0)
	mx = md;
      else
	mn = md;
    }

  /* This is the switch that is the best match but for a different
     front end, or cl_options_count if there is no match at all.  */
  match_wrong_lang = cl_options_count;

  /* Backtrace the chain of possible matches, returning the longest
     one, if any, that fits best.  With current GCC switches, this
     loop executes at most twice.  */
  do
    {
      const struct cl_option *opt = &cl_options[mn];

      /* Is the input either an exact match or a prefix that takes a
	 joined argument?  */
      if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
	  && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
	{
	  /* If language is OK, return it.  */
	  if (opt->flags & lang_mask)
	    return mn;

	  /* If we haven't remembered a prior match, remember this
	     one.  Any prior match is necessarily better.  */
	  if (match_wrong_lang == cl_options_count)
	    match_wrong_lang = mn;
	}

      /* Try the next possibility.  This is cl_options_count if there
	 are no more.  */
      mn = opt->back_chain;
    }
  while (mn != cl_options_count);

  /* Return the best wrong match, or cl_options_count if none.  */
  return match_wrong_lang;
}

/* Return true if NEXT_OPT_IDX cancels OPT_IDX.  Return false if the
   next one is the same as ORIG_NEXT_OPT_IDX.  */

static bool
cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
{
  /* An option can be canceled by the same option or an option with
     Negative.  */
  if (cl_options [next_opt_idx].neg_index == opt_idx)
    return true;

  if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx)
    return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index,
			  orig_next_opt_idx);
    
  return false;
}

/* Filter out options canceled by the ones after them.  */

void
prune_options (int *argcp, char ***argvp)
{
  int argc = *argcp;
  int *options = XNEWVEC (int, argc);
  char **argv = XNEWVEC (char *, argc);
  int i, arg_count, need_prune = 0;
  const struct cl_option *option;
  size_t opt_index;

  /* Scan all arguments.  */
  for (i = 1; i < argc; i++)
    {
      int value = 1;
      const char *opt = (*argvp) [i];

      opt_index = find_opt (opt + 1, -1);
      if (opt_index == cl_options_count
	  && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
	  && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
	{
	  char *dup;

	  /* Drop the "no-" from negative switches.  */
	  size_t len = strlen (opt) - 3;

	  dup = XNEWVEC (char, len + 1);
	  dup[0] = '-';
	  dup[1] = opt[1];
	  memcpy (dup + 2, opt + 5, len - 2 + 1);
	  opt = dup;
	  value = 0;
	  opt_index = find_opt (opt + 1, -1);
	  free (dup);
	}

      if (opt_index == cl_options_count)
	{
cont:
	  options [i] = 0;
	  continue;
	}

      option = &cl_options[opt_index];
      if (option->neg_index < 0)
	goto cont;

      /* Skip joined switches.  */
      if ((option->flags & CL_JOINED))
	goto cont;

      /* Reject negative form of switches that don't take negatives as
	 unrecognized.  */
      if (!value && (option->flags & CL_REJECT_NEGATIVE))
	goto cont;

      options [i] = (int) opt_index;
      need_prune |= options [i];
    }

  if (!need_prune)
    goto done;

  /* Remove arguments which are negated by others after them.  */
  argv [0] = (*argvp) [0];
  arg_count = 1;
  for (i = 1; i < argc; i++)
    {
      int j, opt_idx;

      opt_idx = options [i];
      if (opt_idx)
	{
	  int next_opt_idx;
	  for (j = i + 1; j < argc; j++)
	    {
	      next_opt_idx = options [j];
	      if (next_opt_idx
		  && cancel_option (opt_idx, next_opt_idx,
				    next_opt_idx))
		break;
	    }
	}
      else
	goto keep;

      if (j == argc)
	{
keep:
	  argv [arg_count] = (*argvp) [i];
	  arg_count++;
	}
    }

  if (arg_count != argc)
    {
      *argcp = arg_count;
      *argvp = argv;
    }
  else
    {
done:
      free (argv);
    }

  free (options);
}
