Annotation of 43BSDReno/contrib/emacs-18.55/gdb/command.c, revision 1.1.1.1

1.1       root        1: /* Library for reading command lines and decoding commands.
                      2:    Copyright (C) 1986 Free Software Foundation, Inc.
                      3: 
                      4:                       NO WARRANTY
                      5: 
                      6:   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
                      7: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
                      8: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
                      9: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
                     10: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
                     11: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
                     12: FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
                     13: AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
                     14: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
                     15: CORRECTION.
                     16: 
                     17:  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
                     18: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
                     19: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
                     20: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
                     21: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
                     22: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
                     23: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
                     24: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
                     25: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
                     26: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
                     27: 
                     28:                GENERAL PUBLIC LICENSE TO COPY
                     29: 
                     30:   1. You may copy and distribute verbatim copies of this source file
                     31: as you receive it, in any medium, provided that you conspicuously and
                     32: appropriately publish on each copy a valid copyright notice "Copyright
                     33: (C) 1986 Free Software Foundation, Inc."; and include following the
                     34: copyright notice a verbatim copy of the above disclaimer of warranty
                     35: and of this License.  You may charge a distribution fee for the
                     36: physical act of transferring a copy.
                     37: 
                     38:   2. You may modify your copy or copies of this source file or
                     39: any portion of it, and copy and distribute such modifications under
                     40: the terms of Paragraph 1 above, provided that you also do the following:
                     41: 
                     42:     a) cause the modified files to carry prominent notices stating
                     43:     that you changed the files and the date of any change; and
                     44: 
                     45:     b) cause the whole of any work that you distribute or publish,
                     46:     that in whole or in part contains or is a derivative of this
                     47:     program or any part thereof, to be licensed at no charge to all
                     48:     third parties on terms identical to those contained in this
                     49:     License Agreement (except that you may choose to grant more extensive
                     50:     warranty protection to some or all third parties, at your option).
                     51: 
                     52:     c) You may charge a distribution fee for the physical act of
                     53:     transferring a copy, and you may at your option offer warranty
                     54:     protection in exchange for a fee.
                     55: 
                     56: Mere aggregation of another unrelated program with this program (or its
                     57: derivative) on a volume of a storage or distribution medium does not bring
                     58: the other program under the scope of these terms.
                     59: 
                     60:   3. You may copy and distribute this program (or a portion or derivative
                     61: of it, under Paragraph 2) in object code or executable form under the terms
                     62: of Paragraphs 1 and 2 above provided that you also do one of the following:
                     63: 
                     64:     a) accompany it with the complete corresponding machine-readable
                     65:     source code, which must be distributed under the terms of
                     66:     Paragraphs 1 and 2 above; or,
                     67: 
                     68:     b) accompany it with a written offer, valid for at least three
                     69:     years, to give any third party free (except for a nominal
                     70:     shipping charge) a complete machine-readable copy of the
                     71:     corresponding source code, to be distributed under the terms of
                     72:     Paragraphs 1 and 2 above; or,
                     73: 
                     74:     c) accompany it with the information you received as to where the
                     75:     corresponding source code may be obtained.  (This alternative is
                     76:     allowed only for noncommercial distribution and only if you
                     77:     received the program in object code or executable form alone.)
                     78: 
                     79: For an executable file, complete source code means all the source code for
                     80: all modules it contains; but, as a special exception, it need not include
                     81: source code for modules which are standard libraries that accompany the
                     82: operating system on which the executable file runs.
                     83: 
                     84:   4. You may not copy, sublicense, distribute or transfer this program
                     85: except as expressly provided under this License Agreement.  Any attempt
                     86: otherwise to copy, sublicense, distribute or transfer this program is void and
                     87: your rights to use the program under this License agreement shall be
                     88: automatically terminated.  However, parties who have received computer
                     89: software programs from you with this License Agreement will not have
                     90: their licenses terminated so long as such parties remain in full compliance.
                     91: 
                     92:   5. If you wish to incorporate parts of this program into other free
                     93: programs whose distribution conditions are different, write to the Free
                     94: Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
                     95: worked out a simple rule that can be stated here, but we will often permit
                     96: this.  We will be guided by the two goals of preserving the free status of
                     97: all derivatives of our free software and of promoting the sharing and reuse of
                     98: software.
                     99: 
                    100: 
                    101: In other words, you are welcome to use, share and improve this program.
                    102: You are forbidden to forbid anyone else to use, share and improve
                    103: what you give them.   Help stamp out software-hoarding!  */
                    104: 
                    105: 
                    106: #include "command.h"
                    107: #include <stdio.h>
                    108: 
                    109: extern char *xmalloc ();
                    110: 
                    111: static char *savestring ();
                    112: 
                    113: /* Add element named NAME to command list *LIST.
                    114:    FUN should be the function to execute the command;
                    115:    it will get a character string as argument, with leading
                    116:    and trailing blanks already eliminated.
                    117: 
                    118:    DOC is a documentation string for the command.
                    119:    Its first line should be a complete sentence.
                    120:    It should start with ? for a command that is an abbreviation
                    121:    or with * for a command that most users don't need to know about.  */
                    122: 
                    123: struct cmd_list_element *
                    124: add_cmd (name, class, fun, doc, list)
                    125:      char *name;
                    126:      int class;
                    127:      void (*fun) ();
                    128:      char *doc;
                    129:      struct cmd_list_element **list;
                    130: {
                    131:   register struct cmd_list_element *c
                    132:     = (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
                    133: 
                    134:   delete_cmd (name, list);
                    135:   c->next = *list;
                    136:   c->name = savestring (name, strlen (name));
                    137:   c->class = class;
                    138:   c->function = fun;
                    139:   c->doc = doc;
                    140:   c->prefixlist = 0;
                    141:   c->allow_unknown = 0;
                    142:   c->abbrev_flag = 0;
                    143:   c->aux = 0;
                    144:   *list = c;
                    145:   return c;
                    146: }
                    147: 
                    148: struct cmd_list_element *
                    149: add_alias_cmd (name, oldname, class, abbrev_flag, list)
                    150:      char *name;
                    151:      char *oldname;
                    152:      int class;
                    153:      int abbrev_flag;
                    154:      struct cmd_list_element **list;
                    155: {
                    156:   /* Must do this since lookup_cmd tries to side-effect its first arg */
                    157:   char *copied_name;
                    158:   register struct cmd_list_element *old;
                    159:   register struct cmd_list_element *c;
                    160:   copied_name = (char *) alloca (strlen (oldname) + 1);
                    161:   strcpy (copied_name, oldname);
                    162:   old  = lookup_cmd (&copied_name, *list, 0, 1);
                    163: 
                    164:   if (old == 0)
                    165:     {
                    166:       delete_cmd (name, list);
                    167:       return 0;
                    168:     }
                    169: 
                    170:   c = add_cmd (name, class, old->function, old->doc, list);
                    171:   c->prefixlist = old->prefixlist;
                    172:   c->prefixname = old->prefixname;
                    173:   c->allow_unknown = old->allow_unknown;
                    174:   c->abbrev_flag = abbrev_flag;
                    175:   c->aux = old->aux;
                    176:   return c;
                    177: }
                    178: 
                    179: /* Like add_prefix_cmd but adds an element for a command prefix:
                    180:    a name that should be followed by a subcommand to be looked up
                    181:    in another command list.  PREFIXLIST should be the address
                    182:    of the variable containing that list.  */
                    183: 
                    184: struct cmd_list_element *
                    185: add_prefix_cmd (name, class, fun, doc, prefixlist, prefixname,
                    186:                allow_unknown, list)
                    187:      char *name;
                    188:      int class;
                    189:      void (*fun) ();
                    190:      char *doc;
                    191:      struct cmd_list_element **prefixlist;
                    192:      char *prefixname;
                    193:      int allow_unknown;
                    194:      struct cmd_list_element **list;
                    195: {
                    196:   register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
                    197:   c->prefixlist = prefixlist;
                    198:   c->prefixname = prefixname;
                    199:   c->allow_unknown = allow_unknown;
                    200:   return c;
                    201: }
                    202: 
                    203: /* Remove the command named NAME from the command list.  */
                    204: 
                    205: void
                    206: delete_cmd (name, list)
                    207:      char *name;
                    208:      struct cmd_list_element **list;
                    209: {
                    210:   register struct cmd_list_element *c;
                    211: 
                    212:   while (*list && !strcmp ((*list)->name, name))
                    213:     {
                    214:       *list = (*list)->next;
                    215:     }
                    216: 
                    217:   if (*list)
                    218:     for (c = *list; c->next;)
                    219:       {
                    220:        if (!strcmp (c->next->name, name))
                    221:          c->next = c->next->next;
                    222:        else
                    223:          c = c->next;
                    224:       }
                    225: }
                    226: 
                    227: /* Implement a help command on command list LIST.
                    228:    COMMAND is the argument given (a command from the list to document)
                    229:    or zero for no arg (describe briefly all the commands in the list).
                    230:    CMDTYPE is a string to use in the error message if command COMMAND
                    231:    is not found in the list.  */
                    232: 
                    233: /* CLASS should be -1 to list all commands in LIST,
                    234:    or a nonnegative class number value to list just commands in that class,
                    235:    or -2 to list the classes themselves.  */
                    236: 
                    237: void
                    238: help_cmd (command, list, cmdtype, class, stream)
                    239:      char *command;
                    240:      struct cmd_list_element *list;
                    241:      char *cmdtype;
                    242:      int class;
                    243:      FILE *stream;
                    244: {
                    245:   register struct cmd_list_element *c;
                    246:   register char *p;
                    247:   register int ncmds;
                    248:   struct cmdvec { struct cmd_list_element *cmd; int class; };
                    249:   register struct cmdvec *cmdvec;
                    250:   char *cmdtype1, *cmdtype2;
                    251:   int len;
                    252: 
                    253:   if (command)
                    254:     {
                    255:       c = lookup_cmd (&command, list, cmdtype, 0);
                    256:       if (c == 0)
                    257:        return;
                    258: 
                    259:       /* There are three cases here.
                    260:         If c->prefixlist is nonzer, we have a prefix command.
                    261:         Print its documentation, then list its subcommands.
                    262: 
                    263:         If c->function is nonzero, we really have a command.
                    264:         Print its documentation and return.
                    265: 
                    266:         If c->function is zero, we have a class name.
                    267:         Print its documentation (as if it were a command)
                    268:         and then set class to he number of this class
                    269:         so that the commands in the class will be listed.  */
                    270: 
                    271:       p = c->doc;
                    272:       fprintf (stream, "%s\n", p);
                    273:       if (c->function != 0 && c->prefixlist == 0)
                    274:        return;
                    275:       fputc ('\n', stream);
                    276:       if (c->prefixlist)
                    277:        {
                    278:          list = *c->prefixlist;
                    279:          class = 0;
                    280:          cmdtype = c->prefixname;
                    281:        }
                    282:       else
                    283:        class = c->class;
                    284:     }
                    285: 
                    286:   /* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub"  */
                    287:   len = strlen (cmdtype);
                    288:   cmdtype1 = (char *) alloca (len + 1);
                    289:   cmdtype1[0] = 0;
                    290:   cmdtype2 = (char *) alloca (len + 4);
                    291:   cmdtype2[0] = 0;
                    292:   if (len)
                    293:     {
                    294:       cmdtype1[0] = ' ';
                    295:       strncpy (cmdtype1 + 1, cmdtype, len - 1);
                    296:       cmdtype1[len] = 0;
                    297:       strncpy (cmdtype2, cmdtype, len - 1);
                    298:       strcpy (cmdtype2 + len - 1, " sub");
                    299:     }
                    300: 
                    301:   if (class == -2)
                    302:     fprintf (stream, "List of classes of %scommands:\n\n", cmdtype2);
                    303:   else
                    304:     fprintf (stream, "List of %scommands:\n\n", cmdtype2);
                    305: 
                    306:   for (c = list; c; c = c->next)
                    307:     {
                    308:       if (c->abbrev_flag == 0
                    309:          && (class == -1       /* Listing all */
                    310:              || (c->class == class && c->function != 0) /* Listing one class */
                    311:              || (class == -2 && c->function == 0)))    /* Listing the classes */
                    312:        {
                    313:          fprintf (stream, "%s -- ", c->name);
                    314:          /* Print just first line of documentation.  */
                    315:          p = c->doc;
                    316:          while (*p && *p != '\n') p++;
                    317:          fwrite (c->doc, 1, p - c->doc, stream);
                    318:          fputc ('\n', stream);
                    319:        }
                    320:     }
                    321: 
                    322:   if (class == -2)
                    323:     fprintf (stream, "\n\
                    324: Type \"help%s\" followed by a class name for a list of commands in that class.",
                    325:             cmdtype1);
                    326: 
                    327:   fprintf (stream, "\n\
                    328: Type \"help%s\" followed by %scommand name for full documentation.\n\
                    329: Command name abbreviations are allowed if unambiguous.\n",
                    330:           cmdtype1, cmdtype2);
                    331: }
                    332: 
                    333: /* Look up the contents of *LINE as a command in the command list LIST.
                    334:    LIST is a chain of struct cmd_list_element's.
                    335:    If it is found, return the struct cmd_list_element for that command
                    336:    and update *LINE to point after the command name, at the first argument.
                    337:    If not found, call error if ALLOW_UNKNOWN is zero
                    338:    otherwise (or if error returns) return zero.
                    339:    Call error if specified command is ambiguous,
                    340:    unless ALLOW_UNKNOWN is negative.
                    341:    CMDTYPE precedes the word "command" in the error message.  */
                    342: 
                    343: struct cmd_list_element *
                    344: lookup_cmd (line, list, cmdtype, allow_unknown)
                    345:      char **line;
                    346:      struct cmd_list_element *list;
                    347:      char *cmdtype;
                    348:      int allow_unknown;
                    349: {
                    350:   register char *p;
                    351:   register struct cmd_list_element *c, *found;
                    352:   int nfound;
                    353:   char ambbuf[100];
                    354: 
                    355:   /* Skip leading whitespace.  */
                    356: 
                    357:   while (**line == ' ' || **line == '\t')
                    358:     (*line)++;
                    359: 
                    360:   /* Clear out trailing whitespace.  */
                    361: 
                    362:   p = *line + strlen (*line);
                    363:   while (p != *line && (p[-1] == ' ' || p[-1] == '\t'))
                    364:     p--;
                    365:   *p = 0;
                    366: 
                    367:   /* Find end of command name.  */
                    368: 
                    369:   p = *line;
                    370:   while (*p == '-'
                    371:         || (*p >= 'a' && *p <= 'z')
                    372:         || (*p >= 'A' && *p <= 'Z')
                    373:         || (*p >= '0' && *p <= '9'))
                    374:     {
                    375:       if (*p >= 'A' && *p <= 'Z')
                    376:        *p += 'a' - 'A';
                    377:       p++;
                    378:     }
                    379: 
                    380:   /* Look up the command name.
                    381:      If exact match, keep that.
                    382:      Otherwise, take command abbreviated, if unique.  */
                    383: 
                    384:   found = 0;
                    385:   nfound = 0;
                    386:   for (c = list; c; c = c->next)
                    387:     {
                    388:       if (!strncmp (*line, c->name, p - *line))
                    389:        {
                    390:          found = c;
                    391:          nfound++;
                    392:          if (c->name[p - *line] == 0)
                    393:            {
                    394:              nfound = 1;
                    395:              break;
                    396:            }
                    397:        }
                    398:     }
                    399: 
                    400:   /* Report error for undefined command name.  */
                    401: 
                    402:   if (nfound != 1)
                    403:     {
                    404:       if (nfound > 1 && allow_unknown >= 0)
                    405:        {
                    406:          *p = 0;
                    407:          ambbuf[0] = 0;
                    408:          for (c = list; c; c = c->next)
                    409:            if (!strncmp (*line, c->name, p - *line))
                    410:              {
                    411:                if (strlen (ambbuf) + strlen (c->name) + 6 < sizeof ambbuf)
                    412:                  {
                    413:                    if (strlen (ambbuf))
                    414:                      strcat (ambbuf, ", ");
                    415:                    strcat (ambbuf, c->name);
                    416:                  }
                    417:                else
                    418:                  {
                    419:                    strcat (ambbuf, "..");
                    420:                    break;
                    421:                  }
                    422:              }
                    423:          error ("Ambiguous %scommand \"%s\": %s.", cmdtype, *line, ambbuf);
                    424:        }
                    425:       else if (!allow_unknown)
                    426:        {
                    427:          *p = 0;
                    428:          error ("Undefined %scommand: \"%s\".", cmdtype, *line);
                    429:        }
                    430:       return 0;
                    431:     }
                    432: 
                    433:   /* Skip whitespace before the argument.  */
                    434: 
                    435:   while (*p == ' ' || *p == '\t') p++;
                    436:   *line = p;
                    437: 
                    438:   if (found->prefixlist && *p)
                    439:     {
                    440:       c = lookup_cmd (line, *found->prefixlist, found->prefixname,
                    441:                      found->allow_unknown);
                    442:       if (c)
                    443:        return c;
                    444:     }
                    445: 
                    446:   return found;
                    447: }
                    448: 
                    449: /* Make a copy of the string at PTR with SIZE characters
                    450:    (and add a null character at the end in the copy).
                    451:    Uses malloc to get the space.  Returns the address of the copy.  */
                    452: 
                    453: static char *
                    454: savestring (ptr, size)
                    455:      char *ptr;
                    456:      int size;
                    457: {
                    458:   register char *p = (char *) xmalloc (size + 1);
                    459:   bcopy (ptr, p, size);
                    460:   p[size] = 0;
                    461:   return p;
                    462: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.