/* Kernel Object Display generic routines and callbacks
   Copyright 1998, 1999 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"

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

/* Prototypes for local functions.  */
static void show_kod (char *, int);
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) (void *, void *);
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;

/* Functions imported from the library for all supported OSes.
   FIXME: we really should do something better, such as dynamically
   loading the KOD modules.  */
extern char *ecos_kod_open (void *, void *);
extern void ecos_kod_request (char *, int);
extern void ecos_kod_close ();
extern char *cisco_kod_open (void *, void *);
extern void cisco_kod_request (char *, int);
extern void cisco_kod_close ();


/* 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);
      free (old_operating_system);
    }
  old_operating_system = strdup (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);

      free (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 ()
{
  struct cmd_list_element *c;

  c = add_set_cmd ("os", no_class, var_string,
		   (char *) &operating_system,
		   "Set operating system",
		   &setlist);
  c->function.sfunc = kod_set_os;
  add_show_from_set (c, &showlist);
}
