diff options
| author | Paul Eggert | 2015-01-05 09:07:45 -0800 |
|---|---|---|
| committer | Paul Eggert | 2015-01-05 10:14:58 -0800 |
| commit | 58f2d6ef32b28a787fcc4e0d98b3f331ceb2a68c (patch) | |
| tree | d6d79ad7b7cceafc78c5a9c54f5be1ac441a8ed7 /lib-src | |
| parent | d2cf05d1bac19d8564d0806f515b9f40fe57f4df (diff) | |
| download | emacs-58f2d6ef32b28a787fcc4e0d98b3f331ceb2a68c.tar.gz emacs-58f2d6ef32b28a787fcc4e0d98b3f331ceb2a68c.zip | |
Compute C decls for DEFSYMs automatically
Fixes Bug#15880.
This patch also makes Q constants (e.g., Qnil) constant addresses
from the C point of view.
* make-docfile.c: Revamp to generate table of symbols, too.
Include <stdbool.h>.
(xstrdup): New function.
(main): Don't process the same file twice.
(SYMBOL): New constant in enum global_type.
(struct symbol): Turn 'value' member into a union, either v.value
for int or v.svalue for string. All uses changed.
(add_global): New arg svalue, which overrides value, so that globals
can have a string value.
(close_emacs_global): New arg num_symbols; all uses changed.
Output lispsym decl.
(write_globals): Output symbol globals too. Output more
ATTRIBUTE_CONST, now that Qnil etc. are C constants.
Output defsym_name table.
(scan_c_file): Move most of guts into ...
(scan_c_stream): ... new function. Scan for DEFSYMs and
record symbols found. Don't read past EOF if file doesn't
end in newline.
* alloc.c, bidi.c, buffer.c, bytecode.c, callint.c, casefiddle:
* casetab.c, category.c, ccl.c, charset.c, chartab.c, cmds.c, coding.c:
* composite.c, data.c, dbusbind.c, decompress.c, dired.c, dispnew.c:
* doc.c, editfns.c, emacs.c, eval.c, fileio.c, fns.c, font.c, fontset.c:
* frame.c, fringe.c, ftfont.c, ftxfont.c, gfilenotify.c, gnutls.c:
* image.c, inotify.c, insdel.c, keyboard.c, keymap.c, lread.c:
* macfont.m, macros.c, minibuf.c, nsfns.m, nsfont.m, nsimage.m:
* nsmenu.m, nsselect.m, nsterm.m, print.c, process.c, profiler.c:
* search.c, sound.c, syntax.c, term.c, terminal.c, textprop.c, undo.c:
* window.c, xdisp.c, xfaces.c, xfns.c, xftfont.c, xmenu.c, xml.c:
* xselect.c, xsettings.c, xterm.c:
Remove Q vars that represent symbols (e.g., Qnil, Qt, Qemacs).
These names are now defined automatically by make-docfile.
* alloc.c (init_symbol): New function.
(Fmake_symbol): Use it.
(c_symbol_p): New function.
(valid_lisp_object_p, purecopy): Use it.
* alloc.c (marked_pinned_symbols):
Use make_lisp_symbol instead of make_lisp_ptr.
(garbage_collect_1): Mark lispsym symbols.
(CHECK_ALLOCATED_AND_LIVE_SYMBOL): New macro.
(mark_object): Use it.
(sweep_symbols): Sweep lispsym symbols.
(symbol_uses_obj): New function.
(which_symbols): Use it. Work for lispsym symbols, too.
(init_alloc_once): Initialize Vpurify_flag here; no need to wait,
since Qt's address is already known now.
(syms_of_alloc): Add lispsym count to symbols_consed.
* buffer.c (init_buffer_once): Compare to Qnil, not to make_number (0),
when testing whether storage is all bits zero.
* dispextern (struct image_type):
* font.c (font_property_table):
* frame.c (struct frame_parm_table, frame_parms):
* keyboard.c (scroll_bar_parts, struct event_head):
* xdisp.c (struct props):
Use XSYMBOL_INIT (Qfoo) and struct Lisp_Symbol * rather than &Qfoo and
Lisp_Object *, since Qfoo is no longer an object whose address can be
taken. All uses changed.
* eval.c (run_hook): New function. Most uses of Frun_hooks changed to
use it, so that they no longer need to take the address of a Lisp sym.
(syms_of_eval): Don't use DEFSYM on Vrun_hooks, as it's a variable.
* frame.c (syms_of_frame): Add defsyms for the frame_parms table.
* keyboard.c (syms_of_keyboard): Don't DEFSYM Qmenu_bar here.
DEFSYM Qdeactivate_mark before the corresponding var.
* keymap.c (syms_of_keymap): Use DEFSYM for Qmenu_bar and Qmode_line
instead of interning their symbols; this avoids duplicates.
(LISP_INITIALLY, TAG_PTR)
(DEFINE_LISP_SYMBOL_BEGIN, DEFINE_LISP_SYMBOL_END, XSYMBOL_INIT):
New macros.
(LISP_INITIALLY_ZERO): Use it.
(enum symbol_interned, enum symbol_redirect, struct Lisp_Symbol)
(EXFUN, DEFUN_ARGS_MANY, DEFUN_ARGS_UNEVALLED, DEFUN_ARGS_*):
Move decls up, to avoid forward uses. Include globals.h earlier, too.
(make_lisp_symbol): New function.
(XSETSYMBOL): Use it.
(DEFSYM): Now just a placeholder for make-docfile.
* lread.c (DEFINE_SYMBOLS): Define, for globals.h.
(intern_sym): New function, with body taken from old intern_driver.
(intern_driver): Use it. Last arg is now Lisp integer, not ptrdiff_t.
All uses changed.
(define_symbol): New function.
(init_obarray): Define the C symbols taken from lispsym.
Use plain DEFSYM for Qt and Qnil.
* syntax.c (init_syntax_once): No need to worry about
Qchar_table_extra_slots.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/ChangeLog | 23 | ||||
| -rw-r--r-- | lib-src/make-docfile.c | 279 |
2 files changed, 226 insertions, 76 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index acbbd3a02df..8bdf7d1fb16 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog | |||
| @@ -1,3 +1,26 @@ | |||
| 1 | 2015-01-05 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Compute C decls for DEFSYMs automatically | ||
| 4 | Fixes Bug#15880. | ||
| 5 | * make-docfile.c: Revamp to generate table of symbols, too. | ||
| 6 | Include <stdbool.h>. | ||
| 7 | (xstrdup): New function. | ||
| 8 | (main): Don't process the same file twice. | ||
| 9 | (SYMBOL): New constant in enum global_type. | ||
| 10 | (struct symbol): Turn 'value' member into a union, either v.value | ||
| 11 | for int or v.svalue for string. All uses changed. | ||
| 12 | (add_global): New arg svalue, which overrides value, so that globals | ||
| 13 | can have a string value. | ||
| 14 | (close_emacs_global): New arg num_symbols; all uses changed. | ||
| 15 | Output lispsym decl. | ||
| 16 | (write_globals): Output symbol globals too. Output more | ||
| 17 | ATTRIBUTE_CONST, now that Qnil etc. are C constants. | ||
| 18 | Output defsym_name table. | ||
| 19 | (scan_c_file): Move most of guts into ... | ||
| 20 | (scan_c_stream): ... new function. Scan for DEFSYMs and | ||
| 21 | record symbols found. Don't read past EOF if file doesn't | ||
| 22 | end in newline. | ||
| 23 | |||
| 1 | 2015-01-04 Paul Eggert <eggert@cs.ucla.edu> | 24 | 2015-01-04 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 25 | ||
| 3 | 'temacs -nw' should not call missing functions | 26 | 'temacs -nw' should not call missing functions |
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index f74b3d516d1..b05a634eb75 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c | |||
| @@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 36 | 36 | ||
| 37 | #include <config.h> | 37 | #include <config.h> |
| 38 | 38 | ||
| 39 | #include <stdbool.h> | ||
| 39 | #include <stdio.h> | 40 | #include <stdio.h> |
| 40 | #include <stdlib.h> /* config.h unconditionally includes this anyway */ | 41 | #include <stdlib.h> /* config.h unconditionally includes this anyway */ |
| 41 | 42 | ||
| @@ -63,6 +64,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 63 | static int scan_file (char *filename); | 64 | static int scan_file (char *filename); |
| 64 | static int scan_lisp_file (const char *filename, const char *mode); | 65 | static int scan_lisp_file (const char *filename, const char *mode); |
| 65 | static int scan_c_file (char *filename, const char *mode); | 66 | static int scan_c_file (char *filename, const char *mode); |
| 67 | static int scan_c_stream (FILE *infile); | ||
| 66 | static void start_globals (void); | 68 | static void start_globals (void); |
| 67 | static void write_globals (void); | 69 | static void write_globals (void); |
| 68 | 70 | ||
| @@ -106,6 +108,17 @@ xmalloc (unsigned int size) | |||
| 106 | return result; | 108 | return result; |
| 107 | } | 109 | } |
| 108 | 110 | ||
| 111 | /* Like strdup, but get fatal error if memory is exhausted. */ | ||
| 112 | |||
| 113 | static char * | ||
| 114 | xstrdup (char *s) | ||
| 115 | { | ||
| 116 | char *result = strdup (s); | ||
| 117 | if (! result) | ||
| 118 | fatal ("virtual memory exhausted", 0); | ||
| 119 | return result; | ||
| 120 | } | ||
| 121 | |||
| 109 | /* Like realloc but get fatal error if memory is exhausted. */ | 122 | /* Like realloc but get fatal error if memory is exhausted. */ |
| 110 | 123 | ||
| 111 | static void * | 124 | static void * |
| @@ -123,7 +136,6 @@ main (int argc, char **argv) | |||
| 123 | { | 136 | { |
| 124 | int i; | 137 | int i; |
| 125 | int err_count = 0; | 138 | int err_count = 0; |
| 126 | int first_infile; | ||
| 127 | 139 | ||
| 128 | progname = argv[0]; | 140 | progname = argv[0]; |
| 129 | 141 | ||
| @@ -167,16 +179,21 @@ main (int argc, char **argv) | |||
| 167 | if (generate_globals) | 179 | if (generate_globals) |
| 168 | start_globals (); | 180 | start_globals (); |
| 169 | 181 | ||
| 170 | first_infile = i; | 182 | if (argc <= i) |
| 171 | for (; i < argc; i++) | 183 | scan_c_stream (stdin); |
| 184 | else | ||
| 172 | { | 185 | { |
| 173 | int j; | 186 | int first_infile = i; |
| 174 | /* Don't process one file twice. */ | 187 | for (; i < argc; i++) |
| 175 | for (j = first_infile; j < i; j++) | 188 | { |
| 176 | if (! strcmp (argv[i], argv[j])) | 189 | int j; |
| 177 | break; | 190 | /* Don't process one file twice. */ |
| 178 | if (j == i) | 191 | for (j = first_infile; j < i; j++) |
| 179 | err_count += scan_file (argv[i]); | 192 | if (strcmp (argv[i], argv[j]) == 0) |
| 193 | break; | ||
| 194 | if (j == i) | ||
| 195 | err_count += scan_file (argv[i]); | ||
| 196 | } | ||
| 180 | } | 197 | } |
| 181 | 198 | ||
| 182 | if (err_count == 0 && generate_globals) | 199 | if (err_count == 0 && generate_globals) |
| @@ -528,13 +545,15 @@ write_c_args (char *func, char *buf, int minargs, int maxargs) | |||
| 528 | } | 545 | } |
| 529 | 546 | ||
| 530 | /* The types of globals. These are sorted roughly in decreasing alignment | 547 | /* The types of globals. These are sorted roughly in decreasing alignment |
| 531 | order to avoid allocation gaps, except that functions are last. */ | 548 | order to avoid allocation gaps, except that symbols and functions |
| 549 | are last. */ | ||
| 532 | enum global_type | 550 | enum global_type |
| 533 | { | 551 | { |
| 534 | INVALID, | 552 | INVALID, |
| 535 | LISP_OBJECT, | 553 | LISP_OBJECT, |
| 536 | EMACS_INTEGER, | 554 | EMACS_INTEGER, |
| 537 | BOOLEAN, | 555 | BOOLEAN, |
| 556 | SYMBOL, | ||
| 538 | FUNCTION | 557 | FUNCTION |
| 539 | }; | 558 | }; |
| 540 | 559 | ||
| @@ -543,7 +562,11 @@ struct global | |||
| 543 | { | 562 | { |
| 544 | enum global_type type; | 563 | enum global_type type; |
| 545 | char *name; | 564 | char *name; |
| 546 | int value; | 565 | union |
| 566 | { | ||
| 567 | int value; | ||
| 568 | char const *svalue; | ||
| 569 | } v; | ||
| 547 | }; | 570 | }; |
| 548 | 571 | ||
| 549 | /* All the variable names we saw while scanning C sources in `-g' | 572 | /* All the variable names we saw while scanning C sources in `-g' |
| @@ -553,7 +576,7 @@ int num_globals_allocated; | |||
| 553 | struct global *globals; | 576 | struct global *globals; |
| 554 | 577 | ||
| 555 | static void | 578 | static void |
| 556 | add_global (enum global_type type, char *name, int value) | 579 | add_global (enum global_type type, char *name, int value, char const *svalue) |
| 557 | { | 580 | { |
| 558 | /* Ignore the one non-symbol that can occur. */ | 581 | /* Ignore the one non-symbol that can occur. */ |
| 559 | if (strcmp (name, "...")) | 582 | if (strcmp (name, "...")) |
| @@ -574,7 +597,10 @@ add_global (enum global_type type, char *name, int value) | |||
| 574 | 597 | ||
| 575 | globals[num_globals - 1].type = type; | 598 | globals[num_globals - 1].type = type; |
| 576 | globals[num_globals - 1].name = name; | 599 | globals[num_globals - 1].name = name; |
| 577 | globals[num_globals - 1].value = value; | 600 | if (svalue) |
| 601 | globals[num_globals - 1].v.svalue = svalue; | ||
| 602 | else | ||
| 603 | globals[num_globals - 1].v.value = value; | ||
| 578 | } | 604 | } |
| 579 | } | 605 | } |
| 580 | 606 | ||
| @@ -591,17 +617,44 @@ compare_globals (const void *a, const void *b) | |||
| 591 | } | 617 | } |
| 592 | 618 | ||
| 593 | static void | 619 | static void |
| 594 | close_emacs_globals (void) | 620 | close_emacs_globals (int num_symbols) |
| 595 | { | 621 | { |
| 596 | puts ("};"); | 622 | printf (("};\n" |
| 597 | puts ("extern struct emacs_globals globals;"); | 623 | "extern struct emacs_globals globals;\n" |
| 624 | "\n" | ||
| 625 | "#ifndef DEFINE_SYMBOLS\n" | ||
| 626 | "extern\n" | ||
| 627 | "#endif\n" | ||
| 628 | "struct Lisp_Symbol lispsym[%d];\n"), | ||
| 629 | num_symbols); | ||
| 598 | } | 630 | } |
| 599 | 631 | ||
| 600 | static void | 632 | static void |
| 601 | write_globals (void) | 633 | write_globals (void) |
| 602 | { | 634 | { |
| 603 | int i, seen_defun = 0; | 635 | int i, j; |
| 636 | bool seen_defun = false; | ||
| 637 | int symnum = 0; | ||
| 638 | int num_symbols = 0; | ||
| 604 | qsort (globals, num_globals, sizeof (struct global), compare_globals); | 639 | qsort (globals, num_globals, sizeof (struct global), compare_globals); |
| 640 | |||
| 641 | j = 0; | ||
| 642 | for (i = 0; i < num_globals; i++) | ||
| 643 | { | ||
| 644 | while (i + 1 < num_globals | ||
| 645 | && strcmp (globals[i].name, globals[i + 1].name) == 0) | ||
| 646 | { | ||
| 647 | if (globals[i].type == FUNCTION | ||
| 648 | && globals[i].v.value != globals[i + 1].v.value) | ||
| 649 | error ("function '%s' defined twice with differing signatures", | ||
| 650 | globals[i].name); | ||
| 651 | i++; | ||
| 652 | } | ||
| 653 | num_symbols += globals[i].type == SYMBOL; | ||
| 654 | globals[j++] = globals[i]; | ||
| 655 | } | ||
| 656 | num_globals = j; | ||
| 657 | |||
| 605 | for (i = 0; i < num_globals; ++i) | 658 | for (i = 0; i < num_globals; ++i) |
| 606 | { | 659 | { |
| 607 | char const *type = 0; | 660 | char const *type = 0; |
| @@ -617,12 +670,13 @@ write_globals (void) | |||
| 617 | case LISP_OBJECT: | 670 | case LISP_OBJECT: |
| 618 | type = "Lisp_Object"; | 671 | type = "Lisp_Object"; |
| 619 | break; | 672 | break; |
| 673 | case SYMBOL: | ||
| 620 | case FUNCTION: | 674 | case FUNCTION: |
| 621 | if (!seen_defun) | 675 | if (!seen_defun) |
| 622 | { | 676 | { |
| 623 | close_emacs_globals (); | 677 | close_emacs_globals (num_symbols); |
| 624 | putchar ('\n'); | 678 | putchar ('\n'); |
| 625 | seen_defun = 1; | 679 | seen_defun = true; |
| 626 | } | 680 | } |
| 627 | break; | 681 | break; |
| 628 | default: | 682 | default: |
| @@ -635,6 +689,13 @@ write_globals (void) | |||
| 635 | printf ("#define %s globals.f_%s\n", | 689 | printf ("#define %s globals.f_%s\n", |
| 636 | globals[i].name, globals[i].name); | 690 | globals[i].name, globals[i].name); |
| 637 | } | 691 | } |
| 692 | else if (globals[i].type == SYMBOL) | ||
| 693 | printf (("DEFINE_LISP_SYMBOL_BEGIN (%s)\n" | ||
| 694 | "#define a%s (&lispsym[%d])\n" | ||
| 695 | "#define %s make_lisp_symbol (a%s)\n" | ||
| 696 | "DEFINE_LISP_SYMBOL_END (a%s)\n\n"), | ||
| 697 | globals[i].name, globals[i].name, symnum++, | ||
| 698 | globals[i].name, globals[i].name, globals[i].name); | ||
| 638 | else | 699 | else |
| 639 | { | 700 | { |
| 640 | /* It would be nice to have a cleaner way to deal with these | 701 | /* It would be nice to have a cleaner way to deal with these |
| @@ -647,39 +708,65 @@ write_globals (void) | |||
| 647 | fputs ("_Noreturn ", stdout); | 708 | fputs ("_Noreturn ", stdout); |
| 648 | 709 | ||
| 649 | printf ("EXFUN (%s, ", globals[i].name); | 710 | printf ("EXFUN (%s, ", globals[i].name); |
| 650 | if (globals[i].value == -1) | 711 | if (globals[i].v.value == -1) |
| 651 | fputs ("MANY", stdout); | 712 | fputs ("MANY", stdout); |
| 652 | else if (globals[i].value == -2) | 713 | else if (globals[i].v.value == -2) |
| 653 | fputs ("UNEVALLED", stdout); | 714 | fputs ("UNEVALLED", stdout); |
| 654 | else | 715 | else |
| 655 | printf ("%d", globals[i].value); | 716 | printf ("%d", globals[i].v.value); |
| 656 | putchar (')'); | 717 | putchar (')'); |
| 657 | 718 | ||
| 658 | /* It would be nice to have a cleaner way to deal with these | 719 | /* It would be nice to have a cleaner way to deal with these |
| 659 | special hacks, too. */ | 720 | special hacks, too. */ |
| 660 | if (strcmp (globals[i].name, "Fbyteorder") == 0 | 721 | if (strcmp (globals[i].name, "Fatom") == 0 |
| 722 | || strcmp (globals[i].name, "Fbyteorder") == 0 | ||
| 723 | || strcmp (globals[i].name, "Fcharacterp") == 0 | ||
| 724 | || strcmp (globals[i].name, "Fchar_or_string_p") == 0 | ||
| 725 | || strcmp (globals[i].name, "Fconsp") == 0 | ||
| 726 | || strcmp (globals[i].name, "Feq") == 0 | ||
| 727 | || strcmp (globals[i].name, "Fface_attribute_relative_p") == 0 | ||
| 661 | || strcmp (globals[i].name, "Fframe_windows_min_size") == 0 | 728 | || strcmp (globals[i].name, "Fframe_windows_min_size") == 0 |
| 729 | || strcmp (globals[i].name, "Fgnutls_errorp") == 0 | ||
| 662 | || strcmp (globals[i].name, "Fidentity") == 0 | 730 | || strcmp (globals[i].name, "Fidentity") == 0 |
| 731 | || strcmp (globals[i].name, "Fintegerp") == 0 | ||
| 732 | || strcmp (globals[i].name, "Finteractive") == 0 | ||
| 733 | || strcmp (globals[i].name, "Ffloatp") == 0 | ||
| 734 | || strcmp (globals[i].name, "Flistp") == 0 | ||
| 663 | || strcmp (globals[i].name, "Fmax_char") == 0 | 735 | || strcmp (globals[i].name, "Fmax_char") == 0 |
| 664 | || strcmp (globals[i].name, "Ftool_bar_height") == 0) | 736 | || strcmp (globals[i].name, "Fnatnump") == 0 |
| 737 | || strcmp (globals[i].name, "Fnlistp") == 0 | ||
| 738 | || strcmp (globals[i].name, "Fnull") == 0 | ||
| 739 | || strcmp (globals[i].name, "Fnumberp") == 0 | ||
| 740 | || strcmp (globals[i].name, "Fstringp") == 0 | ||
| 741 | || strcmp (globals[i].name, "Fsymbolp") == 0 | ||
| 742 | || strcmp (globals[i].name, "Ftool_bar_height") == 0 | ||
| 743 | || strcmp (globals[i].name, "Fwindow__sanitize_window_sizes") == 0 | ||
| 744 | #ifndef WINDOWSNT | ||
| 745 | || strcmp (globals[i].name, "Fgnutls_available_p") == 0 | ||
| 746 | || strcmp (globals[i].name, "Fzlib_available_p") == 0 | ||
| 747 | #endif | ||
| 748 | || 0) | ||
| 665 | fputs (" ATTRIBUTE_CONST", stdout); | 749 | fputs (" ATTRIBUTE_CONST", stdout); |
| 666 | 750 | ||
| 667 | puts (";"); | 751 | puts (";"); |
| 668 | } | 752 | } |
| 669 | |||
| 670 | while (i + 1 < num_globals | ||
| 671 | && !strcmp (globals[i].name, globals[i + 1].name)) | ||
| 672 | { | ||
| 673 | if (globals[i].type == FUNCTION | ||
| 674 | && globals[i].value != globals[i + 1].value) | ||
| 675 | error ("function '%s' defined twice with differing signatures", | ||
| 676 | globals[i].name); | ||
| 677 | ++i; | ||
| 678 | } | ||
| 679 | } | 753 | } |
| 680 | 754 | ||
| 681 | if (!seen_defun) | 755 | if (!seen_defun) |
| 682 | close_emacs_globals (); | 756 | close_emacs_globals (num_symbols); |
| 757 | |||
| 758 | puts ("#ifdef DEFINE_SYMBOLS"); | ||
| 759 | puts ("static char const *const defsym_name[] = {"); | ||
| 760 | for (int i = 0; i < num_globals; i++) | ||
| 761 | { | ||
| 762 | if (globals[i].type == SYMBOL) | ||
| 763 | printf ("\t\"%s\",\n", globals[i].v.svalue); | ||
| 764 | while (i + 1 < num_globals | ||
| 765 | && strcmp (globals[i].name, globals[i + 1].name) == 0) | ||
| 766 | i++; | ||
| 767 | } | ||
| 768 | puts ("};"); | ||
| 769 | puts ("#endif"); | ||
| 683 | } | 770 | } |
| 684 | 771 | ||
| 685 | 772 | ||
| @@ -692,9 +779,6 @@ static int | |||
| 692 | scan_c_file (char *filename, const char *mode) | 779 | scan_c_file (char *filename, const char *mode) |
| 693 | { | 780 | { |
| 694 | FILE *infile; | 781 | FILE *infile; |
| 695 | register int c; | ||
| 696 | register int commas; | ||
| 697 | int minargs, maxargs; | ||
| 698 | int extension = filename[strlen (filename) - 1]; | 782 | int extension = filename[strlen (filename) - 1]; |
| 699 | 783 | ||
| 700 | if (extension == 'o') | 784 | if (extension == 'o') |
| @@ -720,8 +804,15 @@ scan_c_file (char *filename, const char *mode) | |||
| 720 | 804 | ||
| 721 | /* Reset extension to be able to detect duplicate files. */ | 805 | /* Reset extension to be able to detect duplicate files. */ |
| 722 | filename[strlen (filename) - 1] = extension; | 806 | filename[strlen (filename) - 1] = extension; |
| 807 | return scan_c_stream (infile); | ||
| 808 | } | ||
| 809 | |||
| 810 | static int | ||
| 811 | scan_c_stream (FILE *infile) | ||
| 812 | { | ||
| 813 | int commas, minargs, maxargs; | ||
| 814 | int c = '\n'; | ||
| 723 | 815 | ||
| 724 | c = '\n'; | ||
| 725 | while (!feof (infile)) | 816 | while (!feof (infile)) |
| 726 | { | 817 | { |
| 727 | int doc_keyword = 0; | 818 | int doc_keyword = 0; |
| @@ -750,37 +841,53 @@ scan_c_file (char *filename, const char *mode) | |||
| 750 | if (c != 'F') | 841 | if (c != 'F') |
| 751 | continue; | 842 | continue; |
| 752 | c = getc (infile); | 843 | c = getc (infile); |
| 753 | if (c != 'V') | 844 | if (c == 'S') |
| 754 | continue; | ||
| 755 | c = getc (infile); | ||
| 756 | if (c != 'A') | ||
| 757 | continue; | ||
| 758 | c = getc (infile); | ||
| 759 | if (c != 'R') | ||
| 760 | continue; | ||
| 761 | c = getc (infile); | ||
| 762 | if (c != '_') | ||
| 763 | continue; | ||
| 764 | |||
| 765 | defvarflag = 1; | ||
| 766 | |||
| 767 | c = getc (infile); | ||
| 768 | defvarperbufferflag = (c == 'P'); | ||
| 769 | if (generate_globals) | ||
| 770 | { | 845 | { |
| 771 | if (c == 'I') | 846 | c = getc (infile); |
| 772 | type = EMACS_INTEGER; | 847 | if (c != 'Y') |
| 773 | else if (c == 'L') | 848 | continue; |
| 774 | type = LISP_OBJECT; | 849 | c = getc (infile); |
| 775 | else if (c == 'B') | 850 | if (c != 'M') |
| 776 | type = BOOLEAN; | 851 | continue; |
| 852 | c = getc (infile); | ||
| 853 | if (c != ' ' && c != '\t' && c != '(') | ||
| 854 | continue; | ||
| 855 | type = SYMBOL; | ||
| 777 | } | 856 | } |
| 857 | else if (c == 'V') | ||
| 858 | { | ||
| 859 | c = getc (infile); | ||
| 860 | if (c != 'A') | ||
| 861 | continue; | ||
| 862 | c = getc (infile); | ||
| 863 | if (c != 'R') | ||
| 864 | continue; | ||
| 865 | c = getc (infile); | ||
| 866 | if (c != '_') | ||
| 867 | continue; | ||
| 778 | 868 | ||
| 779 | c = getc (infile); | 869 | defvarflag = 1; |
| 780 | /* We need to distinguish between DEFVAR_BOOL and | 870 | |
| 781 | DEFVAR_BUFFER_DEFAULTS. */ | 871 | c = getc (infile); |
| 782 | if (generate_globals && type == BOOLEAN && c != 'O') | 872 | defvarperbufferflag = (c == 'P'); |
| 783 | type = INVALID; | 873 | if (generate_globals) |
| 874 | { | ||
| 875 | if (c == 'I') | ||
| 876 | type = EMACS_INTEGER; | ||
| 877 | else if (c == 'L') | ||
| 878 | type = LISP_OBJECT; | ||
| 879 | else if (c == 'B') | ||
| 880 | type = BOOLEAN; | ||
| 881 | } | ||
| 882 | |||
| 883 | c = getc (infile); | ||
| 884 | /* We need to distinguish between DEFVAR_BOOL and | ||
| 885 | DEFVAR_BUFFER_DEFAULTS. */ | ||
| 886 | if (generate_globals && type == BOOLEAN && c != 'O') | ||
| 887 | type = INVALID; | ||
| 888 | } | ||
| 889 | else | ||
| 890 | continue; | ||
| 784 | } | 891 | } |
| 785 | else if (c == 'D') | 892 | else if (c == 'D') |
| 786 | { | 893 | { |
| @@ -797,7 +904,7 @@ scan_c_file (char *filename, const char *mode) | |||
| 797 | 904 | ||
| 798 | if (generate_globals | 905 | if (generate_globals |
| 799 | && (!defvarflag || defvarperbufferflag || type == INVALID) | 906 | && (!defvarflag || defvarperbufferflag || type == INVALID) |
| 800 | && !defunflag) | 907 | && !defunflag && type != SYMBOL) |
| 801 | continue; | 908 | continue; |
| 802 | 909 | ||
| 803 | while (c != '(') | 910 | while (c != '(') |
| @@ -807,15 +914,19 @@ scan_c_file (char *filename, const char *mode) | |||
| 807 | c = getc (infile); | 914 | c = getc (infile); |
| 808 | } | 915 | } |
| 809 | 916 | ||
| 810 | /* Lisp variable or function name. */ | 917 | if (type != SYMBOL) |
| 811 | c = getc (infile); | 918 | { |
| 812 | if (c != '"') | 919 | /* Lisp variable or function name. */ |
| 813 | continue; | 920 | c = getc (infile); |
| 814 | c = read_c_string_or_comment (infile, -1, 0, 0); | 921 | if (c != '"') |
| 922 | continue; | ||
| 923 | c = read_c_string_or_comment (infile, -1, 0, 0); | ||
| 924 | } | ||
| 815 | 925 | ||
| 816 | if (generate_globals) | 926 | if (generate_globals) |
| 817 | { | 927 | { |
| 818 | int i = 0; | 928 | int i = 0; |
| 929 | char const *svalue = 0; | ||
| 819 | 930 | ||
| 820 | /* Skip "," and whitespace. */ | 931 | /* Skip "," and whitespace. */ |
| 821 | do | 932 | do |
| @@ -827,6 +938,8 @@ scan_c_file (char *filename, const char *mode) | |||
| 827 | /* Read in the identifier. */ | 938 | /* Read in the identifier. */ |
| 828 | do | 939 | do |
| 829 | { | 940 | { |
| 941 | if (c < 0) | ||
| 942 | goto eof; | ||
| 830 | input_buffer[i++] = c; | 943 | input_buffer[i++] = c; |
| 831 | c = getc (infile); | 944 | c = getc (infile); |
| 832 | } | 945 | } |
| @@ -837,13 +950,27 @@ scan_c_file (char *filename, const char *mode) | |||
| 837 | name = xmalloc (i + 1); | 950 | name = xmalloc (i + 1); |
| 838 | memcpy (name, input_buffer, i + 1); | 951 | memcpy (name, input_buffer, i + 1); |
| 839 | 952 | ||
| 953 | if (type == SYMBOL) | ||
| 954 | { | ||
| 955 | do | ||
| 956 | c = getc (infile); | ||
| 957 | while (c == ' ' || c == '\t' || c == '\n' || c == '\r'); | ||
| 958 | if (c != '"') | ||
| 959 | continue; | ||
| 960 | c = read_c_string_or_comment (infile, -1, 0, 0); | ||
| 961 | svalue = xstrdup (input_buffer); | ||
| 962 | } | ||
| 963 | |||
| 840 | if (!defunflag) | 964 | if (!defunflag) |
| 841 | { | 965 | { |
| 842 | add_global (type, name, 0); | 966 | add_global (type, name, 0, svalue); |
| 843 | continue; | 967 | continue; |
| 844 | } | 968 | } |
| 845 | } | 969 | } |
| 846 | 970 | ||
| 971 | if (type == SYMBOL) | ||
| 972 | continue; | ||
| 973 | |||
| 847 | /* DEFVAR_LISP ("name", addr, "doc") | 974 | /* DEFVAR_LISP ("name", addr, "doc") |
| 848 | DEFVAR_LISP ("name", addr /\* doc *\/) | 975 | DEFVAR_LISP ("name", addr /\* doc *\/) |
| 849 | DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */ | 976 | DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */ |
| @@ -896,7 +1023,7 @@ scan_c_file (char *filename, const char *mode) | |||
| 896 | 1023 | ||
| 897 | if (generate_globals) | 1024 | if (generate_globals) |
| 898 | { | 1025 | { |
| 899 | add_global (FUNCTION, name, maxargs); | 1026 | add_global (FUNCTION, name, maxargs, 0); |
| 900 | continue; | 1027 | continue; |
| 901 | } | 1028 | } |
| 902 | 1029 | ||