1This file is help.def, from which is created help.c.
2It implements the builtin "help" in Bash.
3
4Copyright (C) 1987-2003 Free Software Foundation, Inc.
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
8Bash is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
12
13Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with Bash; see the file COPYING.  If not, write to the Free Software
20Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
21
22$PRODUCES help.c
23
24$BUILTIN help
25$FUNCTION help_builtin
26$DEPENDS_ON HELP_BUILTIN
27$SHORT_DOC help [-s] [pattern ...]
28Display helpful information about builtin commands.  If PATTERN is
29specified, gives detailed help on all commands matching PATTERN,
30otherwise a list of the builtins is printed.  The -s option
31restricts the output for each builtin command matching PATTERN to
32a short usage synopsis.
33$END
34
35#include <config.h>
36
37#if defined (HELP_BUILTIN)
38#include <stdio.h>
39
40#if defined (HAVE_UNISTD_H)
41#  ifdef _MINIX
42#    include <sys/types.h>
43#  endif
44#  include <unistd.h>
45#endif
46
47#include <errno.h>
48
49#include <filecntl.h>
50
51#include "../bashintl.h"
52
53#include "../shell.h"
54#include "../builtins.h"
55#include "../pathexp.h"
56#include "common.h"
57#include "bashgetopt.h"
58
59#include <glob/strmatch.h>
60#include <glob/glob.h>
61
62#ifndef errno
63extern int errno;
64#endif
65
66static void show_builtin_command_help __P((void));
67static void show_longdoc __P((int));
68
69/* Print out a list of the known functions in the shell, and what they do.
70   If LIST is supplied, print out the list which matches for each pattern
71   specified. */
72int
73help_builtin (list)
74     WORD_LIST *list;
75{
76  register int i;
77  char *pattern, *name;
78  int plen, match_found, sflag;
79
80  sflag = 0;
81  reset_internal_getopt ();
82  while ((i = internal_getopt (list, "s")) != -1)
83    {
84      switch (i)
85	{
86	case 's':
87	  sflag = 1;
88	  break;
89	default:
90	  builtin_usage ();
91	  return (EX_USAGE);
92	}
93    }
94  list = loptend;
95
96  if (list == 0)
97    {
98      show_shell_version (0);
99      show_builtin_command_help ();
100      return (EXECUTION_SUCCESS);
101    }
102
103  /* We should consider making `help bash' do something. */
104
105  if (glob_pattern_p (list->word->word))
106    {
107      if (list->next)
108	printf (_("Shell commands matching keywords `"));
109      else
110	printf (_("Shell commands matching keyword `"));
111      print_word_list (list, ", ");
112      printf ("'\n\n");
113    }
114
115  for (match_found = 0, pattern = ""; list; list = list->next)
116    {
117      pattern = list->word->word;
118      plen = strlen (pattern);
119
120      for (i = 0; name = shell_builtins[i].name; i++)
121	{
122	  QUIT;
123	  if ((strncmp (pattern, name, plen) == 0) ||
124	      (strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH))
125	    {
126	      printf ("%s: %s\n", name, shell_builtins[i].short_doc);
127
128	      if (sflag == 0)
129		show_longdoc (i);
130
131	      match_found++;
132	    }
133	}
134    }
135
136  if (match_found == 0)
137    {
138      builtin_error (_("no help topics match `%s'.  Try `help help' or `man -k %s' or `info %s'."), pattern, pattern, pattern);
139      return (EXECUTION_FAILURE);
140    }
141
142  fflush (stdout);
143  return (EXECUTION_SUCCESS);
144}
145
146/* By convention, enforced by mkbuiltins.c, if separate help files are being
147   used, the long_doc array contains one string -- the full pathname of the
148   help file for this builtin.  */
149static void
150show_longdoc (i)
151     int i;
152{
153  register int j;
154  char * const *doc;
155  int fd;
156
157  doc = shell_builtins[i].long_doc;
158
159  if (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL)
160    {
161      fd = open (doc[0], O_RDONLY);
162      if (fd == -1)
163	{
164	  builtin_error (_("%s: cannot open: %s"), doc[0], strerror (errno));
165	  return;
166	}
167      zcatfd (fd, 1, doc[0]);
168      close (fd);
169    }
170  else
171    for (j = 0; doc[j]; j++)
172      printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j]));
173}
174
175static void
176show_builtin_command_help ()
177{
178  int i, j;
179  char blurb[36];
180
181  printf (
182_("These shell commands are defined internally.  Type `help' to see this list.\n\
183Type `help name' to find out more about the function `name'.\n\
184Use `info bash' to find out more about the shell in general.\n\
185Use `man -k' or `info' to find out more about commands not in this list.\n\
186\n\
187A star (*) next to a name means that the command is disabled.\n\
188\n"));
189
190  for (i = 0; i < num_shell_builtins; i++)
191    {
192      QUIT;
193      blurb[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
194      strncpy (blurb + 1, shell_builtins[i].short_doc, 34);
195      blurb[35] = '\0';
196      printf ("%s", blurb);
197
198      if (i % 2)
199	printf ("\n");
200      else
201	for (j = strlen (blurb); j < 35; j++)
202	  putc (' ', stdout);
203    }
204  if (i % 2)
205    printf ("\n");
206}
207#endif /* HELP_BUILTIN */
208