X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/7cb70fd73eccd2725b8e436bff3295506816f935..25e65510a3d35524ade205c3114970c43dc6ae05:/lib-src/make-docfile.c diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index 4f68fdb78c..dafb7c0afd 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c @@ -1,6 +1,7 @@ /* Generate doc-string file for GNU Emacs from source files. - Copyright (C) 1985-1986, 1992-1994, 1997, 1999-2012 - Free Software Foundation, Inc. + +Copyright (C) 1985-1986, 1992-1994, 1997, 1999-2012 + Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -35,22 +36,26 @@ along with GNU Emacs. If not, see . */ #include -/* Defined to be emacs_main, sys_fopen, etc. in config.h. */ -#undef main -#undef fopen -#undef chdir - #include -#include +#include /* config.h unconditionally includes this anyway */ #ifdef MSDOS #include #endif /* MSDOS */ #ifdef WINDOWSNT +/* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this + is really just insurance. */ +#undef fopen #include #include #endif /* WINDOWSNT */ #ifdef DOS_NT +/* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this + is really just insurance. + + Similarly, msdos defines this as sys_chdir, but we're not linking with the + file where that function is defined. */ +#undef chdir #define READ_TEXT "rt" #define READ_BINARY "rb" #else /* not DOS_NT */ @@ -58,34 +63,12 @@ along with GNU Emacs. If not, see . */ #define READ_BINARY "r" #endif /* not DOS_NT */ -#ifndef DIRECTORY_SEP -#define DIRECTORY_SEP '/' -#endif - -#ifndef IS_DIRECTORY_SEP -#define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP) -#endif - -/* Use this to suppress gcc's `...may be used before initialized' warnings. */ -#ifdef lint -# define IF_LINT(Code) Code -#else -# define IF_LINT(Code) /* empty */ -#endif - static int scan_file (char *filename); static int scan_lisp_file (const char *filename, const char *mode); static int scan_c_file (char *filename, const char *mode); -static void fatal (const char *s1, const char *s2) NO_RETURN; static void start_globals (void); static void write_globals (void); -#ifdef MSDOS -/* s/msdos.h defines this as sys_chdir, but we're not linking with the - file where that function is defined. */ -#undef chdir -#endif - #include /* Stdio stream for output to the DOC file. */ @@ -111,7 +94,7 @@ error (const char *s1, const char *s2) /* Print error message and exit. */ /* VARARGS1 */ -static void +static _Noreturn void fatal (const char *s1, const char *s2) { error (s1, s2); @@ -542,7 +525,7 @@ write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs) /* In C code, `default' is a reserved word, so we spell it `defalt'; demangle that here. */ - if (ident_length == 6 && strncmp (ident_start, "defalt", 6) == 0) + if (ident_length == 6 && memcmp (ident_start, "defalt", 6) == 0) fprintf (out, "DEFAULT"); else while (ident_length-- > 0) @@ -565,6 +548,7 @@ write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs) /* The types of globals. */ enum global_type { + FUNCTION, EMACS_INTEGER, BOOLEAN, LISP_OBJECT, @@ -576,6 +560,7 @@ struct global { enum global_type type; char *name; + int value; }; /* All the variable names we saw while scanning C sources in `-g' @@ -585,7 +570,7 @@ int num_globals_allocated; struct global *globals; static void -add_global (enum global_type type, char *name) +add_global (enum global_type type, char *name, int value) { /* Ignore the one non-symbol that can occur. */ if (strcmp (name, "...")) @@ -606,6 +591,7 @@ add_global (enum global_type type, char *name) globals[num_globals - 1].type = type; globals[num_globals - 1].name = name; + globals[num_globals - 1].value = value; } } @@ -614,13 +600,29 @@ compare_globals (const void *a, const void *b) { const struct global *ga = a; const struct global *gb = b; + + if (ga->type == FUNCTION) + { + if (gb->type != FUNCTION) + return 1; + } + else if (gb->type == FUNCTION) + return -1; + return strcmp (ga->name, gb->name); } +static void +close_emacs_globals (void) +{ + fprintf (outfile, "};\n"); + fprintf (outfile, "extern struct emacs_globals globals;\n"); +} + static void write_globals (void) { - int i; + int i, seen_defun = 0; qsort (globals, num_globals, sizeof (struct global), compare_globals); for (i = 0; i < num_globals; ++i) { @@ -637,20 +639,55 @@ write_globals (void) case LISP_OBJECT: type = "Lisp_Object"; break; + case FUNCTION: + if (!seen_defun) + { + close_emacs_globals (); + fprintf (outfile, "\n"); + seen_defun = 1; + } + break; default: fatal ("not a recognized DEFVAR_", 0); } - fprintf (outfile, " %s f_%s;\n", type, globals[i].name); - fprintf (outfile, "#define %s globals.f_%s\n", - globals[i].name, globals[i].name); + if (globals[i].type != FUNCTION) + { + fprintf (outfile, " %s f_%s;\n", type, globals[i].name); + fprintf (outfile, "#define %s globals.f_%s\n", + globals[i].name, globals[i].name); + } + else + { + /* It would be nice to have a cleaner way to deal with these + special hacks. */ + if (strcmp (globals[i].name, "Fthrow") == 0 + || strcmp (globals[i].name, "Ftop_level") == 0 + || strcmp (globals[i].name, "Fkill_emacs") == 0) + fprintf (outfile, "_Noreturn "); + fprintf (outfile, "EXFUN (%s, ", globals[i].name); + if (globals[i].value == -1) + fprintf (outfile, "MANY"); + else if (globals[i].value == -2) + fprintf (outfile, "UNEVALLED"); + else + fprintf (outfile, "%d", globals[i].value); + fprintf (outfile, ");\n"); + } + while (i + 1 < num_globals && !strcmp (globals[i].name, globals[i + 1].name)) - ++i; + { + if (globals[i].type == FUNCTION + && globals[i].value != globals[i + 1].value) + error ("function '%s' defined twice with differing signatures", + globals[i].name); + ++i; + } } - fprintf (outfile, "};\n"); - fprintf (outfile, "extern struct emacs_globals globals;\n"); + if (!seen_defun) + close_emacs_globals (); } @@ -700,6 +737,7 @@ scan_c_file (char *filename, const char *mode) int defvarperbufferflag = 0; int defvarflag = 0; enum global_type type = INVALID; + char *name IF_LINT (= 0); if (c != '\n' && c != '\r') { @@ -765,8 +803,9 @@ scan_c_file (char *filename, const char *mode) } else continue; - if (generate_globals && (!defvarflag || defvarperbufferflag - || type == INVALID)) + if (generate_globals + && (!defvarflag || defvarperbufferflag || type == INVALID) + && !defunflag) continue; while (c != '(') @@ -785,7 +824,6 @@ scan_c_file (char *filename, const char *mode) if (generate_globals) { int i = 0; - char *name; /* Skip "," and whitespace. */ do @@ -806,8 +844,12 @@ scan_c_file (char *filename, const char *mode) name = xmalloc (i + 1); memcpy (name, input_buffer, i + 1); - add_global (type, name); - continue; + + if (!defunflag) + { + add_global (type, name, 0); + continue; + } } /* DEFVAR_LISP ("name", addr, "doc") @@ -815,7 +857,7 @@ scan_c_file (char *filename, const char *mode) DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */ if (defunflag) - commas = 5; + commas = generate_globals ? 4 : 5; else if (defvarperbufferflag) commas = 3; else if (defvarflag) @@ -842,7 +884,12 @@ scan_c_file (char *filename, const char *mode) scanned = fscanf (infile, "%d", &minargs); else /* Pick up maxargs. */ if (c == 'M' || c == 'U') /* MANY || UNEVALLED */ - maxargs = -1; + { + if (generate_globals) + maxargs = (c == 'M') ? -1 : -2; + else + maxargs = -1; + } else scanned = fscanf (infile, "%d", &maxargs); if (scanned < 0) @@ -855,6 +902,12 @@ scan_c_file (char *filename, const char *mode) c = getc (infile); } + if (generate_globals) + { + add_global (FUNCTION, name, maxargs); + continue; + } + while (c == ' ' || c == '\n' || c == '\r' || c == '\t') c = getc (infile);