/* General utility routines for GDB/Scheme code.

   Copyright (C) 2014-2018 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;
  char *string;

  va_start (args, format);
  string = xstrvprintf (format, args);
  va_end (args);
  scm_puts (string, port);
  xfree (string);
}

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

/* 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;
  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.  */
  VEC (char_ptr) *allocated_strings = NULL;
  char *ptr;

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

  va_start (args, format);

  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')
	    VEC_safe_push (char_ptr, allocated_strings, *(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')
		{
		  VEC_safe_push (char_ptr, allocated_strings,
				 *(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;
	}
    }

  va_end (args);
  VEC_free (char_ptr, allocated_strings);
  return;

 fail:
  va_end (args);
  for (i = 0; VEC_iterate (char_ptr, allocated_strings, i, ptr); ++i)
    xfree (ptr);
  VEC_free (char_ptr, allocated_strings);
  gdbscm_throw (status);
}

/* 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;
}
