diff options
| author | Dmitry Antipov | 2015-01-13 06:39:45 +0300 |
|---|---|---|
| committer | Dmitry Antipov | 2015-01-13 06:39:45 +0300 |
| commit | ad9c4a4091df19064a7f7f53bfdb687931e141f6 (patch) | |
| tree | 203ded274a9f90bff594e91c1c261ff843807e8e /lib-src | |
| parent | 329b902141c68190a2d8a5d6fd9312b6a816471c (diff) | |
| download | emacs-ad9c4a4091df19064a7f7f53bfdb687931e141f6.tar.gz emacs-ad9c4a4091df19064a7f7f53bfdb687931e141f6.zip | |
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')
| -rw-r--r-- | lib-src/ChangeLog | 11 | ||||
| -rw-r--r-- | lib-src/make-docfile.c | 123 |
2 files changed, 95 insertions, 39 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 740359605fd..969aac80124 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2015-01-13 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | Support DEFUN attributes. | ||
| 4 | * make-docfile.c (struct global): New field 'flags'. | ||
| 5 | (DEFUN_noreturn, DEFUN_const): New enum bitfields. | ||
| 6 | (add_global): Now return pointer to global. | ||
| 7 | (write_globals): Add _Noreturn and ATTRIBUTE_CONST attributes | ||
| 8 | if requested by global's flags. | ||
| 9 | (stream_match): New function. | ||
| 10 | (scan_c_stream): Recognize 'attributes:' of DEFUN. | ||
| 11 | |||
| 1 | 2015-01-10 Paul Eggert <eggert@cs.ucla.edu> | 12 | 2015-01-10 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 13 | ||
| 3 | Port to 32-bit --with-wide-int | 14 | Port to 32-bit --with-wide-int |
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 | |||
| 562 | { | 562 | { |
| 563 | enum global_type type; | 563 | enum global_type type; |
| 564 | char *name; | 564 | char *name; |
| 565 | int flags; | ||
| 565 | union | 566 | union |
| 566 | { | 567 | { |
| 567 | int value; | 568 | int value; |
| @@ -569,13 +570,16 @@ struct global | |||
| 569 | } v; | 570 | } v; |
| 570 | }; | 571 | }; |
| 571 | 572 | ||
| 573 | /* Bit values for FLAGS field from the above. Applied for DEFUNs only. */ | ||
| 574 | enum { DEFUN_noreturn = 1, DEFUN_const = 2 }; | ||
| 575 | |||
| 572 | /* All the variable names we saw while scanning C sources in `-g' | 576 | /* All the variable names we saw while scanning C sources in `-g' |
| 573 | mode. */ | 577 | mode. */ |
| 574 | int num_globals; | 578 | int num_globals; |
| 575 | int num_globals_allocated; | 579 | int num_globals_allocated; |
| 576 | struct global *globals; | 580 | struct global *globals; |
| 577 | 581 | ||
| 578 | static void | 582 | static struct global * |
| 579 | add_global (enum global_type type, char *name, int value, char const *svalue) | 583 | add_global (enum global_type type, char *name, int value, char const *svalue) |
| 580 | { | 584 | { |
| 581 | /* Ignore the one non-symbol that can occur. */ | 585 | /* 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) | |||
| 601 | globals[num_globals - 1].v.svalue = svalue; | 605 | globals[num_globals - 1].v.svalue = svalue; |
| 602 | else | 606 | else |
| 603 | globals[num_globals - 1].v.value = value; | 607 | globals[num_globals - 1].v.value = value; |
| 608 | globals[num_globals - 1].flags = 0; | ||
| 609 | return globals + num_globals - 1; | ||
| 604 | } | 610 | } |
| 611 | return NULL; | ||
| 605 | } | 612 | } |
| 606 | 613 | ||
| 607 | static int | 614 | static int |
| @@ -708,13 +715,7 @@ write_globals (void) | |||
| 708 | globals[i].name, globals[i].name, globals[i].name); | 715 | globals[i].name, globals[i].name, globals[i].name); |
| 709 | else | 716 | else |
| 710 | { | 717 | { |
| 711 | /* It would be nice to have a cleaner way to deal with these | 718 | if (globals[i].flags & DEFUN_noreturn) |
| 712 | special hacks. */ | ||
| 713 | if (strcmp (globals[i].name, "Fthrow") == 0 | ||
| 714 | || strcmp (globals[i].name, "Ftop_level") == 0 | ||
| 715 | || strcmp (globals[i].name, "Fkill_emacs") == 0 | ||
| 716 | || strcmp (globals[i].name, "Fexit_recursive_edit") == 0 | ||
| 717 | || strcmp (globals[i].name, "Fabort_recursive_edit") == 0) | ||
| 718 | fputs ("_Noreturn ", stdout); | 719 | fputs ("_Noreturn ", stdout); |
| 719 | 720 | ||
| 720 | printf ("EXFUN (%s, ", globals[i].name); | 721 | printf ("EXFUN (%s, ", globals[i].name); |
| @@ -726,36 +727,7 @@ write_globals (void) | |||
| 726 | printf ("%d", globals[i].v.value); | 727 | printf ("%d", globals[i].v.value); |
| 727 | putchar (')'); | 728 | putchar (')'); |
| 728 | 729 | ||
| 729 | /* It would be nice to have a cleaner way to deal with these | 730 | if (globals[i].flags & DEFUN_const) |
| 730 | special hacks, too. */ | ||
| 731 | if (strcmp (globals[i].name, "Fatom") == 0 | ||
| 732 | || strcmp (globals[i].name, "Fbyteorder") == 0 | ||
| 733 | || strcmp (globals[i].name, "Fcharacterp") == 0 | ||
| 734 | || strcmp (globals[i].name, "Fchar_or_string_p") == 0 | ||
| 735 | || strcmp (globals[i].name, "Fconsp") == 0 | ||
| 736 | || strcmp (globals[i].name, "Feq") == 0 | ||
| 737 | || strcmp (globals[i].name, "Fface_attribute_relative_p") == 0 | ||
| 738 | || strcmp (globals[i].name, "Fframe_windows_min_size") == 0 | ||
| 739 | || strcmp (globals[i].name, "Fgnutls_errorp") == 0 | ||
| 740 | || strcmp (globals[i].name, "Fidentity") == 0 | ||
| 741 | || strcmp (globals[i].name, "Fintegerp") == 0 | ||
| 742 | || strcmp (globals[i].name, "Finteractive") == 0 | ||
| 743 | || strcmp (globals[i].name, "Ffloatp") == 0 | ||
| 744 | || strcmp (globals[i].name, "Flistp") == 0 | ||
| 745 | || strcmp (globals[i].name, "Fmax_char") == 0 | ||
| 746 | || strcmp (globals[i].name, "Fnatnump") == 0 | ||
| 747 | || strcmp (globals[i].name, "Fnlistp") == 0 | ||
| 748 | || strcmp (globals[i].name, "Fnull") == 0 | ||
| 749 | || strcmp (globals[i].name, "Fnumberp") == 0 | ||
| 750 | || strcmp (globals[i].name, "Fstringp") == 0 | ||
| 751 | || strcmp (globals[i].name, "Fsymbolp") == 0 | ||
| 752 | || strcmp (globals[i].name, "Ftool_bar_height") == 0 | ||
| 753 | || strcmp (globals[i].name, "Fwindow__sanitize_window_sizes") == 0 | ||
| 754 | #ifndef WINDOWSNT | ||
| 755 | || strcmp (globals[i].name, "Fgnutls_available_p") == 0 | ||
| 756 | || strcmp (globals[i].name, "Fzlib_available_p") == 0 | ||
| 757 | #endif | ||
| 758 | || 0) | ||
| 759 | fputs (" ATTRIBUTE_CONST", stdout); | 731 | fputs (" ATTRIBUTE_CONST", stdout); |
| 760 | 732 | ||
| 761 | puts (";"); | 733 | puts (";"); |
| @@ -817,6 +789,23 @@ scan_c_file (char *filename, const char *mode) | |||
| 817 | return scan_c_stream (infile); | 789 | return scan_c_stream (infile); |
| 818 | } | 790 | } |
| 819 | 791 | ||
| 792 | /* Return 1 if next input from INFILE is equal to P, -1 if EOF, | ||
| 793 | 0 if input doesn't match. */ | ||
| 794 | |||
| 795 | static int | ||
| 796 | stream_match (FILE *infile, const char *p) | ||
| 797 | { | ||
| 798 | for (; *p; p++) | ||
| 799 | { | ||
| 800 | int c = getc (infile); | ||
| 801 | if (c == EOF) | ||
| 802 | return -1; | ||
| 803 | if (c != *p) | ||
| 804 | return 0; | ||
| 805 | } | ||
| 806 | return 1; | ||
| 807 | } | ||
| 808 | |||
| 820 | static int | 809 | static int |
| 821 | scan_c_stream (FILE *infile) | 810 | scan_c_stream (FILE *infile) |
| 822 | { | 811 | { |
| @@ -1033,7 +1022,63 @@ scan_c_stream (FILE *infile) | |||
| 1033 | 1022 | ||
| 1034 | if (generate_globals) | 1023 | if (generate_globals) |
| 1035 | { | 1024 | { |
| 1036 | add_global (FUNCTION, name, maxargs, 0); | 1025 | struct global *g = add_global (FUNCTION, name, maxargs, 0); |
| 1026 | |||
| 1027 | /* The following code tries to recognize function attributes | ||
| 1028 | specified after the docstring, e.g.: | ||
| 1029 | |||
| 1030 | DEFUN ("foo", Ffoo, Sfoo, X, Y, Z, | ||
| 1031 | doc: /\* doc *\/ | ||
| 1032 | attributes: attribute1 attribute2 ...) | ||
| 1033 | (Lisp_Object arg...) | ||
| 1034 | |||
| 1035 | Now only 'noreturn' and 'const' attributes are used. */ | ||
| 1036 | |||
| 1037 | /* Advance to the end of docstring. */ | ||
| 1038 | c = getc (infile); | ||
| 1039 | if (c == EOF) | ||
| 1040 | goto eof; | ||
| 1041 | int d = getc (infile); | ||
| 1042 | if (d == EOF) | ||
| 1043 | goto eof; | ||
| 1044 | while (1) | ||
| 1045 | { | ||
| 1046 | if (c == '*' && d == '/') | ||
| 1047 | break; | ||
| 1048 | c = d, d = getc (infile); | ||
| 1049 | if (d == EOF) | ||
| 1050 | goto eof; | ||
| 1051 | } | ||
| 1052 | /* Skip spaces, if any. */ | ||
| 1053 | do | ||
| 1054 | { | ||
| 1055 | c = getc (infile); | ||
| 1056 | if (c == EOF) | ||
| 1057 | goto eof; | ||
| 1058 | } | ||
| 1059 | while (c == ' ' || c == '\n' || c == '\r' || c == '\t'); | ||
| 1060 | /* Check for 'attributes:' token. */ | ||
| 1061 | if (c == 'a' && stream_match (infile, "ttributes:")) | ||
| 1062 | { | ||
| 1063 | char *p = input_buffer; | ||
| 1064 | /* Collect attributes up to ')'. */ | ||
| 1065 | while (1) | ||
| 1066 | { | ||
| 1067 | c = getc (infile); | ||
| 1068 | if (c == EOF) | ||
| 1069 | goto eof; | ||
| 1070 | if (c == ')') | ||
| 1071 | break; | ||
| 1072 | if (p - input_buffer > sizeof (input_buffer)) | ||
| 1073 | abort (); | ||
| 1074 | *p++ = c; | ||
| 1075 | } | ||
| 1076 | *p = 0; | ||
| 1077 | if (strstr (input_buffer, "noreturn")) | ||
| 1078 | g->flags |= DEFUN_noreturn; | ||
| 1079 | if (strstr (input_buffer, "const")) | ||
| 1080 | g->flags |= DEFUN_const; | ||
| 1081 | } | ||
| 1037 | continue; | 1082 | continue; |
| 1038 | } | 1083 | } |
| 1039 | 1084 | ||