No specific user configuration
[platform/upstream/bash.git] / builtins / gen-helpfiles.c
1 /* gen-helpfiles - create files containing builtin help text */
2
3 /* Copyright (C) 2012 Free Software Foundation, Inc.
4
5    This file is part of GNU Bash, the Bourne Again SHell.
6
7    Bash is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    Bash is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 /* This links with a specially-generated version of builtins.c and takes
22    the long_doc members of each struct builtin element and writes those to
23    the file named by the `handle' member of the struct builtin element. */
24
25 #if !defined (CROSS_COMPILING) 
26 #  include <config.h>
27 #else   /* CROSS_COMPILING */
28 /* A conservative set of defines based on POSIX/SUS3/XPG6 */
29 #  define HAVE_UNISTD_H
30 #  define HAVE_STRING_H
31 #  define HAVE_STDLIB_H
32
33 #  define HAVE_RENAME
34 #endif /* CROSS_COMPILING */
35
36 #if defined (HAVE_UNISTD_H)
37 #  ifdef _MINIX
38 #    include <sys/types.h>
39 #  endif
40 #  include <unistd.h>
41 #endif
42
43 #ifndef _MINIX
44 #  include "../bashtypes.h"
45 #  if defined (HAVE_SYS_FILE_H)
46 #    include <sys/file.h>
47 #  endif
48 #endif
49
50 #include "posixstat.h"
51 #include "filecntl.h"
52
53 #include "../bashansi.h"
54 #include <stdio.h>
55 #include <errno.h>
56
57 #include "stdc.h"
58
59 #include "../builtins.h"
60 #include "tmpbuiltins.h"
61
62 #if defined (USING_BASH_MALLOC)
63 #undef xmalloc
64 #undef xrealloc
65 #undef xfree
66
67 #undef free             /* defined in xmalloc.h */
68 #endif
69
70 #ifndef errno
71 extern int errno;
72 #endif
73
74 #if !defined (__STDC__) && !defined (strcpy)
75 extern char *strcpy ();
76 #endif /* !__STDC__ && !strcpy */
77
78 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
79
80 /* Flag values that builtins can have. */
81 #define BUILTIN_FLAG_SPECIAL    0x01
82 #define BUILTIN_FLAG_ASSIGNMENT 0x02
83 #define BUILTIN_FLAG_POSIX_BUILTIN 0x04
84
85 #define BASE_INDENT     4
86
87 /* Non-zero means to produce separate help files for each builtin, named by
88    the builtin name, in `./helpfiles'. */
89 int separate_helpfiles = 0;
90
91 /* Non-zero means to create single C strings for each `longdoc', with
92    embedded newlines, for ease of translation. */
93 int single_longdoc_strings = 1;
94
95 /* The name of a directory into which the separate external help files will
96    eventually be installed. */
97 char *helpfile_directory;
98
99 /* Forward declarations. */
100
101 int write_helpfiles __P((struct builtin *));
102
103 /* For each file mentioned on the command line, process it and
104    write the information to STRUCTFILE and EXTERNFILE, while
105    creating the production file if neccessary. */
106 int
107 main (argc, argv)
108      int argc;
109      char **argv;
110 {
111   int arg_index = 1;
112
113   while (arg_index < argc && argv[arg_index][0] == '-')
114     {
115       char *arg = argv[arg_index++];
116
117       if (strcmp (arg, "-noproduction") == 0)
118         ;
119       else if (strcmp (arg, "-H") == 0)
120         helpfile_directory = argv[arg_index++];
121       else if (strcmp (arg, "-S") == 0)
122         single_longdoc_strings = 0;
123       else
124         {
125           fprintf (stderr, "%s: Unknown flag %s.\n", argv[0], arg);
126           exit (2);
127         }
128     }
129
130   write_helpfiles(shell_builtins);
131
132   exit (0);
133 }
134
135 /* Write DOCUMENTATION to STREAM, perhaps surrounding it with double-quotes
136    and quoting special characters in the string.  Handle special things for
137    internationalization (gettext) and the single-string vs. multiple-strings
138    issues. */
139 void
140 write_documentation (stream, documentation, indentation)
141      FILE *stream;
142      char *documentation;
143      int indentation;
144 {
145   if (stream == 0)
146     return;
147
148   if (documentation)
149     fprintf (stream, "%*s%s\n", indentation, " ", documentation);
150 }
151
152 int
153 write_helpfiles (builtins)
154      struct builtin *builtins;
155 {
156   char *helpfile, *bname, *fname;
157   FILE *helpfp;
158   int i, hdlen;
159   struct builtin b;
160
161   i = mkdir ("helpfiles", 0777);
162   if (i < 0 && errno != EEXIST)
163     {
164       fprintf (stderr, "write_helpfiles: helpfiles: cannot create directory\n");
165       return -1;
166     }
167
168   hdlen = strlen ("helpfiles/");
169   for (i = 0; i < num_shell_builtins; i++)
170     {
171       b = builtins[i];
172
173       fname = (char *)b.handle;
174       helpfile = (char *)malloc (hdlen + strlen (fname) + 1);
175       if (helpfile == 0)
176         {
177           fprintf (stderr, "gen-helpfiles: cannot allocate memory\n");
178           exit (1);
179         }
180       sprintf (helpfile, "helpfiles/%s", fname);
181
182       helpfp = fopen (helpfile, "w");
183       if (helpfp == 0)
184         {
185           fprintf (stderr, "write_helpfiles: cannot open %s\n", helpfile);
186           free (helpfile);
187           continue;
188         }
189
190       write_documentation (helpfp, b.long_doc[0], 4);
191
192       fflush (helpfp);
193       fclose (helpfp);
194       free (helpfile);
195     }
196   return 0;
197 }