i-bash/builtins/help.def

386 lines
8.6 KiB
Modula-2
Raw Normal View History

1996-08-26 18:22:31 +00:00
This file is help.def, from which is created help.c.
It implements the builtin "help" in Bash.
2009-01-12 13:36:28 +00:00
Copyright (C) 1987-2009 Free Software Foundation, Inc.
1996-08-26 18:22:31 +00:00
This file is part of GNU Bash, the Bourne Again SHell.
2009-01-12 13:36:28 +00:00
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
1996-08-26 18:22:31 +00:00
2009-01-12 13:36:28 +00:00
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
1996-08-26 18:22:31 +00:00
2009-01-12 13:36:28 +00:00
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
1996-08-26 18:22:31 +00:00
$PRODUCES help.c
$BUILTIN help
$FUNCTION help_builtin
1996-12-23 17:02:34 +00:00
$DEPENDS_ON HELP_BUILTIN
2011-11-21 20:51:19 -05:00
$SHORT_DOC help [-dms] [pattern ...]
2009-01-12 13:36:28 +00:00
Display information about builtin commands.
Displays brief summaries of builtin commands. If PATTERN is
1996-08-26 18:22:31 +00:00
specified, gives detailed help on all commands matching PATTERN,
2009-01-12 13:36:28 +00:00
otherwise the list of help topics is printed.
Options:
-d output short description for each topic
-m display usage in pseudo-manpage format
-s output only a short usage synopsis for each topic matching
PATTERN
Arguments:
PATTERN Pattern specifiying a help topic
Exit Status:
Returns success unless PATTERN is not found or an invalid option is given.
1996-08-26 18:22:31 +00:00
$END
1996-12-23 17:02:34 +00:00
#include <config.h>
#if defined (HELP_BUILTIN)
1996-08-26 18:22:31 +00:00
#include <stdio.h>
1996-12-23 17:02:34 +00:00
#if defined (HAVE_UNISTD_H)
1998-04-17 19:52:44 +00:00
# ifdef _MINIX
# include <sys/types.h>
# endif
1996-12-23 17:02:34 +00:00
# include <unistd.h>
#endif
2002-07-17 14:10:11 +00:00
#include <errno.h>
#include <filecntl.h>
2004-07-27 13:29:18 +00:00
#include "../bashintl.h"
1996-08-26 18:22:31 +00:00
#include "../shell.h"
#include "../builtins.h"
1998-04-17 19:52:44 +00:00
#include "../pathexp.h"
2001-11-13 17:56:06 +00:00
#include "common.h"
1996-12-23 17:02:34 +00:00
#include "bashgetopt.h"
2001-11-13 17:56:06 +00:00
#include <glob/strmatch.h>
1996-12-23 17:02:34 +00:00
#include <glob/glob.h>
1996-08-26 18:22:31 +00:00
2002-07-17 14:10:11 +00:00
#ifndef errno
extern int errno;
#endif
2009-01-12 13:36:28 +00:00
extern const char * const bash_copyright;
extern const char * const bash_license;
2002-07-17 14:10:11 +00:00
static void show_builtin_command_help __P((void));
2009-01-12 13:36:28 +00:00
static int open_helpfile __P((char *));
static void show_desc __P((char *, int));
static void show_manpage __P((char *, int));
2002-07-17 14:10:11 +00:00
static void show_longdoc __P((int));
1996-08-26 18:22:31 +00:00
/* Print out a list of the known functions in the shell, and what they do.
If LIST is supplied, print out the list which matches for each pattern
specified. */
1996-12-23 17:02:34 +00:00
int
1996-08-26 18:22:31 +00:00
help_builtin (list)
WORD_LIST *list;
{
2002-07-17 14:10:11 +00:00
register int i;
1996-12-23 17:02:34 +00:00
char *pattern, *name;
2009-01-12 13:36:28 +00:00
int plen, match_found, sflag, dflag, mflag;
1996-08-26 18:22:31 +00:00
2009-01-12 13:36:28 +00:00
dflag = sflag = mflag = 0;
1996-12-23 17:02:34 +00:00
reset_internal_getopt ();
2009-01-12 13:36:28 +00:00
while ((i = internal_getopt (list, "dms")) != -1)
1996-12-23 17:02:34 +00:00
{
switch (i)
1996-08-26 18:22:31 +00:00
{
2009-01-12 13:36:28 +00:00
case 'd':
dflag = 1;
break;
case 'm':
mflag = 1;
break;
2000-03-17 21:46:59 +00:00
case 's':
sflag = 1;
break;
1996-12-23 17:02:34 +00:00
default:
builtin_usage ();
return (EX_USAGE);
1996-08-26 18:22:31 +00:00
}
}
1996-12-23 17:02:34 +00:00
list = loptend;
1996-08-26 18:22:31 +00:00
1997-06-05 14:59:13 +00:00
if (list == 0)
{
show_shell_version (0);
show_builtin_command_help ();
return (EXECUTION_SUCCESS);
}
1996-12-23 17:02:34 +00:00
/* We should consider making `help bash' do something. */
1996-08-26 18:22:31 +00:00
1996-12-23 17:02:34 +00:00
if (glob_pattern_p (list->word->word))
{
2009-01-12 13:36:28 +00:00
printf (ngettext ("Shell commands matching keyword `", "Shell commands matching keywords `", (list->next ? 2 : 1)));
1996-12-23 17:02:34 +00:00
print_word_list (list, ", ");
printf ("'\n\n");
}
1996-08-26 18:22:31 +00:00
1996-12-23 17:02:34 +00:00
for (match_found = 0, pattern = ""; list; list = list->next)
{
pattern = list->word->word;
plen = strlen (pattern);
1996-08-26 18:22:31 +00:00
1996-12-23 17:02:34 +00:00
for (i = 0; name = shell_builtins[i].name; i++)
{
QUIT;
if ((strncmp (pattern, name, plen) == 0) ||
2001-11-13 17:56:06 +00:00
(strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH))
1996-08-26 18:22:31 +00:00
{
2009-01-12 13:36:28 +00:00
match_found++;
if (dflag)
{
show_desc (name, i);
continue;
}
else if (mflag)
{
show_manpage (name, i);
continue;
}
printf ("%s: %s\n", name, _(shell_builtins[i].short_doc));
1996-08-26 18:22:31 +00:00
2000-03-17 21:46:59 +00:00
if (sflag == 0)
2002-07-17 14:10:11 +00:00
show_longdoc (i);
1996-08-26 18:22:31 +00:00
}
}
1996-12-23 17:02:34 +00:00
}
1996-08-26 18:22:31 +00:00
1996-12-23 17:02:34 +00:00
if (match_found == 0)
{
2004-07-27 13:29:18 +00:00
builtin_error (_("no help topics match `%s'. Try `help help' or `man -k %s' or `info %s'."), pattern, pattern, pattern);
1996-12-23 17:02:34 +00:00
return (EXECUTION_FAILURE);
1996-08-26 18:22:31 +00:00
}
1996-12-23 17:02:34 +00:00
1996-08-26 18:22:31 +00:00
fflush (stdout);
return (EXECUTION_SUCCESS);
}
1996-12-23 17:02:34 +00:00
2009-01-12 13:36:28 +00:00
static int
open_helpfile (name)
char *name;
{
int fd;
fd = open (name, O_RDONLY);
if (fd == -1)
{
builtin_error (_("%s: cannot open: %s"), name, strerror (errno));
return -1;
}
return fd;
}
2002-07-17 14:10:11 +00:00
/* By convention, enforced by mkbuiltins.c, if separate help files are being
used, the long_doc array contains one string -- the full pathname of the
help file for this builtin. */
static void
show_longdoc (i)
int i;
{
register int j;
char * const *doc;
int fd;
doc = shell_builtins[i].long_doc;
if (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL)
{
2009-01-12 13:36:28 +00:00
fd = open_helpfile (doc[0]);
if (fd < 0)
return;
2002-07-17 14:10:11 +00:00
zcatfd (fd, 1, doc[0]);
close (fd);
}
else
for (j = 0; doc[j]; j++)
2005-12-07 14:08:12 +00:00
printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j]));
2002-07-17 14:10:11 +00:00
}
2009-01-12 13:36:28 +00:00
static void
show_desc (name, i)
char *name;
int i;
{
register int j;
char **doc, *line;
int fd, usefile;
doc = (char **)shell_builtins[i].long_doc;
usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL);
if (usefile)
{
fd = open_helpfile (doc[0]);
if (fd < 0)
return;
zmapfd (fd, &line, doc[0]);
close (fd);
}
else
line = doc ? doc[0] : (char *)NULL;
printf ("%s - ", name);
for (j = 0; line && line[j]; j++)
{
putchar (line[j]);
if (line[j] == '\n')
break;
}
fflush (stdout);
if (usefile)
free (line);
}
/* Print builtin help in pseudo-manpage format. */
static void
show_manpage (name, i)
char *name;
int i;
{
register int j;
char **doc, *line;
int fd, usefile;
doc = (char **)shell_builtins[i].long_doc;
usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL);
if (usefile)
{
fd = open_helpfile (doc[0]);
if (fd < 0)
return;
zmapfd (fd, &line, doc[0]);
close (fd);
}
else
line = doc ? _(doc[0]) : (char *)NULL;
/* NAME */
printf ("NAME\n");
printf ("%*s%s - ", BASE_INDENT, " ", name);
for (j = 0; line && line[j]; j++)
{
putchar (line[j]);
if (line[j] == '\n')
break;
}
printf ("\n");
/* SYNOPSIS */
printf ("SYNOPSIS\n");
printf ("%*s%s\n\n", BASE_INDENT, " ", _(shell_builtins[i].short_doc));
2009-01-12 13:36:28 +00:00
/* DESCRIPTION */
printf ("DESCRIPTION\n");
if (usefile == 0)
{
for (j = 0; doc[j]; j++)
printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j]));
}
else
{
for (j = 0; line && line[j]; j++)
{
putchar (line[j]);
if (line[j] == '\n')
printf ("%*s", BASE_INDENT, " ");
}
}
putchar ('\n');
/* SEE ALSO */
printf ("SEE ALSO\n");
printf ("%*sbash(1)\n\n", BASE_INDENT, " ");
/* IMPLEMENTATION */
printf ("IMPLEMENTATION\n");
printf ("%*s", BASE_INDENT, " ");
show_shell_version (0);
printf ("%*s", BASE_INDENT, " ");
printf ("%s\n", _(bash_copyright));
printf ("%*s", BASE_INDENT, " ");
printf ("%s\n", _(bash_license));
fflush (stdout);
if (usefile)
free (line);
}
1996-12-23 17:02:34 +00:00
static void
show_builtin_command_help ()
{
int i, j;
2009-01-12 13:36:28 +00:00
int height, width;
char *t, blurb[128];
1996-12-23 17:02:34 +00:00
printf (
2004-07-27 13:29:18 +00:00
_("These shell commands are defined internally. Type `help' to see this list.\n\
1996-12-23 17:02:34 +00:00
Type `help name' to find out more about the function `name'.\n\
Use `info bash' to find out more about the shell in general.\n\
2002-07-17 14:10:11 +00:00
Use `man -k' or `info' to find out more about commands not in this list.\n\
1996-12-23 17:02:34 +00:00
\n\
A star (*) next to a name means that the command is disabled.\n\
2004-07-27 13:29:18 +00:00
\n"));
1996-12-23 17:02:34 +00:00
2009-01-12 13:36:28 +00:00
t = get_string_value ("COLUMNS");
width = (t && *t) ? atoi (t) : 80;
if (width <= 0)
width = 80;
width /= 2;
if (width > sizeof (blurb))
width = sizeof (blurb);
2011-11-21 20:51:19 -05:00
if (width <= 3)
width = 40;
2009-01-12 13:36:28 +00:00
height = (num_shell_builtins + 1) / 2; /* number of rows */
for (i = 0; i < height; i++)
1996-12-23 17:02:34 +00:00
{
QUIT;
2009-01-12 13:36:28 +00:00
/* first column */
1996-12-23 17:02:34 +00:00
blurb[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
strncpy (blurb + 1, _(shell_builtins[i].short_doc), width - 2);
2009-01-12 13:36:28 +00:00
blurb[width - 2] = '>'; /* indicate truncation */
blurb[width - 1] = '\0';
1996-12-23 17:02:34 +00:00
printf ("%s", blurb);
2009-01-12 13:36:28 +00:00
if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
{
printf ("\n");
break;
}
/* two spaces */
for (j = strlen (blurb); j < width; j++)
putc (' ', stdout);
1996-12-23 17:02:34 +00:00
2009-01-12 13:36:28 +00:00
/* second column */
blurb[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*';
strncpy (blurb + 1, _(shell_builtins[i+height].short_doc), width - 3);
2009-01-12 13:36:28 +00:00
blurb[width - 3] = '>'; /* indicate truncation */
blurb[width - 2] = '\0';
printf ("%s\n", blurb);
1996-12-23 17:02:34 +00:00
}
}
#endif /* HELP_BUILTIN */