1 /* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from
2 a single source file called builtins.def. */
4 /* Copyright (C) 1987, 1989, 1991 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"
42 #define DOCFILE "builtins.texi"
44 static char *xmalloc (), *xrealloc ();
46 #if !defined (__STDC__) && !defined (strcpy)
47 extern char *strcpy ();
48 #endif /* !__STDC__ && !strcpy */
50 #define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
51 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
53 /* Flag values that builtins can have. */
54 #define BUILTIN_FLAG_SPECIAL 0x01
55 #define BUILTIN_FLAG_ASSIGNMENT 0x02
57 /* If this stream descriptor is non-zero, then write
58 texinfo documentation to it. */
59 FILE *documentation_file = (FILE *)NULL;
61 /* Non-zero means to only produce documentation. */
62 int only_documentation = 0;
64 /* Non-zero means to not do any productions. */
65 int inhibit_production = 0;
67 #if !defined (OLDCODE)
68 int no_long_document = 0;
71 /* The name of a directory to precede the filename when reporting
73 char *error_directory = (char *)NULL;
75 /* The name of the structure file. */
76 char *struct_filename = (char *)NULL;
78 /* The name of the external declaration file. */
79 char *extern_filename = (char *)NULL;
81 /* Here is a structure for manipulating arrays of data. */
83 int size; /* Number of slots allocated to array. */
84 int sindex; /* Current location in array. */
85 int width; /* Size of each element. */
86 int growth_rate; /* How fast to grow. */
87 char **array; /* The array itself. */
90 /* Here is a structure defining a single BUILTIN. */
92 char *name; /* The name of this builtin. */
93 char *function; /* The name of the function to call. */
94 char *shortdoc; /* The short documentation for this builtin. */
95 char *docname; /* Possible name for documentation string. */
96 ARRAY *longdoc; /* The long documentation for this builtin. */
97 ARRAY *dependencies; /* Null terminated array of #define names. */
98 int flags; /* Flags for this builtin. */
101 /* Here is a structure which defines a DEF file. */
103 char *filename; /* The name of the input def file. */
104 ARRAY *lines; /* The contents of the file. */
105 int line_number; /* The current line number. */
106 char *production; /* The name of the production file. */
107 FILE *output; /* Open file stream for PRODUCTION. */
108 ARRAY *builtins; /* Null terminated array of BUILTIN_DESC *. */
111 /* The array of all builtins encountered during execution of this code. */
112 ARRAY *saved_builtins = (ARRAY *)NULL;
114 /* The Posix.2 so-called `special' builtins. */
115 char *special_builtins[] =
117 ":", ".", "source", "break", "continue", "eval", "exec", "exit",
118 "export", "readonly", "return", "set", "shift", "trap", "unset",
122 /* The builtin commands that take assignment statements as arguments. */
123 char *assignment_builtins[] =
125 "alias", "declare", "export", "local", "readonly", "typeset",
129 /* Forward declarations. */
130 static int is_special_builtin ();
131 static int is_assignment_builtin ();
133 #if !defined (HAVE_RENAME)
134 static int rename ();
137 void extract_info ();
142 void write_file_headers ();
143 void write_file_footers ();
144 void write_ifdefs ();
145 void write_endifs ();
146 void write_documentation ();
147 void write_longdocs ();
148 void write_builtins ();
151 void add_documentation ();
153 void must_be_building ();
154 void remove_trailing_whitespace ();
156 /* For each file mentioned on the command line, process it and
157 write the information to STRUCTFILE and EXTERNFILE, while
158 creating the production file if neccessary. */
165 FILE *structfile, *externfile;
166 char *documentation_filename, *temp_struct_filename;
168 structfile = externfile = (FILE *)NULL;
169 documentation_filename = DOCFILE;
170 temp_struct_filename = (char *)NULL;
172 while (arg_index < argc && argv[arg_index][0] == '-')
174 char *arg = argv[arg_index++];
176 if (strcmp (arg, "-externfile") == 0)
177 extern_filename = argv[arg_index++];
178 else if (strcmp (arg, "-structfile") == 0)
179 struct_filename = argv[arg_index++];
180 else if (strcmp (arg, "-noproduction") == 0)
181 inhibit_production = 1;
182 else if (strcmp (arg, "-document") == 0)
183 documentation_file = fopen (documentation_filename, "w");
184 else if (strcmp (arg, "-D") == 0)
189 free (error_directory);
191 error_directory = xmalloc (2 + strlen (argv[arg_index]));
192 strcpy (error_directory, argv[arg_index]);
193 len = strlen (error_directory);
195 if (len && error_directory[len - 1] != '/')
196 strcat (error_directory, "/");
200 else if (strcmp (arg, "-documentonly") == 0)
202 only_documentation = 1;
203 documentation_file = fopen (documentation_filename, "w");
205 #if !defined (OLDCODE)
206 else if (strcmp (arg, "-nodocument") == 0)
207 no_long_document = 1;
208 #endif /* !OLDCODE */
211 fprintf (stderr, "%s: Unknown flag %s.\n", argv[0], arg);
216 /* If there are no files to process, just quit now. */
217 if (arg_index == argc)
220 if (!only_documentation)
222 /* Open the files. */
225 temp_struct_filename = xmalloc (15);
226 sprintf (temp_struct_filename, "mk-%d", (int) getpid ());
227 structfile = fopen (temp_struct_filename, "w");
230 file_error (temp_struct_filename);
235 externfile = fopen (extern_filename, "w");
238 file_error (extern_filename);
241 /* Write out the headers. */
242 write_file_headers (structfile, externfile);
245 if (documentation_file)
247 fprintf (documentation_file, "@c Table of builtins created with %s.\n",
249 fprintf (documentation_file, "@ftable @asis\n");
252 /* Process the .def files. */
253 while (arg_index < argc)
257 arg = argv[arg_index++];
259 extract_info (arg, structfile, externfile);
262 /* Close the files. */
263 if (!only_documentation)
265 /* Write the footers. */
266 write_file_footers (structfile, externfile);
270 write_longdocs (structfile, saved_builtins);
272 rename (temp_struct_filename, struct_filename);
279 if (documentation_file)
281 fprintf (documentation_file, "@end ftable\n");
282 fclose (documentation_file);
288 /* **************************************************************** */
290 /* Array Functions and Manipulators */
292 /* **************************************************************** */
294 /* Make a new array, and return a pointer to it. The array will
295 contain elements of size WIDTH, and is initialized to no elements. */
302 array = (ARRAY *)xmalloc (sizeof (ARRAY));
305 array->width = width;
307 /* Default to increasing size in units of 20. */
308 array->growth_rate = 20;
310 array->array = (char **)NULL;
315 /* Copy the array of strings in ARRAY. */
317 copy_string_array (array)
324 return (ARRAY *)NULL;
326 copy = array_create (sizeof (char *));
328 copy->size = array->size;
329 copy->sindex = array->sindex;
330 copy->width = array->width;
332 copy->array = (char **)xmalloc ((1 + array->sindex) * sizeof (char *));
334 for (i = 0; i < array->sindex; i++)
335 copy->array[i] = savestring (array->array[i]);
337 copy->array[i] = (char *)NULL;
342 /* Add ELEMENT to ARRAY, growing the array if neccessary. */
344 array_add (element, array)
348 if (array->sindex + 2 > array->size)
349 array->array = (char **)xrealloc
350 (array->array, (array->size += array->growth_rate) * array->width);
352 #if defined (HAVE_BCOPY)
353 bcopy (&element, (char *) &(array->array[array->sindex]), array->width);
355 bzero ((char *) &(array->array[array->sindex]), array->width);
357 array->array[array->sindex++] = element;
358 array->array[array->sindex] = (char *)NULL;
359 #endif /* !HAVE_BCOPY */
362 /* Free an allocated array and data pointer. */
373 /* **************************************************************** */
375 /* Processing a DEF File */
377 /* **************************************************************** */
379 /* The definition of a function. */
380 typedef int Function ();
382 /* Structure handles processor directives. */
389 builtin_handler (), function_handler (), short_doc_handler (),
390 comment_handler (), depends_on_handler (), produces_handler (),
391 end_handler (), docname_handler ();
393 HANDLER_ENTRY handlers[] = {
394 { "BUILTIN", builtin_handler },
395 { "DOCNAME", docname_handler },
396 { "FUNCTION", function_handler },
397 { "SHORT_DOC", short_doc_handler },
398 { "$", comment_handler },
399 { "COMMENT", comment_handler },
400 { "DEPENDS_ON", depends_on_handler },
401 { "PRODUCES", produces_handler },
402 { "END", end_handler },
403 { (char *)NULL, (Function *)NULL }
406 /* Return the entry in the table of handlers for NAME. */
408 find_directive (directive)
413 for (i = 0; handlers[i].directive; i++)
414 if (strcmp (handlers[i].directive, directive) == 0)
415 return (&handlers[i]);
417 return ((HANDLER_ENTRY *)NULL);
420 /* Non-zero indicates that a $BUILTIN has been seen, but not
421 the corresponding $END. */
422 static int building_builtin = 0;
424 /* Non-zero means to output cpp line and file information before
425 printing the current line to the production file. */
426 int output_cpp_line_info = 0;
428 /* The main function of this program. Read FILENAME and act on what is
429 found. Lines not starting with a dollar sign are copied to the
430 $PRODUCES target, if one is present. Lines starting with a dollar sign
431 are directives to this program, specifying the name of the builtin, the
432 function to call, the short documentation and the long documentation
433 strings. FILENAME can contain multiple $BUILTINs, but only one $PRODUCES
434 target. After the file has been processed, write out the names of
435 builtins found in each $BUILTIN. Plain text found before the $PRODUCES
436 is ignored, as is "$$ comment text". */
438 extract_info (filename, structfile, externfile)
440 FILE *structfile, *externfile;
449 if (stat (filename, &finfo) == -1)
450 file_error (filename);
452 fd = open (filename, O_RDONLY, 0666);
455 file_error (filename);
457 file_size = (size_t)finfo.st_size;
458 buffer = xmalloc (1 + file_size);
460 if ((nr = read (fd, buffer, file_size)) < 0)
461 file_error (filename);
463 /* This is needed on WIN32, and does not hurt on Unix. */
471 fprintf (stderr, "mkbuiltins: %s: skipping zero-length file\n", filename);
475 /* Create and fill in the initial structure describing this file. */
476 defs = (DEF_FILE *)xmalloc (sizeof (DEF_FILE));
477 defs->filename = filename;
478 defs->lines = array_create (sizeof (char *));
479 defs->line_number = 0;
480 defs->production = (char *)NULL;
481 defs->output = (FILE *)NULL;
482 defs->builtins = (ARRAY *)NULL;
484 /* Build the array of lines. */
486 while (i < file_size)
488 array_add (&buffer[i], defs->lines);
490 while (buffer[i] != '\n' && i < file_size)
495 /* Begin processing the input file. We don't write any output
496 until we have a file to write output to. */
497 output_cpp_line_info = 1;
499 /* Process each line in the array. */
500 for (i = 0; line = defs->lines->array[i]; i++)
502 defs->line_number = i;
508 HANDLER_ENTRY *handler;
510 /* Isolate the directive. */
511 for (j = 0; line[j] && !whitespace (line[j]); j++);
513 directive = xmalloc (j);
514 strncpy (directive, line + 1, j - 1);
515 directive[j -1] = '\0';
517 /* Get the function handler and call it. */
518 handler = find_directive (directive);
522 line_error (defs, "Unknown directive `%s'", directive);
528 /* Advance to the first non-whitespace character. */
529 while (whitespace (line[j]))
532 /* Call the directive handler with the FILE, and ARGS. */
533 (*(handler->function)) (directive, defs, line + j);
539 if (building_builtin)
540 add_documentation (defs, line);
541 else if (defs->output)
543 if (output_cpp_line_info)
545 /* If we're handed an absolute pathname, don't prepend
546 the directory name. */
547 if (defs->filename[0] == '/')
548 fprintf (defs->output, "#line %d \"%s\"\n",
549 defs->line_number + 1, defs->filename);
551 fprintf (defs->output, "#line %d \"%s%s\"\n",
552 defs->line_number + 1,
553 error_directory ? error_directory : "./",
555 output_cpp_line_info = 0;
558 fprintf (defs->output, "%s\n", line);
563 /* Close the production file. */
565 fclose (defs->output);
567 /* The file has been processed. Write the accumulated builtins to
568 the builtins.c file, and write the extern definitions to the
570 write_builtins (defs, structfile, externfile);
576 #define free_safely(x) if (x) free (x)
579 free_builtin (builtin)
580 BUILTIN_DESC *builtin;
584 free_safely (builtin->name);
585 free_safely (builtin->function);
586 free_safely (builtin->shortdoc);
587 free_safely (builtin->docname);
589 if (builtin->longdoc)
590 array_free (builtin->longdoc);
592 if (builtin->dependencies)
594 for (i = 0; builtin->dependencies->array[i]; i++)
595 free (builtin->dependencies->array[i]);
596 array_free (builtin->dependencies);
600 /* Free all of the memory allocated to a DEF_FILE. */
606 register BUILTIN_DESC *builtin;
608 if (defs->production)
609 free (defs->production);
612 array_free (defs->lines);
616 for (i = 0; builtin = (BUILTIN_DESC *)defs->builtins->array[i]; i++)
618 free_builtin (builtin);
621 array_free (defs->builtins);
626 /* **************************************************************** */
628 /* The Handler Functions Themselves */
630 /* **************************************************************** */
632 /* Strip surrounding whitespace from STRING, and
633 return a pointer to the start of it. */
635 strip_whitespace (string)
638 while (whitespace (*string))
641 remove_trailing_whitespace (string);
645 /* Remove only the trailing whitespace from STRING. */
647 remove_trailing_whitespace (string)
652 i = strlen (string) - 1;
654 while (i > 0 && whitespace (string[i]))
660 /* Ensure that there is a argument in STRING and return it.
661 FOR_WHOM is the name of the directive which needs the argument.
662 DEFS is the DEF_FILE in which the directive is found.
663 If there is no argument, produce an error. */
665 get_arg (for_whom, defs, string)
666 char *for_whom, *string;
671 new = strip_whitespace (string);
674 line_error (defs, "%s requires an argument", for_whom);
676 return (savestring (new));
679 /* Error if not building a builtin. */
681 must_be_building (directive, defs)
685 if (!building_builtin)
686 line_error (defs, "%s must be inside of a $BUILTIN block", directive);
689 /* Return the current builtin. */
691 current_builtin (directive, defs)
695 must_be_building (directive, defs);
697 return ((BUILTIN_DESC *)defs->builtins->array[defs->builtins->sindex - 1]);
699 return ((BUILTIN_DESC *)NULL);
702 /* Add LINE to the long documentation for the current builtin.
703 Ignore blank lines until the first non-blank line has been seen. */
705 add_documentation (defs, line)
709 register BUILTIN_DESC *builtin;
711 builtin = current_builtin ("(implied LONGDOC)", defs);
713 remove_trailing_whitespace (line);
715 if (!*line && !builtin->longdoc)
718 if (!builtin->longdoc)
719 builtin->longdoc = array_create (sizeof (char *));
721 array_add (line, builtin->longdoc);
724 /* How to handle the $BUILTIN directive. */
726 builtin_handler (self, defs, arg)
733 /* If we are already building a builtin, we cannot start a new one. */
734 if (building_builtin)
736 line_error (defs, "%s found before $END", self);
740 output_cpp_line_info++;
742 /* Get the name of this builtin, and stick it in the array. */
743 name = get_arg (self, defs, arg);
745 /* If this is the first builtin, create the array to hold them. */
747 defs->builtins = array_create (sizeof (BUILTIN_DESC *));
749 new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
751 new->function = (char *)NULL;
752 new->shortdoc = (char *)NULL;
753 new->docname = (char *)NULL;
754 new->longdoc = (ARRAY *)NULL;
755 new->dependencies = (ARRAY *)NULL;
758 if (is_special_builtin (name))
759 new->flags |= BUILTIN_FLAG_SPECIAL;
760 if (is_assignment_builtin (name))
761 new->flags |= BUILTIN_FLAG_ASSIGNMENT;
763 array_add ((char *)new, defs->builtins);
764 building_builtin = 1;
769 /* How to handle the $FUNCTION directive. */
771 function_handler (self, defs, arg)
775 register BUILTIN_DESC *builtin;
777 builtin = current_builtin (self, defs);
781 line_error (defs, "syntax error: no current builtin for $FUNCTION directive");
784 if (builtin->function)
785 line_error (defs, "%s already has a function (%s)",
786 builtin->name, builtin->function);
788 builtin->function = get_arg (self, defs, arg);
793 /* How to handle the $DOCNAME directive. */
795 docname_handler (self, defs, arg)
799 register BUILTIN_DESC *builtin;
801 builtin = current_builtin (self, defs);
803 if (builtin->docname)
804 line_error (defs, "%s already had a docname (%s)",
805 builtin->name, builtin->docname);
807 builtin->docname = get_arg (self, defs, arg);
812 /* How to handle the $SHORT_DOC directive. */
814 short_doc_handler (self, defs, arg)
818 register BUILTIN_DESC *builtin;
820 builtin = current_builtin (self, defs);
822 if (builtin->shortdoc)
823 line_error (defs, "%s already has short documentation (%s)",
824 builtin->name, builtin->shortdoc);
826 builtin->shortdoc = get_arg (self, defs, arg);
831 /* How to handle the $COMMENT directive. */
833 comment_handler (self, defs)
840 /* How to handle the $DEPENDS_ON directive. */
842 depends_on_handler (self, defs, arg)
846 register BUILTIN_DESC *builtin;
849 builtin = current_builtin (self, defs);
850 dependent = get_arg (self, defs, arg);
852 if (!builtin->dependencies)
853 builtin->dependencies = array_create (sizeof (char *));
855 array_add (dependent, builtin->dependencies);
860 /* How to handle the $PRODUCES directive. */
862 produces_handler (self, defs, arg)
866 /* If just hacking documentation, don't change any of the production
868 if (only_documentation)
871 output_cpp_line_info++;
873 if (defs->production)
874 line_error (defs, "%s already has a %s definition", defs->filename, self);
877 defs->production = get_arg (self, defs, arg);
879 if (inhibit_production)
882 defs->output = fopen (defs->production, "w");
885 file_error (defs->production);
887 fprintf (defs->output, "/* %s, created from %s. */\n",
888 defs->production, defs->filename);
893 /* How to handle the $END directive. */
895 end_handler (self, defs, arg)
899 must_be_building (self, defs);
900 building_builtin = 0;
904 /* **************************************************************** */
906 /* Error Handling Functions */
908 /* **************************************************************** */
910 /* Produce an error for DEFS with FORMAT and ARGS. */
912 line_error (defs, format, arg1, arg2)
914 char *format, *arg1, *arg2;
916 if (defs->filename[0] != '/')
917 fprintf (stderr, "%s", error_directory ? error_directory : "./");
918 fprintf (stderr, "%s:%d:", defs->filename, defs->line_number + 1);
919 fprintf (stderr, format, arg1, arg2);
920 fprintf (stderr, "\n");
924 /* Print error message for FILENAME. */
926 file_error (filename)
933 /* **************************************************************** */
935 /* xmalloc and xrealloc () */
937 /* **************************************************************** */
939 static void memory_error_and_abort ();
945 char *temp = (char *)malloc (bytes);
948 memory_error_and_abort ();
953 xrealloc (pointer, bytes)
960 temp = (char *)malloc (bytes);
962 temp = (char *)realloc (pointer, bytes);
965 memory_error_and_abort ();
971 memory_error_and_abort ()
973 fprintf (stderr, "mkbuiltins: out of virtual memory\n");
977 /* **************************************************************** */
979 /* Creating the Struct and Extern Files */
981 /* **************************************************************** */
983 /* Return a pointer to a newly allocated builtin which is
984 an exact copy of BUILTIN. */
986 copy_builtin (builtin)
987 BUILTIN_DESC *builtin;
991 new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
993 new->name = savestring (builtin->name);
994 new->shortdoc = savestring (builtin->shortdoc);
995 new->longdoc = copy_string_array (builtin->longdoc);
996 new->dependencies = copy_string_array (builtin->dependencies);
999 builtin->function ? savestring (builtin->function) : (char *)NULL;
1001 builtin->docname ? savestring (builtin->docname) : (char *)NULL;
1006 /* How to save away a builtin. */
1008 save_builtin (builtin)
1009 BUILTIN_DESC *builtin;
1011 BUILTIN_DESC *newbuiltin;
1013 newbuiltin = copy_builtin (builtin);
1015 /* If this is the first builtin to be saved, create the array
1017 if (!saved_builtins)
1018 saved_builtins = array_create (sizeof (BUILTIN_DESC *));
1020 array_add ((char *)newbuiltin, saved_builtins);
1023 /* Flags that mean something to write_documentation (). */
1024 #define STRING_ARRAY 1
1027 char *structfile_header[] = {
1028 "/* builtins.c -- the built in shell commands. */",
1030 "/* This file is manufactured by ./mkbuiltins, and should not be",
1031 " edited by hand. See the source to mkbuiltins for details. */",
1033 "/* Copyright (C) 1987, 1991, 1992 Free Software Foundation, Inc.",
1035 " This file is part of GNU Bash, the Bourne Again SHell.",
1037 " Bash is free software; you can redistribute it and/or modify it",
1038 " under the terms of the GNU General Public License as published by",
1039 " the Free Software Foundation; either version 2, or (at your option)",
1040 " any later version.",
1042 " Bash is distributed in the hope that it will be useful, but WITHOUT",
1043 " ANY WARRANTY; without even the implied warranty of MERCHANTABILITY",
1044 " or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public",
1045 " License for more details.",
1047 " You should have received a copy of the GNU General Public License",
1048 " along with Bash; see the file COPYING. If not, write to the Free",
1049 " Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */",
1051 "/* The list of shell builtins. Each element is name, function, flags,",
1052 " long-doc, short-doc. The long-doc field contains a pointer to an array",
1053 " of help lines. The function takes a WORD_LIST *; the first word in the",
1054 " list is the first arg to the command. The list has already had word",
1055 " expansion performed.",
1057 " Functions which need to look at only the simple commands (e.g.",
1058 " the enable_builtin ()), should ignore entries where",
1059 " (array[i].function == (Function *)NULL). Such entries are for",
1060 " the list of shell reserved control structures, like `if' and `while'.",
1061 " The end of the list is denoted with a NULL name field. */",
1063 "#include \"../builtins.h\"",
1067 char *structfile_footer[] = {
1068 " { (char *)0x0, (Function *)0x0, 0, (char **)0x0, (char *)0x0 }",
1071 "struct builtin *shell_builtins = static_shell_builtins;",
1072 "struct builtin *current_builtin;",
1074 "int num_shell_builtins =",
1075 "\tsizeof (static_shell_builtins) / sizeof (struct builtin) - 1;",
1079 /* Write out any neccessary opening information for
1080 STRUCTFILE and EXTERNFILE. */
1082 write_file_headers (structfile, externfile)
1083 FILE *structfile, *externfile;
1089 for (i = 0; structfile_header[i]; i++)
1090 fprintf (structfile, "%s\n", structfile_header[i]);
1092 fprintf (structfile, "#include \"%s\"\n",
1093 extern_filename ? extern_filename : "builtext.h");
1094 fprintf (structfile, "\nstruct builtin static_shell_builtins[] = {\n");
1098 fprintf (externfile,
1099 "/* %s - The list of builtins found in libbuiltins.a. */\n",
1100 extern_filename ? extern_filename : "builtext.h");
1103 /* Write out any necessary closing information for
1104 STRUCTFILE and EXTERNFILE. */
1106 write_file_footers (structfile, externfile)
1107 FILE *structfile, *externfile;
1111 /* Write out the footers. */
1114 for (i = 0; structfile_footer[i]; i++)
1115 fprintf (structfile, "%s\n", structfile_footer[i]);
1119 /* Write out the information accumulated in DEFS to
1120 STRUCTFILE and EXTERNFILE. */
1122 write_builtins (defs, structfile, externfile)
1124 FILE *structfile, *externfile;
1128 /* Write out the information. */
1131 register BUILTIN_DESC *builtin;
1133 for (i = 0; i < defs->builtins->sindex; i++)
1135 builtin = (BUILTIN_DESC *)defs->builtins->array[i];
1137 /* Write out any #ifdefs that may be there. */
1138 if (!only_documentation)
1140 if (builtin->dependencies)
1142 write_ifdefs (externfile, builtin->dependencies->array);
1143 write_ifdefs (structfile, builtin->dependencies->array);
1146 /* Write the extern definition. */
1149 if (builtin->function)
1150 fprintf (externfile, "extern int %s ();\n",
1153 fprintf (externfile, "extern char *%s_doc[];\n",
1154 builtin->docname ? builtin->docname : builtin->name);
1157 /* Write the structure definition. */
1160 fprintf (structfile, " { \"%s\", ", builtin->name);
1162 if (builtin->function)
1163 fprintf (structfile, "%s, ", builtin->function);
1165 fprintf (structfile, "(Function *)0x0, ");
1167 fprintf (structfile, "%s%s%s, %s_doc,\n",
1168 "BUILTIN_ENABLED | STATIC_BUILTIN",
1169 (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
1170 (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
1171 builtin->docname ? builtin->docname : builtin->name);
1174 (structfile, " \"%s\", (char *)NULL },\n",
1175 builtin->shortdoc ? builtin->shortdoc : builtin->name);
1177 /* Save away this builtin for later writing of the
1178 long documentation strings. */
1179 save_builtin (builtin);
1182 /* Write out the matching #endif, if neccessary. */
1183 if (builtin->dependencies)
1186 write_endifs (externfile, builtin->dependencies->array);
1189 write_endifs (structfile, builtin->dependencies->array);
1193 if (documentation_file)
1195 fprintf (documentation_file, "@item %s\n", builtin->name);
1197 (documentation_file, builtin->longdoc->array, 0, TEXINFO);
1203 /* Write out the long documentation strings in BUILTINS to STREAM. */
1205 write_longdocs (stream, builtins)
1210 register BUILTIN_DESC *builtin;
1212 for (i = 0; i < builtins->sindex; i++)
1214 builtin = (BUILTIN_DESC *)builtins->array[i];
1216 if (builtin->dependencies)
1217 write_ifdefs (stream, builtin->dependencies->array);
1219 /* Write the long documentation strings. */
1220 fprintf (stream, "char *%s_doc[] =",
1221 builtin->docname ? builtin->docname : builtin->name);
1222 write_documentation (stream, builtin->longdoc->array, 0, STRING_ARRAY);
1224 if (builtin->dependencies)
1225 write_endifs (stream, builtin->dependencies->array);
1230 /* Write an #ifdef string saying what needs to be defined (or not defined)
1231 in order to allow compilation of the code that will follow.
1232 STREAM is the stream to write the information to,
1233 DEFINES is a null terminated array of define names.
1234 If a define is preceded by an `!', then the sense of the test is
1237 write_ifdefs (stream, defines)
1246 fprintf (stream, "#if ");
1248 for (i = 0; defines[i]; i++)
1250 char *def = defines[i];
1253 fprintf (stream, "!defined (%s)", def + 1);
1255 fprintf (stream, "defined (%s)", def);
1258 fprintf (stream, " && ");
1260 fprintf (stream, "\n");
1263 /* Write an #endif string saying what defines controlled the compilation
1264 of the immediately preceding code.
1265 STREAM is the stream to write the information to.
1266 DEFINES is a null terminated array of define names. */
1268 write_endifs (stream, defines)
1277 fprintf (stream, "#endif /* ");
1279 for (i = 0; defines[i]; i++)
1281 fprintf (stream, "%s", defines[i]);
1284 fprintf (stream, " && ");
1287 fprintf (stream, " */\n");
1290 /* Write DOCUMENTAION to STREAM, perhaps surrounding it with double-quotes
1291 and quoting special characters in the string. */
1293 write_documentation (stream, documentation, indentation, flags)
1295 char **documentation;
1296 int indentation, flags;
1299 register char *line;
1300 int string_array, texinfo;
1305 string_array = flags & STRING_ARRAY;
1307 fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n");
1309 #if !defined (OLDCODE)
1310 /* XXX -- clean me up; for experiment only */
1311 if (no_long_document)
1312 goto end_of_document;
1313 #endif /* !OLDCODE */
1315 for (i = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
1317 /* Allow #ifdef's to be written out verbatim. */
1321 fprintf (stream, "%s\n", line);
1326 fprintf (stream, " \"");
1329 for (j = 0; j < indentation; j++)
1330 fprintf (stream, " ");
1334 for (j = 0; line[j]; j++)
1340 fprintf (stream, "\\%c", line[j]);
1344 fprintf (stream, "%c", line[j]);
1348 fprintf (stream, "\",\n");
1352 for (j = 0; line[j]; j++)
1359 fprintf (stream, "@%c", line[j]);
1363 fprintf (stream, "%c", line[j]);
1366 fprintf (stream, "\n");
1369 fprintf (stream, "%s\n", line);
1372 #if !defined (OLDCODE)
1374 #endif /* !OLDCODE */
1377 fprintf (stream, "#endif /* HELP_BUILTIN */\n (char *)NULL\n};\n");
1381 _find_in_table (name, name_table)
1382 char *name, *name_table[];
1386 for (i = 0; name_table[i]; i++)
1387 if (strcmp (name, name_table[i]) == 0)
1393 is_special_builtin (name)
1396 return (_find_in_table (name, special_builtins));
1400 is_assignment_builtin (name)
1403 return (_find_in_table (name, assignment_builtins));
1406 #if !defined (HAVE_RENAME)
1412 if (link (from, to) < 0)
1417 #endif /* !HAVE_RENAME */