1e93f7393Sniklas /* Generic support for remote debugging interfaces.
2e93f7393Sniklas
3b725ae77Skettenis Copyright 1993, 1994, 1995, 1996, 1998, 2000, 2001
4b725ae77Skettenis Free Software Foundation, Inc.
5e93f7393Sniklas
6e93f7393Sniklas This file is part of GDB.
7e93f7393Sniklas
8e93f7393Sniklas This program is free software; you can redistribute it and/or modify
9e93f7393Sniklas it under the terms of the GNU General Public License as published by
10e93f7393Sniklas the Free Software Foundation; either version 2 of the License, or
11e93f7393Sniklas (at your option) any later version.
12e93f7393Sniklas
13e93f7393Sniklas This program is distributed in the hope that it will be useful,
14e93f7393Sniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
15e93f7393Sniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16e93f7393Sniklas GNU General Public License for more details.
17e93f7393Sniklas
18e93f7393Sniklas You should have received a copy of the GNU General Public License
19e93f7393Sniklas along with this program; if not, write to the Free Software
20b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis Boston, MA 02111-1307, USA. */
22e93f7393Sniklas
23e93f7393Sniklas /* This file actually contains two distinct logical "packages". They
24e93f7393Sniklas are packaged together in this one file because they are typically
25e93f7393Sniklas used together.
26e93f7393Sniklas
27e93f7393Sniklas The first package is an addition to the serial package. The
28e93f7393Sniklas addition provides reading and writing with debugging output and
29e93f7393Sniklas timeouts based on user settable variables. These routines are
30e93f7393Sniklas intended to support serial port based remote backends. These
31e93f7393Sniklas functions are prefixed with sr_.
32e93f7393Sniklas
33e93f7393Sniklas The second package is a collection of more or less generic
34e93f7393Sniklas functions for use by remote backends. They support user settable
35e93f7393Sniklas variables for debugging, retries, and the like.
36e93f7393Sniklas
37e93f7393Sniklas Todo:
38e93f7393Sniklas
39e93f7393Sniklas * a pass through mode a la kermit or telnet.
40e93f7393Sniklas * autobaud.
41e93f7393Sniklas * ask remote to change his baud rate.
42e93f7393Sniklas */
43e93f7393Sniklas
44e93f7393Sniklas #include <ctype.h>
45e93f7393Sniklas
46e93f7393Sniklas #include "defs.h"
47e93f7393Sniklas #include "gdb_string.h"
48e93f7393Sniklas #include "gdbcmd.h"
49e93f7393Sniklas #include "target.h"
50e93f7393Sniklas #include "serial.h"
51e93f7393Sniklas #include "gdbcore.h" /* for exec_bfd */
52e93f7393Sniklas #include "inferior.h" /* for generic_mourn_inferior */
53e93f7393Sniklas #include "remote-utils.h"
54b725ae77Skettenis #include "regcache.h"
55e93f7393Sniklas
56b725ae77Skettenis
57b725ae77Skettenis void _initialize_sr_support (void);
58b725ae77Skettenis
59b725ae77Skettenis struct _sr_settings sr_settings =
60b725ae77Skettenis {
61e93f7393Sniklas 4, /* timeout:
62e93f7393Sniklas remote-hms.c had 2
63e93f7393Sniklas remote-bug.c had "with a timeout of 2, we time out waiting for
64e93f7393Sniklas the prompt after an s-record dump."
65e93f7393Sniklas
66e93f7393Sniklas remote.c had (2): This was 5 seconds, which is a long time to
67e93f7393Sniklas sit and wait. Unless this is going though some terminal server
68e93f7393Sniklas or multiplexer or other form of hairy serial connection, I
69e93f7393Sniklas would think 2 seconds would be plenty.
70e93f7393Sniklas */
71e93f7393Sniklas
72e93f7393Sniklas 10, /* retries */
73e93f7393Sniklas NULL, /* device */
74e93f7393Sniklas NULL, /* descriptor */
75e93f7393Sniklas };
76e93f7393Sniklas
77e93f7393Sniklas struct gr_settings *gr_settings = NULL;
78e93f7393Sniklas
79b725ae77Skettenis static void usage (char *, char *);
80b725ae77Skettenis static void sr_com (char *, int);
81e93f7393Sniklas
82e93f7393Sniklas static void
usage(char * proto,char * junk)83b725ae77Skettenis usage (char *proto, char *junk)
84e93f7393Sniklas {
85e93f7393Sniklas if (junk != NULL)
86e93f7393Sniklas fprintf_unfiltered (gdb_stderr, "Unrecognized arguments: `%s'.\n", junk);
87e93f7393Sniklas
88e93f7393Sniklas error ("Usage: target %s [DEVICE [SPEED [DEBUG]]]\n\
89b725ae77Skettenis where DEVICE is the name of a device or HOST:PORT", proto);
90e93f7393Sniklas
91e93f7393Sniklas return;
92e93f7393Sniklas }
93e93f7393Sniklas
94e93f7393Sniklas #define CHECKDONE(p, q) \
95e93f7393Sniklas { \
96e93f7393Sniklas if (q == p) \
97e93f7393Sniklas { \
98e93f7393Sniklas if (*p == '\0') \
99e93f7393Sniklas return; \
100e93f7393Sniklas else \
101e93f7393Sniklas usage(proto, p); \
102e93f7393Sniklas } \
103e93f7393Sniklas }
104e93f7393Sniklas
105e93f7393Sniklas void
sr_scan_args(char * proto,char * args)106b725ae77Skettenis sr_scan_args (char *proto, char *args)
107e93f7393Sniklas {
108e93f7393Sniklas int n;
109e93f7393Sniklas char *p, *q;
110e93f7393Sniklas
111e93f7393Sniklas /* if no args, then nothing to do. */
112e93f7393Sniklas if (args == NULL || *args == '\0')
113e93f7393Sniklas return;
114e93f7393Sniklas
115e93f7393Sniklas /* scan off white space. */
116e93f7393Sniklas for (p = args; isspace (*p); ++p);;
117e93f7393Sniklas
118e93f7393Sniklas /* find end of device name. */
119e93f7393Sniklas for (q = p; *q != '\0' && !isspace (*q); ++q);;
120e93f7393Sniklas
121e93f7393Sniklas /* check for missing or empty device name. */
122e93f7393Sniklas CHECKDONE (p, q);
123e93f7393Sniklas sr_set_device (savestring (p, q - p));
124e93f7393Sniklas
125e93f7393Sniklas /* look for baud rate. */
126e93f7393Sniklas n = strtol (q, &p, 10);
127e93f7393Sniklas
128e93f7393Sniklas /* check for missing or empty baud rate. */
129e93f7393Sniklas CHECKDONE (p, q);
130e93f7393Sniklas baud_rate = n;
131e93f7393Sniklas
132e93f7393Sniklas /* look for debug value. */
133e93f7393Sniklas n = strtol (p, &q, 10);
134e93f7393Sniklas
135e93f7393Sniklas /* check for missing or empty debug value. */
136e93f7393Sniklas CHECKDONE (p, q);
137e93f7393Sniklas sr_set_debug (n);
138e93f7393Sniklas
139e93f7393Sniklas /* scan off remaining white space. */
140e93f7393Sniklas for (p = q; isspace (*p); ++p);;
141e93f7393Sniklas
142e93f7393Sniklas /* if not end of string, then there's unrecognized junk. */
143e93f7393Sniklas if (*p != '\0')
144e93f7393Sniklas usage (proto, p);
145e93f7393Sniklas
146e93f7393Sniklas return;
147e93f7393Sniklas }
148e93f7393Sniklas
149e93f7393Sniklas void
gr_generic_checkin(void)150b725ae77Skettenis gr_generic_checkin (void)
151e93f7393Sniklas {
152e93f7393Sniklas sr_write_cr ("");
153e93f7393Sniklas gr_expect_prompt ();
154e93f7393Sniklas }
155e93f7393Sniklas
156e93f7393Sniklas void
gr_open(char * args,int from_tty,struct gr_settings * gr)157b725ae77Skettenis gr_open (char *args, int from_tty, struct gr_settings *gr)
158e93f7393Sniklas {
159e93f7393Sniklas target_preopen (from_tty);
160e93f7393Sniklas sr_scan_args (gr->ops->to_shortname, args);
161e93f7393Sniklas unpush_target (gr->ops);
162e93f7393Sniklas
163e93f7393Sniklas gr_settings = gr;
164e93f7393Sniklas
165e93f7393Sniklas if (sr_get_desc () != NULL)
166e93f7393Sniklas gr_close (0);
167e93f7393Sniklas
168e93f7393Sniklas /* If no args are specified, then we use the device specified by a
169e93f7393Sniklas previous command or "set remotedevice". But if there is no
170e93f7393Sniklas device, better stop now, not dump core. */
171e93f7393Sniklas
172e93f7393Sniklas if (sr_get_device () == NULL)
173e93f7393Sniklas usage (gr->ops->to_shortname, NULL);
174e93f7393Sniklas
175b725ae77Skettenis sr_set_desc (serial_open (sr_get_device ()));
176e93f7393Sniklas if (!sr_get_desc ())
177e93f7393Sniklas perror_with_name ((char *) sr_get_device ());
178e93f7393Sniklas
179e93f7393Sniklas if (baud_rate != -1)
180e93f7393Sniklas {
181b725ae77Skettenis if (serial_setbaudrate (sr_get_desc (), baud_rate) != 0)
182e93f7393Sniklas {
183b725ae77Skettenis serial_close (sr_get_desc ());
184e93f7393Sniklas perror_with_name (sr_get_device ());
185e93f7393Sniklas }
186e93f7393Sniklas }
187e93f7393Sniklas
188b725ae77Skettenis serial_raw (sr_get_desc ());
189e93f7393Sniklas
190e93f7393Sniklas /* If there is something sitting in the buffer we might take it as a
191e93f7393Sniklas response to a command, which would be bad. */
192b725ae77Skettenis serial_flush_input (sr_get_desc ());
193e93f7393Sniklas
194e93f7393Sniklas /* default retries */
195e93f7393Sniklas if (sr_get_retries () == 0)
196e93f7393Sniklas sr_set_retries (1);
197e93f7393Sniklas
198e93f7393Sniklas /* default clear breakpoint function */
199e93f7393Sniklas if (gr_settings->clear_all_breakpoints == NULL)
200e93f7393Sniklas gr_settings->clear_all_breakpoints = remove_breakpoints;
201e93f7393Sniklas
202e93f7393Sniklas if (from_tty)
203e93f7393Sniklas {
204e93f7393Sniklas printf_filtered ("Remote debugging using `%s'", sr_get_device ());
205e93f7393Sniklas if (baud_rate != -1)
206e93f7393Sniklas printf_filtered (" at baud rate of %d",
207e93f7393Sniklas baud_rate);
208e93f7393Sniklas printf_filtered ("\n");
209e93f7393Sniklas }
210e93f7393Sniklas
211e93f7393Sniklas push_target (gr->ops);
212e93f7393Sniklas gr_checkin ();
213e93f7393Sniklas gr_clear_all_breakpoints ();
214e93f7393Sniklas return;
215e93f7393Sniklas }
216e93f7393Sniklas
217e93f7393Sniklas /* Read a character from the remote system masking it down to 7 bits
218e93f7393Sniklas and doing all the fancy timeout stuff. */
219e93f7393Sniklas
220e93f7393Sniklas int
sr_readchar(void)221b725ae77Skettenis sr_readchar (void)
222e93f7393Sniklas {
223e93f7393Sniklas int buf;
224e93f7393Sniklas
225b725ae77Skettenis buf = serial_readchar (sr_get_desc (), sr_get_timeout ());
226e93f7393Sniklas
227e93f7393Sniklas if (buf == SERIAL_TIMEOUT)
228e93f7393Sniklas error ("Timeout reading from remote system.");
229e93f7393Sniklas
230e93f7393Sniklas if (sr_get_debug () > 0)
231e93f7393Sniklas printf_unfiltered ("%c", buf);
232e93f7393Sniklas
233e93f7393Sniklas return buf & 0x7f;
234e93f7393Sniklas }
235e93f7393Sniklas
236e93f7393Sniklas int
sr_pollchar(void)237b725ae77Skettenis sr_pollchar (void)
238e93f7393Sniklas {
239e93f7393Sniklas int buf;
240e93f7393Sniklas
241b725ae77Skettenis buf = serial_readchar (sr_get_desc (), 0);
242e93f7393Sniklas if (buf == SERIAL_TIMEOUT)
243e93f7393Sniklas buf = 0;
244e93f7393Sniklas if (sr_get_debug () > 0)
245b725ae77Skettenis {
246e93f7393Sniklas if (buf)
247e93f7393Sniklas printf_unfiltered ("%c", buf);
248e93f7393Sniklas else
249e93f7393Sniklas printf_unfiltered ("<empty character poll>");
250b725ae77Skettenis }
251e93f7393Sniklas
252e93f7393Sniklas return buf & 0x7f;
253e93f7393Sniklas }
254e93f7393Sniklas
255e93f7393Sniklas /* Keep discarding input from the remote system, until STRING is found.
256e93f7393Sniklas Let the user break out immediately. */
257e93f7393Sniklas void
sr_expect(char * string)258b725ae77Skettenis sr_expect (char *string)
259e93f7393Sniklas {
260e93f7393Sniklas char *p = string;
261e93f7393Sniklas
262b725ae77Skettenis immediate_quit++;
263e93f7393Sniklas while (1)
264e93f7393Sniklas {
265e93f7393Sniklas if (sr_readchar () == *p)
266e93f7393Sniklas {
267e93f7393Sniklas p++;
268e93f7393Sniklas if (*p == '\0')
269e93f7393Sniklas {
270b725ae77Skettenis immediate_quit--;
271e93f7393Sniklas return;
272e93f7393Sniklas }
273e93f7393Sniklas }
274e93f7393Sniklas else
275e93f7393Sniklas p = string;
276e93f7393Sniklas }
277e93f7393Sniklas }
278e93f7393Sniklas
279e93f7393Sniklas void
sr_write(char * a,int l)280b725ae77Skettenis sr_write (char *a, int l)
281e93f7393Sniklas {
282e93f7393Sniklas int i;
283e93f7393Sniklas
284b725ae77Skettenis if (serial_write (sr_get_desc (), a, l) != 0)
285e93f7393Sniklas perror_with_name ("sr_write: Error writing to remote");
286e93f7393Sniklas
287e93f7393Sniklas if (sr_get_debug () > 0)
288e93f7393Sniklas for (i = 0; i < l; i++)
289e93f7393Sniklas printf_unfiltered ("%c", a[i]);
290e93f7393Sniklas
291e93f7393Sniklas return;
292e93f7393Sniklas }
293e93f7393Sniklas
294e93f7393Sniklas void
sr_write_cr(char * s)295b725ae77Skettenis sr_write_cr (char *s)
296e93f7393Sniklas {
297e93f7393Sniklas sr_write (s, strlen (s));
298e93f7393Sniklas sr_write ("\r", 1);
299e93f7393Sniklas return;
300e93f7393Sniklas }
301e93f7393Sniklas
302e93f7393Sniklas int
sr_timed_read(char * buf,int n)303b725ae77Skettenis sr_timed_read (char *buf, int n)
304e93f7393Sniklas {
305e93f7393Sniklas int i;
306e93f7393Sniklas char c;
307e93f7393Sniklas
308e93f7393Sniklas i = 0;
309e93f7393Sniklas while (i < n)
310e93f7393Sniklas {
311e93f7393Sniklas c = sr_readchar ();
312e93f7393Sniklas
313e93f7393Sniklas if (c == 0)
314e93f7393Sniklas return i;
315e93f7393Sniklas buf[i] = c;
316e93f7393Sniklas i++;
317e93f7393Sniklas
318e93f7393Sniklas }
319e93f7393Sniklas return i;
320e93f7393Sniklas }
321e93f7393Sniklas
322e93f7393Sniklas /* Get a hex digit from the remote system & return its value. If
323e93f7393Sniklas ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
324e93f7393Sniklas
325e93f7393Sniklas int
sr_get_hex_digit(int ignore_space)326b725ae77Skettenis sr_get_hex_digit (int ignore_space)
327e93f7393Sniklas {
328e93f7393Sniklas int ch;
329e93f7393Sniklas
330e93f7393Sniklas while (1)
331e93f7393Sniklas {
332e93f7393Sniklas ch = sr_readchar ();
333e93f7393Sniklas if (ch >= '0' && ch <= '9')
334e93f7393Sniklas return ch - '0';
335e93f7393Sniklas else if (ch >= 'A' && ch <= 'F')
336e93f7393Sniklas return ch - 'A' + 10;
337e93f7393Sniklas else if (ch >= 'a' && ch <= 'f')
338e93f7393Sniklas return ch - 'a' + 10;
339e93f7393Sniklas else if (ch != ' ' || !ignore_space)
340e93f7393Sniklas {
341e93f7393Sniklas gr_expect_prompt ();
342e93f7393Sniklas error ("Invalid hex digit from remote system.");
343e93f7393Sniklas }
344e93f7393Sniklas }
345e93f7393Sniklas }
346e93f7393Sniklas
347e93f7393Sniklas /* Get a byte from the remote and put it in *BYT. Accept any number
348e93f7393Sniklas leading spaces. */
349e93f7393Sniklas void
sr_get_hex_byte(char * byt)350b725ae77Skettenis sr_get_hex_byte (char *byt)
351e93f7393Sniklas {
352e93f7393Sniklas int val;
353e93f7393Sniklas
354e93f7393Sniklas val = sr_get_hex_digit (1) << 4;
355e93f7393Sniklas val |= sr_get_hex_digit (0);
356e93f7393Sniklas *byt = val;
357e93f7393Sniklas }
358e93f7393Sniklas
359e93f7393Sniklas /* Read a 32-bit hex word from the remote, preceded by a space */
360e93f7393Sniklas long
sr_get_hex_word(void)361b725ae77Skettenis sr_get_hex_word (void)
362e93f7393Sniklas {
363e93f7393Sniklas long val;
364e93f7393Sniklas int j;
365e93f7393Sniklas
366e93f7393Sniklas val = 0;
367e93f7393Sniklas for (j = 0; j < 8; j++)
368e93f7393Sniklas val = (val << 4) + sr_get_hex_digit (j == 0);
369e93f7393Sniklas return val;
370e93f7393Sniklas }
371e93f7393Sniklas
372e93f7393Sniklas /* Put a command string, in args, out to the remote. The remote is assumed to
373e93f7393Sniklas be in raw mode, all writing/reading done through desc.
374e93f7393Sniklas Ouput from the remote is placed on the users terminal until the
375e93f7393Sniklas prompt from the remote is seen.
376e93f7393Sniklas FIXME: Can't handle commands that take input. */
377e93f7393Sniklas
378e93f7393Sniklas static void
sr_com(char * args,int fromtty)379b725ae77Skettenis sr_com (char *args, int fromtty)
380e93f7393Sniklas {
381e93f7393Sniklas sr_check_open ();
382e93f7393Sniklas
383e93f7393Sniklas if (!args)
384e93f7393Sniklas return;
385e93f7393Sniklas
386e93f7393Sniklas /* Clear all input so only command relative output is displayed */
387e93f7393Sniklas
388e93f7393Sniklas sr_write_cr (args);
389e93f7393Sniklas sr_write ("\030", 1);
390e93f7393Sniklas registers_changed ();
391e93f7393Sniklas gr_expect_prompt ();
392e93f7393Sniklas }
393e93f7393Sniklas
394e93f7393Sniklas void
gr_close(int quitting)395b725ae77Skettenis gr_close (int quitting)
396e93f7393Sniklas {
397e93f7393Sniklas gr_clear_all_breakpoints ();
398e93f7393Sniklas
399e93f7393Sniklas if (sr_is_open ())
400e93f7393Sniklas {
401b725ae77Skettenis serial_close (sr_get_desc ());
402e93f7393Sniklas sr_set_desc (NULL);
403e93f7393Sniklas }
404e93f7393Sniklas
405e93f7393Sniklas return;
406e93f7393Sniklas }
407e93f7393Sniklas
408e93f7393Sniklas /* gr_detach()
409e93f7393Sniklas takes a program previously attached to and detaches it.
410e93f7393Sniklas We better not have left any breakpoints
411e93f7393Sniklas in the program or it'll die when it hits one.
412e93f7393Sniklas Close the open connection to the remote debugger.
413e93f7393Sniklas Use this when you want to detach and do something else
414e93f7393Sniklas with your gdb. */
415e93f7393Sniklas
416e93f7393Sniklas void
gr_detach(char * args,int from_tty)417b725ae77Skettenis gr_detach (char *args, int from_tty)
418e93f7393Sniklas {
419e93f7393Sniklas if (args)
420e93f7393Sniklas error ("Argument given to \"detach\" when remotely debugging.");
421e93f7393Sniklas
422e93f7393Sniklas if (sr_is_open ())
423e93f7393Sniklas gr_clear_all_breakpoints ();
424e93f7393Sniklas
425e93f7393Sniklas pop_target ();
426e93f7393Sniklas if (from_tty)
427e93f7393Sniklas puts_filtered ("Ending remote debugging.\n");
428e93f7393Sniklas
429e93f7393Sniklas return;
430e93f7393Sniklas }
431e93f7393Sniklas
432e93f7393Sniklas void
gr_files_info(struct target_ops * ops)433b725ae77Skettenis gr_files_info (struct target_ops *ops)
434e93f7393Sniklas {
435e93f7393Sniklas #ifdef __GO32__
436e93f7393Sniklas printf_filtered ("\tAttached to DOS asynctsr\n");
437e93f7393Sniklas #else
438e93f7393Sniklas printf_filtered ("\tAttached to %s", sr_get_device ());
439e93f7393Sniklas if (baud_rate != -1)
440e93f7393Sniklas printf_filtered ("at %d baud", baud_rate);
441e93f7393Sniklas printf_filtered ("\n");
442e93f7393Sniklas #endif
443e93f7393Sniklas
444e93f7393Sniklas if (exec_bfd)
445e93f7393Sniklas {
446e93f7393Sniklas printf_filtered ("\tand running program %s\n",
447e93f7393Sniklas bfd_get_filename (exec_bfd));
448e93f7393Sniklas }
449e93f7393Sniklas printf_filtered ("\tusing the %s protocol.\n", ops->to_shortname);
450e93f7393Sniklas }
451e93f7393Sniklas
452e93f7393Sniklas void
gr_mourn(void)453b725ae77Skettenis gr_mourn (void)
454e93f7393Sniklas {
455e93f7393Sniklas gr_clear_all_breakpoints ();
456e93f7393Sniklas unpush_target (gr_get_ops ());
457e93f7393Sniklas generic_mourn_inferior ();
458e93f7393Sniklas }
459e93f7393Sniklas
460e93f7393Sniklas void
gr_kill(void)461b725ae77Skettenis gr_kill (void)
462e93f7393Sniklas {
463e93f7393Sniklas return;
464e93f7393Sniklas }
465e93f7393Sniklas
466e93f7393Sniklas /* This is called not only when we first attach, but also when the
467e93f7393Sniklas user types "run" after having attached. */
468e93f7393Sniklas void
gr_create_inferior(char * execfile,char * args,char ** env)469b725ae77Skettenis gr_create_inferior (char *execfile, char *args, char **env)
470e93f7393Sniklas {
471e93f7393Sniklas int entry_pt;
472e93f7393Sniklas
473e93f7393Sniklas if (args && *args)
474e93f7393Sniklas error ("Can't pass arguments to remote process.");
475e93f7393Sniklas
476e93f7393Sniklas if (execfile == 0 || exec_bfd == 0)
477b725ae77Skettenis error ("No executable file specified");
478e93f7393Sniklas
479e93f7393Sniklas entry_pt = (int) bfd_get_start_address (exec_bfd);
480e93f7393Sniklas sr_check_open ();
481e93f7393Sniklas
482e93f7393Sniklas gr_kill ();
483e93f7393Sniklas gr_clear_all_breakpoints ();
484e93f7393Sniklas
485e93f7393Sniklas init_wait_for_inferior ();
486e93f7393Sniklas gr_checkin ();
487e93f7393Sniklas
488e93f7393Sniklas insert_breakpoints (); /* Needed to get correct instruction in cache */
489e93f7393Sniklas proceed (entry_pt, -1, 0);
490e93f7393Sniklas }
491e93f7393Sniklas
492e93f7393Sniklas /* Given a null terminated list of strings LIST, read the input until we find one of
493e93f7393Sniklas them. Return the index of the string found or -1 on error. '?' means match
494e93f7393Sniklas any single character. Note that with the algorithm we use, the initial
495e93f7393Sniklas character of the string cannot recur in the string, or we will not find some
496e93f7393Sniklas cases of the string in the input. If PASSTHROUGH is non-zero, then
497e93f7393Sniklas pass non-matching data on. */
498e93f7393Sniklas
499e93f7393Sniklas int
gr_multi_scan(char * list[],int passthrough)500b725ae77Skettenis gr_multi_scan (char *list[], int passthrough)
501e93f7393Sniklas {
502e93f7393Sniklas char *swallowed = NULL; /* holding area */
503e93f7393Sniklas char *swallowed_p = swallowed; /* Current position in swallowed. */
504e93f7393Sniklas int ch;
505e93f7393Sniklas int ch_handled;
506e93f7393Sniklas int i;
507e93f7393Sniklas int string_count;
508e93f7393Sniklas int max_length;
509e93f7393Sniklas char **plist;
510e93f7393Sniklas
511e93f7393Sniklas /* Look through the strings. Count them. Find the largest one so we can
512e93f7393Sniklas allocate a holding area. */
513e93f7393Sniklas
514e93f7393Sniklas for (max_length = string_count = i = 0;
515e93f7393Sniklas list[i] != NULL;
516e93f7393Sniklas ++i, ++string_count)
517e93f7393Sniklas {
518e93f7393Sniklas int length = strlen (list[i]);
519e93f7393Sniklas
520e93f7393Sniklas if (length > max_length)
521e93f7393Sniklas max_length = length;
522e93f7393Sniklas }
523e93f7393Sniklas
524e93f7393Sniklas /* if we have no strings, then something is wrong. */
525e93f7393Sniklas if (string_count == 0)
526e93f7393Sniklas return (-1);
527e93f7393Sniklas
528e93f7393Sniklas /* otherwise, we will need a holding area big enough to hold almost two
529e93f7393Sniklas copies of our largest string. */
530e93f7393Sniklas swallowed_p = swallowed = alloca (max_length << 1);
531e93f7393Sniklas
532e93f7393Sniklas /* and a list of pointers to current scan points. */
533e93f7393Sniklas plist = (char **) alloca (string_count * sizeof (*plist));
534e93f7393Sniklas
535e93f7393Sniklas /* and initialize */
536e93f7393Sniklas for (i = 0; i < string_count; ++i)
537e93f7393Sniklas plist[i] = list[i];
538e93f7393Sniklas
539e93f7393Sniklas for (ch = sr_readchar (); /* loop forever */ ; ch = sr_readchar ())
540e93f7393Sniklas {
541e93f7393Sniklas QUIT; /* Let user quit and leave process running */
542e93f7393Sniklas ch_handled = 0;
543e93f7393Sniklas
544e93f7393Sniklas for (i = 0; i < string_count; ++i)
545e93f7393Sniklas {
546e93f7393Sniklas if (ch == *plist[i] || *plist[i] == '?')
547e93f7393Sniklas {
548e93f7393Sniklas ++plist[i];
549e93f7393Sniklas if (*plist[i] == '\0')
550e93f7393Sniklas return (i);
551e93f7393Sniklas
552e93f7393Sniklas if (!ch_handled)
553e93f7393Sniklas *swallowed_p++ = ch;
554e93f7393Sniklas
555e93f7393Sniklas ch_handled = 1;
556e93f7393Sniklas }
557e93f7393Sniklas else
558e93f7393Sniklas plist[i] = list[i];
559e93f7393Sniklas }
560e93f7393Sniklas
561e93f7393Sniklas if (!ch_handled)
562e93f7393Sniklas {
563e93f7393Sniklas char *p;
564e93f7393Sniklas
565e93f7393Sniklas /* Print out any characters which have been swallowed. */
566e93f7393Sniklas if (passthrough)
567e93f7393Sniklas {
568e93f7393Sniklas for (p = swallowed; p < swallowed_p; ++p)
569e93f7393Sniklas fputc_unfiltered (*p, gdb_stdout);
570e93f7393Sniklas
571e93f7393Sniklas fputc_unfiltered (ch, gdb_stdout);
572e93f7393Sniklas }
573e93f7393Sniklas
574e93f7393Sniklas swallowed_p = swallowed;
575e93f7393Sniklas }
576e93f7393Sniklas }
577e93f7393Sniklas #if 0
578e93f7393Sniklas /* Never reached. */
579e93f7393Sniklas return (-1);
580e93f7393Sniklas #endif
581e93f7393Sniklas }
582e93f7393Sniklas
583e93f7393Sniklas /* Get ready to modify the registers array. On machines which store
584e93f7393Sniklas individual registers, this doesn't need to do anything. On machines
585e93f7393Sniklas which store all the registers in one fell swoop, this makes sure
586e93f7393Sniklas that registers contains all the registers from the program being
587e93f7393Sniklas debugged. */
588e93f7393Sniklas
589e93f7393Sniklas void
gr_prepare_to_store(void)590b725ae77Skettenis gr_prepare_to_store (void)
591e93f7393Sniklas {
592e93f7393Sniklas /* Do nothing, since we assume we can store individual regs */
593e93f7393Sniklas }
594e93f7393Sniklas
595e93f7393Sniklas void
_initialize_sr_support(void)596b725ae77Skettenis _initialize_sr_support (void)
597e93f7393Sniklas {
598e93f7393Sniklas /* FIXME-now: if target is open... */
599*63addd46Skettenis deprecated_add_show_from_set
600*63addd46Skettenis (add_set_cmd ("remotedevice", no_class,
601e93f7393Sniklas var_filename, (char *) &sr_settings.device,
602e93f7393Sniklas "Set device for remote serial I/O.\n\
603e93f7393Sniklas This device is used as the serial port when debugging using remote\n\
604e93f7393Sniklas targets.", &setlist),
605e93f7393Sniklas &showlist);
606e93f7393Sniklas
607e93f7393Sniklas add_com ("remote <command>", class_obscure, sr_com,
608e93f7393Sniklas "Send a command to the remote monitor.");
609e93f7393Sniklas
610e93f7393Sniklas }
611