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);