+/* The types of globals. */
+enum global_type
+{
+ EMACS_INTEGER,
+ 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);
+}
+
+static void
+write_globals (void)
+{
+ int i;
+ qsort (globals, num_globals, sizeof (struct global), compare_globals);
+ for (i = 0; i < num_globals; ++i)
+ {
+ char const *type;
+
+ switch (globals[i].type)
+ {
+ case EMACS_INTEGER:
+ 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");
+}
+
+\f