summaryrefslogtreecommitdiff
path: root/lib-src/make-docfile.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2011-02-08 14:42:56 -0700
committerTom Tromey <tromey@redhat.com>2011-02-08 14:42:56 -0700
commit00b3c7ac85c3811774305d8ccca6a17ec207b3f1 (patch)
tree808628395db74d42f5755e5898d04b3d9b69e1b7 /lib-src/make-docfile.c
parent6ca94a0b49f08f2e59aabc51545eb8a1f726ba8b (diff)
downloademacs-00b3c7ac85c3811774305d8ccca6a17ec207b3f1.tar.gz
Make globals.h a generated header
* configure: Rebuild. * configure.in (NS_OBJC_OBJ): New subst. lib-src * make-docfile.c: Unconditionally include stdlib.h. (generate_globals): New global. (xrealloc): New function. (main): Handle '-g'. Call start_globals, write_globals. (scan_file): Conditionally call put_filename. (start_globals): New function. (struct global): New. (num_globals, globals): New globals. (add_global, compare_globals, write_globals): New functions. (scan_c_file): Update for "-g". (scan_lisp_file): Fail if "-g". (enum global_type): New. src * Makefile.in (NS_OBJC_OBJ): New variable. (base_obj): Rename from 'obj'. (obj): New variable. (globals.h, gl-stamp, $(obj)): New targets. (GLOBAL_SOURCES): New variable. * globals.h: Remove. * nsselect.m (Vselection_alist): Define. Reverts part of 2011-01-19T22:11:33Z!jan.h.d@swipnet.se. * buffer.c: Don't use "no_cell" for name of kill-buffer-hook's variable. * xselect.c (Vselection_alist): Define. Reverts part of 2011-01-19T23:32:42Z!eggert@cs.ucla.edu.
Diffstat (limited to 'lib-src/make-docfile.c')
-rw-r--r--lib-src/make-docfile.c185
1 files changed, 183 insertions, 2 deletions
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index 8addbda0489..6ce0b886ab4 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -41,11 +41,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#undef chdir
#include <stdio.h>
+#include <stdlib.h>
#ifdef MSDOS
#include <fcntl.h>
#endif /* MSDOS */
#ifdef WINDOWSNT
-#include <stdlib.h>
#include <fcntl.h>
#include <direct.h>
#endif /* WINDOWSNT */
@@ -70,6 +70,8 @@ int scan_file (char *filename);
int scan_lisp_file (const char *filename, const char *mode);
int scan_c_file (char *filename, const char *mode);
void fatal (const char *s1, const char *s2) NO_RETURN;
+void start_globals (void);
+void write_globals (void);
#ifdef MSDOS
/* s/msdos.h defines this as sys_chdir, but we're not linking with the
@@ -85,6 +87,9 @@ FILE *outfile;
/* Name this program was invoked with. */
char *progname;
+/* Nonzero if this invocation is generating globals.h. */
+int generate_globals;
+
/* Print error message. `s1' is printf control string, `s2' is arg for it. */
/* VARARGS1 */
@@ -116,6 +121,18 @@ xmalloc (unsigned int size)
fatal ("virtual memory exhausted", 0);
return result;
}
+
+/* Like realloc but get fatal error if memory is exhausted. */
+
+void *
+xrealloc (void *arg, unsigned int size)
+{
+ void *result = (void *) realloc (arg, size);
+ if (result == NULL)
+ fatal ("virtual memory exhausted", 0);
+ return result;
+}
+
int
main (int argc, char **argv)
@@ -164,10 +181,18 @@ main (int argc, char **argv)
}
i += 2;
}
+ if (argc > i && !strcmp (argv[i], "-g"))
+ {
+ generate_globals = 1;
+ ++i;
+ }
if (outfile == 0)
fatal ("No output file specified", "");
+ if (generate_globals)
+ start_globals ();
+
first_infile = i;
for (; i < argc; i++)
{
@@ -179,6 +204,10 @@ main (int argc, char **argv)
if (j == i)
err_count += scan_file (argv[i]);
}
+
+ if (err_count == 0 && generate_globals)
+ write_globals ();
+
return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}
@@ -208,7 +237,8 @@ scan_file (char *filename)
size_t len = strlen (filename);
- put_filename (filename);
+ if (!generate_globals)
+ put_filename (filename);
if (len > 4 && !strcmp (filename + len - 4, ".elc"))
return scan_lisp_file (filename, READ_BINARY);
else if (len > 3 && !strcmp (filename + len - 3, ".el"))
@@ -216,6 +246,14 @@ scan_file (char *filename)
else
return scan_c_file (filename, READ_TEXT);
}
+
+void
+start_globals (void)
+{
+ fprintf (outfile, "/* This file was auto-generated by make-docfile. */\n");
+ fprintf (outfile, "/* DO NOT EDIT. */\n");
+ fprintf (outfile, "struct emacs_globals {\n");
+}
char buf[128];
@@ -517,6 +555,98 @@ write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs)
putc (')', out);
}
+/* The types of globals. */
+enum global_type
+{
+ EMACS_INT,
+ BOOLEAN,
+ LISP_OBJECT,
+ INVALID
+};
+
+/* A single global. */
+struct global
+{
+ enum global_type type;
+ char *name;
+};
+
+/* All the variable names we saw while scanning C sources in `-g'
+ mode. */
+int num_globals;
+int num_globals_allocated;
+struct global *globals;
+
+static void
+add_global (enum global_type type, char *name)
+{
+ /* Ignore the one non-symbol that can occur. */
+ if (strcmp (name, "..."))
+ {
+ ++num_globals;
+
+ if (num_globals_allocated == 0)
+ {
+ num_globals_allocated = 100;
+ globals = xmalloc (num_globals_allocated * sizeof (struct global));
+ }
+ else if (num_globals == num_globals_allocated)
+ {
+ num_globals_allocated *= 2;
+ globals = xrealloc (globals,
+ num_globals_allocated * sizeof (struct global));
+ }
+
+ globals[num_globals - 1].type = type;
+ globals[num_globals - 1].name = name;
+ }
+}
+
+static int
+compare_globals (const void *a, const void *b)
+{
+ const struct global *ga = a;
+ const struct global *gb = b;
+ return strcmp (ga->name, gb->name);
+}
+
+void
+write_globals (void)
+{
+ int i;
+ qsort (globals, num_globals, sizeof (struct global), compare_globals);
+ for (i = 0; i < num_globals; ++i)
+ {
+ char *type;
+
+ switch (globals[i].type)
+ {
+ case EMACS_INT:
+ type = "EMACS_INT";
+ break;
+ case BOOLEAN:
+ type = "int";
+ break;
+ case LISP_OBJECT:
+ type = "Lisp_Object";
+ 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);
+ while (i + 1 < num_globals
+ && !strcmp (globals[i].name, globals[i + 1].name))
+ ++i;
+ }
+
+ fprintf (outfile, "};\n");
+ fprintf (outfile, "extern struct emacs_globals globals;\n");
+}
+
+
/* Read through a c file. If a .o file is named,
the corresponding .c or .m file is read instead.
Looks for DEFUN constructs such as are defined in ../src/lisp.h.
@@ -533,6 +663,7 @@ scan_c_file (char *filename, const char *mode)
register int defvarflag;
int minargs, maxargs;
int extension = filename[strlen (filename) - 1];
+ enum global_type type;
if (extension == 'o')
filename[strlen (filename) - 1] = 'c';
@@ -599,8 +730,23 @@ scan_c_file (char *filename, const char *mode)
c = getc (infile);
defvarperbufferflag = (c == 'P');
+ if (generate_globals)
+ {
+ if (c == 'I')
+ type = EMACS_INT;
+ else if (c == 'L')
+ type = LISP_OBJECT;
+ else if (c == 'B')
+ type = BOOLEAN;
+ else
+ type = INVALID;
+ }
c = getc (infile);
+ /* We need to distinguish between DEFVAR_BOOL and
+ DEFVAR_BUFFER_DEFAULTS. */
+ if (generate_globals && type == BOOLEAN && c != 'O')
+ type = INVALID;
}
else if (c == 'D')
{
@@ -617,6 +763,10 @@ scan_c_file (char *filename, const char *mode)
}
else continue;
+ if (generate_globals && (!defvarflag || defvarperbufferflag
+ || type == INVALID))
+ continue;
+
while (c != '(')
{
if (c < 0)
@@ -630,6 +780,34 @@ scan_c_file (char *filename, const char *mode)
continue;
c = read_c_string_or_comment (infile, -1, 0, 0);
+ if (generate_globals)
+ {
+ int i = 0;
+ char *name;
+
+ /* Skip "," and whitespace. */
+ do
+ {
+ c = getc (infile);
+ }
+ while (c == ',' || c == ' ' || c == '\t' || c == '\n' || c == '\r');
+
+ /* Read in the identifier. */
+ do
+ {
+ buf[i++] = c;
+ c = getc (infile);
+ }
+ while (! (c == ',' || c == ' ' || c == '\t' ||
+ c == '\n' || c == '\r'));
+ buf[i] = '\0';
+
+ name = xmalloc (i + 1);
+ memcpy (name, buf, i + 1);
+ add_global (type, name);
+ continue;
+ }
+
/* DEFVAR_LISP ("name", addr, "doc")
DEFVAR_LISP ("name", addr /\* doc *\/)
DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
@@ -845,6 +1023,9 @@ scan_lisp_file (const char *filename, const char *mode)
register int c;
char *saved_string = 0;
+ if (generate_globals)
+ fatal ("scanning lisp file when -g specified", 0);
+
infile = fopen (filename, mode);
if (infile == NULL)
{