1 /* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from
2 a single source file called builtins.def. */
4 /* Copyright (C) 1987-2020 Free Software Foundation, Inc.
6 This file is part of GNU Bush, the Bourne Again SHell.
8 Bush 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 Bush 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 Bush. 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 "../src/bushtypes.h"
42 # if defined (HAVE_SYS_FILE_H)
43 # include <sys/file.h>
47 #include "posixstat.h"
50 #include "../src/bushansi.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_LOCALVAR 0x04
75 #define BUILTIN_FLAG_POSIX_BUILTIN 0x08
79 /* If this stream descriptor is non-zero, then write
80 texinfo documentation to it. */
81 FILE *documentation_file
= (FILE *)NULL
;
83 /* Non-zero means to only produce documentation. */
84 int only_documentation
= 0;
86 /* Non-zero means to not do any productions. */
87 int inhibit_production
= 0;
89 /* Non-zero means to not add functions (xxx_builtin) to the members of the
90 produced `struct builtin []' */
91 int inhibit_functions
= 0;
93 /* Non-zero means to produce separate help files for each builtin, named by
94 the builtin name, in `./helpfiles'. */
95 int separate_helpfiles
= 0;
97 /* Non-zero means to create single C strings for each `longdoc', with
98 embedded newlines, for ease of translation. */
99 int single_longdoc_strings
= 1;
101 /* The name of a directory into which the separate external help files will
102 eventually be installed. */
103 char *helpfile_directory
;
105 /* The name of a directory to precede the filename when reporting
107 char *error_directory
= (char *)NULL
;
109 /* The name of the structure file. */
110 char *struct_filename
= (char *)NULL
;
112 /* The name of the external declaration file. */
113 char *extern_filename
= (char *)NULL
;
115 /* Here is a structure for manipulating arrays of data. */
117 int size
; /* Number of slots allocated to array. */
118 int sindex
; /* Current location in array. */
119 int width
; /* Size of each element. */
120 int growth_rate
; /* How fast to grow. */
121 char **array
; /* The array itself. */
124 /* Here is a structure defining a single BUILTIN. */
126 char *name
; /* The name of this builtin. */
127 char *function
; /* The name of the function to call. */
128 char *shortdoc
; /* The short documentation for this builtin. */
129 char *docname
; /* Possible name for documentation string. */
130 ARRAY
*longdoc
; /* The long documentation for this builtin. */
131 ARRAY
*dependencies
; /* Null terminated array of #define names. */
132 int flags
; /* Flags for this builtin. */
135 /* Here is a structure which defines a DEF file. */
137 char *filename
; /* The name of the input def file. */
138 ARRAY
*lines
; /* The contents of the file. */
139 int line_number
; /* The current line number. */
140 char *production
; /* The name of the production file. */
141 FILE *output
; /* Open file stream for PRODUCTION. */
142 ARRAY
*builtins
; /* Null terminated array of BUILTIN_DESC *. */
145 /* The array of all builtins encountered during execution of this code. */
146 ARRAY
*saved_builtins
= (ARRAY
*)NULL
;
148 /* The Posix.2 so-called `special' builtins. */
149 char *special_builtins
[] =
151 ":", ".", "source", "break", "continue", "eval", "exec", "exit",
152 "export", "readonly", "return", "set", "shift", "times", "trap", "unset",
156 /* The builtin commands that take assignment statements as arguments. */
157 char *assignment_builtins
[] =
159 "alias", "declare", "export", "local", "readonly", "typeset",
163 char *localvar_builtins
[] =
165 "declare", "local", "typeset", (char *)NULL
168 /* The builtin commands that are special to the POSIX search order. */
169 char *posix_builtins
[] =
171 "alias", "bg", "cd", "command", "false", "fc", "fg", "getopts", "jobs",
172 "kill", "newgrp", "pwd", "read", "true", "umask", "unalias", "wait",
176 /* Forward declarations. */
177 static int is_special_builtin ();
178 static int is_assignment_builtin ();
179 static int is_localvar_builtin ();
180 static int is_posix_builtin ();
182 #if !defined (HAVE_RENAME)
183 static int rename ();
186 void extract_info ();
191 void write_file_headers ();
192 void write_file_footers ();
193 void write_ifdefs ();
194 void write_endifs ();
195 void write_documentation ();
196 void write_longdocs ();
197 void write_builtins ();
199 int write_helpfiles ();
202 void add_documentation ();
204 void must_be_building ();
205 void remove_trailing_whitespace ();
207 #define document_name(b) ((b)->docname ? (b)->docname : (b)->name)
210 /* For each file mentioned on the command line, process it and
211 write the information to STRUCTFILE and EXTERNFILE, while
212 creating the production file if necessary. */
219 FILE *structfile
, *externfile
;
220 char *documentation_filename
, *temp_struct_filename
;
222 structfile
= externfile
= (FILE *)NULL
;
223 documentation_filename
= DOCFILE
;
224 temp_struct_filename
= (char *)NULL
;
226 while (arg_index
< argc
&& argv
[arg_index
][0] == '-')
228 char *arg
= argv
[arg_index
++];
230 if (strcmp (arg
, "-externfile") == 0)
231 extern_filename
= argv
[arg_index
++];
232 else if (strcmp (arg
, "-structfile") == 0)
233 struct_filename
= argv
[arg_index
++];
234 else if (strcmp (arg
, "-noproduction") == 0)
235 inhibit_production
= 1;
236 else if (strcmp (arg
, "-nofunctions") == 0)
237 inhibit_functions
= 1;
238 else if (strcmp (arg
, "-document") == 0)
239 documentation_file
= fopen (documentation_filename
, "w");
240 else if (strcmp (arg
, "-D") == 0)
245 free (error_directory
);
247 error_directory
= xmalloc (2 + strlen (argv
[arg_index
]));
248 strcpy (error_directory
, argv
[arg_index
]);
249 len
= strlen (error_directory
);
251 if (len
&& error_directory
[len
- 1] != '/')
252 strcat (error_directory
, "/");
256 else if (strcmp (arg
, "-documentonly") == 0)
258 only_documentation
= 1;
259 documentation_file
= fopen (documentation_filename
, "w");
261 else if (strcmp (arg
, "-H") == 0)
263 separate_helpfiles
= 1;
264 helpfile_directory
= argv
[arg_index
++];
266 else if (strcmp (arg
, "-S") == 0)
267 single_longdoc_strings
= 0;
270 fprintf (stderr
, "%s: Unknown flag %s.\n", argv
[0], arg
);
275 /* If there are no files to process, just quit now. */
276 if (arg_index
== argc
)
279 if (!only_documentation
)
281 /* Open the files. */
284 temp_struct_filename
= xmalloc (15);
285 sprintf (temp_struct_filename
, "mk-%ld", (long) getpid ());
286 structfile
= fopen (temp_struct_filename
, "w");
289 file_error (temp_struct_filename
);
294 externfile
= fopen (extern_filename
, "w");
297 file_error (extern_filename
);
300 /* Write out the headers. */
301 write_file_headers (structfile
, externfile
);
304 if (documentation_file
)
306 fprintf (documentation_file
, "@c Table of builtins created with %s.\n",
308 fprintf (documentation_file
, "@ftable @asis\n");
311 /* Process the .def files. */
312 while (arg_index
< argc
)
316 arg
= argv
[arg_index
++];
318 extract_info (arg
, structfile
, externfile
);
321 /* Close the files. */
322 if (!only_documentation
)
324 /* Write the footers. */
325 write_file_footers (structfile
, externfile
);
329 write_longdocs (structfile
, saved_builtins
);
331 rename (temp_struct_filename
, struct_filename
);
339 /* This is now done by a different program */
340 if (separate_helpfiles
)
342 write_helpfiles (saved_builtins
);
346 if (documentation_file
)
348 fprintf (documentation_file
, "@end ftable\n");
349 fclose (documentation_file
);
355 /* **************************************************************** */
357 /* Array Functions and Manipulators */
359 /* **************************************************************** */
361 /* Make a new array, and return a pointer to it. The array will
362 contain elements of size WIDTH, and is initialized to no elements. */
369 array
= (ARRAY
*)xmalloc (sizeof (ARRAY
));
372 array
->width
= width
;
374 /* Default to increasing size in units of 20. */
375 array
->growth_rate
= 20;
377 array
->array
= (char **)NULL
;
382 /* Copy the array of strings in ARRAY. */
384 copy_string_array (array
)
391 return (ARRAY
*)NULL
;
393 copy
= array_create (sizeof (char *));
395 copy
->size
= array
->size
;
396 copy
->sindex
= array
->sindex
;
397 copy
->width
= array
->width
;
399 copy
->array
= (char **)xmalloc ((1 + array
->sindex
) * sizeof (char *));
401 for (i
= 0; i
< array
->sindex
; i
++)
402 copy
->array
[i
] = savestring (array
->array
[i
]);
404 copy
->array
[i
] = (char *)NULL
;
409 /* Add ELEMENT to ARRAY, growing the array if necessary. */
411 array_add (element
, array
)
415 if (array
->sindex
+ 2 > array
->size
)
416 array
->array
= (char **)xrealloc
417 (array
->array
, (array
->size
+= array
->growth_rate
) * array
->width
);
419 array
->array
[array
->sindex
++] = element
;
420 array
->array
[array
->sindex
] = (char *)NULL
;
423 /* Free an allocated array and data pointer. */
434 /* **************************************************************** */
436 /* Processing a DEF File */
438 /* **************************************************************** */
440 /* The definition of a function. */
441 typedef int Function ();
442 typedef int mk_handler_func_t
PARAMS((char *, DEF_FILE
*, char *));
444 /* Structure handles processor directives. */
447 mk_handler_func_t
*function
;
450 extern int builtin_handler
PARAMS((char *, DEF_FILE
*, char *));
451 extern int function_handler
PARAMS((char *, DEF_FILE
*, char *));
452 extern int short_doc_handler
PARAMS((char *, DEF_FILE
*, char *));
453 extern int comment_handler
PARAMS((char *, DEF_FILE
*, char *));
454 extern int depends_on_handler
PARAMS((char *, DEF_FILE
*, char *));
455 extern int produces_handler
PARAMS((char *, DEF_FILE
*, char *));
456 extern int end_handler
PARAMS((char *, DEF_FILE
*, char *));
457 extern int docname_handler
PARAMS((char *, DEF_FILE
*, char *));
459 HANDLER_ENTRY handlers
[] = {
460 { "BUILTIN", builtin_handler
},
461 { "DOCNAME", docname_handler
},
462 { "FUNCTION", function_handler
},
463 { "SHORT_DOC", short_doc_handler
},
464 { "$", comment_handler
},
465 { "COMMENT", comment_handler
},
466 { "DEPENDS_ON", depends_on_handler
},
467 { "PRODUCES", produces_handler
},
468 { "END", end_handler
},
469 { (char *)NULL
, (mk_handler_func_t
*)NULL
}
472 /* Return the entry in the table of handlers for NAME. */
474 find_directive (directive
)
479 for (i
= 0; handlers
[i
].directive
; i
++)
480 if (strcmp (handlers
[i
].directive
, directive
) == 0)
481 return (&handlers
[i
]);
483 return ((HANDLER_ENTRY
*)NULL
);
486 /* Non-zero indicates that a $BUILTIN has been seen, but not
487 the corresponding $END. */
488 static int building_builtin
= 0;
490 /* Non-zero means to output cpp line and file information before
491 printing the current line to the production file. */
492 int output_cpp_line_info
= 0;
494 /* The main function of this program. Read FILENAME and act on what is
495 found. Lines not starting with a dollar sign are copied to the
496 $PRODUCES target, if one is present. Lines starting with a dollar sign
497 are directives to this program, specifying the name of the builtin, the
498 function to call, the short documentation and the long documentation
499 strings. FILENAME can contain multiple $BUILTINs, but only one $PRODUCES
500 target. After the file has been processed, write out the names of
501 builtins found in each $BUILTIN. Plain text found before the $PRODUCES
502 is ignored, as is "$$ comment text". */
504 extract_info (filename
, structfile
, externfile
)
506 FILE *structfile
, *externfile
;
515 if (stat (filename
, &finfo
) == -1)
516 file_error (filename
);
518 fd
= open (filename
, O_RDONLY
, 0666);
521 file_error (filename
);
523 file_size
= (size_t)finfo
.st_size
;
524 buffer
= xmalloc (1 + file_size
);
526 if ((nr
= read (fd
, buffer
, file_size
)) < 0)
527 file_error (filename
);
529 /* This is needed on WIN32, and does not hurt on Unix. */
537 fprintf (stderr
, "mkbuiltins: %s: skipping zero-length file\n", filename
);
542 /* Create and fill in the initial structure describing this file. */
543 defs
= (DEF_FILE
*)xmalloc (sizeof (DEF_FILE
));
544 defs
->filename
= filename
;
545 defs
->lines
= array_create (sizeof (char *));
546 defs
->line_number
= 0;
547 defs
->production
= (char *)NULL
;
548 defs
->output
= (FILE *)NULL
;
549 defs
->builtins
= (ARRAY
*)NULL
;
551 /* Build the array of lines. */
553 while (i
< file_size
)
555 array_add (&buffer
[i
], defs
->lines
);
557 while (i
< file_size
&& buffer
[i
] != '\n')
562 /* Begin processing the input file. We don't write any output
563 until we have a file to write output to. */
564 output_cpp_line_info
= 1;
566 /* Process each line in the array. */
567 for (i
= 0; line
= defs
->lines
->array
[i
]; i
++)
569 defs
->line_number
= i
;
575 HANDLER_ENTRY
*handler
;
577 /* Isolate the directive. */
578 for (j
= 0; line
[j
] && !whitespace (line
[j
]); j
++);
580 directive
= xmalloc (j
);
581 strncpy (directive
, line
+ 1, j
- 1);
582 directive
[j
-1] = '\0';
584 /* Get the function handler and call it. */
585 handler
= find_directive (directive
);
589 line_error (defs
, "Unknown directive `%s'", directive
);
595 /* Advance to the first non-whitespace character. */
596 while (whitespace (line
[j
]))
599 /* Call the directive handler with the FILE, and ARGS. */
600 (*(handler
->function
)) (directive
, defs
, line
+ j
);
606 if (building_builtin
)
607 add_documentation (defs
, line
);
608 else if (defs
->output
)
610 if (output_cpp_line_info
)
612 /* If we're handed an absolute pathname, don't prepend
613 the directory name. */
614 if (defs
->filename
[0] == '/')
615 fprintf (defs
->output
, "#line %d \"%s\"\n",
616 defs
->line_number
+ 1, defs
->filename
);
618 fprintf (defs
->output
, "#line %d \"%s%s\"\n",
619 defs
->line_number
+ 1,
620 error_directory
? error_directory
: "./",
622 output_cpp_line_info
= 0;
625 fprintf (defs
->output
, "%s\n", line
);
630 /* Close the production file. */
632 fclose (defs
->output
);
634 /* The file has been processed. Write the accumulated builtins to
635 the builtins.c file, and write the extern definitions to the
637 write_builtins (defs
, structfile
, externfile
);
643 #define free_safely(x) if (x) free (x)
646 free_builtin (builtin
)
647 BUILTIN_DESC
*builtin
;
651 free_safely (builtin
->name
);
652 free_safely (builtin
->function
);
653 free_safely (builtin
->shortdoc
);
654 free_safely (builtin
->docname
);
656 if (builtin
->longdoc
)
657 array_free (builtin
->longdoc
);
659 if (builtin
->dependencies
)
661 for (i
= 0; builtin
->dependencies
->array
[i
]; i
++)
662 free (builtin
->dependencies
->array
[i
]);
663 array_free (builtin
->dependencies
);
667 /* Free all of the memory allocated to a DEF_FILE. */
673 register BUILTIN_DESC
*builtin
;
675 if (defs
->production
)
676 free (defs
->production
);
679 array_free (defs
->lines
);
683 for (i
= 0; builtin
= (BUILTIN_DESC
*)defs
->builtins
->array
[i
]; i
++)
685 free_builtin (builtin
);
688 array_free (defs
->builtins
);
693 /* **************************************************************** */
695 /* The Handler Functions Themselves */
697 /* **************************************************************** */
699 /* Strip surrounding whitespace from STRING, and
700 return a pointer to the start of it. */
702 strip_whitespace (string
)
705 while (whitespace (*string
))
708 remove_trailing_whitespace (string
);
712 /* Remove only the trailing whitespace from STRING. */
714 remove_trailing_whitespace (string
)
719 i
= strlen (string
) - 1;
721 while (i
> 0 && whitespace (string
[i
]))
727 /* Ensure that there is a argument in STRING and return it.
728 FOR_WHOM is the name of the directive which needs the argument.
729 DEFS is the DEF_FILE in which the directive is found.
730 If there is no argument, produce an error. */
732 get_arg (for_whom
, defs
, string
)
733 char *for_whom
, *string
;
738 new = strip_whitespace (string
);
741 line_error (defs
, "%s requires an argument", for_whom
);
743 return (savestring (new));
746 /* Error if not building a builtin. */
748 must_be_building (directive
, defs
)
752 if (!building_builtin
)
753 line_error (defs
, "%s must be inside of a $BUILTIN block", directive
);
756 /* Return the current builtin. */
758 current_builtin (directive
, defs
)
762 must_be_building (directive
, defs
);
764 return ((BUILTIN_DESC
*)defs
->builtins
->array
[defs
->builtins
->sindex
- 1]);
766 return ((BUILTIN_DESC
*)NULL
);
769 /* Add LINE to the long documentation for the current builtin.
770 Ignore blank lines until the first non-blank line has been seen. */
772 add_documentation (defs
, line
)
776 register BUILTIN_DESC
*builtin
;
778 builtin
= current_builtin ("(implied LONGDOC)", defs
);
780 remove_trailing_whitespace (line
);
782 if (!*line
&& !builtin
->longdoc
)
785 if (!builtin
->longdoc
)
786 builtin
->longdoc
= array_create (sizeof (char *));
788 array_add (line
, builtin
->longdoc
);
791 /* How to handle the $BUILTIN directive. */
793 builtin_handler (self
, defs
, arg
)
801 /* If we are already building a builtin, we cannot start a new one. */
802 if (building_builtin
)
804 line_error (defs
, "%s found before $END", self
);
808 output_cpp_line_info
++;
810 /* Get the name of this builtin, and stick it in the array. */
811 name
= get_arg (self
, defs
, arg
);
813 /* If this is the first builtin, create the array to hold them. */
815 defs
->builtins
= array_create (sizeof (BUILTIN_DESC
*));
817 new = (BUILTIN_DESC
*)xmalloc (sizeof (BUILTIN_DESC
));
819 new->function
= (char *)NULL
;
820 new->shortdoc
= (char *)NULL
;
821 new->docname
= (char *)NULL
;
822 new->longdoc
= (ARRAY
*)NULL
;
823 new->dependencies
= (ARRAY
*)NULL
;
826 if (is_special_builtin (name
))
827 new->flags
|= BUILTIN_FLAG_SPECIAL
;
828 if (is_assignment_builtin (name
))
829 new->flags
|= BUILTIN_FLAG_ASSIGNMENT
;
830 if (is_localvar_builtin (name
))
831 new->flags
|= BUILTIN_FLAG_LOCALVAR
;
832 if (is_posix_builtin (name
))
833 new->flags
|= BUILTIN_FLAG_POSIX_BUILTIN
;
835 array_add ((char *)new, defs
->builtins
);
836 building_builtin
= 1;
841 /* How to handle the $FUNCTION directive. */
843 function_handler (self
, defs
, arg
)
848 register BUILTIN_DESC
*builtin
;
850 builtin
= current_builtin (self
, defs
);
854 line_error (defs
, "syntax error: no current builtin for $FUNCTION directive");
857 if (builtin
->function
)
858 line_error (defs
, "%s already has a function (%s)",
859 builtin
->name
, builtin
->function
);
861 builtin
->function
= get_arg (self
, defs
, arg
);
866 /* How to handle the $DOCNAME directive. */
868 docname_handler (self
, defs
, arg
)
873 register BUILTIN_DESC
*builtin
;
875 builtin
= current_builtin (self
, defs
);
877 if (builtin
->docname
)
878 line_error (defs
, "%s already had a docname (%s)",
879 builtin
->name
, builtin
->docname
);
881 builtin
->docname
= get_arg (self
, defs
, arg
);
886 /* How to handle the $SHORT_DOC directive. */
888 short_doc_handler (self
, defs
, arg
)
893 register BUILTIN_DESC
*builtin
;
895 builtin
= current_builtin (self
, defs
);
897 if (builtin
->shortdoc
)
898 line_error (defs
, "%s already has short documentation (%s)",
899 builtin
->name
, builtin
->shortdoc
);
901 builtin
->shortdoc
= get_arg (self
, defs
, arg
);
906 /* How to handle the $COMMENT directive. */
908 comment_handler (self
, defs
, arg
)
916 /* How to handle the $DEPENDS_ON directive. */
918 depends_on_handler (self
, defs
, arg
)
923 register BUILTIN_DESC
*builtin
;
926 builtin
= current_builtin (self
, defs
);
927 dependent
= get_arg (self
, defs
, arg
);
929 if (!builtin
->dependencies
)
930 builtin
->dependencies
= array_create (sizeof (char *));
932 array_add (dependent
, builtin
->dependencies
);
937 /* How to handle the $PRODUCES directive. */
939 produces_handler (self
, defs
, arg
)
944 /* If just hacking documentation, don't change any of the production
946 if (only_documentation
)
949 output_cpp_line_info
++;
951 if (defs
->production
)
952 line_error (defs
, "%s already has a %s definition", defs
->filename
, self
);
955 defs
->production
= get_arg (self
, defs
, arg
);
957 if (inhibit_production
)
960 defs
->output
= fopen (defs
->production
, "w");
963 file_error (defs
->production
);
965 fprintf (defs
->output
, "/* %s, created from %s. */\n",
966 defs
->production
, defs
->filename
);
971 /* How to handle the $END directive. */
973 end_handler (self
, defs
, arg
)
978 must_be_building (self
, defs
);
979 building_builtin
= 0;
983 /* **************************************************************** */
985 /* Error Handling Functions */
987 /* **************************************************************** */
989 /* Produce an error for DEFS with FORMAT and ARGS. */
991 line_error (defs
, format
, arg1
, arg2
)
993 char *format
, *arg1
, *arg2
;
995 if (defs
->filename
[0] != '/')
996 fprintf (stderr
, "%s", error_directory
? error_directory
: "./");
997 fprintf (stderr
, "%s:%d:", defs
->filename
, defs
->line_number
+ 1);
998 fprintf (stderr
, format
, arg1
, arg2
);
999 fprintf (stderr
, "\n");
1003 /* Print error message for FILENAME. */
1005 file_error (filename
)
1012 /* **************************************************************** */
1014 /* xmalloc and xrealloc () */
1016 /* **************************************************************** */
1018 static void memory_error_and_abort ();
1024 char *temp
= (char *)malloc (bytes
);
1027 memory_error_and_abort ();
1032 xrealloc (pointer
, bytes
)
1039 temp
= (char *)malloc (bytes
);
1041 temp
= (char *)realloc (pointer
, bytes
);
1044 memory_error_and_abort ();
1050 memory_error_and_abort ()
1052 fprintf (stderr
, "mkbuiltins: out of virtual memory\n");
1056 /* **************************************************************** */
1058 /* Creating the Struct and Extern Files */
1060 /* **************************************************************** */
1062 /* Return a pointer to a newly allocated builtin which is
1063 an exact copy of BUILTIN. */
1065 copy_builtin (builtin
)
1066 BUILTIN_DESC
*builtin
;
1070 new = (BUILTIN_DESC
*)xmalloc (sizeof (BUILTIN_DESC
));
1072 new->name
= savestring (builtin
->name
);
1073 new->shortdoc
= savestring (builtin
->shortdoc
);
1074 new->longdoc
= copy_string_array (builtin
->longdoc
);
1075 new->dependencies
= copy_string_array (builtin
->dependencies
);
1078 builtin
->function
? savestring (builtin
->function
) : (char *)NULL
;
1080 builtin
->docname
? savestring (builtin
->docname
) : (char *)NULL
;
1085 /* How to save away a builtin. */
1087 save_builtin (builtin
)
1088 BUILTIN_DESC
*builtin
;
1090 BUILTIN_DESC
*newbuiltin
;
1092 newbuiltin
= copy_builtin (builtin
);
1094 /* If this is the first builtin to be saved, create the array
1096 if (!saved_builtins
)
1097 saved_builtins
= array_create (sizeof (BUILTIN_DESC
*));
1099 array_add ((char *)newbuiltin
, saved_builtins
);
1102 /* Flags that mean something to write_documentation (). */
1103 #define STRING_ARRAY 0x01
1104 #define TEXINFO 0x02
1105 #define PLAINTEXT 0x04
1106 #define HELPFILE 0x08
1108 char *structfile_header
[] = {
1109 "/* builtins.c -- the built in shell commands. */",
1111 "/* This file is manufactured by ./mkbuiltins, and should not be",
1112 " edited by hand. See the source to mkbuiltins for details. */",
1114 "/* Copyright (C) 1987-2015 Free Software Foundation, Inc.",
1116 " This file is part of GNU Bush, the Bourne Again SHell.",
1118 " Bush is free software: you can redistribute it and/or modify",
1119 " it under the terms of the GNU General Public License as published by",
1120 " the Free Software Foundation, either version 3 of the License, or",
1121 " (at your option) any later version.",
1123 " Bush is distributed in the hope that it will be useful,",
1124 " but WITHOUT ANY WARRANTY; without even the implied warranty of",
1125 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
1126 " GNU General Public License for more details.",
1128 " You should have received a copy of the GNU General Public License",
1129 " along with Bush. If not, see <http://www.gnu.org/licenses/>.",
1132 "/* The list of shell builtins. Each element is name, function, flags,",
1133 " long-doc, short-doc. The long-doc field contains a pointer to an array",
1134 " of help lines. The function takes a WORD_LIST *; the first word in the",
1135 " list is the first arg to the command. The list has already had word",
1136 " expansion performed.",
1138 " Functions which need to look at only the simple commands (e.g.",
1139 " the enable_builtin ()), should ignore entries where",
1140 " (array[i].function == (sh_builtin_func_t *)NULL). Such entries are for",
1141 " the list of shell reserved control structures, like `if' and `while'.",
1142 " The end of the list is denoted with a NULL name field. */",
1144 "/* TRANSLATORS: Please do not translate command names in descriptions */",
1146 "#include \"../src/builtins.h\"",
1150 char *structfile_footer
[] = {
1151 " { (char *)0x0, (sh_builtin_func_t *)0x0, 0, (char **)0x0, (char *)0x0, (char *)0x0 }",
1154 "struct builtin *shell_builtins = static_shell_builtins;",
1155 "struct builtin *current_builtin;",
1157 "int num_shell_builtins =",
1158 "\tsizeof (static_shell_builtins) / sizeof (struct builtin) - 1;",
1162 /* Write out any necessary opening information for
1163 STRUCTFILE and EXTERNFILE. */
1165 write_file_headers (structfile
, externfile
)
1166 FILE *structfile
, *externfile
;
1172 for (i
= 0; structfile_header
[i
]; i
++)
1173 fprintf (structfile
, "%s\n", structfile_header
[i
]);
1175 fprintf (structfile
, "#include \"%s\"\n",
1176 extern_filename
? extern_filename
: "builtext.h");
1178 fprintf (structfile
, "#include \"src/bushintl.h\"\n");
1180 fprintf (structfile
, "\nstruct builtin static_shell_builtins[] = {\n");
1184 fprintf (externfile
,
1185 "/* %s - The list of builtins found in libbuiltins.a. */\n",
1186 extern_filename
? extern_filename
: "builtext.h");
1189 /* Write out any necessary closing information for
1190 STRUCTFILE and EXTERNFILE. */
1192 write_file_footers (structfile
, externfile
)
1193 FILE *structfile
, *externfile
;
1197 /* Write out the footers. */
1200 for (i
= 0; structfile_footer
[i
]; i
++)
1201 fprintf (structfile
, "%s\n", structfile_footer
[i
]);
1205 /* Write out the information accumulated in DEFS to
1206 STRUCTFILE and EXTERNFILE. */
1208 write_builtins (defs
, structfile
, externfile
)
1210 FILE *structfile
, *externfile
;
1214 /* Write out the information. */
1217 register BUILTIN_DESC
*builtin
;
1219 for (i
= 0; i
< defs
->builtins
->sindex
; i
++)
1221 builtin
= (BUILTIN_DESC
*)defs
->builtins
->array
[i
];
1223 /* Write out any #ifdefs that may be there. */
1224 if (!only_documentation
)
1226 if (builtin
->dependencies
)
1228 write_ifdefs (externfile
, builtin
->dependencies
->array
);
1229 write_ifdefs (structfile
, builtin
->dependencies
->array
);
1232 /* Write the extern definition. */
1235 if (builtin
->function
)
1236 fprintf (externfile
, "extern int %s PARAMS((WORD_LIST *));\n",
1239 fprintf (externfile
, "extern char * const %s_doc[];\n",
1240 document_name (builtin
));
1243 /* Write the structure definition. */
1246 fprintf (structfile
, " { \"%s\", ", builtin
->name
);
1248 if (builtin
->function
&& inhibit_functions
== 0)
1249 fprintf (structfile
, "%s, ", builtin
->function
);
1251 fprintf (structfile
, "(sh_builtin_func_t *)0x0, ");
1253 fprintf (structfile
, "%s%s%s%s%s, %s_doc,\n",
1254 "BUILTIN_ENABLED | STATIC_BUILTIN",
1255 (builtin
->flags
& BUILTIN_FLAG_SPECIAL
) ? " | SPECIAL_BUILTIN" : "",
1256 (builtin
->flags
& BUILTIN_FLAG_ASSIGNMENT
) ? " | ASSIGNMENT_BUILTIN" : "",
1257 (builtin
->flags
& BUILTIN_FLAG_LOCALVAR
) ? " | LOCALVAR_BUILTIN" : "",
1258 (builtin
->flags
& BUILTIN_FLAG_POSIX_BUILTIN
) ? " | POSIX_BUILTIN" : "",
1259 document_name (builtin
));
1261 /* Don't translate short document summaries that are identical
1263 if (builtin
->shortdoc
&& strcmp (builtin
->name
, builtin
->shortdoc
) == 0)
1265 if (inhibit_functions
)
1266 fprintf (structfile
, " \"%s\", \"%s\" },\n",
1267 builtin
->shortdoc
? builtin
->shortdoc
: builtin
->name
,
1268 document_name (builtin
));
1270 fprintf (structfile
, " \"%s\", (char *)NULL },\n",
1271 builtin
->shortdoc
? builtin
->shortdoc
: builtin
->name
);
1275 if (inhibit_functions
)
1276 fprintf (structfile
, " N_(\"%s\"), \"%s\" },\n",
1277 builtin
->shortdoc
? builtin
->shortdoc
: builtin
->name
,
1278 document_name (builtin
));
1280 fprintf (structfile
, " N_(\"%s\"), (char *)NULL },\n",
1281 builtin
->shortdoc
? builtin
->shortdoc
: builtin
->name
);
1285 if (structfile
|| separate_helpfiles
)
1286 /* Save away this builtin for later writing of the
1287 long documentation strings. */
1288 save_builtin (builtin
);
1290 /* Write out the matching #endif, if necessary. */
1291 if (builtin
->dependencies
)
1294 write_endifs (externfile
, builtin
->dependencies
->array
);
1297 write_endifs (structfile
, builtin
->dependencies
->array
);
1301 if (documentation_file
)
1303 fprintf (documentation_file
, "@item %s\n", builtin
->name
);
1305 (documentation_file
, builtin
->longdoc
->array
, 0, TEXINFO
);
1311 /* Write out the long documentation strings in BUILTINS to STREAM. */
1313 write_longdocs (stream
, builtins
)
1318 register BUILTIN_DESC
*builtin
;
1322 for (i
= 0; i
< builtins
->sindex
; i
++)
1324 builtin
= (BUILTIN_DESC
*)builtins
->array
[i
];
1326 if (builtin
->dependencies
)
1327 write_ifdefs (stream
, builtin
->dependencies
->array
);
1329 /* Write the long documentation strings. */
1330 dname
= document_name (builtin
);
1331 fprintf (stream
, "char * const %s_doc[] =", dname
);
1333 if (separate_helpfiles
)
1335 int l
= strlen (helpfile_directory
) + strlen (dname
) + 1;
1336 sarray
[0] = (char *)xmalloc (l
+ 1);
1337 sprintf (sarray
[0], "%s/%s", helpfile_directory
, dname
);
1338 sarray
[1] = (char *)NULL
;
1339 write_documentation (stream
, sarray
, 0, STRING_ARRAY
|HELPFILE
);
1343 write_documentation (stream
, builtin
->longdoc
->array
, 0, STRING_ARRAY
);
1345 if (builtin
->dependencies
)
1346 write_endifs (stream
, builtin
->dependencies
->array
);
1352 write_dummy_declarations (stream
, builtins
)
1357 BUILTIN_DESC
*builtin
;
1359 for (i
= 0; structfile_header
[i
]; i
++)
1360 fprintf (stream
, "%s\n", structfile_header
[i
]);
1362 for (i
= 0; i
< builtins
->sindex
; i
++)
1364 builtin
= (BUILTIN_DESC
*)builtins
->array
[i
];
1366 /* How to guarantee that no builtin is written more than once? */
1367 fprintf (stream
, "int %s () { return (0); }\n", builtin
->function
);
1371 /* Write an #ifdef string saying what needs to be defined (or not defined)
1372 in order to allow compilation of the code that will follow.
1373 STREAM is the stream to write the information to,
1374 DEFINES is a null terminated array of define names.
1375 If a define is preceded by an `!', then the sense of the test is
1378 write_ifdefs (stream
, defines
)
1387 fprintf (stream
, "#if ");
1389 for (i
= 0; defines
[i
]; i
++)
1391 char *def
= defines
[i
];
1394 fprintf (stream
, "!defined (%s)", def
+ 1);
1396 fprintf (stream
, "defined (%s)", def
);
1399 fprintf (stream
, " && ");
1401 fprintf (stream
, "\n");
1404 /* Write an #endif string saying what defines controlled the compilation
1405 of the immediately preceding code.
1406 STREAM is the stream to write the information to.
1407 DEFINES is a null terminated array of define names. */
1409 write_endifs (stream
, defines
)
1418 fprintf (stream
, "#endif /* ");
1420 for (i
= 0; defines
[i
]; i
++)
1422 fprintf (stream
, "%s", defines
[i
]);
1425 fprintf (stream
, " && ");
1428 fprintf (stream
, " */\n");
1431 /* Write DOCUMENTATION to STREAM, perhaps surrounding it with double-quotes
1432 and quoting special characters in the string. Handle special things for
1433 internationalization (gettext) and the single-string vs. multiple-strings
1436 write_documentation (stream
, documentation
, indentation
, flags
)
1438 char **documentation
;
1439 int indentation
, flags
;
1442 register char *line
;
1443 int string_array
, texinfo
, base_indent
, filename_p
;
1448 string_array
= flags
& STRING_ARRAY
;
1449 filename_p
= flags
& HELPFILE
;
1453 fprintf (stream
, " {\n#if defined (HELP_BUILTIN)\n"); /* } */
1454 if (single_longdoc_strings
)
1456 if (filename_p
== 0)
1458 if (documentation
&& documentation
[0] && documentation
[0][0])
1459 fprintf (stream
, "N_(\"");
1461 fprintf (stream
, "N_(\" "); /* the empty string translates specially. */
1464 fprintf (stream
, "\"");
1468 base_indent
= (string_array
&& single_longdoc_strings
&& filename_p
== 0) ? BASE_INDENT
: 0;
1470 for (i
= 0, texinfo
= (flags
& TEXINFO
); documentation
&& (line
= documentation
[i
]); i
++)
1472 /* Allow #ifdef's to be written out verbatim, but don't put them into
1473 separate help files. */
1476 if (string_array
&& filename_p
== 0 && single_longdoc_strings
== 0)
1477 fprintf (stream
, "%s\n", line
);
1481 /* prefix with N_( for gettext */
1482 if (string_array
&& single_longdoc_strings
== 0)
1484 if (filename_p
== 0)
1487 fprintf (stream
, " N_(\"");
1489 fprintf (stream
, " N_(\" "); /* the empty string translates specially. */
1492 fprintf (stream
, " \"");
1496 for (j
= 0; j
< indentation
; j
++)
1497 fprintf (stream
, " ");
1499 /* Don't indent the first line, because of how the help builtin works. */
1501 indentation
+= base_indent
;
1505 for (j
= 0; line
[j
]; j
++)
1511 fprintf (stream
, "\\%c", line
[j
]);
1515 fprintf (stream
, "%c", line
[j
]);
1519 /* closing right paren for gettext */
1520 if (single_longdoc_strings
== 0)
1522 if (filename_p
== 0)
1523 fprintf (stream
, "\"),\n");
1525 fprintf (stream
, "\",\n");
1527 else if (documentation
[i
+1])
1528 /* don't add extra newline after last line */
1529 fprintf (stream
, "\\n\\\n");
1533 for (j
= 0; line
[j
]; j
++)
1540 fprintf (stream
, "@%c", line
[j
]);
1544 fprintf (stream
, "%c", line
[j
]);
1547 fprintf (stream
, "\n");
1550 fprintf (stream
, "%s\n", line
);
1553 /* closing right paren for gettext */
1554 if (string_array
&& single_longdoc_strings
)
1556 if (filename_p
== 0)
1557 fprintf (stream
, "\"),\n");
1559 fprintf (stream
, "\",\n");
1563 fprintf (stream
, "#endif /* HELP_BUILTIN */\n (char *)NULL\n};\n");
1567 write_helpfiles (builtins
)
1570 char *helpfile
, *bname
;
1573 BUILTIN_DESC
*builtin
;
1575 i
= mkdir ("helpfiles", 0777);
1576 if (i
< 0 && errno
!= EEXIST
)
1578 fprintf (stderr
, "write_helpfiles: helpfiles: cannot create directory\n");
1582 hdlen
= strlen ("helpfiles/");
1583 for (i
= 0; i
< builtins
->sindex
; i
++)
1585 builtin
= (BUILTIN_DESC
*)builtins
->array
[i
];
1587 bname
= document_name (builtin
);
1588 helpfile
= (char *)xmalloc (hdlen
+ strlen (bname
) + 1);
1589 sprintf (helpfile
, "helpfiles/%s", bname
);
1591 helpfp
= fopen (helpfile
, "w");
1594 fprintf (stderr
, "write_helpfiles: cannot open %s\n", helpfile
);
1599 write_documentation (helpfp
, builtin
->longdoc
->array
, 4, PLAINTEXT
);
1609 _find_in_table (name
, name_table
)
1610 char *name
, *name_table
[];
1614 for (i
= 0; name_table
[i
]; i
++)
1615 if (strcmp (name
, name_table
[i
]) == 0)
1621 is_special_builtin (name
)
1624 return (_find_in_table (name
, special_builtins
));
1628 is_assignment_builtin (name
)
1631 return (_find_in_table (name
, assignment_builtins
));
1635 is_localvar_builtin (name
)
1638 return (_find_in_table (name
, localvar_builtins
));
1642 is_posix_builtin (name
)
1645 return (_find_in_table (name
, posix_builtins
));
1648 #if !defined (HAVE_RENAME)
1654 if (link (from
, to
) < 0)
1659 #endif /* !HAVE_RENAME */