OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [cli/] [cli-decode.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Handle lists of commands, their decoding and documentation, for GDB.
2
   Copyright 1986, 1989, 1990, 1991, 1998, 2000, 2001
3
   Free Software Foundation, Inc.
4
 
5
   This program is free software; you can redistribute it and/or modify
6
   it under the terms of the GNU General Public License as published by
7
   the Free Software Foundation; either version 2 of the License, or
8
   (at your option) any later version.
9
 
10
   This program is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   GNU General Public License for more details.
14
 
15
   You should have received a copy of the GNU General Public License
16
   along with this program; if not, write to the Free Software
17
   Foundation, Inc., 59 Temple Place - Suite 330,
18
   Boston, MA 02111-1307, USA.  */
19
 
20
#include "defs.h"
21
#include "symtab.h"
22
#include <ctype.h>
23
#include "gnu-regex.h"
24
 
25
#ifdef UI_OUT
26
#include "ui-out.h"
27
#endif
28
 
29
#include "cli/cli-cmds.h"
30
#include "cli/cli-decode.h"
31
 
32
/* Prototypes for local functions */
33
 
34
static void undef_cmd_error (char *, char *);
35
 
36
static struct cmd_list_element *find_cmd (char *command,
37
                                          int len,
38
                                          struct cmd_list_element *clist,
39
                                          int ignore_help_classes,
40
                                          int *nfound);
41
 
42
static void help_all (struct ui_file *stream);
43
 
44
/* Add element named NAME.
45
   CLASS is the top level category into which commands are broken down
46
   for "help" purposes.
47
   FUN should be the function to execute the command;
48
   it will get a character string as argument, with leading
49
   and trailing blanks already eliminated.
50
 
51
   DOC is a documentation string for the command.
52
   Its first line should be a complete sentence.
53
   It should start with ? for a command that is an abbreviation
54
   or with * for a command that most users don't need to know about.
55
 
56
   Add this command to command list *LIST.
57
 
58
   Returns a pointer to the added command (not necessarily the head
59
   of *LIST). */
60
 
61
struct cmd_list_element *
62
add_cmd (char *name, enum command_class class, void (*fun) (char *, int),
63
         char *doc, struct cmd_list_element **list)
64
{
65
  register struct cmd_list_element *c
66
  = (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
67
  struct cmd_list_element *p;
68
 
69
  delete_cmd (name, list);
70
 
71
  if (*list == NULL || strcmp ((*list)->name, name) >= 0)
72
    {
73
      c->next = *list;
74
      *list = c;
75
    }
76
  else
77
    {
78
      p = *list;
79
      while (p->next && strcmp (p->next->name, name) <= 0)
80
        {
81
          p = p->next;
82
        }
83
      c->next = p->next;
84
      p->next = c;
85
    }
86
 
87
  c->name = name;
88
  c->class = class;
89
  c->function.cfunc = fun;
90
  c->doc = doc;
91
  c->flags = 0;
92
  c->replacement = NULL;
93
  c->hook_pre  = NULL;
94
  c->hook_post = NULL;
95
  c->hook_in = 0;
96
  c->prefixlist = NULL;
97
  c->prefixname = NULL;
98
  c->allow_unknown = 0;
99
  c->abbrev_flag = 0;
100
  c->completer = make_symbol_completion_list;
101
  c->type = not_set_cmd;
102
  c->var = NULL;
103
  c->var_type = var_boolean;
104
  c->enums = NULL;
105
  c->user_commands = NULL;
106
  c->hookee_pre = NULL;
107
  c->hookee_post = NULL;
108
  c->cmd_pointer = NULL;
109
 
110
  return c;
111
}
112
 
113
/* Same as above, except that the abbrev_flag is set. */
114
/* Note: Doesn't seem to be used anywhere currently. */
115
 
116
struct cmd_list_element *
117
add_abbrev_cmd (char *name, enum command_class class, void (*fun) (char *, int),
118
                char *doc, struct cmd_list_element **list)
119
{
120
  register struct cmd_list_element *c
121
  = add_cmd (name, class, fun, doc, list);
122
 
123
  c->abbrev_flag = 1;
124
  return c;
125
}
126
 
127
/* Deprecates a command CMD.
128
   REPLACEMENT is the name of the command which should be used in place
129
   of this command, or NULL if no such command exists.
130
 
131
   This function does not check to see if command REPLACEMENT exists
132
   since gdb may not have gotten around to adding REPLACEMENT when this
133
   function is called.
134
 
135
   Returns a pointer to the deprecated command.  */
136
 
137
struct cmd_list_element *
138
deprecate_cmd (struct cmd_list_element *cmd, char *replacement)
139
{
140
  cmd->flags |= (CMD_DEPRECATED | DEPRECATED_WARN_USER);
141
 
142
  if (replacement != NULL)
143
    cmd->replacement = replacement;
144
  else
145
    cmd->replacement = NULL;
146
 
147
  return cmd;
148
}
149
 
150
struct cmd_list_element *
151
add_alias_cmd (char *name, char *oldname, enum command_class class,
152
               int abbrev_flag, struct cmd_list_element **list)
153
{
154
  /* Must do this since lookup_cmd tries to side-effect its first arg */
155
  char *copied_name;
156
  register struct cmd_list_element *old;
157
  register struct cmd_list_element *c;
158
  copied_name = (char *) alloca (strlen (oldname) + 1);
159
  strcpy (copied_name, oldname);
160
  old = lookup_cmd (&copied_name, *list, "", 1, 1);
161
 
162
  if (old == 0)
163
    {
164
      delete_cmd (name, list);
165
      return 0;
166
    }
167
 
168
  c = add_cmd (name, class, old->function.cfunc, old->doc, list);
169
  c->prefixlist = old->prefixlist;
170
  c->prefixname = old->prefixname;
171
  c->allow_unknown = old->allow_unknown;
172
  c->abbrev_flag = abbrev_flag;
173
  c->cmd_pointer = old;
174
  return c;
175
}
176
 
177
/* Like add_cmd but adds an element for a command prefix:
178
   a name that should be followed by a subcommand to be looked up
179
   in another command list.  PREFIXLIST should be the address
180
   of the variable containing that list.  */
181
 
182
struct cmd_list_element *
183
add_prefix_cmd (char *name, enum command_class class, void (*fun) (char *, int),
184
                char *doc, struct cmd_list_element **prefixlist,
185
                char *prefixname, int allow_unknown,
186
                struct cmd_list_element **list)
187
{
188
  register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
189
  c->prefixlist = prefixlist;
190
  c->prefixname = prefixname;
191
  c->allow_unknown = allow_unknown;
192
  return c;
193
}
194
 
195
/* Like add_prefix_cmd but sets the abbrev_flag on the new command. */
196
 
197
struct cmd_list_element *
198
add_abbrev_prefix_cmd (char *name, enum command_class class,
199
                       void (*fun) (char *, int), char *doc,
200
                       struct cmd_list_element **prefixlist, char *prefixname,
201
                       int allow_unknown, struct cmd_list_element **list)
202
{
203
  register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
204
  c->prefixlist = prefixlist;
205
  c->prefixname = prefixname;
206
  c->allow_unknown = allow_unknown;
207
  c->abbrev_flag = 1;
208
  return c;
209
}
210
 
211
/* This is an empty "cfunc".  */
212
void
213
not_just_help_class_command (char *args, int from_tty)
214
{
215
}
216
 
217
/* This is an empty "sfunc".  */
218
static void empty_sfunc (char *, int, struct cmd_list_element *);
219
 
220
static void
221
empty_sfunc (char *args, int from_tty, struct cmd_list_element *c)
222
{
223
}
224
 
225
/* Add element named NAME to command list LIST (the list for set
226
   or some sublist thereof).
227
   CLASS is as in add_cmd.
228
   VAR_TYPE is the kind of thing we are setting.
229
   VAR is address of the variable being controlled by this command.
230
   DOC is the documentation string.  */
231
 
232
struct cmd_list_element *
233
add_set_cmd (char *name,
234
             enum command_class class,
235
             var_types var_type,
236
             void *var,
237
             char *doc,
238
             struct cmd_list_element **list)
239
{
240
  struct cmd_list_element *c
241
  = add_cmd (name, class, NO_FUNCTION, doc, list);
242
 
243
  c->type = set_cmd;
244
  c->var_type = var_type;
245
  c->var = var;
246
  /* This needs to be something besides NO_FUNCTION so that this isn't
247
     treated as a help class.  */
248
  c->function.sfunc = empty_sfunc;
249
  return c;
250
}
251
 
252
/* Add element named NAME to command list LIST (the list for set
253
   or some sublist thereof).
254
   CLASS is as in add_cmd.
255
   ENUMLIST is a list of strings which may follow NAME.
256
   VAR is address of the variable which will contain the matching string
257
   (from ENUMLIST).
258
   DOC is the documentation string.  */
259
 
260
struct cmd_list_element *
261
add_set_enum_cmd (char *name,
262
                  enum command_class class,
263
                  const char *enumlist[],
264
                  const char **var,
265
                  char *doc,
266
                  struct cmd_list_element **list)
267
{
268
  struct cmd_list_element *c
269
  = add_set_cmd (name, class, var_enum, var, doc, list);
270
  c->enums = enumlist;
271
 
272
  return c;
273
}
274
 
275
/* Add element named NAME to command list LIST (the list for set
276
   or some sublist thereof).
277
   CLASS is as in add_cmd.
278
   VAR is address of the variable which will contain the value.
279
   DOC is the documentation string.  */
280
struct cmd_list_element *
281
add_set_auto_boolean_cmd (char *name,
282
                          enum command_class class,
283
                          enum cmd_auto_boolean *var,
284
                          char *doc,
285
                          struct cmd_list_element **list)
286
{
287
  static const char *auto_boolean_enums[] = { "on", "off", "auto", NULL };
288
  struct cmd_list_element *c;
289
  c = add_set_cmd (name, class, var_auto_boolean, var, doc, list);
290
  c->enums = auto_boolean_enums;
291
  return c;
292
}
293
 
294
/* Where SETCMD has already been added, add the corresponding show
295
   command to LIST and return a pointer to the added command (not
296
   necessarily the head of LIST).  */
297
struct cmd_list_element *
298
add_show_from_set (struct cmd_list_element *setcmd,
299
                   struct cmd_list_element **list)
300
{
301
  struct cmd_list_element *showcmd =
302
  (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
303
  struct cmd_list_element *p;
304
 
305
  memcpy (showcmd, setcmd, sizeof (struct cmd_list_element));
306
  delete_cmd (showcmd->name, list);
307
  showcmd->type = show_cmd;
308
 
309
  /* Replace "set " at start of docstring with "show ".  */
310
  if (setcmd->doc[0] == 'S' && setcmd->doc[1] == 'e'
311
      && setcmd->doc[2] == 't' && setcmd->doc[3] == ' ')
312
    showcmd->doc = concat ("Show ", setcmd->doc + 4, NULL);
313
  else
314
    fprintf_unfiltered (gdb_stderr, "GDB internal error: Bad docstring for set command\n");
315
 
316
  if (*list == NULL || strcmp ((*list)->name, showcmd->name) >= 0)
317
    {
318
      showcmd->next = *list;
319
      *list = showcmd;
320
    }
321
  else
322
    {
323
      p = *list;
324
      while (p->next && strcmp (p->next->name, showcmd->name) <= 0)
325
        {
326
          p = p->next;
327
        }
328
      showcmd->next = p->next;
329
      p->next = showcmd;
330
    }
331
 
332
  return showcmd;
333
}
334
 
335
/* Remove the command named NAME from the command list.  */
336
 
337
void
338
delete_cmd (char *name, struct cmd_list_element **list)
339
{
340
  register struct cmd_list_element *c;
341
  struct cmd_list_element *p;
342
 
343
  while (*list && STREQ ((*list)->name, name))
344
    {
345
      if ((*list)->hookee_pre)
346
      (*list)->hookee_pre->hook_pre = 0;   /* Hook slips out of its mouth */
347
      if ((*list)->hookee_post)
348
      (*list)->hookee_post->hook_post = 0; /* Hook slips out of its bottom  */
349
      p = (*list)->next;
350
      xfree (* list);
351
      *list = p;
352
    }
353
 
354
  if (*list)
355
    for (c = *list; c->next;)
356
      {
357
        if (STREQ (c->next->name, name))
358
          {
359
          if (c->next->hookee_pre)
360
            c->next->hookee_pre->hook_pre = 0; /* hooked cmd gets away.  */
361
          if (c->next->hookee_post)
362
            c->next->hookee_post->hook_post = 0; /* remove post hook */
363
                                               /* :( no fishing metaphore */
364
            p = c->next->next;
365
            xfree (c->next);
366
            c->next = p;
367
          }
368
        else
369
          c = c->next;
370
      }
371
}
372
 
373
/* Shorthands to the commands above. */
374
 
375
/* Add an element to the list of info subcommands.  */
376
 
377
struct cmd_list_element *
378
add_info (char *name, void (*fun) (char *, int), char *doc)
379
{
380
  return add_cmd (name, no_class, fun, doc, &infolist);
381
}
382
 
383
/* Add an alias to the list of info subcommands.  */
384
 
385
struct cmd_list_element *
386
add_info_alias (char *name, char *oldname, int abbrev_flag)
387
{
388
  return add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist);
389
}
390
 
391
/* Add an element to the list of commands.  */
392
 
393
struct cmd_list_element *
394
add_com (char *name, enum command_class class, void (*fun) (char *, int),
395
         char *doc)
396
{
397
  return add_cmd (name, class, fun, doc, &cmdlist);
398
}
399
 
400
/* Add an alias or abbreviation command to the list of commands.  */
401
 
402
struct cmd_list_element *
403
add_com_alias (char *name, char *oldname, enum command_class class,
404
               int abbrev_flag)
405
{
406
  return add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist);
407
}
408
 
409
/* Recursively walk the commandlist structures, and print out the
410
   documentation of commands that match our regex in either their
411
   name, or their documentation.
412
*/
413
void
414
apropos_cmd (struct ui_file *stream, struct cmd_list_element *commandlist,
415
                         struct re_pattern_buffer *regex, char *prefix)
416
{
417
  register struct cmd_list_element *c;
418
  int returnvalue=1; /*Needed to avoid double printing*/
419
  /* Walk through the commands */
420
  for (c=commandlist;c;c=c->next)
421
    {
422
      if (c->name != NULL)
423
        {
424
          /* Try to match against the name*/
425
          returnvalue=re_search(regex,c->name,strlen(c->name),0,strlen(c->name),NULL);
426
          if (returnvalue >= 0)
427
            {
428
              /* Stolen from help_cmd_list. We don't directly use
429
               * help_cmd_list because it doesn't let us print out
430
               * single commands
431
               */
432
              fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
433
              print_doc_line (stream, c->doc);
434
              fputs_filtered ("\n", stream);
435
              returnvalue=0; /*Set this so we don't print it again.*/
436
            }
437
        }
438
      if (c->doc != NULL && returnvalue != 0)
439
        {
440
          /* Try to match against documentation */
441
          if (re_search(regex,c->doc,strlen(c->doc),0,strlen(c->doc),NULL) >=0)
442
            {
443
              /* Stolen from help_cmd_list. We don't directly use
444
               * help_cmd_list because it doesn't let us print out
445
               * single commands
446
               */
447
              fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
448
              print_doc_line (stream, c->doc);
449
              fputs_filtered ("\n", stream);
450
            }
451
        }
452
      /* Check if this command has subcommands */
453
      if (c->prefixlist != NULL)
454
        {
455
          /* Recursively call ourselves on the subcommand list,
456
             passing the right prefix in.
457
          */
458
          apropos_cmd (stream,*c->prefixlist,regex,c->prefixname);
459
        }
460
    }
461
}
462
 
463
/* This command really has to deal with two things:
464
 *     1) I want documentation on *this string* (usually called by
465
 * "help commandname").
466
 *     2) I want documentation on *this list* (usually called by
467
 * giving a command that requires subcommands.  Also called by saying
468
 * just "help".)
469
 *
470
 *   I am going to split this into two seperate comamnds, help_cmd and
471
 * help_list.
472
 */
473
 
474
void
475
help_cmd (char *command, struct ui_file *stream)
476
{
477
  struct cmd_list_element *c;
478
  extern struct cmd_list_element *cmdlist;
479
 
480
  if (!command)
481
    {
482
      help_list (cmdlist, "", all_classes, stream);
483
      return;
484
    }
485
 
486
  if (strcmp (command, "all") == 0)
487
    {
488
      help_all (stream);
489
      return;
490
    }
491
 
492
  c = lookup_cmd (&command, cmdlist, "", 0, 0);
493
 
494
  if (c == 0)
495
    return;
496
 
497
  /* There are three cases here.
498
     If c->prefixlist is nonzero, we have a prefix command.
499
     Print its documentation, then list its subcommands.
500
 
501
     If c->function is nonzero, we really have a command.
502
     Print its documentation and return.
503
 
504
     If c->function is zero, we have a class name.
505
     Print its documentation (as if it were a command)
506
     and then set class to the number of this class
507
     so that the commands in the class will be listed.  */
508
 
509
  fputs_filtered (c->doc, stream);
510
  fputs_filtered ("\n", stream);
511
 
512
  if (c->prefixlist == 0 && c->function.cfunc != NULL)
513
    return;
514
  fprintf_filtered (stream, "\n");
515
 
516
  /* If this is a prefix command, print it's subcommands */
517
  if (c->prefixlist)
518
    help_list (*c->prefixlist, c->prefixname, all_commands, stream);
519
 
520
  /* If this is a class name, print all of the commands in the class */
521
  if (c->function.cfunc == NULL)
522
    help_list (cmdlist, "", c->class, stream);
523
 
524
  if (c->hook_pre || c->hook_post)
525
    fprintf_filtered (stream,
526
                      "\nThis command has a hook (or hooks) defined:\n");
527
 
528
  if (c->hook_pre)
529
    fprintf_filtered (stream,
530
                      "\tThis command is run after  : %s (pre hook)\n",
531
                    c->hook_pre->name);
532
  if (c->hook_post)
533
    fprintf_filtered (stream,
534
                      "\tThis command is run before : %s (post hook)\n",
535
                    c->hook_post->name);
536
}
537
 
538
/*
539
 * Get a specific kind of help on a command list.
540
 *
541
 * LIST is the list.
542
 * CMDTYPE is the prefix to use in the title string.
543
 * CLASS is the class with which to list the nodes of this list (see
544
 * documentation for help_cmd_list below),  As usual, ALL_COMMANDS for
545
 * everything, ALL_CLASSES for just classes, and non-negative for only things
546
 * in a specific class.
547
 * and STREAM is the output stream on which to print things.
548
 * If you call this routine with a class >= 0, it recurses.
549
 */
550
void
551
help_list (struct cmd_list_element *list, char *cmdtype,
552
           enum command_class class, struct ui_file *stream)
553
{
554
  int len;
555
  char *cmdtype1, *cmdtype2;
556
 
557
  /* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub"  */
558
  len = strlen (cmdtype);
559
  cmdtype1 = (char *) alloca (len + 1);
560
  cmdtype1[0] = 0;
561
  cmdtype2 = (char *) alloca (len + 4);
562
  cmdtype2[0] = 0;
563
  if (len)
564
    {
565
      cmdtype1[0] = ' ';
566
      strncpy (cmdtype1 + 1, cmdtype, len - 1);
567
      cmdtype1[len] = 0;
568
      strncpy (cmdtype2, cmdtype, len - 1);
569
      strcpy (cmdtype2 + len - 1, " sub");
570
    }
571
 
572
  if (class == all_classes)
573
    fprintf_filtered (stream, "List of classes of %scommands:\n\n", cmdtype2);
574
  else
575
    fprintf_filtered (stream, "List of %scommands:\n\n", cmdtype2);
576
 
577
  help_cmd_list (list, class, cmdtype, (int) class >= 0, stream);
578
 
579
  if (class == all_classes)
580
    fprintf_filtered (stream, "\n\
581
Type \"help%s\" followed by a class name for a list of commands in that class.",
582
                      cmdtype1);
583
 
584
  fprintf_filtered (stream, "\n\
585
Type \"help%s\" followed by %scommand name for full documentation.\n\
586
Command name abbreviations are allowed if unambiguous.\n",
587
                    cmdtype1, cmdtype2);
588
}
589
 
590
static void
591
help_all (struct ui_file *stream)
592
{
593
  struct cmd_list_element *c;
594
  extern struct cmd_list_element *cmdlist;
595
 
596
  for (c = cmdlist; c; c = c->next)
597
    {
598
      if (c->abbrev_flag)
599
        continue;
600
      /* If this is a prefix command, print it's subcommands */
601
      if (c->prefixlist)
602
        help_cmd_list (*c->prefixlist, all_commands, c->prefixname, 0, stream);
603
 
604
      /* If this is a class name, print all of the commands in the class */
605
      else if (c->function.cfunc == NULL)
606
        help_cmd_list (cmdlist, c->class, "", 0, stream);
607
    }
608
}
609
 
610
/* Print only the first line of STR on STREAM.  */
611
void
612
print_doc_line (struct ui_file *stream, char *str)
613
{
614
  static char *line_buffer = 0;
615
  static int line_size;
616
  register char *p;
617
 
618
  if (!line_buffer)
619
    {
620
      line_size = 80;
621
      line_buffer = (char *) xmalloc (line_size);
622
    }
623
 
624
  p = str;
625
  while (*p && *p != '\n' && *p != '.' && *p != ',')
626
    p++;
627
  if (p - str > line_size - 1)
628
    {
629
      line_size = p - str + 1;
630
      xfree (line_buffer);
631
      line_buffer = (char *) xmalloc (line_size);
632
    }
633
  strncpy (line_buffer, str, p - str);
634
  line_buffer[p - str] = '\0';
635
  if (islower (line_buffer[0]))
636
    line_buffer[0] = toupper (line_buffer[0]);
637
#ifdef UI_OUT
638
  ui_out_text (uiout, line_buffer);
639
#else
640
  fputs_filtered (line_buffer, stream);
641
#endif
642
}
643
 
644
/*
645
 * Implement a help command on command list LIST.
646
 * RECURSE should be non-zero if this should be done recursively on
647
 * all sublists of LIST.
648
 * PREFIX is the prefix to print before each command name.
649
 * STREAM is the stream upon which the output should be written.
650
 * CLASS should be:
651
 *      A non-negative class number to list only commands in that
652
 * class.
653
 *      ALL_COMMANDS to list all commands in list.
654
 *      ALL_CLASSES  to list all classes in list.
655
 *
656
 *   Note that RECURSE will be active on *all* sublists, not just the
657
 * ones selected by the criteria above (ie. the selection mechanism
658
 * is at the low level, not the high-level).
659
 */
660
void
661
help_cmd_list (struct cmd_list_element *list, enum command_class class,
662
               char *prefix, int recurse, struct ui_file *stream)
663
{
664
  register struct cmd_list_element *c;
665
 
666
  for (c = list; c; c = c->next)
667
    {
668
      if (c->abbrev_flag == 0 &&
669
          (class == all_commands
670
           || (class == all_classes && c->function.cfunc == NULL)
671
           || (class == c->class && c->function.cfunc != NULL)))
672
        {
673
          fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
674
          print_doc_line (stream, c->doc);
675
          fputs_filtered ("\n", stream);
676
        }
677
      if (recurse
678
          && c->prefixlist != 0
679
          && c->abbrev_flag == 0)
680
        help_cmd_list (*c->prefixlist, class, c->prefixname, 1, stream);
681
    }
682
}
683
 
684
 
685
/* Search the input clist for 'command'.  Return the command if
686
   found (or NULL if not), and return the number of commands
687
   found in nfound */
688
 
689
static struct cmd_list_element *
690
find_cmd (char *command, int len, struct cmd_list_element *clist,
691
          int ignore_help_classes, int *nfound)
692
{
693
  struct cmd_list_element *found, *c;
694
 
695
  found = (struct cmd_list_element *) NULL;
696
  *nfound = 0;
697
  for (c = clist; c; c = c->next)
698
    if (!strncmp (command, c->name, len)
699
        && (!ignore_help_classes || c->function.cfunc))
700
      {
701
        found = c;
702
        (*nfound)++;
703
        if (c->name[len] == '\0')
704
          {
705
            *nfound = 1;
706
            break;
707
          }
708
      }
709
  return found;
710
}
711
 
712
/* This routine takes a line of TEXT and a CLIST in which to start the
713
   lookup.  When it returns it will have incremented the text pointer past
714
   the section of text it matched, set *RESULT_LIST to point to the list in
715
   which the last word was matched, and will return a pointer to the cmd
716
   list element which the text matches.  It will return NULL if no match at
717
   all was possible.  It will return -1 (cast appropriately, ick) if ambigous
718
   matches are possible; in this case *RESULT_LIST will be set to point to
719
   the list in which there are ambiguous choices (and *TEXT will be set to
720
   the ambiguous text string).
721
 
722
   If the located command was an abbreviation, this routine returns the base
723
   command of the abbreviation.
724
 
725
   It does no error reporting whatsoever; control will always return
726
   to the superior routine.
727
 
728
   In the case of an ambiguous return (-1), *RESULT_LIST will be set to point
729
   at the prefix_command (ie. the best match) *or* (special case) will be NULL
730
   if no prefix command was ever found.  For example, in the case of "info a",
731
   "info" matches without ambiguity, but "a" could be "args" or "address", so
732
   *RESULT_LIST is set to the cmd_list_element for "info".  So in this case
733
   RESULT_LIST should not be interpeted as a pointer to the beginning of a
734
   list; it simply points to a specific command.  In the case of an ambiguous
735
   return *TEXT is advanced past the last non-ambiguous prefix (e.g.
736
   "info t" can be "info types" or "info target"; upon return *TEXT has been
737
   advanced past "info ").
738
 
739
   If RESULT_LIST is NULL, don't set *RESULT_LIST (but don't otherwise
740
   affect the operation).
741
 
742
   This routine does *not* modify the text pointed to by TEXT.
743
 
744
   If IGNORE_HELP_CLASSES is nonzero, ignore any command list elements which
745
   are actually help classes rather than commands (i.e. the function field of
746
   the struct cmd_list_element is NULL).  */
747
 
748
struct cmd_list_element *
749
lookup_cmd_1 (char **text, struct cmd_list_element *clist,
750
              struct cmd_list_element **result_list, int ignore_help_classes)
751
{
752
  char *p, *command;
753
  int len, tmp, nfound;
754
  struct cmd_list_element *found, *c;
755
  char *line = *text;
756
 
757
  while (**text == ' ' || **text == '\t')
758
    (*text)++;
759
 
760
  /* Treating underscores as part of command words is important
761
     so that "set args_foo()" doesn't get interpreted as
762
     "set args _foo()".  */
763
  for (p = *text;
764
       *p && (isalnum (*p) || *p == '-' || *p == '_' ||
765
              (tui_version &&
766
               (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
767
              (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
768
       p++)
769
    ;
770
 
771
  /* If nothing but whitespace, return 0.  */
772
  if (p == *text)
773
    return 0;
774
 
775
  len = p - *text;
776
 
777
  /* *text and p now bracket the first command word to lookup (and
778
     it's length is len).  We copy this into a local temporary */
779
 
780
 
781
  command = (char *) alloca (len + 1);
782
  for (tmp = 0; tmp < len; tmp++)
783
    {
784
      char x = (*text)[tmp];
785
      command[tmp] = x;
786
    }
787
  command[len] = '\0';
788
 
789
  /* Look it up.  */
790
  found = 0;
791
  nfound = 0;
792
  found = find_cmd (command, len, clist, ignore_help_classes, &nfound);
793
 
794
  /*
795
     ** We didn't find the command in the entered case, so lower case it
796
     ** and search again.
797
   */
798
  if (!found || nfound == 0)
799
    {
800
      for (tmp = 0; tmp < len; tmp++)
801
        {
802
          char x = command[tmp];
803
          command[tmp] = isupper (x) ? tolower (x) : x;
804
        }
805
      found = find_cmd (command, len, clist, ignore_help_classes, &nfound);
806
    }
807
 
808
  /* If nothing matches, we have a simple failure.  */
809
  if (nfound == 0)
810
    return 0;
811
 
812
  if (nfound > 1)
813
    {
814
      if (result_list != NULL)
815
        /* Will be modified in calling routine
816
           if we know what the prefix command is.  */
817
        *result_list = 0;
818
      return (struct cmd_list_element *) -1;    /* Ambiguous.  */
819
    }
820
 
821
  /* We've matched something on this list.  Move text pointer forward. */
822
 
823
  *text = p;
824
 
825
  if (found->cmd_pointer)
826
    {
827
      /* We drop the alias (abbreviation) in favor of the command it is
828
       pointing to.  If the alias is deprecated, though, we need to
829
       warn the user about it before we drop it.  Note that while we
830
       are warning about the alias, we may also warn about the command
831
       itself and we will adjust the appropriate DEPRECATED_WARN_USER
832
       flags */
833
 
834
      if (found->flags & DEPRECATED_WARN_USER)
835
      deprecated_cmd_warning (&line);
836
      found = found->cmd_pointer;
837
    }
838
  /* If we found a prefix command, keep looking.  */
839
 
840
  if (found->prefixlist)
841
    {
842
      c = lookup_cmd_1 (text, *found->prefixlist, result_list,
843
                        ignore_help_classes);
844
      if (!c)
845
        {
846
          /* Didn't find anything; this is as far as we got.  */
847
          if (result_list != NULL)
848
            *result_list = clist;
849
          return found;
850
        }
851
      else if (c == (struct cmd_list_element *) -1)
852
        {
853
          /* We've gotten this far properly, but the next step
854
             is ambiguous.  We need to set the result list to the best
855
             we've found (if an inferior hasn't already set it).  */
856
          if (result_list != NULL)
857
            if (!*result_list)
858
              /* This used to say *result_list = *found->prefixlist
859
                 If that was correct, need to modify the documentation
860
                 at the top of this function to clarify what is supposed
861
                 to be going on.  */
862
              *result_list = found;
863
          return c;
864
        }
865
      else
866
        {
867
          /* We matched!  */
868
          return c;
869
        }
870
    }
871
  else
872
    {
873
      if (result_list != NULL)
874
        *result_list = clist;
875
      return found;
876
    }
877
}
878
 
879
/* All this hair to move the space to the front of cmdtype */
880
 
881
static void
882
undef_cmd_error (char *cmdtype, char *q)
883
{
884
  error ("Undefined %scommand: \"%s\".  Try \"help%s%.*s\".",
885
         cmdtype,
886
         q,
887
         *cmdtype ? " " : "",
888
         strlen (cmdtype) - 1,
889
         cmdtype);
890
}
891
 
892
/* Look up the contents of *LINE as a command in the command list LIST.
893
   LIST is a chain of struct cmd_list_element's.
894
   If it is found, return the struct cmd_list_element for that command
895
   and update *LINE to point after the command name, at the first argument.
896
   If not found, call error if ALLOW_UNKNOWN is zero
897
   otherwise (or if error returns) return zero.
898
   Call error if specified command is ambiguous,
899
   unless ALLOW_UNKNOWN is negative.
900
   CMDTYPE precedes the word "command" in the error message.
901
 
902
   If INGNORE_HELP_CLASSES is nonzero, ignore any command list
903
   elements which are actually help classes rather than commands (i.e.
904
   the function field of the struct cmd_list_element is 0).  */
905
 
906
struct cmd_list_element *
907
lookup_cmd (char **line, struct cmd_list_element *list, char *cmdtype,
908
            int allow_unknown, int ignore_help_classes)
909
{
910
  struct cmd_list_element *last_list = 0;
911
  struct cmd_list_element *c =
912
  lookup_cmd_1 (line, list, &last_list, ignore_help_classes);
913
 
914
  /* Note: Do not remove trailing whitespace here because this
915
     would be wrong for complete_command.  Jim Kingdon  */
916
 
917
  if (!c)
918
    {
919
      if (!allow_unknown)
920
        {
921
          if (!*line)
922
            error ("Lack of needed %scommand", cmdtype);
923
          else
924
            {
925
              char *p = *line, *q;
926
 
927
              while (isalnum (*p) || *p == '-')
928
                p++;
929
 
930
              q = (char *) alloca (p - *line + 1);
931
              strncpy (q, *line, p - *line);
932
              q[p - *line] = '\0';
933
              undef_cmd_error (cmdtype, q);
934
            }
935
        }
936
      else
937
        return 0;
938
    }
939
  else if (c == (struct cmd_list_element *) -1)
940
    {
941
      /* Ambigous.  Local values should be off prefixlist or called
942
         values.  */
943
      int local_allow_unknown = (last_list ? last_list->allow_unknown :
944
                                 allow_unknown);
945
      char *local_cmdtype = last_list ? last_list->prefixname : cmdtype;
946
      struct cmd_list_element *local_list =
947
      (last_list ? *(last_list->prefixlist) : list);
948
 
949
      if (local_allow_unknown < 0)
950
        {
951
          if (last_list)
952
            return last_list;   /* Found something.  */
953
          else
954
            return 0;            /* Found nothing.  */
955
        }
956
      else
957
        {
958
          /* Report as error.  */
959
          int amb_len;
960
          char ambbuf[100];
961
 
962
          for (amb_len = 0;
963
               ((*line)[amb_len] && (*line)[amb_len] != ' '
964
                && (*line)[amb_len] != '\t');
965
               amb_len++)
966
            ;
967
 
968
          ambbuf[0] = 0;
969
          for (c = local_list; c; c = c->next)
970
            if (!strncmp (*line, c->name, amb_len))
971
              {
972
                if (strlen (ambbuf) + strlen (c->name) + 6 < (int) sizeof ambbuf)
973
                  {
974
                    if (strlen (ambbuf))
975
                      strcat (ambbuf, ", ");
976
                    strcat (ambbuf, c->name);
977
                  }
978
                else
979
                  {
980
                    strcat (ambbuf, "..");
981
                    break;
982
                  }
983
              }
984
          error ("Ambiguous %scommand \"%s\": %s.", local_cmdtype,
985
                 *line, ambbuf);
986
          return 0;              /* lint */
987
        }
988
    }
989
  else
990
    {
991
      /* We've got something.  It may still not be what the caller
992
         wants (if this command *needs* a subcommand).  */
993
      while (**line == ' ' || **line == '\t')
994
        (*line)++;
995
 
996
      if (c->prefixlist && **line && !c->allow_unknown)
997
        undef_cmd_error (c->prefixname, *line);
998
 
999
      /* Seems to be what he wants.  Return it.  */
1000
      return c;
1001
    }
1002
  return 0;
1003
}
1004
 
1005
/* We are here presumably because an alias or command in *TEXT is
1006
   deprecated and a warning message should be generated.  This function
1007
   decodes *TEXT and potentially generates a warning message as outlined
1008
   below.
1009
 
1010
   Example for 'set endian big' which has a fictitious alias 'seb'.
1011
 
1012
   If alias wasn't used in *TEXT, and the command is deprecated:
1013
   "warning: 'set endian big' is deprecated."
1014
 
1015
   If alias was used, and only the alias is deprecated:
1016
   "warning: 'seb' an alias for the command 'set endian big' is deprecated."
1017
 
1018
   If alias was used and command is deprecated (regardless of whether the
1019
   alias itself is deprecated:
1020
 
1021
   "warning: 'set endian big' (seb) is deprecated."
1022
 
1023
   After the message has been sent, clear the appropriate flags in the
1024
   command and/or the alias so the user is no longer bothered.
1025
 
1026
*/
1027
void
1028
deprecated_cmd_warning (char **text)
1029
{
1030
  struct cmd_list_element *alias = NULL;
1031
  struct cmd_list_element *prefix_cmd = NULL;
1032
  struct cmd_list_element *cmd = NULL;
1033
  struct cmd_list_element *c;
1034
  char *type;
1035
 
1036
  if (!lookup_cmd_composition (*text, &alias, &prefix_cmd, &cmd))
1037
    /* return if text doesn't evaluate to a command */
1038
    return;
1039
 
1040
  if (!((alias ? (alias->flags & DEPRECATED_WARN_USER) : 0)
1041
      || (cmd->flags & DEPRECATED_WARN_USER) ) )
1042
    /* return if nothing is deprecated */
1043
    return;
1044
 
1045
  printf_filtered ("Warning:");
1046
 
1047
  if (alias && !(cmd->flags & CMD_DEPRECATED))
1048
    printf_filtered (" '%s', an alias for the", alias->name);
1049
 
1050
  printf_filtered (" command '");
1051
 
1052
  if (prefix_cmd)
1053
    printf_filtered ("%s", prefix_cmd->prefixname);
1054
 
1055
  printf_filtered ("%s", cmd->name);
1056
 
1057
  if (alias && (cmd->flags & CMD_DEPRECATED))
1058
    printf_filtered ("' (%s) is deprecated.\n", alias->name);
1059
  else
1060
    printf_filtered ("' is deprecated.\n");
1061
 
1062
 
1063
  /* if it is only the alias that is deprecated, we want to indicate the
1064
     new alias, otherwise we'll indicate the new command */
1065
 
1066
  if (alias && !(cmd->flags & CMD_DEPRECATED))
1067
    {
1068
      if (alias->replacement)
1069
      printf_filtered ("Use '%s'.\n\n", alias->replacement);
1070
      else
1071
      printf_filtered ("No alternative known.\n\n");
1072
     }
1073
  else
1074
    {
1075
      if (cmd->replacement)
1076
      printf_filtered ("Use '%s'.\n\n", cmd->replacement);
1077
      else
1078
      printf_filtered ("No alternative known.\n\n");
1079
    }
1080
 
1081
  /* We've warned you, now we'll keep quiet */
1082
  if (alias)
1083
    alias->flags &= ~DEPRECATED_WARN_USER;
1084
 
1085
  cmd->flags &= ~DEPRECATED_WARN_USER;
1086
}
1087
 
1088
 
1089
 
1090
/* Look up the contents of LINE as a command in the command list 'cmdlist'.
1091
   Return 1 on success, 0 on failure.
1092
 
1093
   If LINE refers to an alias, *alias will point to that alias.
1094
 
1095
   If LINE is a postfix command (i.e. one that is preceeded by a prefix
1096
   command) set *prefix_cmd.
1097
 
1098
   Set *cmd to point to the command LINE indicates.
1099
 
1100
   If any of *alias, *prefix_cmd, or *cmd cannot be determined or do not
1101
   exist, they are NULL when we return.
1102
 
1103
*/
1104
int
1105
lookup_cmd_composition (char *text,
1106
                      struct cmd_list_element **alias,
1107
                      struct cmd_list_element **prefix_cmd,
1108
                      struct cmd_list_element **cmd)
1109
{
1110
  char *p, *command;
1111
  int len, tmp, nfound;
1112
  struct cmd_list_element *cur_list;
1113
  struct cmd_list_element *prev_cmd;
1114
  *alias = NULL;
1115
  *prefix_cmd = NULL;
1116
  *cmd = NULL;
1117
 
1118
  cur_list = cmdlist;
1119
 
1120
  while (1)
1121
    {
1122
      /* Go through as many command lists as we need to
1123
       to find the command TEXT refers to. */
1124
 
1125
      prev_cmd = *cmd;
1126
 
1127
      while (*text == ' ' || *text == '\t')
1128
      (text)++;
1129
 
1130
      /* Treating underscores as part of command words is important
1131
       so that "set args_foo()" doesn't get interpreted as
1132
       "set args _foo()".  */
1133
      for (p = text;
1134
         *p && (isalnum (*p) || *p == '-' || *p == '_' ||
1135
                (tui_version &&
1136
                 (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
1137
                (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
1138
         p++)
1139
      ;
1140
 
1141
      /* If nothing but whitespace, return.  */
1142
      if (p == text)
1143
      return 0;
1144
 
1145
      len = p - text;
1146
 
1147
      /* text and p now bracket the first command word to lookup (and
1148
       it's length is len).  We copy this into a local temporary */
1149
 
1150
      command = (char *) alloca (len + 1);
1151
      for (tmp = 0; tmp < len; tmp++)
1152
      {
1153
        char x = text[tmp];
1154
        command[tmp] = x;
1155
      }
1156
      command[len] = '\0';
1157
 
1158
      /* Look it up.  */
1159
      *cmd = 0;
1160
      nfound = 0;
1161
      *cmd = find_cmd (command, len, cur_list, 1, &nfound);
1162
 
1163
      /* We didn't find the command in the entered case, so lower case it
1164
       and search again.
1165
      */
1166
      if (!*cmd || nfound == 0)
1167
      {
1168
        for (tmp = 0; tmp < len; tmp++)
1169
          {
1170
            char x = command[tmp];
1171
            command[tmp] = isupper (x) ? tolower (x) : x;
1172
          }
1173
        *cmd = find_cmd (command, len, cur_list, 1, &nfound);
1174
      }
1175
 
1176
      if (*cmd == (struct cmd_list_element *) -1)
1177
      {
1178
        return 0;              /* ambiguous */
1179
      }
1180
 
1181
      if (*cmd == NULL)
1182
      return 0;                /* nothing found */
1183
      else
1184
      {
1185
        if ((*cmd)->cmd_pointer)
1186
          {
1187
            /* cmd was actually an alias, we note that an alias was used
1188
               (by assigning *alais) and we set *cmd.
1189
             */
1190
            *alias = *cmd;
1191
            *cmd = (*cmd)->cmd_pointer;
1192
          }
1193
        *prefix_cmd = prev_cmd;
1194
      }
1195
      if ((*cmd)->prefixlist)
1196
      cur_list = *(*cmd)->prefixlist;
1197
      else
1198
      return 1;
1199
 
1200
      text = p;
1201
    }
1202
}
1203
 
1204
/* Helper function for SYMBOL_COMPLETION_FUNCTION.  */
1205
 
1206
/* Return a vector of char pointers which point to the different
1207
   possible completions in LIST of TEXT.
1208
 
1209
   WORD points in the same buffer as TEXT, and completions should be
1210
   returned relative to this position.  For example, suppose TEXT is "foo"
1211
   and we want to complete to "foobar".  If WORD is "oo", return
1212
   "oobar"; if WORD is "baz/foo", return "baz/foobar".  */
1213
 
1214
char **
1215
complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
1216
{
1217
  struct cmd_list_element *ptr;
1218
  char **matchlist;
1219
  int sizeof_matchlist;
1220
  int matches;
1221
  int textlen = strlen (text);
1222
 
1223
  sizeof_matchlist = 10;
1224
  matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
1225
  matches = 0;
1226
 
1227
  for (ptr = list; ptr; ptr = ptr->next)
1228
    if (!strncmp (ptr->name, text, textlen)
1229
        && !ptr->abbrev_flag
1230
        && (ptr->function.cfunc
1231
            || ptr->prefixlist))
1232
      {
1233
        if (matches == sizeof_matchlist)
1234
          {
1235
            sizeof_matchlist *= 2;
1236
            matchlist = (char **) xrealloc ((char *) matchlist,
1237
                                            (sizeof_matchlist
1238
                                             * sizeof (char *)));
1239
          }
1240
 
1241
        matchlist[matches] = (char *)
1242
          xmalloc (strlen (word) + strlen (ptr->name) + 1);
1243
        if (word == text)
1244
          strcpy (matchlist[matches], ptr->name);
1245
        else if (word > text)
1246
          {
1247
            /* Return some portion of ptr->name.  */
1248
            strcpy (matchlist[matches], ptr->name + (word - text));
1249
          }
1250
        else
1251
          {
1252
            /* Return some of text plus ptr->name.  */
1253
            strncpy (matchlist[matches], word, text - word);
1254
            matchlist[matches][text - word] = '\0';
1255
            strcat (matchlist[matches], ptr->name);
1256
          }
1257
        ++matches;
1258
      }
1259
 
1260
  if (matches == 0)
1261
    {
1262
      xfree (matchlist);
1263
      matchlist = 0;
1264
    }
1265
  else
1266
    {
1267
      matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
1268
                                                        * sizeof (char *)));
1269
      matchlist[matches] = (char *) 0;
1270
    }
1271
 
1272
  return matchlist;
1273
}
1274
 
1275
/* Helper function for SYMBOL_COMPLETION_FUNCTION.  */
1276
 
1277
/* Return a vector of char pointers which point to the different
1278
   possible completions in CMD of TEXT.
1279
 
1280
   WORD points in the same buffer as TEXT, and completions should be
1281
   returned relative to this position.  For example, suppose TEXT is "foo"
1282
   and we want to complete to "foobar".  If WORD is "oo", return
1283
   "oobar"; if WORD is "baz/foo", return "baz/foobar".  */
1284
 
1285
char **
1286
complete_on_enum (const char *enumlist[],
1287
                  char *text,
1288
                  char *word)
1289
{
1290
  char **matchlist;
1291
  int sizeof_matchlist;
1292
  int matches;
1293
  int textlen = strlen (text);
1294
  int i;
1295
  const char *name;
1296
 
1297
  sizeof_matchlist = 10;
1298
  matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
1299
  matches = 0;
1300
 
1301
  for (i = 0; (name = enumlist[i]) != NULL; i++)
1302
    if (strncmp (name, text, textlen) == 0)
1303
      {
1304
        if (matches == sizeof_matchlist)
1305
          {
1306
            sizeof_matchlist *= 2;
1307
            matchlist = (char **) xrealloc ((char *) matchlist,
1308
                                            (sizeof_matchlist
1309
                                             * sizeof (char *)));
1310
          }
1311
 
1312
        matchlist[matches] = (char *)
1313
          xmalloc (strlen (word) + strlen (name) + 1);
1314
        if (word == text)
1315
          strcpy (matchlist[matches], name);
1316
        else if (word > text)
1317
          {
1318
            /* Return some portion of name.  */
1319
            strcpy (matchlist[matches], name + (word - text));
1320
          }
1321
        else
1322
          {
1323
            /* Return some of text plus name.  */
1324
            strncpy (matchlist[matches], word, text - word);
1325
            matchlist[matches][text - word] = '\0';
1326
            strcat (matchlist[matches], name);
1327
          }
1328
        ++matches;
1329
      }
1330
 
1331
  if (matches == 0)
1332
    {
1333
      xfree (matchlist);
1334
      matchlist = 0;
1335
    }
1336
  else
1337
    {
1338
      matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
1339
                                                        * sizeof (char *)));
1340
      matchlist[matches] = (char *) 0;
1341
    }
1342
 
1343
  return matchlist;
1344
}
1345
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.