diff options
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/ChangeLog | 20 | ||||
| -rw-r--r-- | lib-src/make-docfile.c | 185 |
2 files changed, 203 insertions, 2 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 3f4e4b1b9ff..0f93941151e 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog | |||
| @@ -1,3 +1,23 @@ | |||
| 1 | 2011-02-09 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * make-docfile.c (EMACS_INTEGER): Rename from EMACS_INT. | ||
| 4 | This avoids collision with config.h's EMACS_INT on some | ||
| 5 | configurations. All uses changed. | ||
| 6 | |||
| 7 | 2011-02-08 Tom Tromey <tromey@redhat.com> | ||
| 8 | |||
| 9 | * make-docfile.c: Unconditionally include stdlib.h. | ||
| 10 | (generate_globals): New global. | ||
| 11 | (xrealloc): New function. | ||
| 12 | (main): Handle '-g'. Call start_globals, write_globals. | ||
| 13 | (scan_file): Conditionally call put_filename. | ||
| 14 | (start_globals): New function. | ||
| 15 | (struct global): New. | ||
| 16 | (num_globals, globals): New globals. | ||
| 17 | (add_global, compare_globals, write_globals): New functions. | ||
| 18 | (scan_c_file): Update for "-g". | ||
| 19 | (scan_lisp_file): Fail if "-g". | ||
| 20 | |||
| 1 | 2011-02-05 Paul Eggert <eggert@cs.ucla.edu> | 21 | 2011-02-05 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 22 | ||
| 3 | * emacsclient.c: conform to C89 pointer rules | 23 | * emacsclient.c: conform to C89 pointer rules |
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index 8addbda0489..93994c1ed3e 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c | |||
| @@ -41,11 +41,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 41 | #undef chdir | 41 | #undef chdir |
| 42 | 42 | ||
| 43 | #include <stdio.h> | 43 | #include <stdio.h> |
| 44 | #include <stdlib.h> | ||
| 44 | #ifdef MSDOS | 45 | #ifdef MSDOS |
| 45 | #include <fcntl.h> | 46 | #include <fcntl.h> |
| 46 | #endif /* MSDOS */ | 47 | #endif /* MSDOS */ |
| 47 | #ifdef WINDOWSNT | 48 | #ifdef WINDOWSNT |
| 48 | #include <stdlib.h> | ||
| 49 | #include <fcntl.h> | 49 | #include <fcntl.h> |
| 50 | #include <direct.h> | 50 | #include <direct.h> |
| 51 | #endif /* WINDOWSNT */ | 51 | #endif /* WINDOWSNT */ |
| @@ -70,6 +70,8 @@ int scan_file (char *filename); | |||
| 70 | int scan_lisp_file (const char *filename, const char *mode); | 70 | int scan_lisp_file (const char *filename, const char *mode); |
| 71 | int scan_c_file (char *filename, const char *mode); | 71 | int scan_c_file (char *filename, const char *mode); |
| 72 | void fatal (const char *s1, const char *s2) NO_RETURN; | 72 | void fatal (const char *s1, const char *s2) NO_RETURN; |
| 73 | void start_globals (void); | ||
| 74 | void write_globals (void); | ||
| 73 | 75 | ||
| 74 | #ifdef MSDOS | 76 | #ifdef MSDOS |
| 75 | /* s/msdos.h defines this as sys_chdir, but we're not linking with the | 77 | /* s/msdos.h defines this as sys_chdir, but we're not linking with the |
| @@ -85,6 +87,9 @@ FILE *outfile; | |||
| 85 | /* Name this program was invoked with. */ | 87 | /* Name this program was invoked with. */ |
| 86 | char *progname; | 88 | char *progname; |
| 87 | 89 | ||
| 90 | /* Nonzero if this invocation is generating globals.h. */ | ||
| 91 | int generate_globals; | ||
| 92 | |||
| 88 | /* Print error message. `s1' is printf control string, `s2' is arg for it. */ | 93 | /* Print error message. `s1' is printf control string, `s2' is arg for it. */ |
| 89 | 94 | ||
| 90 | /* VARARGS1 */ | 95 | /* VARARGS1 */ |
| @@ -116,6 +121,18 @@ xmalloc (unsigned int size) | |||
| 116 | fatal ("virtual memory exhausted", 0); | 121 | fatal ("virtual memory exhausted", 0); |
| 117 | return result; | 122 | return result; |
| 118 | } | 123 | } |
| 124 | |||
| 125 | /* Like realloc but get fatal error if memory is exhausted. */ | ||
| 126 | |||
| 127 | void * | ||
| 128 | xrealloc (void *arg, unsigned int size) | ||
| 129 | { | ||
| 130 | void *result = (void *) realloc (arg, size); | ||
| 131 | if (result == NULL) | ||
| 132 | fatal ("virtual memory exhausted", 0); | ||
| 133 | return result; | ||
| 134 | } | ||
| 135 | |||
| 119 | 136 | ||
| 120 | int | 137 | int |
| 121 | main (int argc, char **argv) | 138 | main (int argc, char **argv) |
| @@ -164,10 +181,18 @@ main (int argc, char **argv) | |||
| 164 | } | 181 | } |
| 165 | i += 2; | 182 | i += 2; |
| 166 | } | 183 | } |
| 184 | if (argc > i && !strcmp (argv[i], "-g")) | ||
| 185 | { | ||
| 186 | generate_globals = 1; | ||
| 187 | ++i; | ||
| 188 | } | ||
| 167 | 189 | ||
| 168 | if (outfile == 0) | 190 | if (outfile == 0) |
| 169 | fatal ("No output file specified", ""); | 191 | fatal ("No output file specified", ""); |
| 170 | 192 | ||
| 193 | if (generate_globals) | ||
| 194 | start_globals (); | ||
| 195 | |||
| 171 | first_infile = i; | 196 | first_infile = i; |
| 172 | for (; i < argc; i++) | 197 | for (; i < argc; i++) |
| 173 | { | 198 | { |
| @@ -179,6 +204,10 @@ main (int argc, char **argv) | |||
| 179 | if (j == i) | 204 | if (j == i) |
| 180 | err_count += scan_file (argv[i]); | 205 | err_count += scan_file (argv[i]); |
| 181 | } | 206 | } |
| 207 | |||
| 208 | if (err_count == 0 && generate_globals) | ||
| 209 | write_globals (); | ||
| 210 | |||
| 182 | return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS); | 211 | return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS); |
| 183 | } | 212 | } |
| 184 | 213 | ||
| @@ -208,7 +237,8 @@ scan_file (char *filename) | |||
| 208 | 237 | ||
| 209 | size_t len = strlen (filename); | 238 | size_t len = strlen (filename); |
| 210 | 239 | ||
| 211 | put_filename (filename); | 240 | if (!generate_globals) |
| 241 | put_filename (filename); | ||
| 212 | if (len > 4 && !strcmp (filename + len - 4, ".elc")) | 242 | if (len > 4 && !strcmp (filename + len - 4, ".elc")) |
| 213 | return scan_lisp_file (filename, READ_BINARY); | 243 | return scan_lisp_file (filename, READ_BINARY); |
| 214 | else if (len > 3 && !strcmp (filename + len - 3, ".el")) | 244 | else if (len > 3 && !strcmp (filename + len - 3, ".el")) |
| @@ -216,6 +246,14 @@ scan_file (char *filename) | |||
| 216 | else | 246 | else |
| 217 | return scan_c_file (filename, READ_TEXT); | 247 | return scan_c_file (filename, READ_TEXT); |
| 218 | } | 248 | } |
| 249 | |||
| 250 | void | ||
| 251 | start_globals (void) | ||
| 252 | { | ||
| 253 | fprintf (outfile, "/* This file was auto-generated by make-docfile. */\n"); | ||
| 254 | fprintf (outfile, "/* DO NOT EDIT. */\n"); | ||
| 255 | fprintf (outfile, "struct emacs_globals {\n"); | ||
| 256 | } | ||
| 219 | 257 | ||
| 220 | char buf[128]; | 258 | char buf[128]; |
| 221 | 259 | ||
| @@ -517,6 +555,98 @@ write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs) | |||
| 517 | putc (')', out); | 555 | putc (')', out); |
| 518 | } | 556 | } |
| 519 | 557 | ||
| 558 | /* The types of globals. */ | ||
| 559 | enum global_type | ||
| 560 | { | ||
| 561 | EMACS_INTEGER, | ||
| 562 | BOOLEAN, | ||
| 563 | LISP_OBJECT, | ||
| 564 | INVALID | ||
| 565 | }; | ||
| 566 | |||
| 567 | /* A single global. */ | ||
| 568 | struct global | ||
| 569 | { | ||
| 570 | enum global_type type; | ||
| 571 | char *name; | ||
| 572 | }; | ||
| 573 | |||
| 574 | /* All the variable names we saw while scanning C sources in `-g' | ||
| 575 | mode. */ | ||
| 576 | int num_globals; | ||
| 577 | int num_globals_allocated; | ||
| 578 | struct global *globals; | ||
| 579 | |||
| 580 | static void | ||
| 581 | add_global (enum global_type type, char *name) | ||
| 582 | { | ||
| 583 | /* Ignore the one non-symbol that can occur. */ | ||
| 584 | if (strcmp (name, "...")) | ||
| 585 | { | ||
| 586 | ++num_globals; | ||
| 587 | |||
| 588 | if (num_globals_allocated == 0) | ||
| 589 | { | ||
| 590 | num_globals_allocated = 100; | ||
| 591 | globals = xmalloc (num_globals_allocated * sizeof (struct global)); | ||
| 592 | } | ||
| 593 | else if (num_globals == num_globals_allocated) | ||
| 594 | { | ||
| 595 | num_globals_allocated *= 2; | ||
| 596 | globals = xrealloc (globals, | ||
| 597 | num_globals_allocated * sizeof (struct global)); | ||
| 598 | } | ||
| 599 | |||
| 600 | globals[num_globals - 1].type = type; | ||
| 601 | globals[num_globals - 1].name = name; | ||
| 602 | } | ||
| 603 | } | ||
| 604 | |||
| 605 | static int | ||
| 606 | compare_globals (const void *a, const void *b) | ||
| 607 | { | ||
| 608 | const struct global *ga = a; | ||
| 609 | const struct global *gb = b; | ||
| 610 | return strcmp (ga->name, gb->name); | ||
| 611 | } | ||
| 612 | |||
| 613 | void | ||
| 614 | write_globals (void) | ||
| 615 | { | ||
| 616 | int i; | ||
| 617 | qsort (globals, num_globals, sizeof (struct global), compare_globals); | ||
| 618 | for (i = 0; i < num_globals; ++i) | ||
| 619 | { | ||
| 620 | char *type; | ||
| 621 | |||
| 622 | switch (globals[i].type) | ||
| 623 | { | ||
| 624 | case EMACS_INTEGER: | ||
| 625 | type = "EMACS_INT"; | ||
| 626 | break; | ||
| 627 | case BOOLEAN: | ||
| 628 | type = "int"; | ||
| 629 | break; | ||
| 630 | case LISP_OBJECT: | ||
| 631 | type = "Lisp_Object"; | ||
| 632 | break; | ||
| 633 | default: | ||
| 634 | fatal ("not a recognized DEFVAR_", 0); | ||
| 635 | } | ||
| 636 | |||
| 637 | fprintf (outfile, " %s f_%s;\n", type, globals[i].name); | ||
| 638 | fprintf (outfile, "#define %s globals.f_%s\n", | ||
| 639 | globals[i].name, globals[i].name); | ||
| 640 | while (i + 1 < num_globals | ||
| 641 | && !strcmp (globals[i].name, globals[i + 1].name)) | ||
| 642 | ++i; | ||
| 643 | } | ||
| 644 | |||
| 645 | fprintf (outfile, "};\n"); | ||
| 646 | fprintf (outfile, "extern struct emacs_globals globals;\n"); | ||
| 647 | } | ||
| 648 | |||
| 649 | |||
| 520 | /* Read through a c file. If a .o file is named, | 650 | /* Read through a c file. If a .o file is named, |
| 521 | the corresponding .c or .m file is read instead. | 651 | the corresponding .c or .m file is read instead. |
| 522 | Looks for DEFUN constructs such as are defined in ../src/lisp.h. | 652 | Looks for DEFUN constructs such as are defined in ../src/lisp.h. |
| @@ -533,6 +663,7 @@ scan_c_file (char *filename, const char *mode) | |||
| 533 | register int defvarflag; | 663 | register int defvarflag; |
| 534 | int minargs, maxargs; | 664 | int minargs, maxargs; |
| 535 | int extension = filename[strlen (filename) - 1]; | 665 | int extension = filename[strlen (filename) - 1]; |
| 666 | enum global_type type; | ||
| 536 | 667 | ||
| 537 | if (extension == 'o') | 668 | if (extension == 'o') |
| 538 | filename[strlen (filename) - 1] = 'c'; | 669 | filename[strlen (filename) - 1] = 'c'; |
| @@ -599,8 +730,23 @@ scan_c_file (char *filename, const char *mode) | |||
| 599 | 730 | ||
| 600 | c = getc (infile); | 731 | c = getc (infile); |
| 601 | defvarperbufferflag = (c == 'P'); | 732 | defvarperbufferflag = (c == 'P'); |
| 733 | if (generate_globals) | ||
| 734 | { | ||
| 735 | if (c == 'I') | ||
| 736 | type = EMACS_INTEGER; | ||
| 737 | else if (c == 'L') | ||
| 738 | type = LISP_OBJECT; | ||
| 739 | else if (c == 'B') | ||
| 740 | type = BOOLEAN; | ||
| 741 | else | ||
| 742 | type = INVALID; | ||
| 743 | } | ||
| 602 | 744 | ||
| 603 | c = getc (infile); | 745 | c = getc (infile); |
| 746 | /* We need to distinguish between DEFVAR_BOOL and | ||
| 747 | DEFVAR_BUFFER_DEFAULTS. */ | ||
| 748 | if (generate_globals && type == BOOLEAN && c != 'O') | ||
| 749 | type = INVALID; | ||
| 604 | } | 750 | } |
| 605 | else if (c == 'D') | 751 | else if (c == 'D') |
| 606 | { | 752 | { |
| @@ -617,6 +763,10 @@ scan_c_file (char *filename, const char *mode) | |||
| 617 | } | 763 | } |
| 618 | else continue; | 764 | else continue; |
| 619 | 765 | ||
| 766 | if (generate_globals && (!defvarflag || defvarperbufferflag | ||
| 767 | || type == INVALID)) | ||
| 768 | continue; | ||
| 769 | |||
| 620 | while (c != '(') | 770 | while (c != '(') |
| 621 | { | 771 | { |
| 622 | if (c < 0) | 772 | if (c < 0) |
| @@ -630,6 +780,34 @@ scan_c_file (char *filename, const char *mode) | |||
| 630 | continue; | 780 | continue; |
| 631 | c = read_c_string_or_comment (infile, -1, 0, 0); | 781 | c = read_c_string_or_comment (infile, -1, 0, 0); |
| 632 | 782 | ||
| 783 | if (generate_globals) | ||
| 784 | { | ||
| 785 | int i = 0; | ||
| 786 | char *name; | ||
| 787 | |||
| 788 | /* Skip "," and whitespace. */ | ||
| 789 | do | ||
| 790 | { | ||
| 791 | c = getc (infile); | ||
| 792 | } | ||
| 793 | while (c == ',' || c == ' ' || c == '\t' || c == '\n' || c == '\r'); | ||
| 794 | |||
| 795 | /* Read in the identifier. */ | ||
| 796 | do | ||
| 797 | { | ||
| 798 | buf[i++] = c; | ||
| 799 | c = getc (infile); | ||
| 800 | } | ||
| 801 | while (! (c == ',' || c == ' ' || c == '\t' || | ||
| 802 | c == '\n' || c == '\r')); | ||
| 803 | buf[i] = '\0'; | ||
| 804 | |||
| 805 | name = xmalloc (i + 1); | ||
| 806 | memcpy (name, buf, i + 1); | ||
| 807 | add_global (type, name); | ||
| 808 | continue; | ||
| 809 | } | ||
| 810 | |||
| 633 | /* DEFVAR_LISP ("name", addr, "doc") | 811 | /* DEFVAR_LISP ("name", addr, "doc") |
| 634 | DEFVAR_LISP ("name", addr /\* doc *\/) | 812 | DEFVAR_LISP ("name", addr /\* doc *\/) |
| 635 | DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */ | 813 | DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */ |
| @@ -845,6 +1023,9 @@ scan_lisp_file (const char *filename, const char *mode) | |||
| 845 | register int c; | 1023 | register int c; |
| 846 | char *saved_string = 0; | 1024 | char *saved_string = 0; |
| 847 | 1025 | ||
| 1026 | if (generate_globals) | ||
| 1027 | fatal ("scanning lisp file when -g specified", 0); | ||
| 1028 | |||
| 848 | infile = fopen (filename, mode); | 1029 | infile = fopen (filename, mode); |
| 849 | if (infile == NULL) | 1030 | if (infile == NULL) |
| 850 | { | 1031 | { |