diff options
author | Dmitry Antipov <dmantipov@yandex.ru> | 2015-01-13 06:39:45 +0300 |
---|---|---|
committer | Dmitry Antipov <dmantipov@yandex.ru> | 2015-01-13 06:39:45 +0300 |
commit | ad9c4a4091df19064a7f7f53bfdb687931e141f6 (patch) | |
tree | 203ded274a9f90bff594e91c1c261ff843807e8e /lib-src/make-docfile.c | |
parent | 329b902141c68190a2d8a5d6fd9312b6a816471c (diff) | |
download | emacs-ad9c4a4091df19064a7f7f53bfdb687931e141f6.tar.gz |
Support const and noreturn DEFUN attributes.
* lib-src/make-docfile.c (struct global): New field 'flags'.
(DEFUN_noreturn, DEFUN_const): New enum bitfields.
(add_global): Now return pointer to global.
(write_globals): Add _Noreturn and ATTRIBUTE_CONST attributes
if requested by global's flags.
(stream_match): New function.
(scan_c_stream): Recognize 'attributes:' of DEFUN.
* src/callint.c (Finteractive):
* src/character.c (Fcharacterp, Fmax_char):
* src.data.c (Feq, Fnull, Fconsp, Fatom, Flistp, Fnlistp, Fsymbolp)
(Fstringp, Fchar_or_string_p, Fintegerp, Fnatnump, Fnumberp)
(Ffloatp, Fbyteorder):
* src/decompress.c (Fzlib_available_p):
* src/fns.c (Fidentity):
* src/frame.c (Fframe_windows_min_size):
* src/gnutls.c (Fgnutls_error_p, Fgnutls_available_p):
* src/window.c (Fwindow__sanitize_window_sizes):
* src/xdisp.c (Ftool_bar_height):
* src/xfaces.c (Fface_attribute_relative_p): Add const attribute.
* src/emacs.c (Fkill_emacs):
* src/eval.c (Fthrow):
* src/keyboard.c (Ftop_level, Fexit_recursive_edit)
(Fabor_recursive_edit): Add noreturn attribute.
Diffstat (limited to 'lib-src/make-docfile.c')
-rw-r--r-- | lib-src/make-docfile.c | 123 |
1 files changed, 84 insertions, 39 deletions
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index bc5420ea939..79d421a0a8e 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c @@ -562,6 +562,7 @@ struct global { enum global_type type; char *name; + int flags; union { int value; @@ -569,13 +570,16 @@ struct global } v; }; +/* Bit values for FLAGS field from the above. Applied for DEFUNs only. */ +enum { DEFUN_noreturn = 1, DEFUN_const = 2 }; + /* 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 +static struct global * add_global (enum global_type type, char *name, int value, char const *svalue) { /* Ignore the one non-symbol that can occur. */ @@ -601,7 +605,10 @@ add_global (enum global_type type, char *name, int value, char const *svalue) globals[num_globals - 1].v.svalue = svalue; else globals[num_globals - 1].v.value = value; + globals[num_globals - 1].flags = 0; + return globals + num_globals - 1; } + return NULL; } static int @@ -708,13 +715,7 @@ write_globals (void) globals[i].name, 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 - || strcmp (globals[i].name, "Fexit_recursive_edit") == 0 - || strcmp (globals[i].name, "Fabort_recursive_edit") == 0) + if (globals[i].flags & DEFUN_noreturn) fputs ("_Noreturn ", stdout); printf ("EXFUN (%s, ", globals[i].name); @@ -726,36 +727,7 @@ write_globals (void) printf ("%d", globals[i].v.value); putchar (')'); - /* It would be nice to have a cleaner way to deal with these - special hacks, too. */ - if (strcmp (globals[i].name, "Fatom") == 0 - || strcmp (globals[i].name, "Fbyteorder") == 0 - || strcmp (globals[i].name, "Fcharacterp") == 0 - || strcmp (globals[i].name, "Fchar_or_string_p") == 0 - || strcmp (globals[i].name, "Fconsp") == 0 - || strcmp (globals[i].name, "Feq") == 0 - || strcmp (globals[i].name, "Fface_attribute_relative_p") == 0 - || strcmp (globals[i].name, "Fframe_windows_min_size") == 0 - || strcmp (globals[i].name, "Fgnutls_errorp") == 0 - || strcmp (globals[i].name, "Fidentity") == 0 - || strcmp (globals[i].name, "Fintegerp") == 0 - || strcmp (globals[i].name, "Finteractive") == 0 - || strcmp (globals[i].name, "Ffloatp") == 0 - || strcmp (globals[i].name, "Flistp") == 0 - || strcmp (globals[i].name, "Fmax_char") == 0 - || strcmp (globals[i].name, "Fnatnump") == 0 - || strcmp (globals[i].name, "Fnlistp") == 0 - || strcmp (globals[i].name, "Fnull") == 0 - || strcmp (globals[i].name, "Fnumberp") == 0 - || strcmp (globals[i].name, "Fstringp") == 0 - || strcmp (globals[i].name, "Fsymbolp") == 0 - || strcmp (globals[i].name, "Ftool_bar_height") == 0 - || strcmp (globals[i].name, "Fwindow__sanitize_window_sizes") == 0 -#ifndef WINDOWSNT - || strcmp (globals[i].name, "Fgnutls_available_p") == 0 - || strcmp (globals[i].name, "Fzlib_available_p") == 0 -#endif - || 0) + if (globals[i].flags & DEFUN_const) fputs (" ATTRIBUTE_CONST", stdout); puts (";"); @@ -817,6 +789,23 @@ scan_c_file (char *filename, const char *mode) return scan_c_stream (infile); } +/* Return 1 if next input from INFILE is equal to P, -1 if EOF, + 0 if input doesn't match. */ + +static int +stream_match (FILE *infile, const char *p) +{ + for (; *p; p++) + { + int c = getc (infile); + if (c == EOF) + return -1; + if (c != *p) + return 0; + } + return 1; +} + static int scan_c_stream (FILE *infile) { @@ -1033,7 +1022,63 @@ scan_c_stream (FILE *infile) if (generate_globals) { - add_global (FUNCTION, name, maxargs, 0); + struct global *g = add_global (FUNCTION, name, maxargs, 0); + + /* The following code tries to recognize function attributes + specified after the docstring, e.g.: + + DEFUN ("foo", Ffoo, Sfoo, X, Y, Z, + doc: /\* doc *\/ + attributes: attribute1 attribute2 ...) + (Lisp_Object arg...) + + Now only 'noreturn' and 'const' attributes are used. */ + + /* Advance to the end of docstring. */ + c = getc (infile); + if (c == EOF) + goto eof; + int d = getc (infile); + if (d == EOF) + goto eof; + while (1) + { + if (c == '*' && d == '/') + break; + c = d, d = getc (infile); + if (d == EOF) + goto eof; + } + /* Skip spaces, if any. */ + do + { + c = getc (infile); + if (c == EOF) + goto eof; + } + while (c == ' ' || c == '\n' || c == '\r' || c == '\t'); + /* Check for 'attributes:' token. */ + if (c == 'a' && stream_match (infile, "ttributes:")) + { + char *p = input_buffer; + /* Collect attributes up to ')'. */ + while (1) + { + c = getc (infile); + if (c == EOF) + goto eof; + if (c == ')') + break; + if (p - input_buffer > sizeof (input_buffer)) + abort (); + *p++ = c; + } + *p = 0; + if (strstr (input_buffer, "noreturn")) + g->flags |= DEFUN_noreturn; + if (strstr (input_buffer, "const")) + g->flags |= DEFUN_const; + } continue; } |