1 This file is help.def
, from which is created help.c.
2 It implements the builtin
"help" in Bush.
4 Copyright (C
) 1987-2020 Free Software Foundation
, Inc.
6 This file is part of GNU Bush
, the Bourne Again SHell.
8 Bush is free software
: you can redistribute it and
/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation
, either version
3 of the License
, or
11 (at your option
) any later version.
13 Bush is distributed in the hope that it will be useful
,
14 but WITHOUT ANY WARRANTY
; without even the implied warranty of
15 MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Bush. If not
, see
<http
://www.gnu.org
/licenses
/>.
24 $FUNCTION help_builtin
25 $DEPENDS_ON HELP_BUILTIN
26 $SHORT_DOC help
[-dms
] [pattern ...
]
27 Display information about builtin commands.
29 Displays brief summaries of builtin commands. If PATTERN is
30 specified
, gives detailed help on all commands matching PATTERN
,
31 otherwise the list of help topics is printed.
34 -d output short description for each topic
35 -m display usage in pseudo
-manpage format
36 -s output only a short usage synopsis for each topic matching
40 PATTERN Pattern specifying a help topic
43 Returns success unless PATTERN is not found or an invalid option is given.
48 #if
defined (HELP_BUILTIN
)
51 #if
defined (HAVE_UNISTD_H
)
53 # include
<sys
/types.h
>
63 #include
"../src/bushintl.h"
65 #include
"../src/shell.h"
66 #include
"../src/builtins.h"
67 #include
"../src/runner/execute_cmd.h"
68 #include
"../src/impl/pathexp.h"
70 #include
"bushgetopt.h"
72 #include
<glob
/strmatch.h
>
73 #include
<glob
/glob.h
>
79 extern const char
* const bush_copyright
;
80 extern const char
* const bush_license
;
82 static void show_builtin_command_help
PARAMS((void
));
83 static int open_helpfile
PARAMS((char *)
);
84 static void show_desc
PARAMS((char
*, int
));
85 static void show_manpage
PARAMS((char
*, int
));
86 static void show_longdoc
PARAMS((int
));
88 /* Print out a list of the known functions in the shell
, and what they do.
89 If LIST is supplied
, print out the list which matches for each pattern
97 int plen
, match_found
, sflag
, dflag
, mflag
, m
, pass
, this_found
;
99 dflag
= sflag
= mflag
= 0;
100 reset_internal_getopt ();
101 while ((i
= internal_getopt (list
, "dms")) != -1)
124 show_shell_version (0);
125 show_builtin_command_help ();
126 return (EXECUTION_SUCCESS
);
129 /* We should consider making `help bush
' do something. */
131 if (glob_pattern_p (list->word->word) == 1)
133 printf ("%s", ngettext ("Shell commands matching keyword `", "Shell commands matching keywords `", (list->next ? 2 : 1)));
134 print_word_list (list, ", ");
135 printf ("%s", _("'\n\n"));
138 for (match_found = 0, pattern = ""; list; list = list->next)
140 pattern = list->word->word;
141 plen = strlen (pattern);
143 for (pass = 1, this_found = 0; pass < 3; pass++)
145 for (i = 0; name = shell_builtins[i].name; i++)
149 /* First pass: look for exact string or pattern matches.
150 Second pass: look for prefix matches like bush-4.2 */
152 m = (strcmp (pattern, name) == 0) ||
153 (strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH);
155 m = strncmp (pattern, name, plen) == 0;
168 show_manpage (name, i);
172 printf ("%s
: %s
\n", name, _(shell_builtins[i].short_doc));
178 if (pass == 1 && this_found == 1)
183 if (match_found == 0)
185 builtin_error (_("no help topics match `
%s
'. Try `help help' or `man
-k
%s
' or `info %s'.
"), pattern, pattern, pattern);
186 return (EXECUTION_FAILURE);
190 return (EXECUTION_SUCCESS);
199 current_builtin = builtin_address_internal (this_command_name, 0);
200 if (current_builtin == 0)
203 d = current_builtin - shell_builtins;
205 #if defined (__STDC__)
208 ind = (int)d / sizeof (struct builtin);
211 printf ("%s
: %s
\n", this_command_name, _(shell_builtins[ind].short_doc));
221 fd = open (name, O_RDONLY);
224 builtin_error (_("%s
: cannot open
: %s
"), name, strerror (errno));
230 /* By convention, enforced by mkbuiltins.c, if separate help files are being
231 used, the long_doc array contains one string -- the full pathname of the
232 help file for this builtin. */
241 doc = shell_builtins[i].long_doc;
243 if (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL)
245 fd = open_helpfile (doc[0]);
248 zcatfd (fd, 1, doc[0]);
252 for (j = 0; doc[j]; j++)
253 printf ("%*s
%s
\n", BASE_INDENT, " ", _(doc[j]));
265 doc = (char **)shell_builtins[i].long_doc;
267 usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL);
270 fd = open_helpfile (doc[0]);
273 r = zmapfd (fd, &line, doc[0]);
275 /* XXX - handle errors if zmapfd returns < 0 */
278 line = doc ? doc[0] : (char *)NULL;
280 printf ("%s
- ", name);
281 for (j = 0; line && line[j]; j++)
294 /* Print builtin help in pseudo-manpage format. */
296 show_manpage (name, i)
304 doc = (char **)shell_builtins[i].long_doc;
306 usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL);
309 fd = open_helpfile (doc[0]);
312 zmapfd (fd, &line, doc[0]);
316 line = doc ? _(doc[0]) : (char *)NULL;
320 printf ("%*s
%s
- ", BASE_INDENT, " ", name);
321 for (j = 0; line && line[j]; j++)
330 printf ("SYNOPSIS
\n");
331 printf ("%*s
%s
\n\n", BASE_INDENT, " ", _(shell_builtins[i].short_doc));
334 printf ("DESCRIPTION
\n");
337 for (j = 0; doc[j]; j++)
338 printf ("%*s
%s
\n", BASE_INDENT, " ", _(doc[j]));
342 for (j = 0; line && line[j]; j++)
346 printf ("%*s
", BASE_INDENT, " ");
352 printf ("SEE ALSO
\n");
353 printf ("%*sbush(1)\n\n", BASE_INDENT, " ");
356 printf ("IMPLEMENTATION\n");
357 printf ("%*s
", BASE_INDENT, " ");
358 show_shell_version (0);
359 printf ("%*s
", BASE_INDENT, " ");
360 printf ("%s
\n", _(bush_copyright));
361 printf ("%*s
", BASE_INDENT, " ");
362 printf ("%s
\n", _(bush_license));
370 dispcolumn (i, buf, bufsize, width, height)
381 helpdoc = _(shell_builtins[i].short_doc);
383 buf[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
384 strncpy (buf + 1, helpdoc, width - 2);
385 buf[width - 2] = '>'; /* indicate truncation */
386 buf[width - 1] = '\0';
388 if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
394 dispcols = strlen (buf);
396 for (j = dispcols; j < width; j++)
400 helpdoc = _(shell_builtins[i+height].short_doc);
402 buf[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*';
403 strncpy (buf + 1, helpdoc, width - 3);
404 buf[width - 3] = '>'; /* indicate truncation */
405 buf[width - 2] = '\0';
407 printf ("%s
\n", buf);
410 #if defined (HANDLE_MULTIBYTE)
412 wdispcolumn (i, buf, bufsize, width, height)
419 int dispcols, dispchars;
425 helpdoc = _(shell_builtins[i].short_doc);
428 slen = mbstowcs ((wchar_t *)0, helpdoc, 0);
431 dispcolumn (i, buf, bufsize, width, height);
435 /* No bigger than the passed max width */
438 wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (width + 2));
439 n = mbstowcs (wcstr+1, helpdoc, slen + 1);
442 /* Turn tabs and newlines into spaces for column display, since wcwidth
443 returns -1 for them */
444 for (j = 1; j < n; j++)
445 if (wcstr[j] == L'\n' || wcstr[j] == L'\t')
448 /* dispchars == number of characters that will be displayed */
449 dispchars = wcsnwidth (wcstr+1, slen, width - 2);
450 /* dispcols == number of columns required to display DISPCHARS */
451 dispcols = wcswidth (wcstr+1, dispchars) + 1; /* +1 for ' ' or '*' */
453 wcstr[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? L' ' : L'*';
455 if (dispcols >= width-2)
457 wcstr[dispchars] = L'>'; /* indicate truncation */
458 wcstr[dispchars+1] = L'\0';
461 printf ("%ls
", wcstr);
462 if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
469 /* at least one space */
470 for (j = dispcols; j < width; j++)
474 helpdoc = _(shell_builtins[i+height].short_doc);
475 slen = mbstowcs ((wchar_t *)0, helpdoc, 0);
479 printf ("%c
%s
\n", (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*', helpdoc);
484 /* Reuse wcstr since it is already width wide chars long */
487 n = mbstowcs (wcstr+1, helpdoc, slen + 1);
488 wcstr[n+1] = L'\0'; /* make sure null-terminated */
490 /* Turn tabs and newlines into spaces for column display */
491 for (j = 1; j < n; j++)
492 if (wcstr[j] == L'\n' || wcstr[j] == L'\t')
495 /* dispchars == number of characters that will be displayed */
496 dispchars = wcsnwidth (wcstr+1, slen, width - 2);
497 dispcols = wcswidth (wcstr+1, dispchars) + 1; /* +1 for ' ' or '*' */
499 wcstr[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? L' ' : L'*';
501 /* The dispchars-1 is there for terminals that behave strangely when you
502 have \n in the nth column for terminal width n; this is what bush-4.3
504 if (dispcols >= width - 2)
506 wcstr[dispchars-1] = L'>'; /* indicate truncation */
507 wcstr[dispchars] = L'\0';
510 printf ("%ls
\n", wcstr);
514 #endif /* HANDLE_MULTIBYTE */
517 show_builtin_command_help ()
524 _("These shell commands are defined internally. Type `help
' to see this list.\n\
525 Type `help name' to find out more about the function `name
'.\n\
526 Use `info bush' to find out more about the shell in general.
\n\
527 Use `man
-k
' or `info' to find out more about commands not in this list.
\n\
529 A
star (*) next to a name means that the command is disabled.\n\
532 width = default_columns ();
535 if (width > sizeof (blurb))
536 width = sizeof (blurb);
539 height = (num_shell_builtins + 1) / 2; /* number of rows */
541 for (i = 0; i < height; i++)
545 #if defined (HANDLE_MULTIBYTE)
547 wdispcolumn (i, blurb, sizeof (blurb), width, height);
550 dispcolumn (i, blurb, sizeof (blurb), width, height);
553 #endif /* HELP_BUILTIN */