📄 mkbuiltins.c
字号:
return (new);}/* How to save away a builtin. */voidsave_builtin (builtin) BUILTIN_DESC *builtin;{ BUILTIN_DESC *newbuiltin; newbuiltin = copy_builtin (builtin); /* If this is the first builtin to be saved, create the array to hold it. */ if (!saved_builtins) saved_builtins = array_create (sizeof (BUILTIN_DESC *)); array_add ((char *)newbuiltin, saved_builtins);}/* Flags that mean something to write_documentation (). */#define STRING_ARRAY 0x01#define TEXINFO 0x02#define PLAINTEXT 0x04#define HELPFILE 0x08char *structfile_header[] = { "/* builtins.c -- the built in shell commands. */", "", "/* This file is manufactured by ./mkbuiltins, and should not be", " edited by hand. See the source to mkbuiltins for details. */", "", "/* Copyright (C) 1987-2009 Free Software Foundation, Inc.", "", " This file is part of GNU Bash, the Bourne Again SHell.", "", " Bash is free software: you can redistribute it and/or modify", " it under the terms of the GNU General Public License as published by", " the Free Software Foundation, either version 3 of the License, or", " (at your option) any later version.", "", " Bash is distributed in the hope that it will be useful,", " but WITHOUT ANY WARRANTY; without even the implied warranty of", " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", " GNU General Public License for more details.", "", " You should have received a copy of the GNU General Public License", " along with Bash. If not, see <http://www.gnu.org/licenses/>.", "*/", "", "/* The list of shell builtins. Each element is name, function, flags,", " long-doc, short-doc. The long-doc field contains a pointer to an array", " of help lines. The function takes a WORD_LIST *; the first word in the", " list is the first arg to the command. The list has already had word", " expansion performed.", "", " Functions which need to look at only the simple commands (e.g.", " the enable_builtin ()), should ignore entries where", " (array[i].function == (sh_builtin_func_t *)NULL). Such entries are for", " the list of shell reserved control structures, like `if' and `while'.", " The end of the list is denoted with a NULL name field. */", "", "#include \"../builtins.h\"", (char *)NULL };char *structfile_footer[] = { " { (char *)0x0, (sh_builtin_func_t *)0x0, 0, (char **)0x0, (char *)0x0, (char *)0x0 }", "};", "", "struct builtin *shell_builtins = static_shell_builtins;", "struct builtin *current_builtin;", "", "int num_shell_builtins =", "\tsizeof (static_shell_builtins) / sizeof (struct builtin) - 1;", (char *)NULL};/* Write out any neccessary opening information for STRUCTFILE and EXTERNFILE. */voidwrite_file_headers (structfile, externfile) FILE *structfile, *externfile;{ register int i; if (structfile) { for (i = 0; structfile_header[i]; i++) fprintf (structfile, "%s\n", structfile_header[i]); fprintf (structfile, "#include \"%s\"\n", extern_filename ? extern_filename : "builtext.h"); fprintf (structfile, "#include \"bashintl.h\"\n"); fprintf (structfile, "\nstruct builtin static_shell_builtins[] = {\n"); } if (externfile) fprintf (externfile, "/* %s - The list of builtins found in libbuiltins.a. */\n", extern_filename ? extern_filename : "builtext.h");}/* Write out any necessary closing information for STRUCTFILE and EXTERNFILE. */voidwrite_file_footers (structfile, externfile) FILE *structfile, *externfile;{ register int i; /* Write out the footers. */ if (structfile) { for (i = 0; structfile_footer[i]; i++) fprintf (structfile, "%s\n", structfile_footer[i]); }}/* Write out the information accumulated in DEFS to STRUCTFILE and EXTERNFILE. */voidwrite_builtins (defs, structfile, externfile) DEF_FILE *defs; FILE *structfile, *externfile;{ register int i; /* Write out the information. */ if (defs->builtins) { register BUILTIN_DESC *builtin; for (i = 0; i < defs->builtins->sindex; i++) { builtin = (BUILTIN_DESC *)defs->builtins->array[i]; /* Write out any #ifdefs that may be there. */ if (!only_documentation) { if (builtin->dependencies) { write_ifdefs (externfile, builtin->dependencies->array); write_ifdefs (structfile, builtin->dependencies->array); } /* Write the extern definition. */ if (externfile) { if (builtin->function) fprintf (externfile, "extern int %s __P((WORD_LIST *));\n", builtin->function); fprintf (externfile, "extern char * const %s_doc[];\n", document_name (builtin)); } /* Write the structure definition. */ if (structfile) { fprintf (structfile, " { \"%s\", ", builtin->name); if (builtin->function) fprintf (structfile, "%s, ", builtin->function); else fprintf (structfile, "(sh_builtin_func_t *)0x0, "); fprintf (structfile, "%s%s%s%s, %s_doc,\n", "BUILTIN_ENABLED | STATIC_BUILTIN", (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "", (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "", (builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "", document_name (builtin)); fprintf (structfile, " N_(\"%s\"), (char *)NULL },\n", builtin->shortdoc ? builtin->shortdoc : builtin->name); } if (structfile || separate_helpfiles) /* Save away this builtin for later writing of the long documentation strings. */ save_builtin (builtin); /* Write out the matching #endif, if neccessary. */ if (builtin->dependencies) { if (externfile) write_endifs (externfile, builtin->dependencies->array); if (structfile) write_endifs (structfile, builtin->dependencies->array); } } if (documentation_file) { fprintf (documentation_file, "@item %s\n", builtin->name); write_documentation (documentation_file, builtin->longdoc->array, 0, TEXINFO); } } }}/* Write out the long documentation strings in BUILTINS to STREAM. */voidwrite_longdocs (stream, builtins) FILE *stream; ARRAY *builtins;{ register int i; register BUILTIN_DESC *builtin; char *dname; char *sarray[2]; for (i = 0; i < builtins->sindex; i++) { builtin = (BUILTIN_DESC *)builtins->array[i]; if (builtin->dependencies) write_ifdefs (stream, builtin->dependencies->array); /* Write the long documentation strings. */ dname = document_name (builtin); fprintf (stream, "char * const %s_doc[] =", dname); if (separate_helpfiles) { int l = strlen (helpfile_directory) + strlen (dname) + 1; sarray[0] = (char *)xmalloc (l + 1); sprintf (sarray[0], "%s/%s", helpfile_directory, dname); sarray[1] = (char *)NULL; write_documentation (stream, sarray, 0, STRING_ARRAY|HELPFILE); free (sarray[0]); } else write_documentation (stream, builtin->longdoc->array, 0, STRING_ARRAY); if (builtin->dependencies) write_endifs (stream, builtin->dependencies->array); }}/* Write an #ifdef string saying what needs to be defined (or not defined) in order to allow compilation of the code that will follow. STREAM is the stream to write the information to, DEFINES is a null terminated array of define names. If a define is preceded by an `!', then the sense of the test is reversed. */voidwrite_ifdefs (stream, defines) FILE *stream; char **defines;{ register int i; if (!stream) return; fprintf (stream, "#if "); for (i = 0; defines[i]; i++) { char *def = defines[i]; if (*def == '!') fprintf (stream, "!defined (%s)", def + 1); else fprintf (stream, "defined (%s)", def); if (defines[i + 1]) fprintf (stream, " && "); } fprintf (stream, "\n");}/* Write an #endif string saying what defines controlled the compilation of the immediately preceding code. STREAM is the stream to write the information to. DEFINES is a null terminated array of define names. */voidwrite_endifs (stream, defines) FILE *stream; char **defines;{ register int i; if (!stream) return; fprintf (stream, "#endif /* "); for (i = 0; defines[i]; i++) { fprintf (stream, "%s", defines[i]); if (defines[i + 1]) fprintf (stream, " && "); } fprintf (stream, " */\n");}/* Write DOCUMENTATION to STREAM, perhaps surrounding it with double-quotes and quoting special characters in the string. Handle special things for internationalization (gettext) and the single-string vs. multiple-strings issues. */voidwrite_documentation (stream, documentation, indentation, flags) FILE *stream; char **documentation; int indentation, flags;{ register int i, j; register char *line; int string_array, texinfo, base_indent, filename_p; if (stream == 0) return; string_array = flags & STRING_ARRAY; filename_p = flags & HELPFILE; if (string_array) { fprintf (stream, " {\n#if defined (HELP_BUILTIN)\n"); /* } */ if (single_longdoc_strings) { if (filename_p == 0) { if (documentation && documentation[0] && documentation[0][0]) fprintf (stream, "N_(\""); else fprintf (stream, "N_(\" "); /* the empty string translates specially. */ } else fprintf (stream, "\""); } } base_indent = (string_array && single_longdoc_strings && filename_p == 0) ? BASE_INDENT : 0; for (i = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++) { /* Allow #ifdef's to be written out verbatim, but don't put them into separate help files. */ if (*line == '#') { if (string_array && filename_p == 0 && single_longdoc_strings == 0) fprintf (stream, "%s\n", line); continue; } /* prefix with N_( for gettext */ if (string_array && single_longdoc_strings == 0) { if (filename_p == 0) { if (line[0]) fprintf (stream, " N_(\""); else fprintf (stream, " N_(\" "); /* the empty string translates specially. */ } else fprintf (stream, " \""); } if (indentation) for (j = 0; j < indentation; j++) fprintf (stream, " "); /* Don't indent the first line, because of how the help builtin works. */ if (i == 0) indentation += base_indent; if (string_array) { for (j = 0; line[j]; j++) { switch (line[j]) { case '\\': case '"': fprintf (stream, "\\%c", line[j]); break; default: fprintf (stream, "%c", line[j]); } } /* closing right paren for gettext */ if (single_longdoc_strings == 0) { if (filename_p == 0) fprintf (stream, "\"),\n"); else fprintf (stream, "\",\n"); } else if (documentation[i+1]) /* don't add extra newline after last line */ fprintf (stream, "\\n\\\n"); } else if (texinfo) { for (j = 0; line[j]; j++) { switch (line[j]) { case '@': case '{': case '}': fprintf (stream, "@%c", line[j]); break; default: fprintf (stream, "%c", line[j]); } } fprintf (stream, "\n"); } else fprintf (stream, "%s\n", line); } /* closing right paren for gettext */ if (string_array && single_longdoc_strings) { if (filename_p == 0) fprintf (stream, "\"),\n"); else fprintf (stream, "\",\n"); } if (string_array) fprintf (stream, "#endif /* HELP_BUILTIN */\n (char *)NULL\n};\n");}intwrite_helpfiles (builtins) ARRAY *builtins;{ char *helpfile, *bname; FILE *helpfp; int i, hdlen; BUILTIN_DESC *builtin; i = mkdir ("helpfiles", 0777); if (i < 0 && errno != EEXIST) { fprintf (stderr, "write_helpfiles: helpfiles: cannot create directory\n"); return -1; } hdlen = strlen ("helpfiles/"); for (i = 0; i < builtins->sindex; i++) { builtin = (BUILTIN_DESC *)builtins->array[i]; bname = document_name (builtin); helpfile = (char *)xmalloc (hdlen + strlen (bname) + 1); sprintf (helpfile, "helpfiles/%s", bname); helpfp = fopen (helpfile, "w"); if (helpfp == 0) { fprintf (stderr, "write_helpfiles: cannot open %s\n", helpfile); free (helpfile); continue; } write_documentation (helpfp, builtin->longdoc->array, 4, PLAINTEXT); fflush (helpfp); fclose (helpfp); free (helpfile); } return 0;} static int_find_in_table (name, name_table) char *name, *name_table[];{ register int i; for (i = 0; name_table[i]; i++) if (strcmp (name, name_table[i]) == 0) return 1; return 0;}static intis_special_builtin (name) char *name;{ return (_find_in_table (name, special_builtins));}static intis_assignment_builtin (name) char *name;{ return (_find_in_table (name, assignment_builtins));}static intis_posix_builtin (name) char *name;{ return (_find_in_table (name, posix_builtins));}#if !defined (HAVE_RENAME)static intrename (from, to) char *from, *to;{ unlink (to); if (link (from, to) < 0) return (-1); unlink (from); return (0);}#endif /* !HAVE_RENAME */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -