1 /* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from
2 a single source file called builtins.def. */
4 /* Copyright (C) 1987-2002 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 it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING. If not, write to the Free Software
20 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
24 #if defined (HAVE_UNISTD_H)
26 # include <sys/types.h>
32 #include "../bashtypes.h"
36 #include "posixstat.h"
39 #include "../bashansi.h"
45 #define DOCFILE "builtins.texi"
51 static char *xmalloc (), *xrealloc ();
53 #if !defined (__STDC__) && !defined (strcpy)
54 extern char *strcpy ();
55 #endif /* !__STDC__ && !strcpy */
57 #define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
58 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
60 /* Flag values that builtins can have. */
61 #define BUILTIN_FLAG_SPECIAL 0x01
62 #define BUILTIN_FLAG_ASSIGNMENT 0x02
64 /* If this stream descriptor is non-zero, then write
65 texinfo documentation to it. */
66 FILE *documentation_file = (FILE *)NULL;
68 /* Non-zero means to only produce documentation. */
69 int only_documentation = 0;
71 /* Non-zero means to not do any productions. */
72 int inhibit_production = 0;
74 /* Non-zero means to produce separate help files for each builtin, named by
75 the builtin name, in `./helpfiles'. */
76 int separate_helpfiles = 0;
78 /* The name of a directory into which the separate external help files will
79 eventually be installed. */
80 char *helpfile_directory;
82 /* The name of a directory to precede the filename when reporting
84 char *error_directory = (char *)NULL;
86 /* The name of the structure file. */
87 char *struct_filename = (char *)NULL;
89 /* The name of the external declaration file. */
90 char *extern_filename = (char *)NULL;
92 /* Here is a structure for manipulating arrays of data. */
94 int size; /* Number of slots allocated to array. */
95 int sindex; /* Current location in array. */
96 int width; /* Size of each element. */
97 int growth_rate; /* How fast to grow. */
98 char **array; /* The array itself. */
101 /* Here is a structure defining a single BUILTIN. */
103 char *name; /* The name of this builtin. */
104 char *function; /* The name of the function to call. */
105 char *shortdoc; /* The short documentation for this builtin. */
106 char *docname; /* Possible name for documentation string. */
107 ARRAY *longdoc; /* The long documentation for this builtin. */
108 ARRAY *dependencies; /* Null terminated array of #define names. */
109 int flags; /* Flags for this builtin. */
112 /* Here is a structure which defines a DEF file. */
114 char *filename; /* The name of the input def file. */
115 ARRAY *lines; /* The contents of the file. */
116 int line_number; /* The current line number. */
117 char *production; /* The name of the production file. */
118 FILE *output; /* Open file stream for PRODUCTION. */
119 ARRAY *builtins; /* Null terminated array of BUILTIN_DESC *. */
122 /* The array of all builtins encountered during execution of this code. */
123 ARRAY *saved_builtins = (ARRAY *)NULL;
125 /* The Posix.2 so-called `special' builtins. */
126 char *special_builtins[] =
128 ":", ".", "source", "break", "continue", "eval", "exec", "exit",
129 "export", "readonly", "return", "set", "shift", "trap", "unset",
133 /* The builtin commands that take assignment statements as arguments. */
134 char *assignment_builtins[] =
136 "alias", "declare", "export", "local", "readonly", "typeset",
140 /* Forward declarations. */
141 static int is_special_builtin ();
142 static int is_assignment_builtin ();
144 #if !defined (HAVE_RENAME)
145 static int rename ();
148 void extract_info ();
153 void write_file_headers ();
154 void write_file_footers ();
155 void write_ifdefs ();
156 void write_endifs ();
157 void write_documentation ();
158 void write_longdocs ();
159 void write_builtins ();
161 int write_helpfiles ();
164 void add_documentation ();
166 void must_be_building ();
167 void remove_trailing_whitespace ();
169 #define document_name(b) ((b)->docname ? (b)->docname : (b)->name)
172 /* For each file mentioned on the command line, process it and
173 write the information to STRUCTFILE and EXTERNFILE, while
174 creating the production file if neccessary. */
181 FILE *structfile, *externfile;
182 char *documentation_filename, *temp_struct_filename;
184 structfile = externfile = (FILE *)NULL;
185 documentation_filename = DOCFILE;
186 temp_struct_filename = (char *)NULL;
188 while (arg_index < argc && argv[arg_index][0] == '-')
190 char *arg = argv[arg_index++];
192 if (strcmp (arg, "-externfile") == 0)
193 extern_filename = argv[arg_index++];
194 else if (strcmp (arg, "-structfile") == 0)
195 struct_filename = argv[arg_index++];
196 else if (strcmp (arg, "-noproduction") == 0)
197 inhibit_production = 1;
198 else if (strcmp (arg, "-document") == 0)
199 documentation_file = fopen (documentation_filename, "w");
200 else if (strcmp (arg, "-D") == 0)
205 free (error_directory);
207 error_directory = xmalloc (2 + strlen (argv[arg_index]));
208 strcpy (error_directory, argv[arg_index]);
209 len = strlen (error_directory);
211 if (len && error_directory[len - 1] != '/')
212 strcat (error_directory, "/");
216 else if (strcmp (arg, "-documentonly") == 0)
218 only_documentation = 1;
219 documentation_file = fopen (documentation_filename, "w");
221 else if (strcmp (arg, "-H") == 0)
223 separate_helpfiles = 1;
224 helpfile_directory = argv[arg_index++];
228 fprintf (stderr, "%s: Unknown flag %s.\n", argv[0], arg);
233 /* If there are no files to process, just quit now. */
234 if (arg_index == argc)
237 if (!only_documentation)
239 /* Open the files. */
242 temp_struct_filename = xmalloc (15);
243 sprintf (temp_struct_filename, "mk-%ld", (long) getpid ());
244 structfile = fopen (temp_struct_filename, "w");
247 file_error (temp_struct_filename);
252 externfile = fopen (extern_filename, "w");
255 file_error (extern_filename);
258 /* Write out the headers. */
259 write_file_headers (structfile, externfile);
262 if (documentation_file)
264 fprintf (documentation_file, "@c Table of builtins created with %s.\n",
266 fprintf (documentation_file, "@ftable @asis\n");
269 /* Process the .def files. */
270 while (arg_index < argc)
274 arg = argv[arg_index++];
276 extract_info (arg, structfile, externfile);
279 /* Close the files. */
280 if (!only_documentation)
282 /* Write the footers. */
283 write_file_footers (structfile, externfile);
287 write_longdocs (structfile, saved_builtins);
289 rename (temp_struct_filename, struct_filename);
296 if (separate_helpfiles)
298 write_helpfiles (saved_builtins);
301 if (documentation_file)
303 fprintf (documentation_file, "@end ftable\n");
304 fclose (documentation_file);
310 /* **************************************************************** */
312 /* Array Functions and Manipulators */
314 /* **************************************************************** */
316 /* Make a new array, and return a pointer to it. The array will
317 contain elements of size WIDTH, and is initialized to no elements. */
324 array = (ARRAY *)xmalloc (sizeof (ARRAY));
327 array->width = width;
329 /* Default to increasing size in units of 20. */
330 array->growth_rate = 20;
332 array->array = (char **)NULL;
337 /* Copy the array of strings in ARRAY. */
339 copy_string_array (array)
346 return (ARRAY *)NULL;
348 copy = array_create (sizeof (char *));
350 copy->size = array->size;
351 copy->sindex = array->sindex;
352 copy->width = array->width;
354 copy->array = (char **)xmalloc ((1 + array->sindex) * sizeof (char *));
356 for (i = 0; i < array->sindex; i++)
357 copy->array[i] = savestring (array->array[i]);
359 copy->array[i] = (char *)NULL;
364 /* Add ELEMENT to ARRAY, growing the array if neccessary. */
366 array_add (element, array)
370 if (array->sindex + 2 > array->size)
371 array->array = (char **)xrealloc
372 (array->array, (array->size += array->growth_rate) * array->width);
374 #if defined (HAVE_BCOPY)
375 bcopy (&element, (char *) &(array->array[array->sindex]), array->width);
377 bzero ((char *) &(array->array[array->sindex]), array->width);
379 array->array[array->sindex++] = element;
380 array->array[array->sindex] = (char *)NULL;
381 #endif /* !HAVE_BCOPY */
384 /* Free an allocated array and data pointer. */
395 /* **************************************************************** */
397 /* Processing a DEF File */
399 /* **************************************************************** */
401 /* The definition of a function. */
402 typedef int Function ();
403 typedef int mk_handler_func_t __P((char *, DEF_FILE *, char *));
405 /* Structure handles processor directives. */
408 mk_handler_func_t *function;
411 extern int builtin_handler __P((char *, DEF_FILE *, char *));
412 extern int function_handler __P((char *, DEF_FILE *, char *));
413 extern int short_doc_handler __P((char *, DEF_FILE *, char *));
414 extern int comment_handler __P((char *, DEF_FILE *, char *));
415 extern int depends_on_handler __P((char *, DEF_FILE *, char *));
416 extern int produces_handler __P((char *, DEF_FILE *, char *));
417 extern int end_handler __P((char *, DEF_FILE *, char *));
418 extern int docname_handler __P((char *, DEF_FILE *, char *));
420 HANDLER_ENTRY handlers[] = {
421 { "BUILTIN", builtin_handler },
422 { "DOCNAME", docname_handler },
423 { "FUNCTION", function_handler },
424 { "SHORT_DOC", short_doc_handler },
425 { "$", comment_handler },
426 { "COMMENT", comment_handler },
427 { "DEPENDS_ON", depends_on_handler },
428 { "PRODUCES", produces_handler },
429 { "END", end_handler },
430 { (char *)NULL, (mk_handler_func_t *)NULL }
433 /* Return the entry in the table of handlers for NAME. */
435 find_directive (directive)
440 for (i = 0; handlers[i].directive; i++)
441 if (strcmp (handlers[i].directive, directive) == 0)
442 return (&handlers[i]);
444 return ((HANDLER_ENTRY *)NULL);
447 /* Non-zero indicates that a $BUILTIN has been seen, but not
448 the corresponding $END. */
449 static int building_builtin = 0;
451 /* Non-zero means to output cpp line and file information before
452 printing the current line to the production file. */
453 int output_cpp_line_info = 0;
455 /* The main function of this program. Read FILENAME and act on what is
456 found. Lines not starting with a dollar sign are copied to the
457 $PRODUCES target, if one is present. Lines starting with a dollar sign
458 are directives to this program, specifying the name of the builtin, the
459 function to call, the short documentation and the long documentation
460 strings. FILENAME can contain multiple $BUILTINs, but only one $PRODUCES
461 target. After the file has been processed, write out the names of
462 builtins found in each $BUILTIN. Plain text found before the $PRODUCES
463 is ignored, as is "$$ comment text". */
465 extract_info (filename, structfile, externfile)
467 FILE *structfile, *externfile;
476 if (stat (filename, &finfo) == -1)
477 file_error (filename);
479 fd = open (filename, O_RDONLY, 0666);
482 file_error (filename);
484 file_size = (size_t)finfo.st_size;
485 buffer = xmalloc (1 + file_size);
487 if ((nr = read (fd, buffer, file_size)) < 0)
488 file_error (filename);
490 /* This is needed on WIN32, and does not hurt on Unix. */
498 fprintf (stderr, "mkbuiltins: %s: skipping zero-length file\n", filename);
502 /* Create and fill in the initial structure describing this file. */
503 defs = (DEF_FILE *)xmalloc (sizeof (DEF_FILE));
504 defs->filename = filename;
505 defs->lines = array_create (sizeof (char *));
506 defs->line_number = 0;
507 defs->production = (char *)NULL;
508 defs->output = (FILE *)NULL;
509 defs->builtins = (ARRAY *)NULL;
511 /* Build the array of lines. */
513 while (i < file_size)
515 array_add (&buffer[i], defs->lines);
517 while (buffer[i] != '\n' && i < file_size)
522 /* Begin processing the input file. We don't write any output
523 until we have a file to write output to. */
524 output_cpp_line_info = 1;
526 /* Process each line in the array. */
527 for (i = 0; line = defs->lines->array[i]; i++)
529 defs->line_number = i;
535 HANDLER_ENTRY *handler;
537 /* Isolate the directive. */
538 for (j = 0; line[j] && !whitespace (line[j]); j++);
540 directive = xmalloc (j);
541 strncpy (directive, line + 1, j - 1);
542 directive[j -1] = '\0';
544 /* Get the function handler and call it. */
545 handler = find_directive (directive);
549 line_error (defs, "Unknown directive `%s'", directive);
555 /* Advance to the first non-whitespace character. */
556 while (whitespace (line[j]))
559 /* Call the directive handler with the FILE, and ARGS. */
560 (*(handler->function)) (directive, defs, line + j);
566 if (building_builtin)
567 add_documentation (defs, line);
568 else if (defs->output)
570 if (output_cpp_line_info)
572 /* If we're handed an absolute pathname, don't prepend
573 the directory name. */
574 if (defs->filename[0] == '/')
575 fprintf (defs->output, "#line %d \"%s\"\n",
576 defs->line_number + 1, defs->filename);
578 fprintf (defs->output, "#line %d \"%s%s\"\n",
579 defs->line_number + 1,
580 error_directory ? error_directory : "./",
582 output_cpp_line_info = 0;
585 fprintf (defs->output, "%s\n", line);
590 /* Close the production file. */
592 fclose (defs->output);
594 /* The file has been processed. Write the accumulated builtins to
595 the builtins.c file, and write the extern definitions to the
597 write_builtins (defs, structfile, externfile);
603 #define free_safely(x) if (x) free (x)
606 free_builtin (builtin)
607 BUILTIN_DESC *builtin;
611 free_safely (builtin->name);
612 free_safely (builtin->function);
613 free_safely (builtin->shortdoc);
614 free_safely (builtin->docname);
616 if (builtin->longdoc)
617 array_free (builtin->longdoc);
619 if (builtin->dependencies)
621 for (i = 0; builtin->dependencies->array[i]; i++)
622 free (builtin->dependencies->array[i]);
623 array_free (builtin->dependencies);
627 /* Free all of the memory allocated to a DEF_FILE. */
633 register BUILTIN_DESC *builtin;
635 if (defs->production)
636 free (defs->production);
639 array_free (defs->lines);
643 for (i = 0; builtin = (BUILTIN_DESC *)defs->builtins->array[i]; i++)
645 free_builtin (builtin);
648 array_free (defs->builtins);
653 /* **************************************************************** */
655 /* The Handler Functions Themselves */
657 /* **************************************************************** */
659 /* Strip surrounding whitespace from STRING, and
660 return a pointer to the start of it. */
662 strip_whitespace (string)
665 while (whitespace (*string))
668 remove_trailing_whitespace (string);
672 /* Remove only the trailing whitespace from STRING. */
674 remove_trailing_whitespace (string)
679 i = strlen (string) - 1;
681 while (i > 0 && whitespace (string[i]))
687 /* Ensure that there is a argument in STRING and return it.
688 FOR_WHOM is the name of the directive which needs the argument.
689 DEFS is the DEF_FILE in which the directive is found.
690 If there is no argument, produce an error. */
692 get_arg (for_whom, defs, string)
693 char *for_whom, *string;
698 new = strip_whitespace (string);
701 line_error (defs, "%s requires an argument", for_whom);
703 return (savestring (new));
706 /* Error if not building a builtin. */
708 must_be_building (directive, defs)
712 if (!building_builtin)
713 line_error (defs, "%s must be inside of a $BUILTIN block", directive);
716 /* Return the current builtin. */
718 current_builtin (directive, defs)
722 must_be_building (directive, defs);
724 return ((BUILTIN_DESC *)defs->builtins->array[defs->builtins->sindex - 1]);
726 return ((BUILTIN_DESC *)NULL);
729 /* Add LINE to the long documentation for the current builtin.
730 Ignore blank lines until the first non-blank line has been seen. */
732 add_documentation (defs, line)
736 register BUILTIN_DESC *builtin;
738 builtin = current_builtin ("(implied LONGDOC)", defs);
740 remove_trailing_whitespace (line);
742 if (!*line && !builtin->longdoc)
745 if (!builtin->longdoc)
746 builtin->longdoc = array_create (sizeof (char *));
748 array_add (line, builtin->longdoc);
751 /* How to handle the $BUILTIN directive. */
753 builtin_handler (self, defs, arg)
761 /* If we are already building a builtin, we cannot start a new one. */
762 if (building_builtin)
764 line_error (defs, "%s found before $END", self);
768 output_cpp_line_info++;
770 /* Get the name of this builtin, and stick it in the array. */
771 name = get_arg (self, defs, arg);
773 /* If this is the first builtin, create the array to hold them. */
775 defs->builtins = array_create (sizeof (BUILTIN_DESC *));
777 new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
779 new->function = (char *)NULL;
780 new->shortdoc = (char *)NULL;
781 new->docname = (char *)NULL;
782 new->longdoc = (ARRAY *)NULL;
783 new->dependencies = (ARRAY *)NULL;
786 if (is_special_builtin (name))
787 new->flags |= BUILTIN_FLAG_SPECIAL;
788 if (is_assignment_builtin (name))
789 new->flags |= BUILTIN_FLAG_ASSIGNMENT;
791 array_add ((char *)new, defs->builtins);
792 building_builtin = 1;
797 /* How to handle the $FUNCTION directive. */
799 function_handler (self, defs, arg)
804 register BUILTIN_DESC *builtin;
806 builtin = current_builtin (self, defs);
810 line_error (defs, "syntax error: no current builtin for $FUNCTION directive");
813 if (builtin->function)
814 line_error (defs, "%s already has a function (%s)",
815 builtin->name, builtin->function);
817 builtin->function = get_arg (self, defs, arg);
822 /* How to handle the $DOCNAME directive. */
824 docname_handler (self, defs, arg)
829 register BUILTIN_DESC *builtin;
831 builtin = current_builtin (self, defs);
833 if (builtin->docname)
834 line_error (defs, "%s already had a docname (%s)",
835 builtin->name, builtin->docname);
837 builtin->docname = get_arg (self, defs, arg);
842 /* How to handle the $SHORT_DOC directive. */
844 short_doc_handler (self, defs, arg)
849 register BUILTIN_DESC *builtin;
851 builtin = current_builtin (self, defs);
853 if (builtin->shortdoc)
854 line_error (defs, "%s already has short documentation (%s)",
855 builtin->name, builtin->shortdoc);
857 builtin->shortdoc = get_arg (self, defs, arg);
862 /* How to handle the $COMMENT directive. */
864 comment_handler (self, defs, arg)
872 /* How to handle the $DEPENDS_ON directive. */
874 depends_on_handler (self, defs, arg)
879 register BUILTIN_DESC *builtin;
882 builtin = current_builtin (self, defs);
883 dependent = get_arg (self, defs, arg);
885 if (!builtin->dependencies)
886 builtin->dependencies = array_create (sizeof (char *));
888 array_add (dependent, builtin->dependencies);
893 /* How to handle the $PRODUCES directive. */
895 produces_handler (self, defs, arg)
900 /* If just hacking documentation, don't change any of the production
902 if (only_documentation)
905 output_cpp_line_info++;
907 if (defs->production)
908 line_error (defs, "%s already has a %s definition", defs->filename, self);
911 defs->production = get_arg (self, defs, arg);
913 if (inhibit_production)
916 defs->output = fopen (defs->production, "w");
919 file_error (defs->production);
921 fprintf (defs->output, "/* %s, created from %s. */\n",
922 defs->production, defs->filename);
927 /* How to handle the $END directive. */
929 end_handler (self, defs, arg)
934 must_be_building (self, defs);
935 building_builtin = 0;
939 /* **************************************************************** */
941 /* Error Handling Functions */
943 /* **************************************************************** */
945 /* Produce an error for DEFS with FORMAT and ARGS. */
947 line_error (defs, format, arg1, arg2)
949 char *format, *arg1, *arg2;
951 if (defs->filename[0] != '/')
952 fprintf (stderr, "%s", error_directory ? error_directory : "./");
953 fprintf (stderr, "%s:%d:", defs->filename, defs->line_number + 1);
954 fprintf (stderr, format, arg1, arg2);
955 fprintf (stderr, "\n");
959 /* Print error message for FILENAME. */
961 file_error (filename)
968 /* **************************************************************** */
970 /* xmalloc and xrealloc () */
972 /* **************************************************************** */
974 static void memory_error_and_abort ();
980 char *temp = (char *)malloc (bytes);
983 memory_error_and_abort ();
988 xrealloc (pointer, bytes)
995 temp = (char *)malloc (bytes);
997 temp = (char *)realloc (pointer, bytes);
1000 memory_error_and_abort ();
1006 memory_error_and_abort ()
1008 fprintf (stderr, "mkbuiltins: out of virtual memory\n");
1012 /* **************************************************************** */
1014 /* Creating the Struct and Extern Files */
1016 /* **************************************************************** */
1018 /* Return a pointer to a newly allocated builtin which is
1019 an exact copy of BUILTIN. */
1021 copy_builtin (builtin)
1022 BUILTIN_DESC *builtin;
1026 new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
1028 new->name = savestring (builtin->name);
1029 new->shortdoc = savestring (builtin->shortdoc);
1030 new->longdoc = copy_string_array (builtin->longdoc);
1031 new->dependencies = copy_string_array (builtin->dependencies);
1034 builtin->function ? savestring (builtin->function) : (char *)NULL;
1036 builtin->docname ? savestring (builtin->docname) : (char *)NULL;
1041 /* How to save away a builtin. */
1043 save_builtin (builtin)
1044 BUILTIN_DESC *builtin;
1046 BUILTIN_DESC *newbuiltin;
1048 newbuiltin = copy_builtin (builtin);
1050 /* If this is the first builtin to be saved, create the array
1052 if (!saved_builtins)
1053 saved_builtins = array_create (sizeof (BUILTIN_DESC *));
1055 array_add ((char *)newbuiltin, saved_builtins);
1058 /* Flags that mean something to write_documentation (). */
1059 #define STRING_ARRAY 1
1063 char *structfile_header[] = {
1064 "/* builtins.c -- the built in shell commands. */",
1066 "/* This file is manufactured by ./mkbuiltins, and should not be",
1067 " edited by hand. See the source to mkbuiltins for details. */",
1069 "/* Copyright (C) 1987-2002 Free Software Foundation, Inc.",
1071 " This file is part of GNU Bash, the Bourne Again SHell.",
1073 " Bash is free software; you can redistribute it and/or modify it",
1074 " under the terms of the GNU General Public License as published by",
1075 " the Free Software Foundation; either version 2, or (at your option)",
1076 " any later version.",
1078 " Bash is distributed in the hope that it will be useful, but WITHOUT",
1079 " ANY WARRANTY; without even the implied warranty of MERCHANTABILITY",
1080 " or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public",
1081 " License for more details.",
1083 " You should have received a copy of the GNU General Public License",
1084 " along with Bash; see the file COPYING. If not, write to the Free",
1085 " Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */",
1087 "/* The list of shell builtins. Each element is name, function, flags,",
1088 " long-doc, short-doc. The long-doc field contains a pointer to an array",
1089 " of help lines. The function takes a WORD_LIST *; the first word in the",
1090 " list is the first arg to the command. The list has already had word",
1091 " expansion performed.",
1093 " Functions which need to look at only the simple commands (e.g.",
1094 " the enable_builtin ()), should ignore entries where",
1095 " (array[i].function == (sh_builtin_func_t *)NULL). Such entries are for",
1096 " the list of shell reserved control structures, like `if' and `while'.",
1097 " The end of the list is denoted with a NULL name field. */",
1099 "#include \"../builtins.h\"",
1103 char *structfile_footer[] = {
1104 " { (char *)0x0, (sh_builtin_func_t *)0x0, 0, (char **)0x0, (char *)0x0 }",
1107 "struct builtin *shell_builtins = static_shell_builtins;",
1108 "struct builtin *current_builtin;",
1110 "int num_shell_builtins =",
1111 "\tsizeof (static_shell_builtins) / sizeof (struct builtin) - 1;",
1115 /* Write out any neccessary opening information for
1116 STRUCTFILE and EXTERNFILE. */
1118 write_file_headers (structfile, externfile)
1119 FILE *structfile, *externfile;
1125 for (i = 0; structfile_header[i]; i++)
1126 fprintf (structfile, "%s\n", structfile_header[i]);
1128 fprintf (structfile, "#include \"%s\"\n",
1129 extern_filename ? extern_filename : "builtext.h");
1130 fprintf (structfile, "\nstruct builtin static_shell_builtins[] = {\n");
1134 fprintf (externfile,
1135 "/* %s - The list of builtins found in libbuiltins.a. */\n",
1136 extern_filename ? extern_filename : "builtext.h");
1139 /* Write out any necessary closing information for
1140 STRUCTFILE and EXTERNFILE. */
1142 write_file_footers (structfile, externfile)
1143 FILE *structfile, *externfile;
1147 /* Write out the footers. */
1150 for (i = 0; structfile_footer[i]; i++)
1151 fprintf (structfile, "%s\n", structfile_footer[i]);
1155 /* Write out the information accumulated in DEFS to
1156 STRUCTFILE and EXTERNFILE. */
1158 write_builtins (defs, structfile, externfile)
1160 FILE *structfile, *externfile;
1164 /* Write out the information. */
1167 register BUILTIN_DESC *builtin;
1169 for (i = 0; i < defs->builtins->sindex; i++)
1171 builtin = (BUILTIN_DESC *)defs->builtins->array[i];
1173 /* Write out any #ifdefs that may be there. */
1174 if (!only_documentation)
1176 if (builtin->dependencies)
1178 write_ifdefs (externfile, builtin->dependencies->array);
1179 write_ifdefs (structfile, builtin->dependencies->array);
1182 /* Write the extern definition. */
1185 if (builtin->function)
1186 fprintf (externfile, "extern int %s __P((WORD_LIST *));\n",
1189 fprintf (externfile, "extern char * const %s_doc[];\n",
1190 document_name (builtin));
1193 /* Write the structure definition. */
1196 fprintf (structfile, " { \"%s\", ", builtin->name);
1198 if (builtin->function)
1199 fprintf (structfile, "%s, ", builtin->function);
1201 fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
1203 fprintf (structfile, "%s%s%s, %s_doc,\n",
1204 "BUILTIN_ENABLED | STATIC_BUILTIN",
1205 (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
1206 (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
1207 document_name (builtin));
1210 (structfile, " \"%s\", (char *)NULL },\n",
1211 builtin->shortdoc ? builtin->shortdoc : builtin->name);
1215 if (structfile || separate_helpfiles)
1216 /* Save away this builtin for later writing of the
1217 long documentation strings. */
1218 save_builtin (builtin);
1220 /* Write out the matching #endif, if neccessary. */
1221 if (builtin->dependencies)
1224 write_endifs (externfile, builtin->dependencies->array);
1227 write_endifs (structfile, builtin->dependencies->array);
1231 if (documentation_file)
1233 fprintf (documentation_file, "@item %s\n", builtin->name);
1235 (documentation_file, builtin->longdoc->array, 0, TEXINFO);
1241 /* Write out the long documentation strings in BUILTINS to STREAM. */
1243 write_longdocs (stream, builtins)
1248 register BUILTIN_DESC *builtin;
1252 for (i = 0; i < builtins->sindex; i++)
1254 builtin = (BUILTIN_DESC *)builtins->array[i];
1256 if (builtin->dependencies)
1257 write_ifdefs (stream, builtin->dependencies->array);
1259 /* Write the long documentation strings. */
1260 dname = document_name (builtin);
1261 fprintf (stream, "char * const %s_doc[] =", dname);
1263 if (separate_helpfiles)
1265 int l = strlen (helpfile_directory) + strlen (dname) + 1;
1266 sarray[0] = (char *)xmalloc (l + 1);
1267 sprintf (sarray[0], "%s/%s", helpfile_directory, dname);
1268 sarray[1] = (char *)NULL;
1269 write_documentation (stream, sarray, 0, STRING_ARRAY);
1273 write_documentation (stream, builtin->longdoc->array, 0, STRING_ARRAY);
1275 if (builtin->dependencies)
1276 write_endifs (stream, builtin->dependencies->array);
1281 /* Write an #ifdef string saying what needs to be defined (or not defined)
1282 in order to allow compilation of the code that will follow.
1283 STREAM is the stream to write the information to,
1284 DEFINES is a null terminated array of define names.
1285 If a define is preceded by an `!', then the sense of the test is
1288 write_ifdefs (stream, defines)
1297 fprintf (stream, "#if ");
1299 for (i = 0; defines[i]; i++)
1301 char *def = defines[i];
1304 fprintf (stream, "!defined (%s)", def + 1);
1306 fprintf (stream, "defined (%s)", def);
1309 fprintf (stream, " && ");
1311 fprintf (stream, "\n");
1314 /* Write an #endif string saying what defines controlled the compilation
1315 of the immediately preceding code.
1316 STREAM is the stream to write the information to.
1317 DEFINES is a null terminated array of define names. */
1319 write_endifs (stream, defines)
1328 fprintf (stream, "#endif /* ");
1330 for (i = 0; defines[i]; i++)
1332 fprintf (stream, "%s", defines[i]);
1335 fprintf (stream, " && ");
1338 fprintf (stream, " */\n");
1341 /* Write DOCUMENTAION to STREAM, perhaps surrounding it with double-quotes
1342 and quoting special characters in the string. */
1344 write_documentation (stream, documentation, indentation, flags)
1346 char **documentation;
1347 int indentation, flags;
1350 register char *line;
1351 int string_array, texinfo;
1356 string_array = flags & STRING_ARRAY;
1358 fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n");
1360 for (i = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
1362 /* Allow #ifdef's to be written out verbatim. */
1366 fprintf (stream, "%s\n", line);
1371 fprintf (stream, " \"");
1374 for (j = 0; j < indentation; j++)
1375 fprintf (stream, " ");
1379 for (j = 0; line[j]; j++)
1385 fprintf (stream, "\\%c", line[j]);
1389 fprintf (stream, "%c", line[j]);
1393 fprintf (stream, "\",\n");
1397 for (j = 0; line[j]; j++)
1404 fprintf (stream, "@%c", line[j]);
1408 fprintf (stream, "%c", line[j]);
1411 fprintf (stream, "\n");
1414 fprintf (stream, "%s\n", line);
1418 fprintf (stream, "#endif /* HELP_BUILTIN */\n (char *)NULL\n};\n");
1422 write_helpfiles (builtins)
1425 char *helpfile, *bname;
1428 BUILTIN_DESC *builtin;
1430 i = mkdir ("helpfiles", 0777);
1431 if (i < 0 && errno != EEXIST)
1433 fprintf (stderr, "write_helpfiles: helpfiles: cannot create directory\n");
1437 hdlen = strlen ("helpfiles/");
1438 for (i = 0; i < builtins->sindex; i++)
1440 builtin = (BUILTIN_DESC *)builtins->array[i];
1442 bname = document_name (builtin);
1443 helpfile = (char *)xmalloc (hdlen + strlen (bname) + 1);
1444 sprintf (helpfile, "helpfiles/%s", bname);
1446 helpfp = fopen (helpfile, "w");
1449 fprintf (stderr, "write_helpfiles: cannot open %s\n", helpfile);
1454 write_documentation (helpfp, builtin->longdoc->array, 4, PLAINTEXT);
1464 _find_in_table (name, name_table)
1465 char *name, *name_table[];
1469 for (i = 0; name_table[i]; i++)
1470 if (strcmp (name, name_table[i]) == 0)
1476 is_special_builtin (name)
1479 return (_find_in_table (name, special_builtins));
1483 is_assignment_builtin (name)
1486 return (_find_in_table (name, assignment_builtins));
1489 #if !defined (HAVE_RENAME)
1495 if (link (from, to) < 0)
1500 #endif /* !HAVE_RENAME */