/* Data structures and API for location specs in GDB.
   Copyright (C) 2013-2023 Free Software Foundation, Inc.

   This file is part of GDB.

   This program 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 of the License, or
   (at your option) any later version.

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "gdbsupport/gdb_assert.h"
#include "gdbsupport/gdb-checked-static-cast.h"
#include "location.h"
#include "symtab.h"
#include "language.h"
#include "linespec.h"
#include "cli/cli-utils.h"
#include "probe.h"
#include "cp-support.h"

#include <ctype.h>
#include <string.h>

static std::string
  explicit_to_string_internal (bool as_linespec,
			       const explicit_location_spec *explicit_loc);

/* Return a xstrdup of STR if not NULL, otherwise return NULL.  */

static char *
maybe_xstrdup (const char *str)
{
  return (str != nullptr ? xstrdup (str) : nullptr);
}

probe_location_spec::probe_location_spec (std::string &&probe)
  : location_spec (PROBE_LOCATION_SPEC, std::move (probe))
{
}

location_spec_up
probe_location_spec::clone () const
{
  return location_spec_up (new probe_location_spec (*this));
}

bool
probe_location_spec::empty_p () const
{
  return false;
}

std::string probe_location_spec::compute_string () const
{
  return std::move (m_as_string);
}

/* A "normal" linespec.  */
linespec_location_spec::linespec_location_spec
  (const char **linespec, symbol_name_match_type match_type_)
  : location_spec (LINESPEC_LOCATION_SPEC),
    match_type (match_type_)
{
  if (*linespec != NULL)
    {
      const char *p;
      const char *orig = *linespec;

      linespec_lex_to_end (linespec);
      p = remove_trailing_whitespace (orig, *linespec);

      /* If there is no valid linespec then this will leave the
	 spec_string as nullptr.  This behaviour is relied on in the
	 breakpoint setting code, where spec_string being nullptr means
	 to use the default breakpoint location.  */
      if ((p - orig) > 0)
	spec_string = savestring (orig, p - orig);
    }
}

linespec_location_spec::~linespec_location_spec ()
{
  xfree (spec_string);
}

location_spec_up
linespec_location_spec::clone () const
{
  return location_spec_up (new linespec_location_spec (*this));
}

bool
linespec_location_spec::empty_p () const
{
  return false;
}

linespec_location_spec::linespec_location_spec
  (const linespec_location_spec &other)
  : location_spec (other),
    match_type (other.match_type),
    spec_string (maybe_xstrdup (other.spec_string))
{
}

std::string
linespec_location_spec::compute_string () const
{
  if (spec_string != nullptr)
    {
      if (match_type == symbol_name_match_type::FULL)
	return std::string ("-qualified ") + spec_string;
      else
	return spec_string;
    }
  return {};
}

address_location_spec::address_location_spec (CORE_ADDR addr,
					      const char *addr_string,
					      int addr_string_len)
  : location_spec (ADDRESS_LOCATION_SPEC),
    address (addr)
{
  if (addr_string != nullptr)
    m_as_string = std::string (addr_string, addr_string_len);
}

location_spec_up
address_location_spec::clone () const
{
  return location_spec_up (new address_location_spec (*this));
}

bool
address_location_spec::empty_p () const
{
  return false;
}

address_location_spec::address_location_spec
  (const address_location_spec &other)
  : location_spec (other),
    address (other.address)
{
}

std::string
address_location_spec::compute_string () const
{
  const char *addr_string = core_addr_to_string (address);
  return std::string ("*") + addr_string;
}

explicit_location_spec::explicit_location_spec ()
  : location_spec (EXPLICIT_LOCATION_SPEC)
{
}

explicit_location_spec::~explicit_location_spec ()
{
  xfree (source_filename);
  xfree (function_name);
  xfree (label_name);
}

explicit_location_spec::explicit_location_spec
  (const explicit_location_spec &other)
  : location_spec (other),
    source_filename (maybe_xstrdup (other.source_filename)),
    function_name (maybe_xstrdup (other.function_name)),
    func_name_match_type (other.func_name_match_type),
    label_name (maybe_xstrdup (other.label_name)),
    line_offset (other.line_offset)
{
}

location_spec_up
explicit_location_spec::clone () const
{
  return location_spec_up (new explicit_location_spec (*this));
}

bool
explicit_location_spec::empty_p () const
{
  return (source_filename == nullptr
	  && function_name == nullptr
	  && label_name == nullptr
	  && line_offset.sign == LINE_OFFSET_UNKNOWN);
}

std::string
explicit_location_spec::compute_string () const
{
  return explicit_to_string_internal (false, this);
}

/* See description in location.h.  */

location_spec_up
new_linespec_location_spec (const char **linespec,
			    symbol_name_match_type match_type)
{
  return location_spec_up (new linespec_location_spec (linespec,
						       match_type));
}

/* See description in location.h.  */

const linespec_location_spec *
as_linespec_location_spec (const location_spec *locspec)
{
  gdb_assert (locspec->type () == LINESPEC_LOCATION_SPEC);
  return gdb::checked_static_cast<const linespec_location_spec *> (locspec);
}

/* See description in location.h.  */

location_spec_up
new_address_location_spec (CORE_ADDR addr, const char *addr_string,
			   int addr_string_len)
{
  return location_spec_up (new address_location_spec (addr, addr_string,
						      addr_string_len));
}

/* See description in location.h.  */

const address_location_spec *
as_address_location_spec (const location_spec *locspec)
{
  gdb_assert (locspec->type () == ADDRESS_LOCATION_SPEC);
  return gdb::checked_static_cast<const address_location_spec *> (locspec);
}

/* See description in location.h.  */

location_spec_up
new_probe_location_spec (std::string &&probe)
{
  return location_spec_up (new probe_location_spec (std::move (probe)));
}

/* See description in location.h.  */

const probe_location_spec *
as_probe_location_spec (const location_spec *locspec)
{
  gdb_assert (locspec->type () == PROBE_LOCATION_SPEC);
  return gdb::checked_static_cast<const probe_location_spec *> (locspec);
}

/* See description in location.h.  */

const explicit_location_spec *
as_explicit_location_spec (const location_spec *locspec)
{
  gdb_assert (locspec->type () == EXPLICIT_LOCATION_SPEC);
  return gdb::checked_static_cast<const explicit_location_spec *> (locspec);
}

/* See description in location.h.  */

explicit_location_spec *
as_explicit_location_spec (location_spec *locspec)
{
  gdb_assert (locspec->type () == EXPLICIT_LOCATION_SPEC);
  return gdb::checked_static_cast<explicit_location_spec *> (locspec);
}

/* Return a string representation of the explicit location spec in
   EXPLICIT_LOCSPEC.

   AS_LINESPEC is true if this string should be a linespec.  Otherwise
   it will be output in explicit form.  */

static std::string
explicit_to_string_internal (bool as_linespec,
			     const explicit_location_spec *explicit_loc)
{
  bool need_space = false;
  char space = as_linespec ? ':' : ' ';
  string_file buf;

  if (explicit_loc->source_filename != NULL)
    {
      if (!as_linespec)
	buf.puts ("-source ");
      buf.puts (explicit_loc->source_filename);
      need_space = true;
    }

  if (explicit_loc->function_name != NULL)
    {
      if (need_space)
	buf.putc (space);
      if (explicit_loc->func_name_match_type == symbol_name_match_type::FULL)
	buf.puts ("-qualified ");
      if (!as_linespec)
	buf.puts ("-function ");
      buf.puts (explicit_loc->function_name);
      need_space = true;
    }

  if (explicit_loc->label_name != NULL)
    {
      if (need_space)
	buf.putc (space);
      if (!as_linespec)
	buf.puts ("-label ");
      buf.puts (explicit_loc->label_name);
      need_space = true;
    }

  if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN)
    {
      if (need_space)
	buf.putc (space);
      if (!as_linespec)
	buf.puts ("-line ");
      buf.printf ("%s%d",
		  (explicit_loc->line_offset.sign == LINE_OFFSET_NONE ? ""
		   : (explicit_loc->line_offset.sign
		      == LINE_OFFSET_PLUS ? "+" : "-")),
		  explicit_loc->line_offset.offset);
    }

  return buf.release ();
}

/* See description in location.h.  */

std::string
explicit_location_spec::to_linespec () const
{
  return explicit_to_string_internal (true, this);
}

/* Find an instance of the quote character C in the string S that is
   outside of all single- and double-quoted strings (i.e., any quoting
   other than C).  */

static const char *
find_end_quote (const char *s, char end_quote_char)
{
  /* zero if we're not in quotes;
     '"' if we're in a double-quoted string;
     '\'' if we're in a single-quoted string.  */
  char nested_quote_char = '\0';

  for (const char *scan = s; *scan != '\0'; scan++)
    {
      if (nested_quote_char != '\0')
	{
	  if (*scan == nested_quote_char)
	    nested_quote_char = '\0';
	  else if (scan[0] == '\\' && *(scan + 1) != '\0')
	    scan++;
	}
      else if (*scan == end_quote_char && nested_quote_char == '\0')
	return scan;
      else if (*scan == '"' || *scan == '\'')
	nested_quote_char = *scan;
    }

  return 0;
}

/* A lexer for explicit location specs.  This function will advance
   INP past any strings that it lexes.  Returns a malloc'd copy of the
   lexed string or NULL if no lexing was done.  */

static gdb::unique_xmalloc_ptr<char>
explicit_location_spec_lex_one (const char **inp,
				const struct language_defn *language,
				explicit_completion_info *completion_info)
{
  const char *start = *inp;

  if (*start == '\0')
    return NULL;

  /* If quoted, skip to the ending quote.  */
  if (strchr (get_gdb_linespec_parser_quote_characters (), *start))
    {
      if (completion_info != NULL)
	completion_info->quoted_arg_start = start;

      const char *end = find_end_quote (start + 1, *start);

      if (end == NULL)
	{
	  if (completion_info == NULL)
	    error (_("Unmatched quote, %s."), start);

	  end = start + strlen (start);
	  *inp = end;
	  return gdb::unique_xmalloc_ptr<char> (savestring (start + 1,
							    *inp - start - 1));
	}

      if (completion_info != NULL)
	completion_info->quoted_arg_end = end;
      *inp = end + 1;
      return gdb::unique_xmalloc_ptr<char> (savestring (start + 1,
							*inp - start - 2));
    }

  /* If the input starts with '-' or '+', the string ends with the next
     whitespace or comma.  */
  if (*start == '-' || *start == '+')
    {
      while (*inp[0] != '\0' && *inp[0] != ',' && !isspace (*inp[0]))
	++(*inp);
    }
  else
    {
      /* Handle numbers first, stopping at the next whitespace or ','.  */
      while (isdigit (*inp[0]))
	++(*inp);
      if (*inp[0] == '\0' || isspace (*inp[0]) || *inp[0] == ',')
	return gdb::unique_xmalloc_ptr<char> (savestring (start,
							  *inp - start));

      /* Otherwise stop at the next occurrence of whitespace, '\0',
	 keyword, or ','.  */
      *inp = start;
      while ((*inp)[0]
	     && (*inp)[0] != ','
	     && !(isspace ((*inp)[0])
		  || linespec_lexer_lex_keyword (&(*inp)[1])))
	{
	  /* Special case: C++ operator,.  */
	  if (language->la_language == language_cplus
	      && startswith (*inp, CP_OPERATOR_STR))
	    (*inp) += CP_OPERATOR_LEN;
	  ++(*inp);
	}
    }

  if (*inp - start > 0)
    return gdb::unique_xmalloc_ptr<char> (savestring (start, *inp - start));

  return NULL;
}

/* Return true if COMMA points past "operator".  START is the start of
   the line that COMMAND points to, hence when reading backwards, we
   must not read any character before START.  */

static bool
is_cp_operator (const char *start, const char *comma)
{
  if (comma != NULL
      && (comma - start) >= CP_OPERATOR_LEN)
    {
      const char *p = comma;

      while (p > start && isspace (p[-1]))
	p--;
      if (p - start >= CP_OPERATOR_LEN)
	{
	  p -= CP_OPERATOR_LEN;
	  if (strncmp (p, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0
	      && (p == start
		  || !(isalnum (p[-1]) || p[-1] == '_')))
	    {
	      return true;
	    }
	}
    }
  return false;
}

/* When scanning the input string looking for the next explicit
   location spec option/delimiter, we jump to the next option by looking
   for ",", and "-".  Such a character can also appear in C++ symbols
   like "operator," and "operator-".  So when we find such a
   character, we call this function to check if we found such a
   symbol, meaning we had a false positive for an option string.  In
   that case, we keep looking for the next delimiter, until we find
   one that is not a false positive, or we reach end of string.  FOUND
   is the character that scanning found (either '-' or ','), and START
   is the start of the line that FOUND points to, hence when reading
   backwards, we must not read any character before START.  Returns a
   pointer to the next non-false-positive delimiter character, or NULL
   if none was found.  */

static const char *
skip_op_false_positives (const char *start, const char *found)
{
  while (found != NULL && is_cp_operator (start, found))
    {
      if (found[0] == '-' && found[1] == '-')
	start = found + 2;
      else
	start = found + 1;
      found = find_toplevel_char (start, *found);
    }

  return found;
}

/* Assuming both FIRST and NEW_TOK point into the same string, return
   the pointer that is closer to the start of the string.  If FIRST is
   NULL, returns NEW_TOK.  If NEW_TOK is NULL, returns FIRST.  */

static const char *
first_of (const char *first, const char *new_tok)
{
  if (first == NULL)
    return new_tok;
  else if (new_tok != NULL && new_tok < first)
    return new_tok;
  else
    return first;
}

/* A lexer for functions in explicit location specs.  This function will
   advance INP past a function until the next option, or until end of
   string.  Returns a malloc'd copy of the lexed string or NULL if no
   lexing was done.  */

static gdb::unique_xmalloc_ptr<char>
explicit_location_spec_lex_one_function
  (const char **inp,
   const struct language_defn *language,
   explicit_completion_info *completion_info)
{
  const char *start = *inp;

  if (*start == '\0')
    return NULL;

  /* If quoted, skip to the ending quote.  */
  if (strchr (get_gdb_linespec_parser_quote_characters (), *start))
    {
      char quote_char = *start;

      /* If the input is not an Ada operator, skip to the matching
	 closing quote and return the string.  */
      if (!(language->la_language == language_ada
	    && quote_char == '\"' && is_ada_operator (start)))
	{
	  if (completion_info != NULL)
	    completion_info->quoted_arg_start = start;

	  const char *end = find_toplevel_char (start + 1, quote_char);

	  if (end == NULL)
	    {
	      if (completion_info == NULL)
		error (_("Unmatched quote, %s."), start);

	      end = start + strlen (start);
	      *inp = end;
	      char *saved = savestring (start + 1, *inp - start - 1);
	      return gdb::unique_xmalloc_ptr<char> (saved);
	    }

	  if (completion_info != NULL)
	    completion_info->quoted_arg_end = end;
	  *inp = end + 1;
	  char *saved = savestring (start + 1, *inp - start - 2);
	  return gdb::unique_xmalloc_ptr<char> (saved);
	}
    }

  const char *comma = find_toplevel_char (start, ',');

  /* If we have "-function -myfunction", or perhaps better example,
     "-function -[BasicClass doIt]" (objc selector), treat
     "-myfunction" as the function name.  I.e., skip the first char if
     it is an hyphen.  Don't skip the first char always, because we
     may have C++ "operator<", and find_toplevel_char needs to see the
     'o' in that case.  */
  const char *hyphen
    = (*start == '-'
       ? find_toplevel_char (start + 1, '-')
       : find_toplevel_char (start, '-'));

  /* Check for C++ "operator," and "operator-".  */
  comma = skip_op_false_positives (start, comma);
  hyphen = skip_op_false_positives (start, hyphen);

  /* Pick the one that appears first.  */
  const char *end = first_of (hyphen, comma);

  /* See if a linespec keyword appears first.  */
  const char *s = start;
  const char *ws = find_toplevel_char (start, ' ');
  while (ws != NULL && linespec_lexer_lex_keyword (ws + 1) == NULL)
    {
      s = ws + 1;
      ws = find_toplevel_char (s, ' ');
    }
  if (ws != NULL)
    end = first_of (end, ws + 1);

  /* If we don't have any terminator, then take the whole string.  */
  if (end == NULL)
    end = start + strlen (start);

  /* Trim whitespace at the end.  */
  while (end > start && end[-1] == ' ')
    end--;

  *inp = end;

  if (*inp - start > 0)
    return gdb::unique_xmalloc_ptr<char> (savestring (start, *inp - start));

  return NULL;
}

/* See description in location.h.  */

location_spec_up
string_to_explicit_location_spec (const char **argp,
				  const struct language_defn *language,
				  explicit_completion_info *completion_info)
{
  /* It is assumed that input beginning with '-' and a non-digit
     character is an explicit location.  "-p" is reserved, though,
     for probe locations.  */
  if (argp == NULL
      || *argp == NULL
      || *argp[0] != '-'
      || !isalpha ((*argp)[1])
      || ((*argp)[0] == '-' && (*argp)[1] == 'p'))
    return NULL;

  std::unique_ptr<explicit_location_spec> locspec
    (new explicit_location_spec ());

  /* Process option/argument pairs.  dprintf_command
     requires that processing stop on ','.  */
  while ((*argp)[0] != '\0' && (*argp)[0] != ',')
    {
      int len;
      const char *start;

      /* Clear these on each iteration, since they should be filled
	 with info about the last option.  */
      if (completion_info != NULL)
	{
	  completion_info->quoted_arg_start = NULL;
	  completion_info->quoted_arg_end = NULL;
	}

      /* If *ARGP starts with a keyword, stop processing
	 options.  */
      if (linespec_lexer_lex_keyword (*argp) != NULL)
	break;

      /* Mark the start of the string in case we need to rewind.  */
      start = *argp;

      if (completion_info != NULL)
	completion_info->last_option = start;

      /* Get the option string.  */
      gdb::unique_xmalloc_ptr<char> opt
	= explicit_location_spec_lex_one (argp, language, NULL);

      /* Use the length of the option to allow abbreviations.  */
      len = strlen (opt.get ());

      /* Get the argument string.  */
      *argp = skip_spaces (*argp);

      /* All options have a required argument.  Checking for this
	 required argument is deferred until later.  */
      gdb::unique_xmalloc_ptr<char> oarg;
      /* True if we have an argument.  This is required because we'll
	 move from OARG before checking whether we have an
	 argument.  */
      bool have_oarg = false;

      /* True if the option needs an argument.  */
      bool need_oarg = false;

      /* Convenience to consistently set both OARG/HAVE_OARG from
	 ARG.  */
      auto set_oarg = [&] (gdb::unique_xmalloc_ptr<char> arg)
	{
	  if (completion_info != NULL)
	    {
	      /* We do this here because the set of options that take
		 arguments matches the set of explicit location
		 options.  */
	      completion_info->saw_explicit_location_spec_option = true;
	    }
	  oarg = std::move (arg);
	  have_oarg = oarg != NULL;
	  need_oarg = true;
	};

      if (strncmp (opt.get (), "-source", len) == 0)
	{
	  set_oarg (explicit_location_spec_lex_one (argp, language,
						    completion_info));
	  locspec->source_filename = oarg.release ();
	}
      else if (strncmp (opt.get (), "-function", len) == 0)
	{
	  set_oarg (explicit_location_spec_lex_one_function (argp, language,
							     completion_info));
	  locspec->function_name = oarg.release ();
	}
      else if (strncmp (opt.get (), "-qualified", len) == 0)
	{
	  locspec->func_name_match_type = symbol_name_match_type::FULL;
	}
      else if (strncmp (opt.get (), "-line", len) == 0)
	{
	  set_oarg (explicit_location_spec_lex_one (argp, language, NULL));
	  *argp = skip_spaces (*argp);
	  if (have_oarg)
	    {
	      locspec->line_offset = linespec_parse_line_offset (oarg.get ());
	      continue;
	    }
	}
      else if (strncmp (opt.get (), "-label", len) == 0)
	{
	  set_oarg (explicit_location_spec_lex_one (argp, language,
						    completion_info));
	  locspec->label_name = oarg.release ();
	}
      /* Only emit an "invalid argument" error for options
	 that look like option strings.  */
      else if (opt.get ()[0] == '-' && !isdigit (opt.get ()[1]))
	{
	  if (completion_info == NULL)
	    error (_("invalid explicit location argument, \"%s\""), opt.get ());
	}
      else
	{
	  /* End of the explicit location specification.
	     Stop parsing and return whatever explicit location was
	     parsed.  */
	  *argp = start;
	  break;
	}

      *argp = skip_spaces (*argp);

      /* It's a little lame to error after the fact, but in this
	 case, it provides a much better user experience to issue
	 the "invalid argument" error before any missing
	 argument error.  */
      if (need_oarg && !have_oarg && completion_info == NULL)
	error (_("missing argument for \"%s\""), opt.get ());
    }

  /* One special error check:  If a source filename was given
     without offset, function, or label, issue an error.  */
  if (locspec->source_filename != NULL
      && locspec->function_name == NULL
      && locspec->label_name == NULL
      && (locspec->line_offset.sign == LINE_OFFSET_UNKNOWN)
      && completion_info == NULL)
    {
      error (_("Source filename requires function, label, or "
	       "line offset."));
    }

  return location_spec_up (locspec.release ());
}

/* See description in location.h.  */

location_spec_up
string_to_location_spec_basic (const char **stringp,
			       const struct language_defn *language,
			       symbol_name_match_type match_type)
{
  location_spec_up locspec;
  const char *cs;

  /* Try the input as a probe spec.  */
  cs = *stringp;
  if (cs != NULL && probe_linespec_to_static_ops (&cs) != NULL)
    {
      locspec = new_probe_location_spec (*stringp);
      *stringp += strlen (*stringp);
    }
  else
    {
      /* Try an address location spec.  */
      if (*stringp != NULL && **stringp == '*')
	{
	  const char *arg, *orig;
	  CORE_ADDR addr;

	  orig = arg = *stringp;
	  addr = linespec_expression_to_pc (&arg);
	  locspec = new_address_location_spec (addr, orig, arg - orig);
	  *stringp += arg - orig;
	}
      else
	{
	  /* Everything else is a linespec.  */
	  locspec = new_linespec_location_spec (stringp, match_type);
	}
    }

  return locspec;
}

/* See description in location.h.  */

location_spec_up
string_to_location_spec (const char **stringp,
			 const struct language_defn *language,
			 symbol_name_match_type match_type)
{
  const char *arg, *orig;

  /* Try an explicit location spec.  */
  orig = arg = *stringp;
  location_spec_up locspec
    = string_to_explicit_location_spec (&arg, language, NULL);
  if (locspec != nullptr)
    {
      /* It was a valid explicit location.  Advance STRINGP to
	 the end of input.  */
      *stringp += arg - orig;

      /* If the user really specified a location spec, then we're
	 done.  */
      if (!locspec->empty_p ())
	return locspec;

      /* Otherwise, the user _only_ specified optional flags like
	 "-qualified", otherwise string_to_explicit_location_spec
	 would have thrown an error.  Save the flags for "basic"
	 linespec parsing below and discard the explicit location
	 spec.  */
      explicit_location_spec *xloc
	= gdb::checked_static_cast<explicit_location_spec *> (locspec.get ());
      match_type = xloc->func_name_match_type;
    }

  /* Everything else is a "basic" linespec, address, or probe location
     spec.  */
  return string_to_location_spec_basic (stringp, language, match_type);
}
