1/* help.c, created from help.def. */
2#line 23 "help.def"
3
4#line 34 "help.def"
5
6#include <config.h>
7
8#if defined (HELP_BUILTIN)
9#include <stdio.h>
10
11#if defined (HAVE_UNISTD_H)
12#  ifdef _MINIX
13#    include <sys/types.h>
14#  endif
15#  include <unistd.h>
16#endif
17
18#include <errno.h>
19
20#include <filecntl.h>
21
22#include "../bashintl.h"
23
24#include "../shell.h"
25#include "../builtins.h"
26#include "../pathexp.h"
27#include "common.h"
28#include "bashgetopt.h"
29
30#include <glob/strmatch.h>
31#include <glob/glob.h>
32
33#ifndef errno
34extern int errno;
35#endif
36
37static void show_builtin_command_help __P((void));
38static void show_longdoc __P((int));
39
40/* Print out a list of the known functions in the shell, and what they do.
41   If LIST is supplied, print out the list which matches for each pattern
42   specified. */
43int
44help_builtin (list)
45     WORD_LIST *list;
46{
47  register int i;
48  char *pattern, *name;
49  int plen, match_found, sflag;
50
51  sflag = 0;
52  reset_internal_getopt ();
53  while ((i = internal_getopt (list, "s")) != -1)
54    {
55      switch (i)
56	{
57	case 's':
58	  sflag = 1;
59	  break;
60	default:
61	  builtin_usage ();
62	  return (EX_USAGE);
63	}
64    }
65  list = loptend;
66
67  if (list == 0)
68    {
69      show_shell_version (0);
70      show_builtin_command_help ();
71      return (EXECUTION_SUCCESS);
72    }
73
74  /* We should consider making `help bash' do something. */
75
76  if (glob_pattern_p (list->word->word))
77    {
78      if (list->next)
79	printf (_("Shell commands matching keywords `"));
80      else
81	printf (_("Shell commands matching keyword `"));
82      print_word_list (list, ", ");
83      printf ("'\n\n");
84    }
85
86  for (match_found = 0, pattern = ""; list; list = list->next)
87    {
88      pattern = list->word->word;
89      plen = strlen (pattern);
90
91      for (i = 0; name = shell_builtins[i].name; i++)
92	{
93	  QUIT;
94	  if ((strncmp (pattern, name, plen) == 0) ||
95	      (strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH))
96	    {
97	      printf ("%s: %s\n", name, shell_builtins[i].short_doc);
98
99	      if (sflag == 0)
100		show_longdoc (i);
101
102	      match_found++;
103	    }
104	}
105    }
106
107  if (match_found == 0)
108    {
109      builtin_error (_("no help topics match `%s'.  Try `help help' or `man -k %s' or `info %s'."), pattern, pattern, pattern);
110      return (EXECUTION_FAILURE);
111    }
112
113  fflush (stdout);
114  return (EXECUTION_SUCCESS);
115}
116
117/* By convention, enforced by mkbuiltins.c, if separate help files are being
118   used, the long_doc array contains one string -- the full pathname of the
119   help file for this builtin.  */
120static void
121show_longdoc (i)
122     int i;
123{
124  register int j;
125  char * const *doc;
126  int fd;
127
128  doc = shell_builtins[i].long_doc;
129
130  if (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL)
131    {
132      fd = open (doc[0], O_RDONLY);
133      if (fd == -1)
134	{
135	  builtin_error (_("%s: cannot open: %s"), doc[0], strerror (errno));
136	  return;
137	}
138      zcatfd (fd, 1, doc[0]);
139      close (fd);
140    }
141  else
142    for (j = 0; doc[j]; j++)
143      printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j]));
144}
145
146static void
147show_builtin_command_help ()
148{
149  int i, j;
150  char blurb[36];
151
152  printf (
153_("These shell commands are defined internally.  Type `help' to see this list.\n\
154Type `help name' to find out more about the function `name'.\n\
155Use `info bash' to find out more about the shell in general.\n\
156Use `man -k' or `info' to find out more about commands not in this list.\n\
157\n\
158A star (*) next to a name means that the command is disabled.\n\
159\n"));
160
161  for (i = 0; i < num_shell_builtins; i++)
162    {
163      QUIT;
164      blurb[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
165      strncpy (blurb + 1, shell_builtins[i].short_doc, 34);
166      blurb[35] = '\0';
167      printf ("%s", blurb);
168
169      if (i % 2)
170	printf ("\n");
171      else
172	for (j = strlen (blurb); j < 35; j++)
173	  putc (' ', stdout);
174    }
175  if (i % 2)
176    printf ("\n");
177}
178#endif /* HELP_BUILTIN */
179