1 /* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from
2 a single source file called builtins.def. */
4 /* Copyright (C) 1987-2011 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
8 Bash 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 Bash 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 Bash. If not, see <http://www.gnu.org/licenses/>.
22 #if !defined (CROSS_COMPILING)
24 #else /* CROSS_COMPILING */
25 /* A conservative set of defines based on POSIX/SUS3/XPG6 */
26 # define HAVE_UNISTD_H
27 # define HAVE_STRING_H
28 # define HAVE_STDLIB_H
31 #endif /* CROSS_COMPILING */
33 #if defined (HAVE_UNISTD_H)
35 # include <sys/types.h>
41 # include "../bashtypes.h"
42 # if defined (HAVE_SYS_FILE_H)
43 # include <sys/file.h>
47 #include "posixstat.h"
50 #include "../bashansi.h"
56 #define DOCFILE "builtins.texi"
62 static char *xmalloc (), *xrealloc ();
64 #if !defined (__STDC__) && !defined (strcpy)
65 extern char *strcpy ();
66 #endif /* !__STDC__ && !strcpy */
68 #define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
69 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
71 /* Flag values that builtins can have. */
72 #define BUILTIN_FLAG_SPECIAL 0x01
73 #define BUILTIN_FLAG_ASSIGNMENT 0x02
74 #define BUILTIN_FLAG_POSIX_BUILTIN 0x04
78 /* If this stream descriptor is non-zero, then write
79 texinfo documentation to it. */
80 FILE *documentation_file = (FILE *)NULL;
82 /* Non-zero means to only produce documentation. */
83 int only_documentation = 0;
85 /* Non-zero means to not do any productions. */
86 int inhibit_production = 0;
88 /* Non-zero means to not add functions (xxx_builtin) to the members of the
89 produced `struct builtin []' */
90 int inhibit_functions = 0;
92 /* Non-zero means to produce separate help files for each builtin, named by
93 the builtin name, in `./helpfiles'. */
94 int separate_helpfiles = 0;
96 /* Non-zero means to create single C strings for each `longdoc', with
97 embedded newlines, for ease of translation. */
98 int single_longdoc_strings = 1;
100 /* The name of a directory into which the separate external help files will
101 eventually be installed. */
102 char *helpfile_directory;
104 /* The name of a directory to precede the filename when reporting
106 char *error_directory = (char *)NULL;
108 /* The name of the structure file. */
109 char *struct_filename = (char *)NULL;
111 /* The name of the external declaration file. */
112 char *extern_filename = (char *)NULL;
114 /* Here is a structure for manipulating arrays of data. */
116 int size; /* Number of slots allocated to array. */
117 int sindex; /* Current location in array. */
118 int width; /* Size of each element. */
119 int growth_rate; /* How fast to grow. */
120 char **array; /* The array itself. */
123 /* Here is a structure defining a single BUILTIN. */
125 char *name; /* The name of this builtin. */
126 char *function; /* The name of the function to call. */
127 char *shortdoc; /* The short documentation for this builtin. */
128 char *docname; /* Possible name for documentation string. */
129 ARRAY *longdoc; /* The long documentation for this builtin. */
130 ARRAY *dependencies; /* Null terminated array of #define names. */
131 int flags; /* Flags for this builtin. */
134 /* Here is a structure which defines a DEF file. */
136 char *filename; /* The name of the input def file. */
137 ARRAY *lines; /* The contents of the file. */
138 int line_number; /* The current line number. */
139 char *production; /* The name of the production file. */
140 FILE *output; /* Open file stream for PRODUCTION. */
141 ARRAY *builtins; /* Null terminated array of BUILTIN_DESC *. */
144 /* The array of all builtins encountered during execution of this code. */
145 ARRAY *saved_builtins = (ARRAY *)NULL;
147 /* The Posix.2 so-called `special' builtins. */
148 char *special_builtins[] =
150 ":", ".", "source", "break", "continue", "eval", "exec", "exit",
151 "export", "readonly", "return", "set", "shift", "times", "trap", "unset",
155 /* The builtin commands that take assignment statements as arguments. */
156 char *assignment_builtins[] =
158 "alias", "declare", "export", "local", "readonly", "typeset",
162 /* The builtin commands that are special to the POSIX search order. */
163 char *posix_builtins[] =
165 "alias", "bg", "cd", "command", "false", "fc", "fg", "getopts", "jobs",
166 "kill", "newgrp", "pwd", "read", "true", "umask", "unalias", "wait",
170 /* Forward declarations. */
171 static int is_special_builtin ();
172 static int is_assignment_builtin ();
173 static int is_posix_builtin ();
175 #if !defined (HAVE_RENAME)
176 static int rename ();
179 void extract_info ();
184 void write_file_headers ();
185 void write_file_footers ();
186 void write_ifdefs ();
187 void write_endifs ();
188 void write_documentation ();
189 void write_longdocs ();
190 void write_builtins ();
192 int write_helpfiles ();
195 void add_documentation ();
197 void must_be_building ();
198 void remove_trailing_whitespace ();
200 #define document_name(b) ((b)->docname ? (b)->docname : (b)->name)
203 /* For each file mentioned on the command line, process it and
204 write the information to STRUCTFILE and EXTERNFILE, while
205 creating the production file if necessary. */
212 FILE *structfile, *externfile;
213 char *documentation_filename, *temp_struct_filename;
215 structfile = externfile = (FILE *)NULL;
216 documentation_filename = DOCFILE;
217 temp_struct_filename = (char *)NULL;
219 while (arg_index < argc && argv[arg_index][0] == '-')
221 char *arg = argv[arg_index++];
223 if (strcmp (arg, "-externfile") == 0)
224 extern_filename = argv[arg_index++];
225 else if (strcmp (arg, "-structfile") == 0)
226 struct_filename = argv[arg_index++];
227 else if (strcmp (arg, "-noproduction") == 0)
228 inhibit_production = 1;
229 else if (strcmp (arg, "-nofunctions") == 0)
230 inhibit_functions = 1;
231 else if (strcmp (arg, "-document") == 0)
232 documentation_file = fopen (documentation_filename, "w");
233 else if (strcmp (arg, "-D") == 0)
238 free (error_directory);
240 error_directory = xmalloc (2 + strlen (argv[arg_index]));
241 strcpy (error_directory, argv[arg_index]);
242 len = strlen (error_directory);
244 if (len && error_directory[len - 1] != '/')
245 strcat (error_directory, "/");
249 else if (strcmp (arg, "-documentonly") == 0)
251 only_documentation = 1;
252 documentation_file = fopen (documentation_filename, "w");
254 else if (strcmp (arg, "-H") == 0)
256 separate_helpfiles = 1;
257 helpfile_directory = argv[arg_index++];
259 else if (strcmp (arg, "-S") == 0)
260 single_longdoc_strings = 0;
263 fprintf (stderr, "%s: Unknown flag %s.\n", argv[0], arg);
268 /* If there are no files to process, just quit now. */
269 if (arg_index == argc)
272 if (!only_documentation)
274 /* Open the files. */
277 temp_struct_filename = xmalloc (15);
278 sprintf (temp_struct_filename, "mk-%ld", (long) getpid ());
279 structfile = fopen (temp_struct_filename, "w");
282 file_error (temp_struct_filename);
287 externfile = fopen (extern_filename, "w");
290 file_error (extern_filename);
293 /* Write out the headers. */
294 write_file_headers (structfile, externfile);
297 if (documentation_file)
299 fprintf (documentation_file, "@c Table of builtins created with %s.\n",
301 fprintf (documentation_file, "@ftable @asis\n");
304 /* Process the .def files. */
305 while (arg_index < argc)
309 arg = argv[arg_index++];
311 extract_info (arg, structfile, externfile);
314 /* Close the files. */
315 if (!only_documentation)
317 /* Write the footers. */
318 write_file_footers (structfile, externfile);
322 write_longdocs (structfile, saved_builtins);
324 rename (temp_struct_filename, struct_filename);
332 /* This is now done by a different program */
333 if (separate_helpfiles)
335 write_helpfiles (saved_builtins);
339 if (documentation_file)
341 fprintf (documentation_file, "@end ftable\n");
342 fclose (documentation_file);
348 /* **************************************************************** */
350 /* Array Functions and Manipulators */
352 /* **************************************************************** */
354 /* Make a new array, and return a pointer to it. The array will
355 contain elements of size WIDTH, and is initialized to no elements. */
362 array = (ARRAY *)xmalloc (sizeof (ARRAY));
365 array->width = width;
367 /* Default to increasing size in units of 20. */
368 array->growth_rate = 20;
370 array->array = (char **)NULL;
375 /* Copy the array of strings in ARRAY. */
377 copy_string_array (array)
384 return (ARRAY *)NULL;
386 copy = array_create (sizeof (char *));
388 copy->size = array->size;
389 copy->sindex = array->sindex;
390 copy->width = array->width;
392 copy->array = (char **)xmalloc ((1 + array->sindex) * sizeof (char *));
394 for (i = 0; i < array->sindex; i++)
395 copy->array[i] = savestring (array->array[i]);
397 copy->array[i] = (char *)NULL;
402 /* Add ELEMENT to ARRAY, growing the array if necessary. */
404 array_add (element, array)
408 if (array->sindex + 2 > array->size)
409 array->array = (char **)xrealloc
410 (array->array, (array->size += array->growth_rate) * array->width);
412 array->array[array->sindex++] = element;
413 array->array[array->sindex] = (char *)NULL;
416 /* Free an allocated array and data pointer. */
427 /* **************************************************************** */
429 /* Processing a DEF File */
431 /* **************************************************************** */
433 /* The definition of a function. */
434 typedef int Function ();
435 typedef int mk_handler_func_t __P((char *, DEF_FILE *, char *));
437 /* Structure handles processor directives. */
440 mk_handler_func_t *function;
443 extern int builtin_handler __P((char *, DEF_FILE *, char *));
444 extern int function_handler __P((char *, DEF_FILE *, char *));
445 extern int short_doc_handler __P((char *, DEF_FILE *, char *));
446 extern int comment_handler __P((char *, DEF_FILE *, char *));
447 extern int depends_on_handler __P((char *, DEF_FILE *, char *));
448 extern int produces_handler __P((char *, DEF_FILE *, char *));
449 extern int end_handler __P((char *, DEF_FILE *, char *));
450 extern int docname_handler __P((char *, DEF_FILE *, char *));
452 HANDLER_ENTRY handlers[] = {
453 { "BUILTIN", builtin_handler },
454 { "DOCNAME", docname_handler },
455 { "FUNCTION", function_handler },
456 { "SHORT_DOC", short_doc_handler },
457 { "$", comment_handler },
458 { "COMMENT", comment_handler },
459 { "DEPENDS_ON", depends_on_handler },
460 { "PRODUCES", produces_handler },
461 { "END", end_handler },
462 { (char *)NULL, (mk_handler_func_t *)NULL }
465 /* Return the entry in the table of handlers for NAME. */
467 find_directive (directive)
472 for (i = 0; handlers[i].directive; i++)
473 if (strcmp (handlers[i].directive, directive) == 0)
474 return (&handlers[i]);
476 return ((HANDLER_ENTRY *)NULL);
479 /* Non-zero indicates that a $BUILTIN has been seen, but not
480 the corresponding $END. */
481 static int building_builtin = 0;
483 /* Non-zero means to output cpp line and file information before
484 printing the current line to the production file. */
485 int output_cpp_line_info = 0;
487 /* The main function of this program. Read FILENAME and act on what is
488 found. Lines not starting with a dollar sign are copied to the
489 $PRODUCES target, if one is present. Lines starting with a dollar sign
490 are directives to this program, specifying the name of the builtin, the
491 function to call, the short documentation and the long documentation
492 strings. FILENAME can contain multiple $BUILTINs, but only one $PRODUCES
493 target. After the file has been processed, write out the names of
494 builtins found in each $BUILTIN. Plain text found before the $PRODUCES
495 is ignored, as is "$$ comment text". */
497 extract_info (filename, structfile, externfile)
499 FILE *structfile, *externfile;
508 if (stat (filename, &finfo) == -1)
509 file_error (filename);
511 fd = open (filename, O_RDONLY, 0666);
514 file_error (filename);
516 file_size = (size_t)finfo.st_size;
517 buffer = xmalloc (1 + file_size);
519 if ((nr = read (fd, buffer, file_size)) < 0)
520 file_error (filename);
522 /* This is needed on WIN32, and does not hurt on Unix. */
530 fprintf (stderr, "mkbuiltins: %s: skipping zero-length file\n", filename);
535 /* Create and fill in the initial structure describing this file. */
536 defs = (DEF_FILE *)xmalloc (sizeof (DEF_FILE));
537 defs->filename = filename;
538 defs->lines = array_create (sizeof (char *));
539 defs->line_number = 0;
540 defs->production = (char *)NULL;
541 defs->output = (FILE *)NULL;
542 defs->builtins = (ARRAY *)NULL;
544 /* Build the array of lines. */
546 while (i < file_size)
548 array_add (&buffer[i], defs->lines);
550 while (i < file_size && buffer[i] != '\n')
555 /* Begin processing the input file. We don't write any output
556 until we have a file to write output to. */
557 output_cpp_line_info = 1;
559 /* Process each line in the array. */
560 for (i = 0; line = defs->lines->array[i]; i++)
562 defs->line_number = i;
568 HANDLER_ENTRY *handler;
570 /* Isolate the directive. */
571 for (j = 0; line[j] && !whitespace (line[j]); j++);
573 directive = xmalloc (j);
574 strncpy (directive, line + 1, j - 1);
575 directive[j -1] = '\0';
577 /* Get the function handler and call it. */
578 handler = find_directive (directive);
582 line_error (defs, "Unknown directive `%s'", directive);
588 /* Advance to the first non-whitespace character. */
589 while (whitespace (line[j]))
592 /* Call the directive handler with the FILE, and ARGS. */
593 (*(handler->function)) (directive, defs, line + j);
599 if (building_builtin)
600 add_documentation (defs, line);
601 else if (defs->output)
603 if (output_cpp_line_info)
605 /* If we're handed an absolute pathname, don't prepend
606 the directory name. */
607 if (defs->filename[0] == '/')
608 fprintf (defs->output, "#line %d \"%s\"\n",
609 defs->line_number + 1, defs->filename);
611 fprintf (defs->output, "#line %d \"%s%s\"\n",
612 defs->line_number + 1,
613 error_directory ? error_directory : "./",
615 output_cpp_line_info = 0;
618 fprintf (defs->output, "%s\n", line);
623 /* Close the production file. */
625 fclose (defs->output);
627 /* The file has been processed. Write the accumulated builtins to
628 the builtins.c file, and write the extern definitions to the
630 write_builtins (defs, structfile, externfile);
636 #define free_safely(x) if (x) free (x)
639 free_builtin (builtin)
640 BUILTIN_DESC *builtin;
644 free_safely (builtin->name);
645 free_safely (builtin->function);
646 free_safely (builtin->shortdoc);
647 free_safely (builtin->docname);
649 if (builtin->longdoc)
650 array_free (builtin->longdoc);
652 if (builtin->dependencies)
654 for (i = 0; builtin->dependencies->array[i]; i++)
655 free (builtin->dependencies->array[i]);
656 array_free (builtin->dependencies);
660 /* Free all of the memory allocated to a DEF_FILE. */
666 register BUILTIN_DESC *builtin;
668 if (defs->production)
669 free (defs->production);
672 array_free (defs->lines);
676 for (i = 0; builtin = (BUILTIN_DESC *)defs->builtins->array[i]; i++)
678 free_builtin (builtin);
681 array_free (defs->builtins);
686 /* **************************************************************** */
688 /* The Handler Functions Themselves */
690 /* **************************************************************** */
692 /* Strip surrounding whitespace from STRING, and
693 return a pointer to the start of it. */
695 strip_whitespace (string)
698 while (whitespace (*string))
701 remove_trailing_whitespace (string);
705 /* Remove only the trailing whitespace from STRING. */
707 remove_trailing_whitespace (string)
712 i = strlen (string) - 1;
714 while (i > 0 && whitespace (string[i]))
720 /* Ensure that there is a argument in STRING and return it.
721 FOR_WHOM is the name of the directive which needs the argument.
722 DEFS is the DEF_FILE in which the directive is found.
723 If there is no argument, produce an error. */
725 get_arg (for_whom, defs, string)
726 char *for_whom, *string;
731 new = strip_whitespace (string);
734 line_error (defs, "%s requires an argument", for_whom);
736 return (savestring (new));
739 /* Error if not building a builtin. */
741 must_be_building (directive, defs)
745 if (!building_builtin)
746 line_error (defs, "%s must be inside of a $BUILTIN block", directive);
749 /* Return the current builtin. */
751 current_builtin (directive, defs)
755 must_be_building (directive, defs);
757 return ((BUILTIN_DESC *)defs->builtins->array[defs->builtins->sindex - 1]);
759 return ((BUILTIN_DESC *)NULL);
762 /* Add LINE to the long documentation for the current builtin.
763 Ignore blank lines until the first non-blank line has been seen. */
765 add_documentation (defs, line)
769 register BUILTIN_DESC *builtin;
771 builtin = current_builtin ("(implied LONGDOC)", defs);
773 remove_trailing_whitespace (line);
775 if (!*line && !builtin->longdoc)
778 if (!builtin->longdoc)
779 builtin->longdoc = array_create (sizeof (char *));
781 array_add (line, builtin->longdoc);
784 /* How to handle the $BUILTIN directive. */
786 builtin_handler (self, defs, arg)
794 /* If we are already building a builtin, we cannot start a new one. */
795 if (building_builtin)
797 line_error (defs, "%s found before $END", self);
801 output_cpp_line_info++;
803 /* Get the name of this builtin, and stick it in the array. */
804 name = get_arg (self, defs, arg);
806 /* If this is the first builtin, create the array to hold them. */
808 defs->builtins = array_create (sizeof (BUILTIN_DESC *));
810 new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
812 new->function = (char *)NULL;
813 new->shortdoc = (char *)NULL;
814 new->docname = (char *)NULL;
815 new->longdoc = (ARRAY *)NULL;
816 new->dependencies = (ARRAY *)NULL;
819 if (is_special_builtin (name))
820 new->flags |= BUILTIN_FLAG_SPECIAL;
821 if (is_assignment_builtin (name))
822 new->flags |= BUILTIN_FLAG_ASSIGNMENT;
823 if (is_posix_builtin (name))
824 new->flags |= BUILTIN_FLAG_POSIX_BUILTIN;
826 array_add ((char *)new, defs->builtins);
827 building_builtin = 1;
832 /* How to handle the $FUNCTION directive. */
834 function_handler (self, defs, arg)
839 register BUILTIN_DESC *builtin;
841 builtin = current_builtin (self, defs);
845 line_error (defs, "syntax error: no current builtin for $FUNCTION directive");
848 if (builtin->function)
849 line_error (defs, "%s already has a function (%s)",
850 builtin->name, builtin->function);
852 builtin->function = get_arg (self, defs, arg);
857 /* How to handle the $DOCNAME directive. */
859 docname_handler (self, defs, arg)
864 register BUILTIN_DESC *builtin;
866 builtin = current_builtin (self, defs);
868 if (builtin->docname)
869 line_error (defs, "%s already had a docname (%s)",
870 builtin->name, builtin->docname);
872 builtin->docname = get_arg (self, defs, arg);
877 /* How to handle the $SHORT_DOC directive. */
879 short_doc_handler (self, defs, arg)
884 register BUILTIN_DESC *builtin;
886 builtin = current_builtin (self, defs);
888 if (builtin->shortdoc)
889 line_error (defs, "%s already has short documentation (%s)",
890 builtin->name, builtin->shortdoc);
892 builtin->shortdoc = get_arg (self, defs, arg);
897 /* How to handle the $COMMENT directive. */
899 comment_handler (self, defs, arg)
907 /* How to handle the $DEPENDS_ON directive. */
909 depends_on_handler (self, defs, arg)
914 register BUILTIN_DESC *builtin;
917 builtin = current_builtin (self, defs);
918 dependent = get_arg (self, defs, arg);
920 if (!builtin->dependencies)
921 builtin->dependencies = array_create (sizeof (char *));
923 array_add (dependent, builtin->dependencies);
928 /* How to handle the $PRODUCES directive. */
930 produces_handler (self, defs, arg)
935 /* If just hacking documentation, don't change any of the production
937 if (only_documentation)
940 output_cpp_line_info++;
942 if (defs->production)
943 line_error (defs, "%s already has a %s definition", defs->filename, self);
946 defs->production = get_arg (self, defs, arg);
948 if (inhibit_production)
951 defs->output = fopen (defs->production, "w");
954 file_error (defs->production);
956 fprintf (defs->output, "/* %s, created from %s. */\n",
957 defs->production, defs->filename);
962 /* How to handle the $END directive. */
964 end_handler (self, defs, arg)
969 must_be_building (self, defs);
970 building_builtin = 0;
974 /* **************************************************************** */
976 /* Error Handling Functions */
978 /* **************************************************************** */
980 /* Produce an error for DEFS with FORMAT and ARGS. */
982 line_error (defs, format, arg1, arg2)
984 char *format, *arg1, *arg2;
986 if (defs->filename[0] != '/')
987 fprintf (stderr, "%s", error_directory ? error_directory : "./");
988 fprintf (stderr, "%s:%d:", defs->filename, defs->line_number + 1);
989 fprintf (stderr, format, arg1, arg2);
990 fprintf (stderr, "\n");
994 /* Print error message for FILENAME. */
996 file_error (filename)
1003 /* **************************************************************** */
1005 /* xmalloc and xrealloc () */
1007 /* **************************************************************** */
1009 static void memory_error_and_abort ();
1015 char *temp = (char *)malloc (bytes);
1018 memory_error_and_abort ();
1023 xrealloc (pointer, bytes)
1030 temp = (char *)malloc (bytes);
1032 temp = (char *)realloc (pointer, bytes);
1035 memory_error_and_abort ();
1041 memory_error_and_abort ()
1043 fprintf (stderr, "mkbuiltins: out of virtual memory\n");
1047 /* **************************************************************** */
1049 /* Creating the Struct and Extern Files */
1051 /* **************************************************************** */
1053 /* Return a pointer to a newly allocated builtin which is
1054 an exact copy of BUILTIN. */
1056 copy_builtin (builtin)
1057 BUILTIN_DESC *builtin;
1061 new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
1063 new->name = savestring (builtin->name);
1064 new->shortdoc = savestring (builtin->shortdoc);
1065 new->longdoc = copy_string_array (builtin->longdoc);
1066 new->dependencies = copy_string_array (builtin->dependencies);
1069 builtin->function ? savestring (builtin->function) : (char *)NULL;
1071 builtin->docname ? savestring (builtin->docname) : (char *)NULL;
1076 /* How to save away a builtin. */
1078 save_builtin (builtin)
1079 BUILTIN_DESC *builtin;
1081 BUILTIN_DESC *newbuiltin;
1083 newbuiltin = copy_builtin (builtin);
1085 /* If this is the first builtin to be saved, create the array
1087 if (!saved_builtins)
1088 saved_builtins = array_create (sizeof (BUILTIN_DESC *));
1090 array_add ((char *)newbuiltin, saved_builtins);
1093 /* Flags that mean something to write_documentation (). */
1094 #define STRING_ARRAY 0x01
1095 #define TEXINFO 0x02
1096 #define PLAINTEXT 0x04
1097 #define HELPFILE 0x08
1099 char *structfile_header[] = {
1100 "/* builtins.c -- the built in shell commands. */",
1102 "/* This file is manufactured by ./mkbuiltins, and should not be",
1103 " edited by hand. See the source to mkbuiltins for details. */",
1105 "/* Copyright (C) 1987-2012 Free Software Foundation, Inc.",
1107 " This file is part of GNU Bash, the Bourne Again SHell.",
1109 " Bash is free software: you can redistribute it and/or modify",
1110 " it under the terms of the GNU General Public License as published by",
1111 " the Free Software Foundation, either version 3 of the License, or",
1112 " (at your option) any later version.",
1114 " Bash is distributed in the hope that it will be useful,",
1115 " but WITHOUT ANY WARRANTY; without even the implied warranty of",
1116 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
1117 " GNU General Public License for more details.",
1119 " You should have received a copy of the GNU General Public License",
1120 " along with Bash. If not, see <http://www.gnu.org/licenses/>.",
1123 "/* The list of shell builtins. Each element is name, function, flags,",
1124 " long-doc, short-doc. The long-doc field contains a pointer to an array",
1125 " of help lines. The function takes a WORD_LIST *; the first word in the",
1126 " list is the first arg to the command. The list has already had word",
1127 " expansion performed.",
1129 " Functions which need to look at only the simple commands (e.g.",
1130 " the enable_builtin ()), should ignore entries where",
1131 " (array[i].function == (sh_builtin_func_t *)NULL). Such entries are for",
1132 " the list of shell reserved control structures, like `if' and `while'.",
1133 " The end of the list is denoted with a NULL name field. */",
1135 "#include \"../builtins.h\"",
1139 char *structfile_footer[] = {
1140 " { (char *)0x0, (sh_builtin_func_t *)0x0, 0, (char **)0x0, (char *)0x0, (char *)0x0 }",
1143 "struct builtin *shell_builtins = static_shell_builtins;",
1144 "struct builtin *current_builtin;",
1146 "int num_shell_builtins =",
1147 "\tsizeof (static_shell_builtins) / sizeof (struct builtin) - 1;",
1151 /* Write out any necessary opening information for
1152 STRUCTFILE and EXTERNFILE. */
1154 write_file_headers (structfile, externfile)
1155 FILE *structfile, *externfile;
1161 for (i = 0; structfile_header[i]; i++)
1162 fprintf (structfile, "%s\n", structfile_header[i]);
1164 fprintf (structfile, "#include \"%s\"\n",
1165 extern_filename ? extern_filename : "builtext.h");
1167 fprintf (structfile, "#include \"bashintl.h\"\n");
1169 fprintf (structfile, "\nstruct builtin static_shell_builtins[] = {\n");
1173 fprintf (externfile,
1174 "/* %s - The list of builtins found in libbuiltins.a. */\n",
1175 extern_filename ? extern_filename : "builtext.h");
1178 /* Write out any necessary closing information for
1179 STRUCTFILE and EXTERNFILE. */
1181 write_file_footers (structfile, externfile)
1182 FILE *structfile, *externfile;
1186 /* Write out the footers. */
1189 for (i = 0; structfile_footer[i]; i++)
1190 fprintf (structfile, "%s\n", structfile_footer[i]);
1194 /* Write out the information accumulated in DEFS to
1195 STRUCTFILE and EXTERNFILE. */
1197 write_builtins (defs, structfile, externfile)
1199 FILE *structfile, *externfile;
1203 /* Write out the information. */
1206 register BUILTIN_DESC *builtin;
1208 for (i = 0; i < defs->builtins->sindex; i++)
1210 builtin = (BUILTIN_DESC *)defs->builtins->array[i];
1212 /* Write out any #ifdefs that may be there. */
1213 if (!only_documentation)
1215 if (builtin->dependencies)
1217 write_ifdefs (externfile, builtin->dependencies->array);
1218 write_ifdefs (structfile, builtin->dependencies->array);
1221 /* Write the extern definition. */
1224 if (builtin->function)
1225 fprintf (externfile, "extern int %s __P((WORD_LIST *));\n",
1228 fprintf (externfile, "extern char * const %s_doc[];\n",
1229 document_name (builtin));
1232 /* Write the structure definition. */
1235 fprintf (structfile, " { \"%s\", ", builtin->name);
1237 if (builtin->function && inhibit_functions == 0)
1238 fprintf (structfile, "%s, ", builtin->function);
1240 fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
1242 fprintf (structfile, "%s%s%s%s, %s_doc,\n",
1243 "BUILTIN_ENABLED | STATIC_BUILTIN",
1244 (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
1245 (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
1246 (builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "",
1247 document_name (builtin));
1249 if (inhibit_functions)
1251 (structfile, " N_(\"%s\"), \"%s\" },\n",
1252 builtin->shortdoc ? builtin->shortdoc : builtin->name,
1253 document_name (builtin));
1256 (structfile, " N_(\"%s\"), (char *)NULL },\n",
1257 builtin->shortdoc ? builtin->shortdoc : builtin->name);
1261 if (structfile || separate_helpfiles)
1262 /* Save away this builtin for later writing of the
1263 long documentation strings. */
1264 save_builtin (builtin);
1266 /* Write out the matching #endif, if necessary. */
1267 if (builtin->dependencies)
1270 write_endifs (externfile, builtin->dependencies->array);
1273 write_endifs (structfile, builtin->dependencies->array);
1277 if (documentation_file)
1279 fprintf (documentation_file, "@item %s\n", builtin->name);
1281 (documentation_file, builtin->longdoc->array, 0, TEXINFO);
1287 /* Write out the long documentation strings in BUILTINS to STREAM. */
1289 write_longdocs (stream, builtins)
1294 register BUILTIN_DESC *builtin;
1298 for (i = 0; i < builtins->sindex; i++)
1300 builtin = (BUILTIN_DESC *)builtins->array[i];
1302 if (builtin->dependencies)
1303 write_ifdefs (stream, builtin->dependencies->array);
1305 /* Write the long documentation strings. */
1306 dname = document_name (builtin);
1307 fprintf (stream, "char * const %s_doc[] =", dname);
1309 if (separate_helpfiles)
1311 int l = strlen (helpfile_directory) + strlen (dname) + 1;
1312 sarray[0] = (char *)xmalloc (l + 1);
1313 sprintf (sarray[0], "%s/%s", helpfile_directory, dname);
1314 sarray[1] = (char *)NULL;
1315 write_documentation (stream, sarray, 0, STRING_ARRAY|HELPFILE);
1319 write_documentation (stream, builtin->longdoc->array, 0, STRING_ARRAY);
1321 if (builtin->dependencies)
1322 write_endifs (stream, builtin->dependencies->array);
1328 write_dummy_declarations (stream, builtins)
1333 BUILTIN_DESC *builtin;
1335 for (i = 0; structfile_header[i]; i++)
1336 fprintf (stream, "%s\n", structfile_header[i]);
1338 for (i = 0; i < builtins->sindex; i++)
1340 builtin = (BUILTIN_DESC *)builtins->array[i];
1342 /* How to guarantee that no builtin is written more than once? */
1343 fprintf (stream, "int %s () { return (0); }\n", builtin->function);
1347 /* Write an #ifdef string saying what needs to be defined (or not defined)
1348 in order to allow compilation of the code that will follow.
1349 STREAM is the stream to write the information to,
1350 DEFINES is a null terminated array of define names.
1351 If a define is preceded by an `!', then the sense of the test is
1354 write_ifdefs (stream, defines)
1363 fprintf (stream, "#if ");
1365 for (i = 0; defines[i]; i++)
1367 char *def = defines[i];
1370 fprintf (stream, "!defined (%s)", def + 1);
1372 fprintf (stream, "defined (%s)", def);
1375 fprintf (stream, " && ");
1377 fprintf (stream, "\n");
1380 /* Write an #endif string saying what defines controlled the compilation
1381 of the immediately preceding code.
1382 STREAM is the stream to write the information to.
1383 DEFINES is a null terminated array of define names. */
1385 write_endifs (stream, defines)
1394 fprintf (stream, "#endif /* ");
1396 for (i = 0; defines[i]; i++)
1398 fprintf (stream, "%s", defines[i]);
1401 fprintf (stream, " && ");
1404 fprintf (stream, " */\n");
1407 /* Write DOCUMENTATION to STREAM, perhaps surrounding it with double-quotes
1408 and quoting special characters in the string. Handle special things for
1409 internationalization (gettext) and the single-string vs. multiple-strings
1412 write_documentation (stream, documentation, indentation, flags)
1414 char **documentation;
1415 int indentation, flags;
1418 register char *line;
1419 int string_array, texinfo, base_indent, filename_p;
1424 string_array = flags & STRING_ARRAY;
1425 filename_p = flags & HELPFILE;
1429 fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n"); /* } */
1430 if (single_longdoc_strings)
1432 if (filename_p == 0)
1434 if (documentation && documentation[0] && documentation[0][0])
1435 fprintf (stream, "N_(\"");
1437 fprintf (stream, "N_(\" "); /* the empty string translates specially. */
1440 fprintf (stream, "\"");
1444 base_indent = (string_array && single_longdoc_strings && filename_p == 0) ? BASE_INDENT : 0;
1446 for (i = 0, texinfo = (flags & TEXINFO); documentation && (line = documentation[i]); i++)
1448 /* Allow #ifdef's to be written out verbatim, but don't put them into
1449 separate help files. */
1452 if (string_array && filename_p == 0 && single_longdoc_strings == 0)
1453 fprintf (stream, "%s\n", line);
1457 /* prefix with N_( for gettext */
1458 if (string_array && single_longdoc_strings == 0)
1460 if (filename_p == 0)
1463 fprintf (stream, " N_(\"");
1465 fprintf (stream, " N_(\" "); /* the empty string translates specially. */
1468 fprintf (stream, " \"");
1472 for (j = 0; j < indentation; j++)
1473 fprintf (stream, " ");
1475 /* Don't indent the first line, because of how the help builtin works. */
1477 indentation += base_indent;
1481 for (j = 0; line[j]; j++)
1487 fprintf (stream, "\\%c", line[j]);
1491 fprintf (stream, "%c", line[j]);
1495 /* closing right paren for gettext */
1496 if (single_longdoc_strings == 0)
1498 if (filename_p == 0)
1499 fprintf (stream, "\"),\n");
1501 fprintf (stream, "\",\n");
1503 else if (documentation[i+1])
1504 /* don't add extra newline after last line */
1505 fprintf (stream, "\\n\\\n");
1509 for (j = 0; line[j]; j++)
1516 fprintf (stream, "@%c", line[j]);
1520 fprintf (stream, "%c", line[j]);
1523 fprintf (stream, "\n");
1526 fprintf (stream, "%s\n", line);
1529 /* closing right paren for gettext */
1530 if (string_array && single_longdoc_strings)
1532 if (filename_p == 0)
1533 fprintf (stream, "\"),\n");
1535 fprintf (stream, "\",\n");
1539 fprintf (stream, "#endif /* HELP_BUILTIN */\n (char *)NULL\n};\n");
1543 write_helpfiles (builtins)
1546 char *helpfile, *bname;
1549 BUILTIN_DESC *builtin;
1551 i = mkdir ("helpfiles", 0777);
1552 if (i < 0 && errno != EEXIST)
1554 fprintf (stderr, "write_helpfiles: helpfiles: cannot create directory\n");
1558 hdlen = strlen ("helpfiles/");
1559 for (i = 0; i < builtins->sindex; i++)
1561 builtin = (BUILTIN_DESC *)builtins->array[i];
1563 bname = document_name (builtin);
1564 helpfile = (char *)xmalloc (hdlen + strlen (bname) + 1);
1565 sprintf (helpfile, "helpfiles/%s", bname);
1567 helpfp = fopen (helpfile, "w");
1570 fprintf (stderr, "write_helpfiles: cannot open %s\n", helpfile);
1575 write_documentation (helpfp, builtin->longdoc->array, 4, PLAINTEXT);
1585 _find_in_table (name, name_table)
1586 char *name, *name_table[];
1590 for (i = 0; name_table[i]; i++)
1591 if (strcmp (name, name_table[i]) == 0)
1597 is_special_builtin (name)
1600 return (_find_in_table (name, special_builtins));
1604 is_assignment_builtin (name)
1607 return (_find_in_table (name, assignment_builtins));
1611 is_posix_builtin (name)
1614 return (_find_in_table (name, posix_builtins));
1617 #if !defined (HAVE_RENAME)
1623 if (link (from, to) < 0)
1628 #endif /* !HAVE_RENAME */