/* Kernel Object Display generic routines and callbacks
   Copyright 1998, 1999, 2000 Free Software Foundation, Inc.

   Written by Fernando Nasser <fnasser@cygnus.com> for Cygnus Solutions.

   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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"
#include "command.h"
#include "gdbcmd.h"
#include "target.h"
#include "gdb_string.h"
#include "kod.h"

/* Prototypes for exported functions.  */
void _initialize_kod (void);

/* Prototypes for local functions.  */
static void info_kod_command (char *, int);
static void load_kod_library (char *);

/* Prototypes for callbacks.  These are passed into the KOD modules.  */
static void gdb_kod_display (char *);
static void gdb_kod_query (char *, char *, int *);

/* These functions are imported from the KOD module.
   
   gdb_kod_open - initiates the KOD connection to the remote.  The
   first argument is the display function the module should use to
   communicate with the user.  The second argument is the query
   function the display should use to communicate with the target.
   This should call error() if there is an error.  Otherwise it should
   return a malloc()d string of the form:
   
   NAME VERSION - DESCRIPTION
   
   Neither NAME nor VERSION should contain a hyphen.

   
   gdb_kod_request - This is used when the user enters an "info
   <module>" request.  The remaining arguments are passed as the first
   argument.  The second argument is the standard `from_tty'
   argument.

   
   gdb_kod_close - This is called when the KOD connection to the
   remote should be terminated.  */

static char *(*gdb_kod_open) (kod_display_callback_ftype *display,
			      kod_query_callback_ftype *query);
static void (*gdb_kod_request) (char *, int);
static void (*gdb_kod_close) ();


/* Name of inferior's operating system.  */
char *operating_system;

/* We save a copy of the OS so that we can properly reset when
   switching OS's.  */
static char *old_operating_system;

/* Print a line of data generated by the module.  */

static void
gdb_kod_display (char *arg)
{
  printf_filtered ("%s", arg);
}

/* Queries the target on behalf of the module.  */

static void
gdb_kod_query (char *arg, char *result, int *maxsiz)
{
  int bufsiz = 0;

  /* Check if current target has remote_query capabilities.
     If not, it does not have kod either.  */
  if (! current_target.to_query)
    {
      strcpy (result,
              "ERR: Kernel Object Display not supported by current target\n");
      return;
    }

  /* Just get the maximum buffer size.  */
  target_query ((int) 'K', 0, 0, &bufsiz);

  /* Check if *we* were called just for getting the buffer size.  */
  if (*maxsiz == 0)
    {
      *maxsiz = bufsiz;
      strcpy (result, "OK");
      return;
    }

  /* Check if caller can handle a buffer this large, if not, adjust.  */
  if (bufsiz > *maxsiz)
    bufsiz = *maxsiz;

  /* See if buffer can hold the query (usually it can, as the query is
     short).  */
  if (strlen (arg) >= bufsiz)
    error ("kod: query argument too long");

  /* Send actual request.  */
  if (target_query ((int) 'K', arg, result, &bufsiz))
    strcpy (result, "ERR: remote query failed");
}

/* Print name of kod command after selecting the appropriate kod
   formatting library module.  As a side effect we create a new "info"
   subcommand which is what the user actually uses to query the OS.  */

static void
kod_set_os (char *arg, int from_tty, struct cmd_list_element *command)
{
  char *p;

  if (command->type != set_cmd)
    return;

  /* If we had already had an open OS, close it.  */
  if (gdb_kod_close)
    (*gdb_kod_close) ();

  /* Also remove the old OS's command.  */
  if (old_operating_system)
    {
      delete_cmd (old_operating_system, &infolist);
      xfree (old_operating_system);
    }
  old_operating_system = xstrdup (operating_system);

  if (! operating_system || ! *operating_system)
    {
      /* If user set operating system to empty, we want to forget we
	 had a module open.  Setting these variables is just nice for
	 debugging and clarity.  */
      gdb_kod_open = NULL;
      gdb_kod_request = NULL;
      gdb_kod_close = NULL;
    }
  else
    {
      char *kodlib;

      load_kod_library (operating_system);

      kodlib = (*gdb_kod_open) (gdb_kod_display, gdb_kod_query);

      /* Add kod related info commands to gdb.  */
      add_info (operating_system, info_kod_command,
		"Displays information about Kernel Objects.");

      p = strrchr (kodlib, '-');
      if (p != NULL)
	p++;
      else
	p = "Unknown KOD library";
      printf_filtered ("%s - %s\n", operating_system, p);

      xfree (kodlib);
    }
}

/* Print information about currently known kernel objects of the
   specified type or a list of all known kernel object types if
   argument is empty.  */

static void
info_kod_command (char *arg, int from_tty)
{
  (*gdb_kod_request) (arg, from_tty);
}

/* Print name of kod command after selecting the appropriate kod
   formatting library module.  */

static void
load_kod_library (char *lib)
{
#if 0
  /* FIXME: Don't have the eCos code here.  */
  if (! strcmp (lib, "ecos"))
    {
      gdb_kod_open = ecos_kod_open;
      gdb_kod_request = ecos_kod_request;
      gdb_kod_close = ecos_kod_close;
    }
  else
#endif /* 0 */
   if (! strcmp (lib, "cisco"))
    {
      gdb_kod_open = cisco_kod_open;
      gdb_kod_request = cisco_kod_request;
      gdb_kod_close = cisco_kod_close;
    }
  else
    error ("Unknown operating system: %s\n", operating_system);
}

void
_initialize_kod (void)
{
  struct cmd_list_element *c;

  c = add_set_cmd ("os", no_class, var_string,
		   (char *) &operating_system,
		   "Set operating system",
		   &setlist);
  set_cmd_sfunc (c, kod_set_os);
  add_show_from_set (c, &showlist);
}
