1 /* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from
2 a single source file called builtins.def. */
4 /* Copyright (C) 1987-2009 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 produce separate help files for each builtin, named by
89 the builtin name, in `./helpfiles'. */
90 int separate_helpfiles = 0;
92 /* Non-zero means to create single C strings for each `longdoc', with
93 embedded newlines, for ease of translation. */
94 int single_longdoc_strings = 1;
96 /* The name of a directory into which the separate external help files will
97 eventually be installed. */
98 char *helpfile_directory;
100 /* The name of a directory to precede the filename when reporting
102 char *error_directory = (char *)NULL;
104 /* The name of the structure file. */
105 char *struct_filename = (char *)NULL;
107 /* The name of the external declaration file. */
108 char *extern_filename = (char *)NULL;
110 /* Here is a structure for manipulating arrays of data. */
112 int size; /* Number of slots allocated to array. */
113 int sindex; /* Current location in array. */
114 int width; /* Size of each element. */
115 int growth_rate; /* How fast to grow. */
116 char **array; /* The array itself. */
119 /* Here is a structure defining a single BUILTIN. */
121 char *name; /* The name of this builtin. */
122 char *function; /* The name of the function to call. */
123 char *shortdoc; /* The short documentation for this builtin. */
124 char *docname; /* Possible name for documentation string. */
125 ARRAY *longdoc; /* The long documentation for this builtin. */
126 ARRAY *dependencies; /* Null terminated array of #define names. */
127 int flags; /* Flags for this builtin. */
130 /* Here is a structure which defines a DEF file. */
132 char *filename; /* The name of the input def file. */
133 ARRAY *lines; /* The contents of the file. */
134 int line_number; /* The current line number. */
135 char *production; /* The name of the production file. */
136 FILE *output; /* Open file stream for PRODUCTION. */
137 ARRAY *builtins; /* Null terminated array of BUILTIN_DESC *. */
140 /* The array of all builtins encountered during execution of this code. */
141 ARRAY *saved_builtins = (ARRAY *)NULL;
143 /* The Posix.2 so-called `special' builtins. */
144 char *special_builtins[] =
146 ":", ".", "source", "break", "continue", "eval", "exec", "exit",
147 "export", "readonly", "return", "set", "shift", "times", "trap", "unset",
151 /* The builtin commands that take assignment statements as arguments. */
152 char *assignment_builtins[] =
154 "alias", "declare", "export", "local", "readonly", "typeset",
158 /* The builtin commands that are special to the POSIX search order. */
159 char *posix_builtins[] =
161 "alias", "bg", "cd", "command", "false", "fc", "fg", "getopts", "jobs",
162 "kill", "newgrp", "pwd", "read", "true", "umask", "unalias", "wait",
166 /* Forward declarations. */
167 static int is_special_builtin ();
168 static int is_assignment_builtin ();
169 static int is_posix_builtin ();
171 #if !defined (HAVE_RENAME)
172 static int rename ();
175 void extract_info ();
180 void write_file_headers ();
181 void write_file_footers ();
182 void write_ifdefs ();
183 void write_endifs ();
184 void write_documentation ();
185 void write_longdocs ();
186 void write_builtins ();
188 int write_helpfiles ();
191 void add_documentation ();
193 void must_be_building ();
194 void remove_trailing_whitespace ();
196 #define document_name(b) ((b)->docname ? (b)->docname : (b)->name)
199 /* For each file mentioned on the command line, process it and
200 write the information to STRUCTFILE and EXTERNFILE, while
201 creating the production file if neccessary. */
208 FILE *structfile, *externfile;
209 char *documentation_filename, *temp_struct_filename;
211 structfile = externfile = (FILE *)NULL;
212 documentation_filename = DOCFILE;
213 temp_struct_filename = (char *)NULL;
215 while (arg_index < argc && argv[arg_index][0] == '-')
217 char *arg = argv[arg_index++];
219 if (strcmp (arg, "-externfile") == 0)
220 extern_filename = argv[arg_index++];
221 else if (strcmp (arg, "-structfile") == 0)
222 struct_filename = argv[arg_index++];
223 else if (strcmp (arg, "-noproduction") == 0)
224 inhibit_production = 1;
225 else if (strcmp (arg, "-document") == 0)
226 documentation_file = fopen (documentation_filename, "w");
227 else if (strcmp (arg, "-D") == 0)
232 free (error_directory);
234 error_directory = xmalloc (2 + strlen (argv[arg_index]));
235 strcpy (error_directory, argv[arg_index]);
236 len = strlen (error_directory);
238 if (len && error_directory[len - 1] != '/')
239 strcat (error_directory, "/");
243 else if (strcmp (arg, "-documentonly") == 0)
245 only_documentation = 1;
246 documentation_file = fopen (documentation_filename, "w");
248 else if (strcmp (arg, "-H") == 0)
250 separate_helpfiles = 1;
251 helpfile_directory = argv[arg_index++];
253 else if (strcmp (arg, "-S") == 0)
254 single_longdoc_strings = 0;
257 fprintf (stderr, "%s: Unknown flag %s.\n", argv[0], arg);
262 /* If there are no files to process, just quit now. */
263 if (arg_index == argc)
266 if (!only_documentation)
268 /* Open the files. */
271 temp_struct_filename = xmalloc (15);
272 sprintf (temp_struct_filename, "mk-%ld", (long) getpid ());
273 structfile = fopen (temp_struct_filename, "w");
276 file_error (temp_struct_filename);
281 externfile = fopen (extern_filename, "w");
284 file_error (extern_filename);
287 /* Write out the headers. */
288 write_file_headers (structfile, externfile);
291 if (documentation_file)
293 fprintf (documentation_file, "@c Table of builtins created with %s.\n",
295 fprintf (documentation_file, "@ftable @asis\n");
298 /* Process the .def files. */
299 while (arg_index < argc)
303 arg = argv[arg_index++];
305 extract_info (arg, structfile, externfile);
308 /* Close the files. */
309 if (!only_documentation)
311 /* Write the footers. */
312 write_file_footers (structfile, externfile);
316 write_longdocs (structfile, saved_builtins);
318 rename (temp_struct_filename, struct_filename);
325 if (separate_helpfiles)
327 write_helpfiles (saved_builtins);
330 if (documentation_file)
332 fprintf (documentation_file, "@end ftable\n");
333 fclose (documentation_file);
339 /* **************************************************************** */
341 /* Array Functions and Manipulators */
343 /* **************************************************************** */
345 /* Make a new array, and return a pointer to it. The array will
346 contain elements of size WIDTH, and is initialized to no elements. */
353 array = (ARRAY *)xmalloc (sizeof (ARRAY));
356 array->width = width;
358 /* Default to increasing size in units of 20. */
359 array->growth_rate = 20;
361 array->array = (char **)NULL;
366 /* Copy the array of strings in ARRAY. */
368 copy_string_array (array)
375 return (ARRAY *)NULL;
377 copy = array_create (sizeof (char *));
379 copy->size = array->size;
380 copy->sindex = array->sindex;
381 copy->width = array->width;
383 copy->array = (char **)xmalloc ((1 + array->sindex) * sizeof (char *));
385 for (i = 0; i < array->sindex; i++)
386 copy->array[i] = savestring (array->array[i]);
388 copy->array[i] = (char *)NULL;
393 /* Add ELEMENT to ARRAY, growing the array if neccessary. */
395 array_add (element, array)
399 if (array->sindex + 2 > array->size)
400 array->array = (char **)xrealloc
401 (array->array, (array->size += array->growth_rate) * array->width);
403 array->array[array->sindex++] = element;
404 array->array[array->sindex] = (char *)NULL;
407 /* Free an allocated array and data pointer. */
418 /* **************************************************************** */
420 /* Processing a DEF File */
422 /* **************************************************************** */
424 /* The definition of a function. */
425 typedef int Function ();
426 typedef int mk_handler_func_t __P((char *, DEF_FILE *, char *));
428 /* Structure handles processor directives. */
431 mk_handler_func_t *function;
434 extern int builtin_handler __P((char *, DEF_FILE *, char *));
435 extern int function_handler __P((char *, DEF_FILE *, char *));
436 extern int short_doc_handler __P((char *, DEF_FILE *, char *));
437 extern int comment_handler __P((char *, DEF_FILE *, char *));
438 extern int depends_on_handler __P((char *, DEF_FILE *, char *));
439 extern int produces_handler __P((char *, DEF_FILE *, char *));
440 extern int end_handler __P((char *, DEF_FILE *, char *));
441 extern int docname_handler __P((char *, DEF_FILE *, char *));
443 HANDLER_ENTRY handlers[] = {
444 { "BUILTIN", builtin_handler },
445 { "DOCNAME", docname_handler },
446 { "FUNCTION", function_handler },
447 { "SHORT_DOC", short_doc_handler },
448 { "$", comment_handler },
449 { "COMMENT", comment_handler },
450 { "DEPENDS_ON", depends_on_handler },
451 { "PRODUCES", produces_handler },
452 { "END", end_handler },
453 { (char *)NULL, (mk_handler_func_t *)NULL }
456 /* Return the entry in the table of handlers for NAME. */
458 find_directive (directive)
463 for (i = 0; handlers[i].directive; i++)
464 if (strcmp (handlers[i].directive, directive) == 0)
465 return (&handlers[i]);
467 return ((HANDLER_ENTRY *)NULL);
470 /* Non-zero indicates that a $BUILTIN has been seen, but not
471 the corresponding $END. */
472 static int building_builtin = 0;
474 /* Non-zero means to output cpp line and file information before
475 printing the current line to the production file. */
476 int output_cpp_line_info = 0;
478 /* The main function of this program. Read FILENAME and act on what is
479 found. Lines not starting with a dollar sign are copied to the
480 $PRODUCES target, if one is present. Lines starting with a dollar sign
481 are directives to this program, specifying the name of the builtin, the
482 function to call, the short documentation and the long documentation
483 strings. FILENAME can contain multiple $BUILTINs, but only one $PRODUCES
484 target. After the file has been processed, write out the names of
485 builtins found in each $BUILTIN. Plain text found before the $PRODUCES
486 is ignored, as is "$$ comment text". */
488 extract_info (filename, structfile, externfile)
490 FILE *structfile, *externfile;
499 if (stat (filename, &finfo) == -1)
500 file_error (filename);
502 fd = open (filename, O_RDONLY, 0666);
505 file_error (filename);
507 file_size = (size_t)finfo.st_size;
508 buffer = xmalloc (1 + file_size);
510 if ((nr = read (fd, buffer, file_size)) < 0)
511 file_error (filename);
513 /* This is needed on WIN32, and does not hurt on Unix. */
521 fprintf (stderr, "mkbuiltins: %s: skipping zero-length file\n", filename);
525 /* Create and fill in the initial structure describing this file. */
526 defs = (DEF_FILE *)xmalloc (sizeof (DEF_FILE));
527 defs->filename = filename;
528 defs->lines = array_create (sizeof (char *));
529 defs->line_number = 0;
530 defs->production = (char *)NULL;
531 defs->output = (FILE *)NULL;
532 defs->builtins = (ARRAY *)NULL;
534 /* Build the array of lines. */
536 while (i < file_size)
538 array_add (&buffer[i], defs->lines);
540 while (buffer[i] != '\n' && i < file_size)
545 /* Begin processing the input file. We don't write any output
546 until we have a file to write output to. */
547 output_cpp_line_info = 1;
549 /* Process each line in the array. */
550 for (i = 0; line = defs->lines->array[i]; i++)
552 defs->line_number = i;
558 HANDLER_ENTRY *handler;
560 /* Isolate the directive. */
561 for (j = 0; line[j] && !whitespace (line[j]); j++);
563 directive = xmalloc (j);
564 strncpy (directive, line + 1, j - 1);
565 directive[j -1] = '\0';
567 /* Get the function handler and call it. */
568 handler = find_directive (directive);
572 line_error (defs, "Unknown directive `%s'", directive);
578 /* Advance to the first non-whitespace character. */
579 while (whitespace (line[j]))
582 /* Call the directive handler with the FILE, and ARGS. */
583 (*(handler->function)) (directive, defs, line + j);
589 if (building_builtin)
590 add_documentation (defs, line);
591 else if (defs->output)
593 if (output_cpp_line_info)
595 /* If we're handed an absolute pathname, don't prepend
596 the directory name. */
597 if (defs->filename[0] == '/')
598 fprintf (defs->output, "#line %d \"%s\"\n",
599 defs->line_number + 1, defs->filename);
601 fprintf (defs->output, "#line %d \"%s%s\"\n",
602 defs->line_number + 1,
603 error_directory ? error_directory : "./",
605 output_cpp_line_info = 0;
608 fprintf (defs->output, "%s\n", line);
613 /* Close the production file. */
615 fclose (defs->output);
617 /* The file has been processed. Write the accumulated builtins to
618 the builtins.c file, and write the extern definitions to the
620 write_builtins (defs, structfile, externfile);
626 #define free_safely(x) if (x) free (x)
629 free_builtin (builtin)
630 BUILTIN_DESC *builtin;
634 free_safely (builtin->name);
635 free_safely (builtin->function);
636 free_safely (builtin->shortdoc);
637 free_safely (builtin->docname);
639 if (builtin->longdoc)
640 array_free (builtin->longdoc);
642 if (builtin->dependencies)
644 for (i = 0; builtin->dependencies->array[i]; i++)
645 free (builtin->dependencies->array[i]);
646 array_free (builtin->dependencies);
650 /* Free all of the memory allocated to a DEF_FILE. */
656 register BUILTIN_DESC *builtin;
658 if (defs->production)
659 free (defs->production);
662 array_free (defs->lines);
666 for (i = 0; builtin = (BUILTIN_DESC *)defs->builtins->array[i]; i++)
668 free_builtin (builtin);
671 array_free (defs->builtins);
676 /* **************************************************************** */
678 /* The Handler Functions Themselves */
680 /* **************************************************************** */
682 /* Strip surrounding whitespace from STRING, and
683 return a pointer to the start of it. */
685 strip_whitespace (string)
688 while (whitespace (*string))
691 remove_trailing_whitespace (string);
695 /* Remove only the trailing whitespace from STRING. */
697 remove_trailing_whitespace (string)
702 i = strlen (string) - 1;
704 while (i > 0 && whitespace (string[i]))
710 /* Ensure that there is a argument in STRING and return it.
711 FOR_WHOM is the name of the directive which needs the argument.
712 DEFS is the DEF_FILE in which the directive is found.
713 If there is no argument, produce an error. */
715 get_arg (for_whom, defs, string)
716 char *for_whom, *string;
721 new = strip_whitespace (string);
724 line_error (defs, "%s requires an argument", for_whom);
726 return (savestring (new));
729 /* Error if not building a builtin. */
731 must_be_building (directive, defs)
735 if (!building_builtin)
736 line_error (defs, "%s must be inside of a $BUILTIN block", directive);
739 /* Return the current builtin. */
741 current_builtin (directive, defs)
745 must_be_building (directive, defs);
747 return ((BUILTIN_DESC *)defs->builtins->array[defs->builtins->sindex - 1]);
749 return ((BUILTIN_DESC *)NULL);
752 /* Add LINE to the long documentation for the current builtin.
753 Ignore blank lines until the first non-blank line has been seen. */
755 add_documentation (defs, line)
759 register BUILTIN_DESC *builtin;
761 builtin = current_builtin ("(implied LONGDOC)", defs);
763 remove_trailing_whitespace (line);
765 if (!*line && !builtin->longdoc)
768 if (!builtin->longdoc)
769 builtin->longdoc = array_create (sizeof (char *));
771 array_add (line, builtin->longdoc);
774 /* How to handle the $BUILTIN directive. */
776 builtin_handler (self, defs, arg)
784 /* If we are already building a builtin, we cannot start a new one. */
785 if (building_builtin)
787 line_error (defs, "%s found before $END", self);
791 output_cpp_line_info++;
793 /* Get the name of this builtin, and stick it in the array. */
794 name = get_arg (self, defs, arg);
796 /* If this is the first builtin, create the array to hold them. */
798 defs->builtins = array_create (sizeof (BUILTIN_DESC *));
800 new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
802 new->function = (char *)NULL;
803 new->shortdoc = (char *)NULL;
804 new->docname = (char *)NULL;
805 new->longdoc = (ARRAY *)NULL;
806 new->dependencies = (ARRAY *)NULL;
809 if (is_special_builtin (name))
810 new->flags |= BUILTIN_FLAG_SPECIAL;
811 if (is_assignment_builtin (name))
812 new->flags |= BUILTIN_FLAG_ASSIGNMENT;
813 if (is_posix_builtin (name))
814 new->flags |= BUILTIN_FLAG_POSIX_BUILTIN;
816 array_add ((char *)new, defs->builtins);
817 building_builtin = 1;
822 /* How to handle the $FUNCTION directive. */
824 function_handler (self, defs, arg)
829 register BUILTIN_DESC *builtin;
831 builtin = current_builtin (self, defs);
835 line_error (defs, "syntax error: no current builtin for $FUNCTION directive");
838 if (builtin->function)
839 line_error (defs, "%s already has a function (%s)",
840 builtin->name, builtin->function);
842 builtin->function = get_arg (self, defs, arg);
847 /* How to handle the $DOCNAME directive. */
849 docname_handler (self, defs, arg)
854 register BUILTIN_DESC *builtin;
856 builtin = current_builtin (self, defs);
858 if (builtin->docname)
859 line_error (defs, "%s already had a docname (%s)",
860 builtin->name, builtin->docname);
862 builtin->docname = get_arg (self, defs, arg);
867 /* How to handle the $SHORT_DOC directive. */
869 short_doc_handler (self, defs, arg)
874 register BUILTIN_DESC *builtin;
876 builtin = current_builtin (self, defs);
878 if (builtin->shortdoc)
879 line_error (defs, "%s already has short documentation (%s)",
880 builtin->name, builtin->shortdoc);
882 builtin->shortdoc = get_arg (self, defs, arg);
887 /* How to handle the $COMMENT directive. */
889 comment_handler (self, defs, arg)
897 /* How to handle the $DEPENDS_ON directive. */
899 depends_on_handler (self, defs, arg)
904 register BUILTIN_DESC *builtin;
907 builtin = current_builtin (self, defs);
908 dependent = get_arg (self, defs, arg);
910 if (!builtin->dependencies)
911 builtin->dependencies = array_create (sizeof (char *));
913 array_add (dependent, builtin->dependencies);
918 /* How to handle the $PRODUCES directive. */
920 produces_handler (self, defs, arg)
925 /* If just hacking documentation, don't change any of the production
927 if (only_documentation)
930 output_cpp_line_info++;
932 if (defs->production)
933 line_error (defs, "%s already has a %s definition", defs->filename, self);
936 defs->production = get_arg (self, defs, arg);
938 if (inhibit_production)
941 defs->output = fopen (defs->production, "w");
944 file_error (defs->production);
946 fprintf (defs->output, "/* %s, created from %s. */\n",
947 defs->production, defs->filename);
952 /* How to handle the $END directive. */
954 end_handler (self, defs, arg)
959 must_be_building (self, defs);
960 building_builtin = 0;
964 /* **************************************************************** */
966 /* Error Handling Functions */
968 /* **************************************************************** */
970 /* Produce an error for DEFS with FORMAT and ARGS. */
972 line_error (defs, format, arg1, arg2)
974 char *format, *arg1, *arg2;
976 if (defs->filename[0] != '/')
977 fprintf (stderr, "%s", error_directory ? error_directory : "./");
978 fprintf (stderr, "%s:%d:", defs->filename, defs->line_number + 1);
979 fprintf (stderr, format, arg1, arg2);
980 fprintf (stderr, "\n");
984 /* Print error message for FILENAME. */
986 file_error (filename)
993 /* **************************************************************** */
995 /* xmalloc and xrealloc () */
997 /* **************************************************************** */
999 static void memory_error_and_abort ();
1005 char *temp = (char *)malloc (bytes);
1008 memory_error_and_abort ();
1013 xrealloc (pointer, bytes)
1020 temp = (char *)malloc (bytes);
1022 temp = (char *)realloc (pointer, bytes);
1025 memory_error_and_abort ();
1031 memory_error_and_abort ()
1033 fprintf (stderr, "mkbuiltins: out of virtual memory\n");
1037 /* **************************************************************** */
1039 /* Creating the Struct and Extern Files */
1041 /* **************************************************************** */
1043 /* Return a pointer to a newly allocated builtin which is
1044 an exact copy of BUILTIN. */
1046 copy_builtin (builtin)
1047 BUILTIN_DESC *builtin;
1051 new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
1053 new->name = savestring (builtin->name);
1054 new->shortdoc = savestring (builtin->shortdoc);
1055 new->longdoc = copy_string_array (builtin->longdoc);
1056 new->dependencies = copy_string_array (builtin->dependencies);
1059 builtin->function ? savestring (builtin->function) : (char *)NULL;
1061 builtin->docname ? savestring (builtin->docname) : (char *)NULL;
1066 /* How to save away a builtin. */
1068 save_builtin (builtin)
1069 BUILTIN_DESC *builtin;
1071 BUILTIN_DESC *newbuiltin;
1073 newbuiltin = copy_builtin (builtin);
1075 /* If this is the first builtin to be saved, create the array
1077 if (!saved_builtins)
1078 saved_builtins = array_create (sizeof (BUILTIN_DESC *));
1080 array_add ((char *)newbuiltin, saved_builtins);
1083 /* Flags that mean something to write_documentation (). */
1084 #define STRING_ARRAY 0x01
1085 #define TEXINFO 0x02
1086 #define PLAINTEXT 0x04
1087 #define HELPFILE 0x08
1089 char *structfile_header[] = {
1090 "/* builtins.c -- the built in shell commands. */",
1092 "/* This file is manufactured by ./mkbuiltins, and should not be",
1093 " edited by hand. See the source to mkbuiltins for details. */",
1095 "/* Copyright (C) 1987-2009 Free Software Foundation, Inc.",
1097 " This file is part of GNU Bash, the Bourne Again SHell.",
1099 " Bash is free software: you can redistribute it and/or modify",
1100 " it under the terms of the GNU General Public License as published by",
1101 " the Free Software Foundation, either version 3 of the License, or",
1102 " (at your option) any later version.",
1104 " Bash is distributed in the hope that it will be useful,",
1105 " but WITHOUT ANY WARRANTY; without even the implied warranty of",
1106 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
1107 " GNU General Public License for more details.",
1109 " You should have received a copy of the GNU General Public License",
1110 " along with Bash. If not, see <http://www.gnu.org/licenses/>.",
1113 "/* The list of shell builtins. Each element is name, function, flags,",
1114 " long-doc, short-doc. The long-doc field contains a pointer to an array",
1115 " of help lines. The function takes a WORD_LIST *; the first word in the",
1116 " list is the first arg to the command. The list has already had word",
1117 " expansion performed.",
1119 " Functions which need to look at only the simple commands (e.g.",
1120 " the enable_builtin ()), should ignore entries where",
1121 " (array[i].function == (sh_builtin_func_t *)NULL). Such entries are for",
1122 " the list of shell reserved control structures, like `if' and `while'.",
1123 " The end of the list is denoted with a NULL name field. */",
1125 "#include \"../builtins.h\"",
1129 char *structfile_footer[] = {
1130 " { (char *)0x0, (sh_builtin_func_t *)0x0, 0, (char **)0x0, (char *)0x0 }",
1133 "struct builtin *shell_builtins = static_shell_builtins;",
1134 "struct builtin *current_builtin;",
1136 "int num_shell_builtins =",
1137 "\tsizeof (static_shell_builtins) / sizeof (struct builtin) - 1;",
1141 /* Write out any neccessary opening information for
1142 STRUCTFILE and EXTERNFILE. */
1144 write_file_headers (structfile, externfile)
1145 FILE *structfile, *externfile;
1151 for (i = 0; structfile_header[i]; i++)
1152 fprintf (structfile, "%s\n", structfile_header[i]);
1154 fprintf (structfile, "#include \"%s\"\n",
1155 extern_filename ? extern_filename : "builtext.h");
1157 fprintf (structfile, "#include \"bashintl.h\"\n");
1159 fprintf (structfile, "\nstruct builtin static_shell_builtins[] = {\n");
1163 fprintf (externfile,
1164 "/* %s - The list of builtins found in libbuiltins.a. */\n",
1165 extern_filename ? extern_filename : "builtext.h");
1168 /* Write out any necessary closing information for
1169 STRUCTFILE and EXTERNFILE. */
1171 write_file_footers (structfile, externfile)
1172 FILE *structfile, *externfile;
1176 /* Write out the footers. */
1179 for (i = 0; structfile_footer[i]; i++)
1180 fprintf (structfile, "%s\n", structfile_footer[i]);
1184 /* Write out the information accumulated in DEFS to
1185 STRUCTFILE and EXTERNFILE. */
1187 write_builtins (defs, structfile, externfile)
1189 FILE *structfile, *externfile;
1193 /* Write out the information. */
1196 register BUILTIN_DESC *builtin;
1198 for (i = 0; i < defs->builtins->sindex; i++)
1200 builtin = (BUILTIN_DESC *)defs->builtins->array[i];
1202 /* Write out any #ifdefs that may be there. */
1203 if (!only_documentation)
1205 if (builtin->dependencies)
1207 write_ifdefs (externfile, builtin->dependencies->array);
1208 write_ifdefs (structfile, builtin->dependencies->array);
1211 /* Write the extern definition. */
1214 if (builtin->function)
1215 fprintf (externfile, "extern int %s __P((WORD_LIST *));\n",
1218 fprintf (externfile, "extern char * const %s_doc[];\n",
1219 document_name (builtin));
1222 /* Write the structure definition. */
1225 fprintf (structfile, " { \"%s\", ", builtin->name);
1227 if (builtin->function)
1228 fprintf (structfile, "%s, ", builtin->function);
1230 fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
1232 fprintf (structfile, "%s%s%s%s, %s_doc,\n",
1233 "BUILTIN_ENABLED | STATIC_BUILTIN",
1234 (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
1235 (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
1236 (builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "",
1237 document_name (builtin));
1240 (structfile, " N_(\"%s\"), (char *)NULL },\n",
1241 builtin->shortdoc ? builtin->shortdoc : builtin->name);
1245 if (structfile || separate_helpfiles)
1246 /* Save away this builtin for later writing of the
1247 long documentation strings. */
1248 save_builtin (builtin);
1250 /* Write out the matching #endif, if neccessary. */
1251 if (builtin->dependencies)
1254 write_endifs (externfile, builtin->dependencies->array);
1257 write_endifs (structfile, builtin->dependencies->array);
1261 if (documentation_file)
1263 fprintf (documentation_file, "@item %s\n", builtin->name);
1265 (documentation_file, builtin->longdoc->array, 0, TEXINFO);
1271 /* Write out the long documentation strings in BUILTINS to STREAM. */
1273 write_longdocs (stream, builtins)
1278 register BUILTIN_DESC *builtin;
1282 for (i = 0; i < builtins->sindex; i++)
1284 builtin = (BUILTIN_DESC *)builtins->array[i];
1286 if (builtin->dependencies)
1287 write_ifdefs (stream, builtin->dependencies->array);
1289 /* Write the long documentation strings. */
1290 dname = document_name (builtin);
1291 fprintf (stream, "char * const %s_doc[] =", dname);
1293 if (separate_helpfiles)
1295 int l = strlen (helpfile_directory) + strlen (dname) + 1;
1296 sarray[0] = (char *)xmalloc (l + 1);
1297 sprintf (sarray[0], "%s/%s", helpfile_directory, dname);
1298 sarray[1] = (char *)NULL;
1299 write_documentation (stream, sarray, 0, STRING_ARRAY|HELPFILE);
1303 write_documentation (stream, builtin->longdoc->array, 0, STRING_ARRAY);
1305 if (builtin->dependencies)
1306 write_endifs (stream, builtin->dependencies->array);
1311 /* Write an #ifdef string saying what needs to be defined (or not defined)
1312 in order to allow compilation of the code that will follow.
1313 STREAM is the stream to write the information to,
1314 DEFINES is a null terminated array of define names.
1315 If a define is preceded by an `!', then the sense of the test is
1318 write_ifdefs (stream, defines)
1327 fprintf (stream, "#if ");
1329 for (i = 0; defines[i]; i++)
1331 char *def = defines[i];
1334 fprintf (stream, "!defined (%s)", def + 1);
1336 fprintf (stream, "defined (%s)", def);
1339 fprintf (stream, " && ");
1341 fprintf (stream, "\n");
1344 /* Write an #endif string saying what defines controlled the compilation
1345 of the immediately preceding code.
1346 STREAM is the stream to write the information to.
1347 DEFINES is a null terminated array of define names. */
1349 write_endifs (stream, defines)
1358 fprintf (stream, "#endif /* ");
1360 for (i = 0; defines[i]; i++)
1362 fprintf (stream, "%s", defines[i]);
1365 fprintf (stream, " && ");
1368 fprintf (stream, " */\n");
1371 /* Write DOCUMENTATION to STREAM, perhaps surrounding it with double-quotes
1372 and quoting special characters in the string. Handle special things for
1373 internationalization (gettext) and the single-string vs. multiple-strings
1376 write_documentation (stream, documentation, indentation, flags)
1378 char **documentation;
1379 int indentation, flags;
1382 register char *line;
1383 int string_array, texinfo, base_indent, last_cpp, filename_p;
1388 string_array = flags & STRING_ARRAY;
1389 filename_p = flags & HELPFILE;
1393 fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n"); /* } */
1394 if (single_longdoc_strings)
1396 if (filename_p == 0)
1398 if (documentation && documentation[0] && documentation[0][0])
1399 fprintf (stream, "N_(\"");
1401 fprintf (stream, "N_(\" "); /* the empty string translates specially. */
1404 fprintf (stream, "\"");
1408 base_indent = (string_array && single_longdoc_strings && filename_p == 0) ? BASE_INDENT : 0;
1410 for (i = last_cpp = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
1412 /* Allow #ifdef's to be written out verbatim, but don't put them into
1413 separate help files. */
1416 if (string_array && filename_p == 0 && single_longdoc_strings == 0)
1417 fprintf (stream, "%s\n", line);
1424 /* prefix with N_( for gettext */
1425 if (string_array && single_longdoc_strings == 0)
1427 if (filename_p == 0)
1430 fprintf (stream, " N_(\"");
1432 fprintf (stream, " N_(\" "); /* the empty string translates specially. */
1435 fprintf (stream, " \"");
1439 for (j = 0; j < indentation; j++)
1440 fprintf (stream, " ");
1442 /* Don't indent the first line, because of how the help builtin works. */
1444 indentation += base_indent;
1448 for (j = 0; line[j]; j++)
1454 fprintf (stream, "\\%c", line[j]);
1458 fprintf (stream, "%c", line[j]);
1462 /* closing right paren for gettext */
1463 if (single_longdoc_strings == 0)
1465 if (filename_p == 0)
1466 fprintf (stream, "\"),\n");
1468 fprintf (stream, "\",\n");
1470 else if (documentation[i+1])
1471 /* don't add extra newline after last line */
1472 fprintf (stream, "\\n\\\n");
1476 for (j = 0; line[j]; j++)
1483 fprintf (stream, "@%c", line[j]);
1487 fprintf (stream, "%c", line[j]);
1490 fprintf (stream, "\n");
1493 fprintf (stream, "%s\n", line);
1496 /* closing right paren for gettext */
1497 if (string_array && single_longdoc_strings)
1499 if (filename_p == 0)
1500 fprintf (stream, "\"),\n");
1502 fprintf (stream, "\",\n");
1506 fprintf (stream, "#endif /* HELP_BUILTIN */\n (char *)NULL\n};\n");
1510 write_helpfiles (builtins)
1513 char *helpfile, *bname;
1516 BUILTIN_DESC *builtin;
1518 i = mkdir ("helpfiles", 0777);
1519 if (i < 0 && errno != EEXIST)
1521 fprintf (stderr, "write_helpfiles: helpfiles: cannot create directory\n");
1525 hdlen = strlen ("helpfiles/");
1526 for (i = 0; i < builtins->sindex; i++)
1528 builtin = (BUILTIN_DESC *)builtins->array[i];
1530 bname = document_name (builtin);
1531 helpfile = (char *)xmalloc (hdlen + strlen (bname) + 1);
1532 sprintf (helpfile, "helpfiles/%s", bname);
1534 helpfp = fopen (helpfile, "w");
1537 fprintf (stderr, "write_helpfiles: cannot open %s\n", helpfile);
1542 write_documentation (helpfp, builtin->longdoc->array, 4, PLAINTEXT);
1552 _find_in_table (name, name_table)
1553 char *name, *name_table[];
1557 for (i = 0; name_table[i]; i++)
1558 if (strcmp (name, name_table[i]) == 0)
1564 is_special_builtin (name)
1567 return (_find_in_table (name, special_builtins));
1571 is_assignment_builtin (name)
1574 return (_find_in_table (name, assignment_builtins));
1578 is_posix_builtin (name)
1581 return (_find_in_table (name, posix_builtins));
1584 #if !defined (HAVE_RENAME)
1590 if (link (from, to) < 0)
1595 #endif /* !HAVE_RENAME */