aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/ChangeLog17
-rw-r--r--lib-src/make-docfile.c135
2 files changed, 113 insertions, 39 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 740359605fd..e9205fdd12a 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,20 @@
12015-01-13 Paul Eggert <eggert@cs.ucla.edu>
2
3 Don't say Fnext_read_file_uses_dialog_p is const
4 * make-docfile.c (write_globals):
5 Add a special hack for Fnext_read_file_uses_dialog_p.
6
72015-01-13 Dmitry Antipov <dmantipov@yandex.ru>
8
9 Support DEFUN attributes.
10 * make-docfile.c (struct global): New field 'flags'.
11 (DEFUN_noreturn, DEFUN_const): New enum bitfields.
12 (add_global): Now return pointer to global.
13 (write_globals): Add _Noreturn and ATTRIBUTE_CONST attributes
14 if requested by global's flags.
15 (stream_match): New function.
16 (scan_c_stream): Recognize 'attributes:' of DEFUN.
17
12015-01-10 Paul Eggert <eggert@cs.ucla.edu> 182015-01-10 Paul Eggert <eggert@cs.ucla.edu>
2 19
3 Port to 32-bit --with-wide-int 20 Port to 32-bit --with-wide-int
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index bc5420ea939..741fa4bfa42 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,37 +727,20 @@ 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);
732 else if (strcmp (globals[i].name, "Fnext_read_file_uses_dialog_p")
733 == 0)
734 {
735 /* It would be nice to have a cleaner way to deal with this
736 special hack. */
737 fputs (("\n"
738 "#if ! (defined USE_GTK || defined USE_MOTIF \\\n"
739 " || defined HAVE_NS || defined HAVE_NTGUI)\n"
740 "\tATTRIBUTE_CONST\n"
741 "#endif\n"),
742 stdout);
743 }
760 744
761 puts (";"); 745 puts (";");
762 } 746 }
@@ -817,6 +801,23 @@ scan_c_file (char *filename, const char *mode)
817 return scan_c_stream (infile); 801 return scan_c_stream (infile);
818} 802}
819 803
804/* Return 1 if next input from INFILE is equal to P, -1 if EOF,
805 0 if input doesn't match. */
806
807static int
808stream_match (FILE *infile, const char *p)
809{
810 for (; *p; p++)
811 {
812 int c = getc (infile);
813 if (c == EOF)
814 return -1;
815 if (c != *p)
816 return 0;
817 }
818 return 1;
819}
820
820static int 821static int
821scan_c_stream (FILE *infile) 822scan_c_stream (FILE *infile)
822{ 823{
@@ -1033,7 +1034,63 @@ scan_c_stream (FILE *infile)
1033 1034
1034 if (generate_globals) 1035 if (generate_globals)
1035 { 1036 {
1036 add_global (FUNCTION, name, maxargs, 0); 1037 struct global *g = add_global (FUNCTION, name, maxargs, 0);
1038
1039 /* The following code tries to recognize function attributes
1040 specified after the docstring, e.g.:
1041
1042 DEFUN ("foo", Ffoo, Sfoo, X, Y, Z,
1043 doc: /\* doc *\/
1044 attributes: attribute1 attribute2 ...)
1045 (Lisp_Object arg...)
1046
1047 Now only 'noreturn' and 'const' attributes are used. */
1048
1049 /* Advance to the end of docstring. */
1050 c = getc (infile);
1051 if (c == EOF)
1052 goto eof;
1053 int d = getc (infile);
1054 if (d == EOF)
1055 goto eof;
1056 while (1)
1057 {
1058 if (c == '*' && d == '/')
1059 break;
1060 c = d, d = getc (infile);
1061 if (d == EOF)
1062 goto eof;
1063 }
1064 /* Skip spaces, if any. */
1065 do
1066 {
1067 c = getc (infile);
1068 if (c == EOF)
1069 goto eof;
1070 }
1071 while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
1072 /* Check for 'attributes:' token. */
1073 if (c == 'a' && stream_match (infile, "ttributes:"))
1074 {
1075 char *p = input_buffer;
1076 /* Collect attributes up to ')'. */
1077 while (1)
1078 {
1079 c = getc (infile);
1080 if (c == EOF)
1081 goto eof;
1082 if (c == ')')
1083 break;
1084 if (p - input_buffer > sizeof (input_buffer))
1085 abort ();
1086 *p++ = c;
1087 }
1088 *p = 0;
1089 if (strstr (input_buffer, "noreturn"))
1090 g->flags |= DEFUN_noreturn;
1091 if (strstr (input_buffer, "const"))
1092 g->flags |= DEFUN_const;
1093 }
1037 continue; 1094 continue;
1038 } 1095 }
1039 1096