/* Provide option suggestion for --complete option and a misspelled
   used by a user.
   Copyright (C) 2016-2018 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 "coretypes.h"
#include "tm.h"
#include "opts.h"
#include "params.h"
#include "spellcheck.h"
#include "opt-suggestions.h"
#include "common/common-target.h"
#include "selftest.h"

option_proposer::~option_proposer ()
{
  delete m_option_suggestions;
}

const char *
option_proposer::suggest_option (const char *bad_opt)
{
  /* Lazily populate m_option_suggestions.  */
  if (!m_option_suggestions)
    build_option_suggestions (NULL);
  gcc_assert (m_option_suggestions);

  /* "m_option_suggestions" is now populated.  Use it.  */
  return find_closest_string
    (bad_opt,
     (auto_vec <const char *> *) m_option_suggestions);
}

/* Populate RESULTS with valid completions of options that begin
   with OPTION_PREFIX.  */

void
option_proposer::get_completions (const char *option_prefix,
				  auto_string_vec &results)
{
  /* Bail out for an invalid input.  */
  if (option_prefix == NULL || option_prefix[0] == '\0')
    return;

  /* Option suggestions are built without first leading dash character.  */
  if (option_prefix[0] == '-')
    option_prefix++;

  size_t length = strlen (option_prefix);

  /* Handle OPTION_PREFIX starting with "-param".  */
  const char *prefix = "-param";
  if (length >= strlen (prefix)
      && strstr (option_prefix, prefix) == option_prefix)
    {
      /* We support both '-param-xyz=123' and '-param xyz=123' */
      option_prefix += strlen (prefix);
      char separator = option_prefix[0];
      option_prefix++;
      if (separator == ' ' || separator == '=')
	find_param_completions (separator, option_prefix, results);
    }
  else
    {
      /* Lazily populate m_option_suggestions.  */
      if (!m_option_suggestions)
	build_option_suggestions (option_prefix);
      gcc_assert (m_option_suggestions);

      for (unsigned i = 0; i < m_option_suggestions->length (); i++)
	{
	  char *candidate = (*m_option_suggestions)[i];
	  if (strlen (candidate) >= length
	      && strstr (candidate, option_prefix) == candidate)
	    results.safe_push (concat ("-", candidate, NULL));
	}
    }
}

/* Print on stdout a list of valid options that begin with OPTION_PREFIX,
   one per line, suitable for use by Bash completion.

   Implementation of the "-completion=" option.  */

void
option_proposer::suggest_completion (const char *option_prefix)
{
  auto_string_vec results;
  get_completions (option_prefix, results);
  for (unsigned i = 0; i < results.length (); i++)
    printf ("%s\n", results[i]);
}

void
option_proposer::build_option_suggestions (const char *prefix)
{
  gcc_assert (m_option_suggestions == NULL);
  m_option_suggestions = new auto_string_vec ();

  /* We build a vec of m_option_suggestions, using add_misspelling_candidates
     to add copies of strings, without a leading dash.  */

  for (unsigned int i = 0; i < cl_options_count; i++)
    {
      const struct cl_option *option = &cl_options[i];
      const char *opt_text = option->opt_text;
      switch (i)
	{
	default:
	  if (option->var_type == CLVC_ENUM)
	    {
	      const struct cl_enum *e = &cl_enums[option->var_enum];
	      for (unsigned j = 0; e->values[j].arg != NULL; j++)
		{
		  char *with_arg = concat (opt_text, e->values[j].arg, NULL);
		  add_misspelling_candidates (m_option_suggestions, option,
					      with_arg);
		  free (with_arg);
		}
	    }
	  else
	    {
	      if (option->flags & CL_TARGET)
		{
		  vec<const char *> option_values
		    = targetm_common.get_valid_option_values (i, prefix);
		  if (!option_values.is_empty ())
		    {
		      for (unsigned j = 0; j < option_values.length (); j++)
			{
			  char *with_arg = concat (opt_text, option_values[j],
						   NULL);
			  add_misspelling_candidates (m_option_suggestions, option,
						      with_arg);
			  free (with_arg);
			}
		    }
		  option_values.release ();
		}
	      else
		add_misspelling_candidates (m_option_suggestions, option,
					    opt_text);
	    }
	  break;

	case OPT_fsanitize_:
	case OPT_fsanitize_recover_:
	  /* -fsanitize= and -fsanitize-recover= can take
	     a comma-separated list of arguments.  Given that combinations
	     are supported, we can't add all potential candidates to the
	     vec, but if we at least add them individually without commas,
	     we should do a better job e.g. correcting
	       "-sanitize=address"
	     to
	       "-fsanitize=address"
	     rather than to "-Wframe-address" (PR driver/69265).  */
	  {
	    for (int j = 0; sanitizer_opts[j].name != NULL; ++j)
	      {
		struct cl_option optb;
		/* -fsanitize=all is not valid, only -fno-sanitize=all.
		   So don't register the positive misspelling candidates
		   for it.  */
		if (sanitizer_opts[j].flag == ~0U && i == OPT_fsanitize_)
		  {
		    optb = *option;
		    optb.opt_text = opt_text = "-fno-sanitize=";
		    optb.cl_reject_negative = true;
		    option = &optb;
		  }
		/* Get one arg at a time e.g. "-fsanitize=address".  */
		char *with_arg = concat (opt_text,
					 sanitizer_opts[j].name,
					 NULL);
		/* Add with_arg and all of its variant spellings e.g.
		   "-fno-sanitize=address" to candidates (albeit without
		   leading dashes).  */
		add_misspelling_candidates (m_option_suggestions, option,
					    with_arg);
		free (with_arg);
	      }
	  }
	  break;
	}
    }
}

/* Find parameter completions for --param format with SEPARATOR.
   Again, save the completions into results.  */

void
option_proposer::find_param_completions (const char separator,
					 const char *param_prefix,
					 auto_string_vec &results)
{
  char separator_str[] = {separator, '\0'};
  size_t length = strlen (param_prefix);
  for (unsigned i = 0; i < get_num_compiler_params (); ++i)
    {
      const char *candidate = compiler_params[i].option;
      if (strlen (candidate) >= length
	  && strstr (candidate, param_prefix) == candidate)
	results.safe_push (concat ("--param", separator_str, candidate, NULL));
    }
}

#if CHECKING_P

namespace selftest {

/* Verify that PROPOSER generates sane auto-completion suggestions
   for OPTION_PREFIX.  */

static void
verify_autocompletions (option_proposer &proposer, const char *option_prefix)
{
  auto_string_vec suggestions;
  proposer.get_completions (option_prefix, suggestions);

  /* There must be at least one suggestion, and every suggestion must
     indeed begin with OPTION_PREFIX.  */

  ASSERT_GT (suggestions.length (), 0);

  for (unsigned i = 0; i < suggestions.length (); i++)
    ASSERT_STR_STARTSWITH (suggestions[i], option_prefix);
}

/* Verify that valid options are auto-completed correctly.  */

static void
test_completion_valid_options (option_proposer &proposer)
{
  const char *option_prefixes[] =
  {
    "-fno-var-tracking-assignments-toggle",
    "-fpredictive-commoning",
    "--param=stack-clash-protection-guard-size",
    "--param=max-predicted-iterations",
    "-ftree-loop-distribute-patterns",
    "-fno-var-tracking",
    "-Walloc-zero",
    "--param=ipa-cp-value-list-size",
    "-Wsync-nand",
    "-Wno-attributes",
    "--param=tracer-dynamic-coverage-feedback",
    "-Wno-format-contains-nul",
    "-Wnamespaces",
    "-fisolate-erroneous-paths-attribute",
    "-Wno-underflow",
    "-Wtarget-lifetime",
    "--param=asan-globals",
    "-Wno-empty-body",
    "-Wno-odr",
    "-Wformat-zero-length",
    "-Wstringop-truncation",
    "-fno-ipa-vrp",
    "-fmath-errno",
    "-Warray-temporaries",
    "-Wno-unused-label",
    "-Wreturn-local-addr",
    "--param=sms-dfa-history",
    "--param=asan-instrument-reads",
    "-Wreturn-type",
    "-Wc++17-compat",
    "-Wno-effc++",
    "--param=max-fields-for-field-sensitive",
    "-fisolate-erroneous-paths-dereference",
    "-fno-defer-pop",
    "-Wcast-align=strict",
    "-foptimize-strlen",
    "-Wpacked-not-aligned",
    "-funroll-loops",
    "-fif-conversion2",
    "-Wdesignated-init",
    "--param=max-iterations-computation-cost",
    "-Wmultiple-inheritance",
    "-fno-sel-sched-reschedule-pipelined",
    "-Wassign-intercept",
    "-Wno-format-security",
    "-fno-sched-stalled-insns",
    "-fbtr-bb-exclusive",
    "-fno-tree-tail-merge",
    "-Wlong-long",
    "-Wno-unused-but-set-parameter",
    NULL
  };

  for (const char **ptr = option_prefixes; *ptr != NULL; ptr++)
    verify_autocompletions (proposer, *ptr);
}

/* Verify that valid parameters are auto-completed correctly,
   both with the "--param=PARAM" form and the "--param PARAM" form.  */

static void
test_completion_valid_params (option_proposer &proposer)
{
  const char *option_prefixes[] =
  {
    "--param=sched-state-edge-prob-cutoff",
    "--param=iv-consider-all-candidates-bound",
    "--param=align-threshold",
    "--param=prefetch-min-insn-to-mem-ratio",
    "--param=max-unrolled-insns",
    "--param=max-early-inliner-iterations",
    "--param=max-vartrack-reverse-op-size",
    "--param=ipa-cp-loop-hint-bonus",
    "--param=tracer-min-branch-ratio",
    "--param=graphite-max-arrays-per-scop",
    "--param=sink-frequency-threshold",
    "--param=max-cse-path-length",
    "--param=sra-max-scalarization-size-Osize",
    "--param=prefetch-latency",
    "--param=dse-max-object-size",
    "--param=asan-globals",
    "--param=max-vartrack-size",
    "--param=case-values-threshold",
    "--param=max-slsr-cand-scan",
    "--param=min-insn-to-prefetch-ratio",
    "--param=tracer-min-branch-probability",
    "--param sink-frequency-threshold",
    "--param max-cse-path-length",
    "--param sra-max-scalarization-size-Osize",
    "--param prefetch-latency",
    "--param dse-max-object-size",
    "--param asan-globals",
    "--param max-vartrack-size",
    NULL
  };

  for (const char **ptr = option_prefixes; *ptr != NULL; ptr++)
    verify_autocompletions (proposer, *ptr);
}

/* Return true when EXPECTED is one of completions for OPTION_PREFIX string.  */

static bool
in_completion_p (option_proposer &proposer, const char *option_prefix,
		 const char *expected)
{
  auto_string_vec suggestions;
  proposer.get_completions (option_prefix, suggestions);

  for (unsigned i = 0; i < suggestions.length (); i++)
    {
      char *r = suggestions[i];
      if (strcmp (r, expected) == 0)
	return true;
    }

  return false;
}

/* Return true when PROPOSER does not find any partial completion
   for OPTION_PREFIX.  */

static bool
empty_completion_p (option_proposer &proposer, const char *option_prefix)
{
  auto_string_vec suggestions;
  proposer.get_completions (option_prefix, suggestions);
  return suggestions.is_empty ();
}

/* Verify autocompletions of partially-complete options.  */

static void
test_completion_partial_match (option_proposer &proposer)
{
  ASSERT_TRUE (in_completion_p (proposer, "-fsani", "-fsanitize=address"));
  ASSERT_TRUE (in_completion_p (proposer, "-fsani",
				"-fsanitize-address-use-after-scope"));
  ASSERT_TRUE (in_completion_p (proposer, "-fipa-icf", "-fipa-icf-functions"));
  ASSERT_TRUE (in_completion_p (proposer, "-fipa-icf", "-fipa-icf"));
  ASSERT_TRUE (in_completion_p (proposer, "--param=",
				"--param=max-vartrack-reverse-op-size"));
  ASSERT_TRUE (in_completion_p (proposer, "--param ",
				"--param max-vartrack-reverse-op-size"));

  ASSERT_FALSE (in_completion_p (proposer, "-fipa-icf", "-fipa"));
  ASSERT_FALSE (in_completion_p (proposer, "-fipa-icf-functions", "-fipa-icf"));

  ASSERT_FALSE (empty_completion_p (proposer, "-"));
  ASSERT_FALSE (empty_completion_p (proposer, "-fipa"));
  ASSERT_FALSE (empty_completion_p (proposer, "--par"));
}

/* Verify that autocompletion does not return any match for garbage inputs.  */

static void
test_completion_garbage (option_proposer &proposer)
{
  ASSERT_TRUE (empty_completion_p (proposer, NULL));
  ASSERT_TRUE (empty_completion_p (proposer, ""));
  ASSERT_TRUE (empty_completion_p (proposer, "- "));
  ASSERT_TRUE (empty_completion_p (proposer, "123456789"));
  ASSERT_TRUE (empty_completion_p (proposer, "---------"));
  ASSERT_TRUE (empty_completion_p (proposer, "#########"));
  ASSERT_TRUE (empty_completion_p (proposer, "- - - - - -"));
  ASSERT_TRUE (empty_completion_p (proposer, "-fsanitize=address2"));
}

/* Run all of the selftests within this file.  */

void
opt_proposer_c_tests ()
{
  option_proposer proposer;

  test_completion_valid_options (proposer);
  test_completion_valid_params (proposer);
  test_completion_partial_match (proposer);
  test_completion_garbage (proposer);
}

} // namespace selftest

#endif /* #if CHECKING_P */
