ec5bfc08761092216da459fc2a40e50dea842f73
1 /* Library for reading command lines and decoding commands.
2 Copyright (C) 1986 Free Software Foundation, Inc.
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
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.
28 GENERAL PUBLIC LICENSE TO COPY
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.
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:
42 a) cause the modified files to carry prominent notices stating
43 that you changed the files and the date of any change; and
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).
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.
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.
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:
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,
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,
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.)
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.
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.
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
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! */
109 extern char *xmalloc ();
111 static char *savestring ();
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.
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. */
123 struct cmd_list_element
*
124 add_cmd (name
, class, fun
, doc
, list
)
129 struct cmd_list_element
**list
;
131 register struct cmd_list_element
*c
132 = (struct cmd_list_element
*) xmalloc (sizeof (struct cmd_list_element
));
134 delete_cmd (name
, list
);
136 c
->name
= savestring (name
, strlen (name
));
141 c
->allow_unknown
= 0;
148 struct cmd_list_element
*
149 add_alias_cmd (name
, oldname
, class, abbrev_flag
, list
)
154 struct cmd_list_element
**list
;
156 /* Must do this since lookup_cmd tries to side-effect its first arg */
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);
166 delete_cmd (name
, list
);
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
;
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. */
184 struct cmd_list_element
*
185 add_prefix_cmd (name
, class, fun
, doc
, prefixlist
, prefixname
,
191 struct cmd_list_element
**prefixlist
;
194 struct cmd_list_element
**list
;
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
;
203 /* Remove the command named NAME from the command list. */
206 delete_cmd (name
, list
)
208 struct cmd_list_element
**list
;
210 register struct cmd_list_element
*c
;
212 while (*list
&& !strcmp ((*list
)->name
, name
))
214 *list
= (*list
)->next
;
218 for (c
= *list
; c
->next
;)
220 if (!strcmp (c
->next
->name
, name
))
221 c
->next
= c
->next
->next
;
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. */
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. */
238 help_cmd (command
, list
, cmdtype
, class, stream
)
240 struct cmd_list_element
*list
;
245 register struct cmd_list_element
*c
;
248 struct cmdvec
{ struct cmd_list_element
*cmd
; int class; };
249 register struct cmdvec
*cmdvec
;
250 char *cmdtype1
, *cmdtype2
;
255 c
= lookup_cmd (&command
, list
, cmdtype
, 0);
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.
263 If c->function is nonzero, we really have a command.
264 Print its documentation and return.
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. */
272 fprintf (stream
, "%s\n", p
);
273 if (c
->function
!= 0 && c
->prefixlist
== 0)
275 fputc ('\n', stream
);
278 list
= *c
->prefixlist
;
280 cmdtype
= c
->prefixname
;
286 /* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub" */
287 len
= strlen (cmdtype
);
288 cmdtype1
= (char *) alloca (len
+ 1);
290 cmdtype2
= (char *) alloca (len
+ 4);
295 strncpy (cmdtype1
+ 1, cmdtype
, len
- 1);
297 strncpy (cmdtype2
, cmdtype
, len
- 1);
298 strcpy (cmdtype2
+ len
- 1, " sub");
302 fprintf (stream
, "List of classes of %scommands:\n\n", cmdtype2
);
304 fprintf (stream
, "List of %scommands:\n\n", cmdtype2
);
306 for (c
= list
; c
; c
= c
->next
)
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 */
313 fprintf (stream
, "%s -- ", c
->name
);
314 /* Print just first line of documentation. */
316 while (*p
&& *p
!= '\n') p
++;
317 fwrite (c
->doc
, 1, p
- c
->doc
, stream
);
318 fputc ('\n', stream
);
323 fprintf (stream
, "\n\
324 Type \"help%s\" followed by a class name for a list of commands in that class.",
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",
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. */
343 struct cmd_list_element
*
344 lookup_cmd (line
, list
, cmdtype
, allow_unknown
)
346 struct cmd_list_element
*list
;
351 register struct cmd_list_element
*c
, *found
;
355 /* Skip leading whitespace. */
357 while (**line
== ' ' || **line
== '\t')
360 /* Clear out trailing whitespace. */
362 p
= *line
+ strlen (*line
);
363 while (p
!= *line
&& (p
[-1] == ' ' || p
[-1] == '\t'))
367 /* Find end of command name. */
371 || (*p
>= 'a' && *p
<= 'z')
372 || (*p
>= 'A' && *p
<= 'Z')
373 || (*p
>= '1' && *p
<= '9'))
375 if (*p
>= 'A' && *p
<= 'Z')
380 /* Look up the command name.
381 If exact match, keep that.
382 Otherwise, take command abbreviated, if unique. */
386 for (c
= list
; c
; c
= c
->next
)
388 if (!strncmp (*line
, c
->name
, p
- *line
))
392 if (c
->name
[p
- *line
] == 0)
400 /* Report error for undefined command name. */
404 if (nfound
> 1 && allow_unknown
>= 0)
408 for (c
= list
; c
; c
= c
->next
)
409 if (!strncmp (*line
, c
->name
, p
- *line
))
411 if (strlen (ambbuf
) + strlen (c
->name
) + 6 < sizeof ambbuf
)
414 strcat (ambbuf
, ", ");
415 strcat (ambbuf
, c
->name
);
419 strcat (ambbuf
, "..");
423 error ("Ambiguous %scommand \"%s\": %s.", cmdtype
, *line
, ambbuf
);
425 else if (!allow_unknown
)
428 error ("Undefined %scommand: \"%s\".", cmdtype
, *line
);
433 /* Skip whitespace before the argument. */
435 while (*p
== ' ' || *p
== '\t') p
++;
438 if (found
->prefixlist
&& *p
)
440 c
= lookup_cmd (line
, *found
->prefixlist
, found
->prefixname
,
441 found
->allow_unknown
);
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. */
454 savestring (ptr
, size
)
458 register char *p
= (char *) xmalloc (size
+ 1);
459 bcopy (ptr
, p
, size
);
This page took 0.0381010000000001 seconds and 4 git commands to generate.