/* General utility routines for GDB/Scheme code.

   Copyright (C) 2014-2021 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/>.  */

/* See README file in this directory for implementation notes, coding
   conventions, et.al.  */

#include "defs.h"
#include "guile-internal.h"

/* Define VARIABLES in the gdb module.  */

void
gdbscm_define_variables (const scheme_variable *variables, int is_public)
{
  const scheme_variable *sv;

  for (sv = variables; sv->name != NULL; ++sv)
    {
      scm_c_define (sv->name, sv->value);
      if (is_public)
	scm_c_export (sv->name, NULL);
    }
}

/* Define FUNCTIONS in the gdb module.  */

void
gdbscm_define_functions (const scheme_function *functions, int is_public)
{
  const scheme_function *sf;

  for (sf = functions; sf->name != NULL; ++sf)
    {
      SCM proc = scm_c_define_gsubr (sf->name, sf->required, sf->optional,
				     sf->rest, sf->func);

      scm_set_procedure_property_x (proc, gdbscm_documentation_symbol,
				    gdbscm_scm_from_c_string (sf->doc_string));
      if (is_public)
	scm_c_export (sf->name, NULL);
    }
}

/* Define CONSTANTS in the gdb module.  */

void
gdbscm_define_integer_constants (const scheme_integer_constant *constants,
				 int is_public)
{
  const scheme_integer_constant *sc;

  for (sc = constants; sc->name != NULL; ++sc)
    {
      scm_c_define (sc->name, scm_from_int (sc->value));
      if (is_public)
	scm_c_export (sc->name, NULL);
    }
}

/* scm_printf, alas it doesn't exist.  */

void
gdbscm_printf (SCM port, const char *format, ...)
{
  va_list args;

  va_start (args, format);
  std::string string = string_vprintf (format, args);
  va_end (args);
  scm_puts (string.c_str (), port);
}

/* Utility for calling from gdb to "display" an SCM object.  */

void
gdbscm_debug_display (SCM obj)
{
  SCM port = scm_current_output_port ();

  scm_display (obj, port);
  scm_newline (port);
  scm_force_output (port);
}

/* Utility for calling from gdb to "write" an SCM object.  */

void
gdbscm_debug_write (SCM obj)
{
  SCM port = scm_current_output_port ();

  scm_write (obj, port);
  scm_newline (port);
  scm_force_output (port);
}

/* Subroutine of gdbscm_parse_function_args to simplify it.
   Return the number of keyword arguments.  */

static int
count_keywords (const SCM *keywords)
{
  int i;

  if (keywords == NULL)
    return 0;
  for (i = 0; keywords[i] != SCM_BOOL_F; ++i)
    continue;

  return i;
}

/* Subroutine of gdbscm_parse_function_args to simplify it.
   Validate an argument format string.
   The result is a boolean indicating if "." was seen.  */

static int
validate_arg_format (const char *format)
{
  const char *p;
  int length = strlen (format);
  int optional_position = -1;
  int keyword_position = -1;
  int dot_seen = 0;

  gdb_assert (length > 0);

  for (p = format; *p != '\0'; ++p)
    {
      switch (*p)
	{
	case 's':
	case 't':
	case 'i':
	case 'u':
	case 'l':
	case 'n':
	case 'L':
	case 'U':
	case 'O':
	  break;
	case '|':
	  gdb_assert (keyword_position < 0);
	  gdb_assert (optional_position < 0);
	  optional_position = p - format;
	  break;
	case '#':
	  gdb_assert (keyword_position < 0);
	  keyword_position = p - format;
	  break;
	case '.':
	  gdb_assert (p[1] == '\0');
	  dot_seen = 1;
	  break;
	default:
	  gdb_assert_not_reached ("invalid argument format character");
	}
    }

  return dot_seen;
}

/* Our version of SCM_ASSERT_TYPE that calls gdbscm_make_type_error.  */
#define CHECK_TYPE(ok, arg, position, func_name, expected_type)		\
  do {									\
    if (!(ok))								\
      {									\
	return gdbscm_make_type_error ((func_name), (position), (arg),	\
				       (expected_type));		\
      }									\
  } while (0)

/* Subroutine of gdbscm_parse_function_args to simplify it.
   Check the type of ARG against FORMAT_CHAR and extract the value.
   POSITION is the position of ARG in the argument list.
   The result is #f upon success or a <gdb:exception> object.  */

static SCM
extract_arg (char format_char, SCM arg, void *argp,
	     const char *func_name, int position)
{
  switch (format_char)
    {
    case 's':
      {
	char **arg_ptr = (char **) argp;

	CHECK_TYPE (gdbscm_is_true (scm_string_p (arg)), arg, position,
		    func_name, _("string"));
	*arg_ptr = gdbscm_scm_to_c_string (arg).release ();
	break;
      }
    case 't':
      {
	int *arg_ptr = (int *) argp;

	/* While in Scheme, anything non-#f is "true", we're strict.  */
	CHECK_TYPE (gdbscm_is_bool (arg), arg, position, func_name,
		    _("boolean"));
	*arg_ptr = gdbscm_is_true (arg);
	break;
      }
    case 'i':
      {
	int *arg_ptr = (int *) argp;

	CHECK_TYPE (scm_is_signed_integer (arg, INT_MIN, INT_MAX),
		    arg, position, func_name, _("int"));
	*arg_ptr = scm_to_int (arg);
	break;
      }
    case 'u':
      {
	int *arg_ptr = (int *) argp;

	CHECK_TYPE (scm_is_unsigned_integer (arg, 0, UINT_MAX),
		    arg, position, func_name, _("unsigned int"));
	*arg_ptr = scm_to_uint (arg);
	break;
      }
    case 'l':
      {
	long *arg_ptr = (long *) argp;

	CHECK_TYPE (scm_is_signed_integer (arg, LONG_MIN, LONG_MAX),
		    arg, position, func_name, _("long"));
	*arg_ptr = scm_to_long (arg);
	break;
      }
    case 'n':
      {
	unsigned long *arg_ptr = (unsigned long *) argp;

	CHECK_TYPE (scm_is_unsigned_integer (arg, 0, ULONG_MAX),
		    arg, position, func_name, _("unsigned long"));
	*arg_ptr = scm_to_ulong (arg);
	break;
      }
    case 'L':
      {
	LONGEST *arg_ptr = (LONGEST *) argp;

	CHECK_TYPE (scm_is_signed_integer (arg, INT64_MIN, INT64_MAX),
		    arg, position, func_name, _("LONGEST"));
	*arg_ptr = gdbscm_scm_to_longest (arg);
	break;
      }
    case 'U':
      {
	ULONGEST *arg_ptr = (ULONGEST *) argp;

	CHECK_TYPE (scm_is_unsigned_integer (arg, 0, UINT64_MAX),
		    arg, position, func_name, _("ULONGEST"));
	*arg_ptr = gdbscm_scm_to_ulongest (arg);
	break;
      }
    case 'O':
      {
	SCM *arg_ptr = (SCM *) argp;

	*arg_ptr = arg;
	break;
      }
    default:
      gdb_assert_not_reached ("invalid argument format character");
    }

  return SCM_BOOL_F;
}

#undef CHECK_TYPE

/* Look up KEYWORD in KEYWORD_LIST.
   The result is the index of the keyword in the list or -1 if not found.  */

static int
lookup_keyword (const SCM *keyword_list, SCM keyword)
{
  int i = 0;

  while (keyword_list[i] != SCM_BOOL_F)
    {
      if (scm_is_eq (keyword_list[i], keyword))
	return i;
      ++i;
    }

  return -1;
}


/* Helper for gdbscm_parse_function_args that does most of the work,
   in a separate function wrapped with gdbscm_wrap so that we can use
   non-trivial-dtor objects here.  The result is #f upon success or a
   <gdb:exception> object otherwise.  */

static SCM
gdbscm_parse_function_args_1 (const char *func_name,
			      int beginning_arg_pos,
			      const SCM *keywords,
			      const char *format, va_list args)
{
  const char *p;
  int i, have_rest, num_keywords, position;
  int have_optional = 0;
  SCM status;
  SCM rest = SCM_EOL;
  /* Keep track of malloc'd strings.  We need to free them upon error.  */
  std::vector<char *> allocated_strings;

  have_rest = validate_arg_format (format);
  num_keywords = count_keywords (keywords);

  p = format;
  position = beginning_arg_pos;

  /* Process required, optional arguments.  */

  while (*p && *p != '#' && *p != '.')
    {
      SCM arg;
      void *arg_ptr;

      if (*p == '|')
	{
	  have_optional = 1;
	  ++p;
	  continue;
	}

      arg = va_arg (args, SCM);
      if (!have_optional || !SCM_UNBNDP (arg))
	{
	  arg_ptr = va_arg (args, void *);
	  status = extract_arg (*p, arg, arg_ptr, func_name, position);
	  if (!gdbscm_is_false (status))
	    goto fail;
	  if (*p == 's')
	    allocated_strings.push_back (*(char **) arg_ptr);
	}
      ++p;
      ++position;
    }

  /* Process keyword arguments.  */

  if (have_rest || num_keywords > 0)
    rest = va_arg (args, SCM);

  if (num_keywords > 0)
    {
      SCM *keyword_args = XALLOCAVEC (SCM, num_keywords);
      int *keyword_positions = XALLOCAVEC (int, num_keywords);

      gdb_assert (*p == '#');
      ++p;

      for (i = 0; i < num_keywords; ++i)
	{
	  keyword_args[i] = SCM_UNSPECIFIED;
	  keyword_positions[i] = -1;
	}

      while (scm_is_pair (rest)
	     && scm_is_keyword (scm_car (rest)))
	{
	  SCM keyword = scm_car (rest);

	  i = lookup_keyword (keywords, keyword);
	  if (i < 0)
	    {
	      status = gdbscm_make_error (scm_arg_type_key, func_name,
					  _("Unrecognized keyword: ~a"),
					  scm_list_1 (keyword), keyword);
	      goto fail;
	    }
	  if (!scm_is_pair (scm_cdr (rest)))
	    {
	      status = gdbscm_make_error
		(scm_arg_type_key, func_name,
		 _("Missing value for keyword argument"),
		 scm_list_1 (keyword), keyword);
	      goto fail;
	    }
	  keyword_args[i] = scm_cadr (rest);
	  keyword_positions[i] = position + 1;
	  rest = scm_cddr (rest);
	  position += 2;
	}

      for (i = 0; i < num_keywords; ++i)
	{
	  int *arg_pos_ptr = va_arg (args, int *);
	  void *arg_ptr = va_arg (args, void *);
	  SCM arg = keyword_args[i];

	  if (! scm_is_eq (arg, SCM_UNSPECIFIED))
	    {
	      *arg_pos_ptr = keyword_positions[i];
	      status = extract_arg (p[i], arg, arg_ptr, func_name,
				    keyword_positions[i]);
	      if (!gdbscm_is_false (status))
		goto fail;
	      if (p[i] == 's')
		allocated_strings.push_back (*(char **) arg_ptr);
	    }
	}
    }

  /* Process "rest" arguments.  */

  if (have_rest)
    {
      if (num_keywords > 0)
	{
	  SCM *rest_ptr = va_arg (args, SCM *);

	  *rest_ptr = rest;
	}
    }
  else
    {
      if (! scm_is_null (rest))
	{
	  status = gdbscm_make_error (scm_args_number_key, func_name,
				      _("Too many arguments"),
				      SCM_EOL, SCM_BOOL_F);
	  goto fail;
	}
    }

  /* Return anything not-an-exception.  */
  return SCM_BOOL_F;

 fail:
  for (char *ptr : allocated_strings)
    xfree (ptr);

  /* Return the exception, which gdbscm_wrap takes care of
     throwing.  */
  return status;
}

/* Utility to parse required, optional, and keyword arguments to Scheme
   functions.  Modelled on PyArg_ParseTupleAndKeywords, but no attempt is made
   at similarity or functionality.
   There is no result, if there's an error a Scheme exception is thrown.

   Guile provides scm_c_bind_keyword_arguments, and feel free to use it.
   This is for times when we want a bit more parsing.

   BEGINNING_ARG_POS is the position of the first argument passed to this
   routine.  It should be one of the SCM_ARGn values.  It could be > SCM_ARG1
   if the caller chooses not to parse one or more required arguments.

   KEYWORDS may be NULL if there are no keywords.

   FORMAT:
   s - string -> char *, malloc'd
   t - boolean (gdb uses "t", for biT?) -> int
   i - int
   u - unsigned int
   l - long
   n - unsigned long
   L - longest
   U - unsigned longest
   O - random scheme object
   | - indicates the next set is for optional arguments
   # - indicates the next set is for keyword arguments (must follow |)
   . - indicates "rest" arguments are present, this character must appear last

   FORMAT must match the definition from scm_c_{make,define}_gsubr.
   Required and optional arguments appear in order in the format string.
   Afterwards, keyword-based arguments are processed.  There must be as many
   remaining characters in the format string as their are keywords.
   Except for "|#.", the number of characters in the format string must match
   #required + #optional + #keywords.

   The function is required to be defined in a compatible manner:
   #required-args and #optional-arguments must match, and rest-arguments
   must be specified if keyword args are desired, and/or regular "rest" args.

   Example:  For this function,
   scm_c_define_gsubr ("execute", 2, 3, 1, foo);
   the format string + keyword list could be any of:
   1) "ss|ttt#tt", { "key1", "key2", NULL }
   2) "ss|ttt.", { NULL }
   3) "ss|ttt#t.", { "key1", NULL }

   For required and optional args pass the SCM of the argument, and a
   pointer to the value to hold the parsed result (type depends on format
   char).  After that pass the SCM containing the "rest" arguments followed
   by pointers to values to hold parsed keyword arguments, and if specified
   a pointer to hold the remaining contents of "rest".

   For keyword arguments pass two pointers: the first is a pointer to an int
   that will contain the position of the argument in the arg list, and the
   second will contain result of processing the argument.  The int pointed
   to by the first value should be initialized to -1.  It can then be used
   to tell whether the keyword was present.

   If both keyword and rest arguments are present, the caller must pass a
   pointer to contain the new value of rest (after keyword args have been
   removed).

   There's currently no way, that I know of, to specify default values for
   optional arguments in C-provided functions.  At the moment they're a
   work-in-progress.  The caller should test SCM_UNBNDP for each optional
   argument.  Unbound optional arguments are ignored.  */

void
gdbscm_parse_function_args (const char *func_name,
			    int beginning_arg_pos,
			    const SCM *keywords,
			    const char *format, ...)
{
  va_list args;
  va_start (args, format);

  gdbscm_wrap (gdbscm_parse_function_args_1, func_name,
	       beginning_arg_pos, keywords, format, args);

  va_end (args);
}


/* Return longest L as a scheme object.  */

SCM
gdbscm_scm_from_longest (LONGEST l)
{
  return scm_from_int64 (l);
}

/* Convert scheme object L to LONGEST.
   It is an error to call this if L is not an integer in range of LONGEST.
   (because the underlying Scheme function will thrown an exception,
   which is not part of our contract with the caller).  */

LONGEST
gdbscm_scm_to_longest (SCM l)
{
  return scm_to_int64 (l);
}

/* Return unsigned longest L as a scheme object.  */

SCM
gdbscm_scm_from_ulongest (ULONGEST l)
{
  return scm_from_uint64 (l);
}

/* Convert scheme object U to ULONGEST.
   It is an error to call this if U is not an integer in range of ULONGEST
   (because the underlying Scheme function will thrown an exception,
   which is not part of our contract with the caller).  */

ULONGEST
gdbscm_scm_to_ulongest (SCM u)
{
  return scm_to_uint64 (u);
}

/* Same as scm_dynwind_free, but uses xfree.  */

void
gdbscm_dynwind_xfree (void *ptr)
{
  scm_dynwind_unwind_handler (xfree, ptr, SCM_F_WIND_EXPLICITLY);
}

/* Return non-zero if PROC is a procedure.  */

int
gdbscm_is_procedure (SCM proc)
{
  return gdbscm_is_true (scm_procedure_p (proc));
}

/* Same as xstrdup, but the string is allocated on the GC heap.  */

char *
gdbscm_gc_xstrdup (const char *str)
{
  size_t len = strlen (str);
  char *result
    = (char *) scm_gc_malloc_pointerless (len + 1, "gdbscm_gc_xstrdup");

  strcpy (result, str);
  return result;
}

/* Return a duplicate of ARGV living on the GC heap.  */

const char * const *
gdbscm_gc_dup_argv (char **argv)
{
  int i, len;
  size_t string_space;
  char *p, **result;

  for (len = 0, string_space = 0; argv[len] != NULL; ++len)
    string_space += strlen (argv[len]) + 1;

  /* Allocating "pointerless" works because the pointers are all
     self-contained within the object.  */
  result = (char **) scm_gc_malloc_pointerless (((len + 1) * sizeof (char *))
						+ string_space,
						"parameter enum list");
  p = (char *) &result[len + 1];

  for (i = 0; i < len; ++i)
    {
      result[i] = p;
      strcpy (p, argv[i]);
      p += strlen (p) + 1;
    }
  result[i] = NULL;

  return (const char * const *) result;
}

/* Return non-zero if the version of Guile being used it at least
   MAJOR.MINOR.MICRO.  */

int
gdbscm_guile_version_is_at_least (int major, int minor, int micro)
{
  if (major > gdbscm_guile_major_version)
    return 0;
  if (major < gdbscm_guile_major_version)
    return 1;
  if (minor > gdbscm_guile_minor_version)
    return 0;
  if (minor < gdbscm_guile_minor_version)
    return 1;
  if (micro > gdbscm_guile_micro_version)
    return 0;
  return 1;
}
