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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 #include "../bashansi.h"
23 #include "../config.h"
25 #include <sys/types.h>
28 #include "../filecntl.h"
30 #if defined (HAVE_UNISTD_H)
32 #endif /* HAVE_UNISTD_H */
34 #if defined (HAVE_STRING_H)
36 #else /* !HAVE_STRING_H */
38 #endif /* !HAVE_STRING_H */
40 #define DOCFILE "builtins.texi"
42 static char *xmalloc (), *xrealloc ();
44 #if !defined (__STDC__) && !defined (strcpy)
45 extern char *strcpy ();
46 #endif /* !__STDC__ && !strcpy */
48 #define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
49 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
51 /* Flag values that builtins can have. */
52 #define BUILTIN_FLAG_SPECIAL 0x01
54 /* If this stream descriptor is non-zero, then write
55 texinfo documentation to it. */
56 FILE *documentation_file = (FILE *)NULL;
58 /* Non-zero means to only produce documentation. */
59 int only_documentation = 0;
61 /* Non-zero means to not do any productions. */
62 int inhibit_production = 0;
64 #if !defined (OLDCODE)
65 int no_long_document = 0;
68 /* The name of a directory to precede the filename when reporting
70 char *error_directory = (char *)NULL;
72 /* The name of the structure file. */
73 char *struct_filename = (char *)NULL;
75 /* The name of the external declaration file. */
76 char *extern_filename = (char *)NULL;
78 /* Here is a structure for manipulating arrays of data. */
80 int size; /* Number of slots allocated to array. */
81 int sindex; /* Current location in array. */
82 int width; /* Size of each element. */
83 int growth_rate; /* How fast to grow. */
84 char **array; /* The array itself. */
87 /* Here is a structure defining a single BUILTIN. */
89 char *name; /* The name of this builtin. */
90 char *function; /* The name of the function to call. */
91 char *shortdoc; /* The short documentation for this builtin. */
92 char *docname; /* Possible name for documentation string. */
93 ARRAY *longdoc; /* The long documentation for this builtin. */
94 ARRAY *dependencies; /* Null terminated array of #define names. */
95 int flags; /* Flags for this builtin. */
98 /* Here is a structure which defines a DEF file. */
100 char *filename; /* The name of the input def file. */
101 ARRAY *lines; /* The contents of the file. */
102 int line_number; /* The current line number. */
103 char *production; /* The name of the production file. */
104 FILE *output; /* Open file stream for PRODUCTION. */
105 ARRAY *builtins; /* Null terminated array of BUILTIN_DESC *. */
108 /* The array of all builtins encountered during execution of this code. */
109 ARRAY *saved_builtins = (ARRAY *)NULL;
111 /* The Posix.2 so-called `special' builtins. */
112 char *special_builtins[] =
114 ":", ".", "source", "break", "continue", "eval", "exec", "exit",
115 "export", "readonly", "return", "set", "shift", "trap", "unset",
118 static int is_special_builtin ();
121 /* For each file mentioned on the command line, process it and
122 write the information to STRUCTFILE and EXTERNFILE, while
123 creating the production file if neccessary. */
129 FILE *structfile, *externfile;
130 char *documentation_filename, *temp_struct_filename;
132 structfile = externfile = (FILE *)NULL;
133 documentation_filename = DOCFILE;
134 temp_struct_filename = (char *)NULL;
136 while (arg_index < argc && argv[arg_index][0] == '-')
138 char *arg = argv[arg_index++];
140 if (strcmp (arg, "-externfile") == 0)
141 extern_filename = argv[arg_index++];
142 else if (strcmp (arg, "-structfile") == 0)
143 struct_filename = argv[arg_index++];
144 else if (strcmp (arg, "-noproduction") == 0)
145 inhibit_production = 1;
146 else if (strcmp (arg, "-document") == 0)
147 documentation_file = fopen (documentation_filename, "w");
148 else if (strcmp (arg, "-D") == 0)
153 free (error_directory);
155 error_directory = xmalloc (2 + strlen (argv[arg_index]));
156 strcpy (error_directory, argv[arg_index]);
157 len = strlen (error_directory);
159 if (len && error_directory[len - 1] != '/')
160 strcat (error_directory, "/");
164 else if (strcmp (arg, "-documentonly") == 0)
166 only_documentation = 1;
167 documentation_file = fopen (documentation_filename, "w");
169 #if !defined (OLDCODE)
170 else if (strcmp (arg, "-nodocument") == 0)
171 no_long_document = 1;
172 #endif /* !OLDCODE */
175 fprintf (stderr, "%s: Unknown flag %s.\n", argv[0], arg);
180 /* If there are no files to process, just quit now. */
181 if (arg_index == argc)
184 if (!only_documentation)
186 /* Open the files. */
189 temp_struct_filename = xmalloc (15);
190 sprintf (temp_struct_filename, "mk-%d", (int) getpid ());
191 structfile = fopen (temp_struct_filename, "w");
194 file_error (temp_struct_filename);
199 externfile = fopen (extern_filename, "w");
202 file_error (extern_filename);
205 /* Write out the headers. */
206 write_file_headers (structfile, externfile);
209 if (documentation_file)
211 fprintf (documentation_file, "@c Table of builtins created with %s.\n",
213 fprintf (documentation_file, "@ftable @asis\n");
216 /* Process the .def files. */
217 while (arg_index < argc)
221 arg = argv[arg_index++];
223 extract_info (arg, structfile, externfile);
226 /* Close the files. */
227 if (!only_documentation)
229 /* Write the footers. */
230 write_file_footers (structfile, externfile);
234 write_longdocs (structfile, saved_builtins);
236 link (temp_struct_filename, struct_filename);
237 unlink (temp_struct_filename);
244 if (documentation_file)
246 fprintf (documentation_file, "@end ftable\n");
247 fclose (documentation_file);
253 /* **************************************************************** */
255 /* Array Functions and Manipulators */
257 /* **************************************************************** */
259 /* Make a new array, and return a pointer to it. The array will
260 contain elements of size WIDTH, and is initialized to no elements. */
267 array = (ARRAY *)xmalloc (sizeof (ARRAY));
270 array->width = width;
272 /* Default to increasing size in units of 20. */
273 array->growth_rate = 20;
275 array->array = (char **)NULL;
280 /* Copy the array of strings in ARRAY. */
282 copy_string_array (array)
289 return (ARRAY *)NULL;
291 copy = array_create (sizeof (char *));
293 copy->size = array->size;
294 copy->sindex = array->sindex;
295 copy->width = array->width;
297 copy->array = (char **)xmalloc ((1 + array->sindex) * sizeof (char *));
299 for (i = 0; i < array->sindex; i++)
300 copy->array[i] = savestring (array->array[i]);
302 copy->array[i] = (char *)NULL;
307 /* Add ELEMENT to ARRAY, growing the array if neccessary. */
308 array_add (element, array)
312 if (array->sindex + 2 > array->size)
313 array->array = (char **)xrealloc
314 (array->array, (array->size += array->growth_rate) * array->width);
316 #if defined (HAVE_BCOPY)
317 bcopy (&element, &(array->array[array->sindex]), array->width);
319 bzero (&(array->array[array->sindex]), array->width);
321 array->array[array->sindex++] = element;
322 array->array[array->sindex] = (char *)NULL;
323 #endif /* !HAVE_BCOPY */
326 /* Free an allocated array and data pointer. */
336 /* **************************************************************** */
338 /* Processing a DEF File */
340 /* **************************************************************** */
342 /* The definition of a function. */
343 typedef int Function ();
345 /* Structure handles processor directives. */
352 builtin_handler (), function_handler (), short_doc_handler (),
353 comment_handler (), depends_on_handler (), produces_handler (),
354 end_handler (), docname_handler ();
356 HANDLER_ENTRY handlers[] = {
357 { "BUILTIN", builtin_handler },
358 { "DOCNAME", docname_handler },
359 { "FUNCTION", function_handler },
360 { "SHORT_DOC", short_doc_handler },
361 { "$", comment_handler },
362 { "COMMENT", comment_handler },
363 { "DEPENDS_ON", depends_on_handler },
364 { "PRODUCES", produces_handler },
365 { "END", end_handler },
366 { (char *)NULL, (Function *)NULL }
369 /* Return the entry in the table of handlers for NAME. */
371 find_directive (directive)
376 for (i = 0; handlers[i].directive; i++)
377 if (strcmp (handlers[i].directive, directive) == 0)
378 return (&handlers[i]);
380 return ((HANDLER_ENTRY *)NULL);
383 /* Non-zero indicates that a $BUILTIN has been seen, but not
384 the corresponding $END. */
385 static int building_builtin = 0;
387 /* Non-zero means to output cpp line and file information before
388 printing the current line to the production file. */
389 int output_cpp_line_info = 0;
391 /* The main function of this program. Read FILENAME and act on what is
392 found. Lines not starting with a dollar sign are copied to the
393 $PRODUCES target, if one is present. Lines starting with a dollar sign
394 are directives to this program, specifying the name of the builtin, the
395 function to call, the short documentation and the long documentation
396 strings. FILENAME can contain multiple $BUILTINs, but only one $PRODUCES
397 target. After the file has been processed, write out the names of
398 builtins found in each $BUILTIN. Plain text found before the $PRODUCES
399 is ignored, as is "$$ comment text". */
400 extract_info (filename, structfile, externfile)
402 FILE *structfile, *externfile;
410 if (stat (filename, &finfo) == -1)
411 file_error (filename);
413 fd = open (filename, O_RDONLY, 0666);
416 file_error (filename);
418 buffer = xmalloc (1 + (int)finfo.st_size);
420 if (read (fd, buffer, finfo.st_size) != finfo.st_size)
421 file_error (filename);
425 /* Create and fill in the initial structure describing this file. */
426 defs = (DEF_FILE *)xmalloc (sizeof (DEF_FILE));
427 defs->filename = filename;
428 defs->lines = array_create (sizeof (char *));
429 defs->line_number = 0;
430 defs->production = (char *)NULL;
431 defs->output = (FILE *)NULL;
432 defs->builtins = (ARRAY *)NULL;
434 /* Build the array of lines. */
436 while (i < finfo.st_size)
438 array_add (&buffer[i], defs->lines);
440 while (buffer[i] != '\n' && i < finfo.st_size)
445 /* Begin processing the input file. We don't write any output
446 until we have a file to write output to. */
447 output_cpp_line_info = 1;
449 /* Process each line in the array. */
450 for (i = 0; line = defs->lines->array[i]; i++)
452 defs->line_number = i;
458 HANDLER_ENTRY *handler;
460 /* Isolate the directive. */
461 for (j = 0; line[j] && !whitespace (line[j]); j++);
463 directive = xmalloc (j);
464 strncpy (directive, line + 1, j - 1);
465 directive[j -1] = '\0';
467 /* Get the function handler and call it. */
468 handler = find_directive (directive);
472 line_error (defs, "Unknown directive `%s'", directive);
478 /* Advance to the first non-whitespace character. */
479 while (whitespace (line[j]))
482 /* Call the directive handler with the FILE, and ARGS. */
483 (*(handler->function)) (directive, defs, line + j);
489 if (building_builtin)
490 add_documentation (defs, line);
491 else if (defs->output)
493 if (output_cpp_line_info)
495 /* If we're handed an absolute pathname, don't prepend
496 the directory name. */
497 if (defs->filename[0] == '/')
498 fprintf (defs->output, "#line %d \"%s\"\n",
499 defs->line_number + 1, defs->filename);
501 fprintf (defs->output, "#line %d \"%s%s\"\n",
502 defs->line_number + 1,
503 error_directory ? error_directory : "./",
505 output_cpp_line_info = 0;
508 fprintf (defs->output, "%s\n", line);
513 /* Close the production file. */
515 fclose (defs->output);
517 /* The file has been processed. Write the accumulated builtins to
518 the builtins.c file, and write the extern definitions to the
520 write_builtins (defs, structfile, externfile);
526 #define free_safely(x) if (x) free (x)
529 free_builtin (builtin)
530 BUILTIN_DESC *builtin;
534 free_safely (builtin->name);
535 free_safely (builtin->function);
536 free_safely (builtin->shortdoc);
537 free_safely (builtin->docname);
539 if (builtin->longdoc)
540 array_free (builtin->longdoc);
542 if (builtin->dependencies)
544 for (i = 0; builtin->dependencies->array[i]; i++)
545 free (builtin->dependencies->array[i]);
546 array_free (builtin->dependencies);
550 /* Free all of the memory allocated to a DEF_FILE. */
555 register BUILTIN_DESC *builtin;
557 if (defs->production)
558 free (defs->production);
561 array_free (defs->lines);
565 for (i = 0; builtin = (BUILTIN_DESC *)defs->builtins->array[i]; i++)
567 free_builtin (builtin);
570 array_free (defs->builtins);
575 /* **************************************************************** */
577 /* The Handler Functions Themselves */
579 /* **************************************************************** */
581 /* Strip surrounding whitespace from STRING, and
582 return a pointer to the start of it. */
584 strip_whitespace (string)
587 while (whitespace (*string))
590 remove_trailing_whitespace (string);
594 /* Remove only the trailing whitespace from STRING. */
595 remove_trailing_whitespace (string)
600 i = strlen (string) - 1;
602 while (i > 0 && whitespace (string[i]))
608 /* Ensure that there is a argument in STRING and return it.
609 FOR_WHOM is the name of the directive which needs the argument.
610 DEFS is the DEF_FILE in which the directive is found.
611 If there is no argument, produce an error. */
613 get_arg (for_whom, defs, string)
614 char *for_whom, *string;
619 new = strip_whitespace (string);
622 line_error (defs, "%s requires an argument", for_whom);
624 return (savestring (new));
627 /* Error if not building a builtin. */
628 must_be_building (directive, defs)
632 if (!building_builtin)
633 line_error (defs, "%s must be inside of a $BUILTIN block", directive);
636 /* Return the current builtin. */
638 current_builtin (directive, defs)
642 must_be_building (directive, defs);
643 return ((BUILTIN_DESC *)defs->builtins->array[defs->builtins->sindex - 1]);
646 /* Add LINE to the long documentation for the current builtin.
647 Ignore blank lines until the first non-blank line has been seen. */
648 add_documentation (defs, line)
652 register BUILTIN_DESC *builtin;
654 builtin = current_builtin ("(implied LONGDOC)", defs);
656 remove_trailing_whitespace (line);
658 if (!*line && !builtin->longdoc)
661 if (!builtin->longdoc)
662 builtin->longdoc = array_create (sizeof (char *));
664 array_add (line, builtin->longdoc);
667 /* How to handle the $BUILTIN directive. */
669 builtin_handler (self, defs, arg)
673 /* If we are already building a builtin, we cannot start a new one. */
674 if (building_builtin)
675 return (line_error (defs, "%s found before $END", self));
677 output_cpp_line_info++;
679 /* Get the name of this builtin, and stick it in the array. */
684 name = get_arg (self, defs, arg);
686 /* If this is the first builtin, create the array to hold them. */
688 defs->builtins = array_create (sizeof (BUILTIN_DESC *));
690 new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
692 new->function = (char *)NULL;
693 new->shortdoc = (char *)NULL;
694 new->docname = (char *)NULL;
695 new->longdoc = (ARRAY *)NULL;
696 new->dependencies = (ARRAY *)NULL;
699 if (is_special_builtin (name))
700 new->flags |= BUILTIN_FLAG_SPECIAL;
702 array_add ((char *)new, defs->builtins);
703 building_builtin = 1;
708 /* How to handle the $FUNCTION directive. */
710 function_handler (self, defs, arg)
714 register BUILTIN_DESC *builtin;
716 builtin = current_builtin (self, defs);
718 if (builtin->function)
719 line_error (defs, "%s already has a function (%s)",
720 builtin->name, builtin->function);
722 builtin->function = get_arg (self, defs, arg);
727 /* How to handle the $DOCNAME directive. */
729 docname_handler (self, defs, arg)
733 register BUILTIN_DESC *builtin;
735 builtin = current_builtin (self, defs);
737 if (builtin->docname)
738 line_error (defs, "%s already had a docname (%s)",
739 builtin->name, builtin->docname);
741 builtin->docname = get_arg (self, defs, arg);
746 /* How to handle the $SHORT_DOC directive. */
747 short_doc_handler (self, defs, arg)
751 register BUILTIN_DESC *builtin;
753 builtin = current_builtin (self, defs);
755 if (builtin->shortdoc)
756 line_error (defs, "%s already has short documentation (%s)",
757 builtin->name, builtin->shortdoc);
759 builtin->shortdoc = get_arg (self, defs, arg);
764 /* How to handle the $COMMENT directive. */
765 comment_handler (self, defs)
771 /* How to handle the $DEPENDS_ON directive. */
772 depends_on_handler (self, defs, arg)
776 register BUILTIN_DESC *builtin;
779 builtin = current_builtin (self, defs);
780 dependent = get_arg (self, defs, arg);
782 if (!builtin->dependencies)
783 builtin->dependencies = array_create (sizeof (char *));
785 array_add (dependent, builtin->dependencies);
790 /* How to handle the $PRODUCES directive. */
791 produces_handler (self, defs, arg)
795 /* If just hacking documentation, don't change any of the production
797 if (only_documentation)
800 output_cpp_line_info++;
802 if (defs->production)
803 line_error (defs, "%s already has a %s definition", defs->filename, self);
806 defs->production = get_arg (self, defs, arg);
808 if (inhibit_production)
811 defs->output = fopen (defs->production, "w");
814 file_error (defs->production);
816 fprintf (defs->output, "/* %s, created from %s. */\n",
817 defs->production, defs->filename);
822 /* How to handle the $END directive. */
823 end_handler (self, defs, arg)
827 must_be_building (self, defs);
828 building_builtin = 0;
831 /* **************************************************************** */
833 /* Error Handling Functions */
835 /* **************************************************************** */
837 /* Produce an error for DEFS with FORMAT and ARGS. */
838 line_error (defs, format, arg1, arg2)
840 char *format, *arg1, *arg2;
842 if (defs->filename[0] != '/')
843 fprintf (stderr, "%s", error_directory ? error_directory : "./");
844 fprintf (stderr, "%s:%d:", defs->filename, defs->line_number + 1);
845 fprintf (stderr, format, arg1, arg2);
846 fprintf (stderr, "\n");
850 /* Print error message for FILENAME. */
851 file_error (filename)
858 /* **************************************************************** */
860 /* xmalloc and xrealloc () */
862 /* **************************************************************** */
864 static void memory_error_and_abort ();
870 char *temp = (char *)malloc (bytes);
873 memory_error_and_abort ();
878 xrealloc (pointer, bytes)
885 temp = (char *)malloc (bytes);
887 temp = (char *)realloc (pointer, bytes);
890 memory_error_and_abort ();
896 memory_error_and_abort ()
898 fprintf (stderr, "mkbuiltins: Out of virtual memory!\n");
902 /* **************************************************************** */
904 /* Creating the Struct and Extern Files */
906 /* **************************************************************** */
908 /* Return a pointer to a newly allocated builtin which is
909 an exact copy of BUILTIN. */
911 copy_builtin (builtin)
912 BUILTIN_DESC *builtin;
916 new = (BUILTIN_DESC *)xmalloc (sizeof (BUILTIN_DESC));
918 new->name = savestring (builtin->name);
919 new->shortdoc = savestring (builtin->shortdoc);
920 new->longdoc = copy_string_array (builtin->longdoc);
921 new->dependencies = copy_string_array (builtin->dependencies);
924 builtin->function ? savestring (builtin->function) : (char *)NULL;
926 builtin->docname ? savestring (builtin->docname) : (char *)NULL;
931 /* How to save away a builtin. */
932 save_builtin (builtin)
933 BUILTIN_DESC *builtin;
935 BUILTIN_DESC *newbuiltin;
937 newbuiltin = copy_builtin (builtin);
939 /* If this is the first builtin to be saved, create the array
942 saved_builtins = array_create (sizeof (BUILTIN_DESC *));
944 array_add ((char *)newbuiltin, saved_builtins);
947 /* Flags that mean something to write_documentation (). */
948 #define STRING_ARRAY 1
951 char *structfile_header[] = {
952 "/* builtins.c -- the built in shell commands. */",
954 "/* This file is manufactured by ./mkbuiltins, and should not be",
955 " edited by hand. See the source to mkbuiltins for details. */",
957 "/* Copyright (C) 1987, 1991, 1992 Free Software Foundation, Inc.",
959 " This file is part of GNU Bash, the Bourne Again SHell.",
961 " Bash is free software; you can redistribute it and/or modify it",
962 " under the terms of the GNU General Public License as published by",
963 " the Free Software Foundation; either version 1, or (at your option)",
964 " any later version.",
966 " Bash is distributed in the hope that it will be useful, but WITHOUT",
967 " ANY WARRANTY; without even the implied warranty of MERCHANTABILITY",
968 " or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public",
969 " License for more details.",
971 " You should have received a copy of the GNU General Public License",
972 " along with Bash; see the file COPYING. If not, write to the Free",
973 " Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */",
975 "/* The list of shell builtins. Each element is name, function, enabled-p,",
976 " long-doc, short-doc. The long-doc field contains a pointer to an array",
977 " of help lines. The function takes a WORD_LIST *; the first word in the",
978 " list is the first arg to the command. The list has already had word",
979 " expansion performed.",
981 " Functions which need to look at only the simple commands (e.g.",
982 " the enable_builtin ()), should ignore entries where",
983 " (array[i].function == (Function *)NULL). Such entries are for",
984 " the list of shell reserved control structures, like `if' and `while'.",
985 " The end of the list is denoted with a NULL name field. */",
987 "#include \"../builtins.h\"",
991 char *structfile_footer[] = {
992 " { (char *)0x0, (Function *)0x0, 0, (char **)0x0, (char *)0x0 }",
995 "int num_shell_builtins =",
996 "\tsizeof (shell_builtins) / sizeof (struct builtin) - 1;",
1000 /* Write out any neccessary opening information for
1001 STRUCTFILE and EXTERNFILE. */
1002 write_file_headers (structfile, externfile)
1003 FILE *structfile, *externfile;
1009 for (i = 0; structfile_header[i]; i++)
1010 fprintf (structfile, "%s\n", structfile_header[i]);
1012 fprintf (structfile, "#include \"%s\"\n",
1013 extern_filename ? extern_filename : "builtext.h");
1014 fprintf (structfile, "\nstruct builtin shell_builtins[] = {\n");
1018 fprintf (externfile,
1019 "/* %s - The list of builtins found in libbuiltins.a. */\n",
1020 extern_filename ? extern_filename : "builtext.h");
1023 /* Write out any necessary closing information for
1024 STRUCTFILE and EXTERNFILE. */
1025 write_file_footers (structfile, externfile)
1026 FILE *structfile, *externfile;
1030 /* Write out the footers. */
1033 for (i = 0; structfile_footer[i]; i++)
1034 fprintf (structfile, "%s\n", structfile_footer[i]);
1038 /* Write out the information accumulated in DEFS to
1039 STRUCTFILE and EXTERNFILE. */
1040 write_builtins (defs, structfile, externfile)
1042 FILE *structfile, *externfile;
1046 /* Write out the information. */
1049 register BUILTIN_DESC *builtin;
1051 for (i = 0; i < defs->builtins->sindex; i++)
1053 builtin = (BUILTIN_DESC *)defs->builtins->array[i];
1055 /* Write out any #ifdefs that may be there. */
1056 if (!only_documentation)
1058 if (builtin->dependencies)
1060 if (builtin->function)
1061 write_ifdefs (externfile, builtin->dependencies->array);
1062 write_ifdefs (structfile, builtin->dependencies->array);
1065 /* Write the extern definition. */
1068 if (builtin->function)
1069 fprintf (externfile, "extern int %s ();\n",
1072 fprintf (externfile, "extern char *%s_doc[];\n",
1073 builtin->docname ?builtin->docname : builtin->name);
1076 /* Write the structure definition. */
1079 fprintf (structfile, " { \"%s\", ", builtin->name);
1081 if (builtin->function)
1082 fprintf (structfile, "%s, ", builtin->function);
1084 fprintf (structfile, "(Function *)0x0, ");
1086 #define SPECIAL_FLAG_STRING "BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN"
1087 #define NORMAL_FLAG_STRING "BUILTIN_ENABLED | STATIC_BUILTIN"
1089 fprintf (structfile, "%s, %s_doc,\n",
1090 (builtin->flags & BUILTIN_FLAG_SPECIAL) ?
1091 SPECIAL_FLAG_STRING :
1093 builtin->docname ? builtin->docname : builtin->name);
1095 #undef SPECIAL_FLAG_STRING
1096 #undef NORMAL_FLAG_STRING
1099 (structfile, " \"%s\" },\n",
1100 builtin->shortdoc ? builtin->shortdoc : builtin->name);
1102 /* Save away this builtin for later writing of the
1103 long documentation strings. */
1104 save_builtin (builtin);
1107 /* Write out the matching #endif, if neccessary. */
1108 if (builtin->dependencies)
1111 write_endifs (externfile, builtin->dependencies->array);
1114 write_endifs (structfile, builtin->dependencies->array);
1118 if (documentation_file)
1120 fprintf (documentation_file, "@item %s\n", builtin->name);
1122 (documentation_file, builtin->longdoc->array, 0, TEXINFO);
1128 /* Write out the long documentation strings in BUILTINS to STREAM. */
1129 write_longdocs (stream, builtins)
1134 register BUILTIN_DESC *builtin;
1136 for (i = 0; i < builtins->sindex; i++)
1138 builtin = (BUILTIN_DESC *)builtins->array[i];
1140 if (builtin->dependencies)
1141 write_ifdefs (stream, builtin->dependencies->array);
1143 /* Write the long documentation strings. */
1144 fprintf (stream, "char *%s_doc[] =",
1145 builtin->docname ? builtin->docname : builtin->name);
1146 write_documentation (stream, builtin->longdoc->array, 0, STRING_ARRAY);
1148 if (builtin->dependencies)
1149 write_endifs (stream, builtin->dependencies->array);
1154 /* Write an #ifdef string saying what needs to be defined (or not defined)
1155 in order to allow compilation of the code that will follow.
1156 STREAM is the stream to write the information to,
1157 DEFINES is a null terminated array of define names.
1158 If a define is preceded by an `!', then the sense of the test is
1160 write_ifdefs (stream, defines)
1169 fprintf (stream, "#if ");
1171 for (i = 0; defines[i]; i++)
1173 char *def = defines[i];
1176 fprintf (stream, "!defined (%s)", def + 1);
1178 fprintf (stream, "defined (%s)", def);
1181 fprintf (stream, " && ");
1183 fprintf (stream, "\n");
1186 /* Write an #endif string saying what defines controlled the compilation
1187 of the immediately preceding code.
1188 STREAM is the stream to write the information to.
1189 DEFINES is a null terminated array of define names. */
1190 write_endifs (stream, defines)
1199 fprintf (stream, "#endif /* ");
1201 for (i = 0; defines[i]; i++)
1203 fprintf (stream, "%s", defines[i]);
1206 fprintf (stream, " && ");
1209 fprintf (stream, " */\n");
1212 /* Write DOCUMENTAION to STREAM, perhaps surrounding it with double-quotes
1213 and quoting special characters in the string. */
1214 write_documentation (stream, documentation, indentation, flags)
1216 char **documentation;
1217 int indentation, flags;
1220 register char *line;
1221 int string_array = (flags & STRING_ARRAY); /* Mutually exclusive. */
1222 int texinfo = (flags & TEXINFO);
1228 fprintf (stream, " {\n");
1230 #if !defined (OLDCODE)
1231 /* XXX -- clean me up; for experiment only */
1232 if (no_long_document)
1233 goto end_of_document;
1234 #endif /* !OLDCODE */
1236 for (i = 0; line = documentation[i]; i++)
1238 /* Allow #ifdef's to be written out verbatim. */
1242 fprintf (stream, "%s\n", line);
1247 fprintf (stream, " \"");
1250 for (j = 0; j < indentation; j++)
1251 fprintf (stream, " ");
1255 for (j = 0; line[j]; j++)
1261 fprintf (stream, "\\%c", line[j]);
1265 fprintf (stream, "%c", line[j]);
1269 fprintf (stream, "\",\n");
1273 for (j = 0; line[j]; j++)
1280 fprintf (stream, "@%c", line[j]);
1284 fprintf (stream, "%c", line[j]);
1287 fprintf (stream, "\n");
1290 fprintf (stream, "%s\n", line);
1293 #if !defined (OLDCODE)
1295 #endif /* !OLDCODE */
1298 fprintf (stream, " (char *)NULL\n};\n");
1302 is_special_builtin (name)
1307 for (i = 0; special_builtins[i]; i++)
1308 if (strcmp (name, special_builtins[i]) == 0)