/* Provide option suggestion for --complete option and a misspelled
   used by a user.
   Copyright (C) 2016-2021 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 "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);

  /* 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);
		}

	      /* Add also variant without an option argument.  */
	      add_misspelling_candidates (m_option_suggestions, option,
					  opt_text);
	    }
	  else
	    {
	      bool option_added = false;
	      if (option->flags & CL_TARGET)
		{
		  vec<const char *> option_values
		    = targetm_common.get_valid_option_values (i, prefix);
		  if (!option_values.is_empty ())
		    {
		      option_added = true;
		      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 ();
		}

	      if (!option_added)
		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).  */
	  {
	    /* Add also variant without an option argument.  */
	    add_misspelling_candidates (m_option_suggestions, option,
					opt_text);

	    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;
	}
    }
}

#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",
    "-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 */
