X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/6e9ddbb313cf7db66550f93a74cbba12e39e93c0..404dbd373a91c0b994005e88fe703d9144873b27:/lib-src/make-docfile.c diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index 3e79cae4f4..2a5f028976 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c @@ -35,7 +35,7 @@ along with GNU Emacs. If not, see . */ #include -/* defined to be emacs_main, sys_fopen, etc. in config.h */ +/* Defined to be emacs_main, sys_fopen, etc. in config.h. */ #undef main #undef fopen #undef chdir @@ -66,7 +66,7 @@ along with GNU Emacs. If not, see . */ #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP) #endif -/* Use this to suppress gcc's `...may be used before initialized' warnings. */ +/* Use this to suppress gcc's `...may be used before initialized' warnings. */ #ifdef lint # define IF_LINT(Code) Code #else @@ -76,7 +76,6 @@ along with GNU Emacs. If not, see . */ 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); @@ -111,7 +110,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); @@ -226,7 +225,7 @@ put_filename (char *filename) for (tmp = filename; *tmp; tmp++) { - if (IS_DIRECTORY_SEP(*tmp)) + if (IS_DIRECTORY_SEP (*tmp)) filename = tmp + 1; } @@ -565,6 +564,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 +576,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 +586,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 +607,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 +616,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 +655,49 @@ 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; } - fprintf (outfile, "};\n"); - fprintf (outfile, "extern struct emacs_globals globals;\n"); + if (!seen_defun) + close_emacs_globals (); } @@ -675,14 +722,14 @@ scan_c_file (char *filename, const char *mode) if (infile == NULL && extension == 'o') { - /* try .m */ + /* Try .m. */ filename[strlen (filename) - 1] = 'm'; infile = fopen (filename, mode); if (infile == NULL) - filename[strlen (filename) - 1] = 'c'; /* don't confuse people */ + filename[strlen (filename) - 1] = 'c'; /* Don't confuse people. */ } - /* No error if non-ex input file */ + /* No error if non-ex input file. */ if (infile == NULL) { perror (filename); @@ -700,6 +747,7 @@ scan_c_file (char *filename, const char *mode) int defvarperbufferflag = 0; int defvarflag = 0; enum global_type type = INVALID; + char *name; if (c != '\n' && c != '\r') { @@ -765,8 +813,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 +834,6 @@ scan_c_file (char *filename, const char *mode) if (generate_globals) { int i = 0; - char *name; /* Skip "," and whitespace. */ do @@ -800,14 +848,18 @@ scan_c_file (char *filename, const char *mode) input_buffer[i++] = c; c = getc (infile); } - while (! (c == ',' || c == ' ' || c == '\t' || - c == '\n' || c == '\r')); + while (! (c == ',' || c == ' ' || c == '\t' + || c == '\n' || c == '\r')); input_buffer[i] = '\0'; 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,12 +867,12 @@ 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) commas = 1; - else /* For DEFSIMPLE and DEFPRED */ + else /* For DEFSIMPLE and DEFPRED. */ commas = 2; while (commas) @@ -838,11 +890,16 @@ scan_c_file (char *filename, const char *mode) if (c < 0) goto eof; ungetc (c, infile); - if (commas == 2) /* pick up minargs */ + if (commas == 2) /* Pick up minargs. */ scanned = fscanf (infile, "%d", &minargs); - else /* pick up maxargs */ + 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 +912,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); @@ -893,7 +956,7 @@ scan_c_file (char *filename, const char *mode) fprintf (outfile, "%s\n", input_buffer); if (comment) - getc (infile); /* Skip past `*' */ + getc (infile); /* Skip past `*'. */ c = read_c_string_or_comment (infile, 1, comment, &saw_usage); /* If this is a defun, find the arguments and print them. If @@ -979,7 +1042,7 @@ scan_c_file (char *filename, const char *mode) problem because byte-compiler output follows this convention. The NAME and DOCSTRING are output. NAME is preceded by `F' for a function or `V' for a variable. - An entry is output only if DOCSTRING has \ newline just after the opening " + An entry is output only if DOCSTRING has \ newline just after the opening ". */ static void @@ -1019,6 +1082,34 @@ read_lisp_symbol (FILE *infile, char *buffer) skip_white (infile); } +static int +search_lisp_doc_at_eol (FILE *infile) +{ + char c = 0, c1 = 0, c2 = 0; + + /* Skip until the end of line; remember two previous chars. */ + while (c != '\n' && c != '\r' && c != EOF) + { + c2 = c1; + c1 = c; + c = getc (infile); + } + + /* If two previous characters were " and \, + this is a doc string. Otherwise, there is none. */ + if (c2 != '"' || c1 != '\\') + { +#ifdef DEBUG + fprintf (stderr, "## non-docstring in %s (%s)\n", + buffer, filename); +#endif + if (c != EOF) + ungetc (c, infile); + return 0; + } + return 1; +} + static int scan_lisp_file (const char *filename, const char *mode) { @@ -1033,7 +1124,7 @@ scan_lisp_file (const char *filename, const char *mode) if (infile == NULL) { perror (filename); - return 0; /* No error */ + return 0; /* No error. */ } c = '\n'; @@ -1110,7 +1201,7 @@ scan_lisp_file (const char *filename, const char *mode) type = 'F'; read_lisp_symbol (infile, buffer); - /* Skip the arguments: either "nil" or a list in parens */ + /* Skip the arguments: either "nil" or a list in parens. */ c = getc (infile); if (c == 'n') /* nil */ @@ -1154,39 +1245,18 @@ scan_lisp_file (const char *filename, const char *mode) || ! strcmp (buffer, "defconst") || ! strcmp (buffer, "defcustom")) { - char c1 = 0, c2 = 0; type = 'V'; read_lisp_symbol (infile, buffer); if (saved_string == 0) - { - - /* Skip until the end of line; remember two previous chars. */ - while (c != '\n' && c != '\r' && c >= 0) - { - c2 = c1; - c1 = c; - c = getc (infile); - } - - /* If two previous characters were " and \, - this is a doc string. Otherwise, there is none. */ - if (c2 != '"' || c1 != '\\') - { -#ifdef DEBUG - fprintf (stderr, "## non-docstring in %s (%s)\n", - buffer, filename); -#endif - continue; - } - } + if (!search_lisp_doc_at_eol (infile)) + continue; } else if (! strcmp (buffer, "custom-declare-variable") || ! strcmp (buffer, "defvaralias") ) { - char c1 = 0, c2 = 0; type = 'V'; c = getc (infile); @@ -1221,31 +1291,12 @@ scan_lisp_file (const char *filename, const char *mode) } if (saved_string == 0) - { - /* Skip to end of line; remember the two previous chars. */ - while (c != '\n' && c != '\r' && c >= 0) - { - c2 = c1; - c1 = c; - c = getc (infile); - } - - /* If two previous characters were " and \, - this is a doc string. Otherwise, there is none. */ - if (c2 != '"' || c1 != '\\') - { -#ifdef DEBUG - fprintf (stderr, "## non-docstring in %s (%s)\n", - buffer, filename); -#endif - continue; - } - } + if (!search_lisp_doc_at_eol (infile)) + continue; } else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias")) { - char c1 = 0, c2 = 0; type = 'F'; c = getc (infile); @@ -1278,26 +1329,8 @@ scan_lisp_file (const char *filename, const char *mode) } if (saved_string == 0) - { - /* Skip to end of line; remember the two previous chars. */ - while (c != '\n' && c != '\r' && c >= 0) - { - c2 = c1; - c1 = c; - c = getc (infile); - } - - /* If two previous characters were " and \, - this is a doc string. Otherwise, there is none. */ - if (c2 != '"' || c1 != '\\') - { -#ifdef DEBUG - fprintf (stderr, "## non-docstring in %s (%s)\n", - buffer, filename); -#endif - continue; - } - } + if (!search_lisp_doc_at_eol (infile)) + continue; } else if (! strcmp (buffer, "autoload")) @@ -1339,29 +1372,16 @@ scan_lisp_file (const char *filename, const char *mode) continue; } read_c_string_or_comment (infile, 0, 0, 0); - skip_white (infile); if (saved_string == 0) - { - /* If the next three characters aren't `dquote bslash newline' - then we're not reading a docstring. */ - if ((c = getc (infile)) != '"' - || (c = getc (infile)) != '\\' - || ((c = getc (infile)) != '\n' && c != '\r')) - { -#ifdef DEBUG - fprintf (stderr, "## non-docstring in %s (%s)\n", - buffer, filename); -#endif - continue; - } - } + if (!search_lisp_doc_at_eol (infile)) + continue; } #ifdef DEBUG else if (! strcmp (buffer, "if") || ! strcmp (buffer, "byte-code")) - ; + continue; #endif else @@ -1373,12 +1393,10 @@ scan_lisp_file (const char *filename, const char *mode) continue; } - /* At this point, we should either use the previous - dynamic doc string in saved_string - or gobble a doc string from the input file. - - In the latter case, the opening quote (and leading - backslash-newline) have already been read. */ + /* At this point, we should either use the previous dynamic doc string in + saved_string or gobble a doc string from the input file. + In the latter case, the opening quote (and leading backslash-newline) + have already been read. */ putc (037, outfile); putc (type, outfile);