* kod.c (kod_set_os): Remove unnecessary check that
[external/binutils.git] / gdb / kod.c
1 /* Kernel Object Display generic routines and callbacks
2    Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
3
4    Written by Fernando Nasser <fnasser@cygnus.com> for Cygnus Solutions.
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, USA.  */
22
23 #include "defs.h"
24 #include "command.h"
25 #include "gdbcmd.h"
26 #include "target.h"
27 #include "gdb_string.h"
28 #include "kod.h"
29
30 /* Prototypes for exported functions.  */
31 void _initialize_kod (void);
32
33 /* Prototypes for local functions.  */
34 static void info_kod_command (char *, int);
35 static void load_kod_library (char *);
36
37 /* Prototypes for callbacks.  These are passed into the KOD modules.  */
38 static void gdb_kod_display (char *);
39 static void gdb_kod_query (char *, char *, int *);
40
41 /* These functions are imported from the KOD module.
42    
43    gdb_kod_open - initiates the KOD connection to the remote.  The
44    first argument is the display function the module should use to
45    communicate with the user.  The second argument is the query
46    function the display should use to communicate with the target.
47    This should call error() if there is an error.  Otherwise it should
48    return a malloc()d string of the form:
49    
50    NAME VERSION - DESCRIPTION
51    
52    Neither NAME nor VERSION should contain a hyphen.
53
54    
55    gdb_kod_request - This is used when the user enters an "info
56    <module>" request.  The remaining arguments are passed as the first
57    argument.  The second argument is the standard `from_tty'
58    argument.
59
60    
61    gdb_kod_close - This is called when the KOD connection to the
62    remote should be terminated.  */
63
64 static char *(*gdb_kod_open) (kod_display_callback_ftype *display,
65                               kod_query_callback_ftype *query);
66 static void (*gdb_kod_request) (char *, int);
67 static void (*gdb_kod_close) ();
68
69
70 /* Name of inferior's operating system.  */
71 char *operating_system;
72
73 /* We save a copy of the OS so that we can properly reset when
74    switching OS's.  */
75 static char *old_operating_system;
76
77 /* Print a line of data generated by the module.  */
78
79 static void
80 gdb_kod_display (char *arg)
81 {
82   printf_filtered ("%s", arg);
83 }
84
85 /* Queries the target on behalf of the module.  */
86
87 static void
88 gdb_kod_query (char *arg, char *result, int *maxsiz)
89 {
90   int bufsiz = 0;
91
92   /* Check if current target has remote_query capabilities.
93      If not, it does not have kod either.  */
94   if (! current_target.to_query)
95     {
96       strcpy (result,
97               "ERR: Kernel Object Display not supported by current target\n");
98       return;
99     }
100
101   /* Just get the maximum buffer size.  */
102   target_query ((int) 'K', 0, 0, &bufsiz);
103
104   /* Check if *we* were called just for getting the buffer size.  */
105   if (*maxsiz == 0)
106     {
107       *maxsiz = bufsiz;
108       strcpy (result, "OK");
109       return;
110     }
111
112   /* Check if caller can handle a buffer this large, if not, adjust.  */
113   if (bufsiz > *maxsiz)
114     bufsiz = *maxsiz;
115
116   /* See if buffer can hold the query (usually it can, as the query is
117      short).  */
118   if (strlen (arg) >= bufsiz)
119     error ("kod: query argument too long");
120
121   /* Send actual request.  */
122   if (target_query ((int) 'K', arg, result, &bufsiz))
123     strcpy (result, "ERR: remote query failed");
124 }
125
126 /* Print name of kod command after selecting the appropriate kod
127    formatting library module.  As a side effect we create a new "info"
128    subcommand which is what the user actually uses to query the OS.  */
129
130 static void
131 kod_set_os (char *arg, int from_tty, struct cmd_list_element *command)
132 {
133   char *p;
134
135   /* If we had already had an open OS, close it.  */
136   if (gdb_kod_close)
137     (*gdb_kod_close) ();
138
139   /* Also remove the old OS's command.  */
140   if (old_operating_system)
141     {
142       delete_cmd (old_operating_system, &infolist);
143       xfree (old_operating_system);
144     }
145   old_operating_system = xstrdup (operating_system);
146
147   if (! operating_system || ! *operating_system)
148     {
149       /* If user set operating system to empty, we want to forget we
150          had a module open.  Setting these variables is just nice for
151          debugging and clarity.  */
152       gdb_kod_open = NULL;
153       gdb_kod_request = NULL;
154       gdb_kod_close = NULL;
155     }
156   else
157     {
158       char *kodlib;
159
160       load_kod_library (operating_system);
161
162       kodlib = (*gdb_kod_open) (gdb_kod_display, gdb_kod_query);
163
164       /* Add kod related info commands to gdb.  */
165       add_info (operating_system, info_kod_command,
166                 "Displays information about Kernel Objects.");
167
168       p = strrchr (kodlib, '-');
169       if (p != NULL)
170         p++;
171       else
172         p = "Unknown KOD library";
173       printf_filtered ("%s - %s\n", operating_system, p);
174
175       xfree (kodlib);
176     }
177 }
178
179 /* Print information about currently known kernel objects of the
180    specified type or a list of all known kernel object types if
181    argument is empty.  */
182
183 static void
184 info_kod_command (char *arg, int from_tty)
185 {
186   (*gdb_kod_request) (arg, from_tty);
187 }
188
189 /* Print name of kod command after selecting the appropriate kod
190    formatting library module.  */
191
192 static void
193 load_kod_library (char *lib)
194 {
195 #if 0
196   /* FIXME: Don't have the eCos code here.  */
197   if (! strcmp (lib, "ecos"))
198     {
199       gdb_kod_open = ecos_kod_open;
200       gdb_kod_request = ecos_kod_request;
201       gdb_kod_close = ecos_kod_close;
202     }
203   else
204 #endif /* 0 */
205    if (! strcmp (lib, "cisco"))
206     {
207       gdb_kod_open = cisco_kod_open;
208       gdb_kod_request = cisco_kod_request;
209       gdb_kod_close = cisco_kod_close;
210     }
211   else
212     error ("Unknown operating system: %s\n", operating_system);
213 }
214
215 void
216 _initialize_kod (void)
217 {
218   struct cmd_list_element *c;
219
220   c = add_set_cmd ("os", no_class, var_string,
221                    (char *) &operating_system,
222                    "Set operating system",
223                    &setlist);
224   set_cmd_sfunc (c, kod_set_os);
225   add_show_from_set (c, &showlist);
226 }