aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorDmitry Antipov2015-01-13 06:39:45 +0300
committerDmitry Antipov2015-01-13 06:39:45 +0300
commitad9c4a4091df19064a7f7f53bfdb687931e141f6 (patch)
tree203ded274a9f90bff594e91c1c261ff843807e8e /lib-src
parent329b902141c68190a2d8a5d6fd9312b6a816471c (diff)
downloademacs-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/ChangeLog11
-rw-r--r--lib-src/make-docfile.c123
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 @@
12015-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
12015-01-10 Paul Eggert <eggert@cs.ucla.edu> 122015-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. */
574enum { 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. */
574int num_globals; 578int num_globals;
575int num_globals_allocated; 579int num_globals_allocated;
576struct global *globals; 580struct global *globals;
577 581
578static void 582static struct global *
579add_global (enum global_type type, char *name, int value, char const *svalue) 583add_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
607static int 614static 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
795static int
796stream_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
820static int 809static int
821scan_c_stream (FILE *infile) 810scan_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