diff options
| author | John Wiegley | 2016-02-15 14:09:12 -0800 |
|---|---|---|
| committer | John Wiegley | 2016-02-15 14:09:12 -0800 |
| commit | a644fa367504c4587c1b9e5fc20b7af79e6e99a0 (patch) | |
| tree | 4647c040ba7c430db2d102e39180950ffd90e49f /lib-src | |
| parent | 8c4e041bdbc07a159305b41e1bcb64f1d301b99f (diff) | |
| parent | f5d6b9bb5b307067547f0b26c74e9f538464bfc6 (diff) | |
| download | emacs-a644fa367504c4587c1b9e5fc20b7af79e6e99a0.tar.gz emacs-a644fa367504c4587c1b9e5fc20b7af79e6e99a0.zip | |
Merge from origin/emacs-25
f5d6b9b Revert "Support integer image rotation and respect EXIF rotations"
afe7d1f Revert "Document EXIF image rotation"
c6f377c Document OS X LANG default
eb4a18c Set locale when run from OS X GUI
456c0a3 make-docfile cleanup for I/O, etc.
25ec995 Memory-management cleanup in make-docfile
02d925e Kevin Gallagher has new email address
4ef153b Improve doc strings of 'forward/backward-word-strictly'
3ad05a0 Describe Makefile test targets in test/README
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/make-docfile.c | 326 |
1 files changed, 182 insertions, 144 deletions
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index 02b5e766ee2..12222c3db3c 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c | |||
| @@ -37,6 +37,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 37 | #include <config.h> | 37 | #include <config.h> |
| 38 | 38 | ||
| 39 | #include <stdbool.h> | 39 | #include <stdbool.h> |
| 40 | #include <stddef.h> | ||
| 41 | #include <stdint.h> | ||
| 40 | #include <stdio.h> | 42 | #include <stdio.h> |
| 41 | #include <stdlib.h> /* config.h unconditionally includes this anyway */ | 43 | #include <stdlib.h> /* config.h unconditionally includes this anyway */ |
| 42 | 44 | ||
| @@ -48,6 +50,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 48 | #endif /* WINDOWSNT */ | 50 | #endif /* WINDOWSNT */ |
| 49 | 51 | ||
| 50 | #include <binary-io.h> | 52 | #include <binary-io.h> |
| 53 | #include <intprops.h> | ||
| 54 | #include <min-max.h> | ||
| 51 | 55 | ||
| 52 | #ifdef DOS_NT | 56 | #ifdef DOS_NT |
| 53 | /* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this | 57 | /* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this |
| @@ -61,72 +65,79 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 61 | #define IS_SLASH(c) ((c) == '/') | 65 | #define IS_SLASH(c) ((c) == '/') |
| 62 | #endif /* not DOS_NT */ | 66 | #endif /* not DOS_NT */ |
| 63 | 67 | ||
| 64 | static int scan_file (char *filename); | 68 | static void scan_file (char *filename); |
| 65 | static int scan_lisp_file (const char *filename, const char *mode); | 69 | static void scan_lisp_file (const char *filename, const char *mode); |
| 66 | static int scan_c_file (char *filename, const char *mode); | 70 | static void scan_c_file (char *filename, const char *mode); |
| 67 | static int scan_c_stream (FILE *infile); | 71 | static void scan_c_stream (FILE *infile); |
| 68 | static void start_globals (void); | 72 | static void start_globals (void); |
| 69 | static void write_globals (void); | 73 | static void write_globals (void); |
| 70 | 74 | ||
| 71 | #include <unistd.h> | 75 | #include <unistd.h> |
| 72 | 76 | ||
| 73 | /* Name this program was invoked with. */ | 77 | /* Name this program was invoked with. */ |
| 74 | char *progname; | 78 | static char *progname; |
| 75 | 79 | ||
| 76 | /* Nonzero if this invocation is generating globals.h. */ | 80 | /* True if this invocation is generating globals.h. */ |
| 77 | int generate_globals; | 81 | static bool generate_globals; |
| 78 | 82 | ||
| 79 | /* Print error message. `s1' is printf control string, `s2' is arg for it. */ | 83 | /* Print error message. Args are like vprintf. */ |
| 80 | 84 | ||
| 81 | /* VARARGS1 */ | 85 | static void ATTRIBUTE_FORMAT_PRINTF (1, 0) |
| 82 | static void | 86 | verror (char const *m, va_list ap) |
| 83 | error (const char *s1, const char *s2) | ||
| 84 | { | 87 | { |
| 85 | fprintf (stderr, "%s: ", progname); | 88 | fprintf (stderr, "%s: ", progname); |
| 86 | fprintf (stderr, s1, s2); | 89 | vfprintf (stderr, m, ap); |
| 87 | fprintf (stderr, "\n"); | 90 | fprintf (stderr, "\n"); |
| 88 | } | 91 | } |
| 89 | 92 | ||
| 90 | /* Print error message and exit. */ | 93 | /* Print error message. Args are like printf. */ |
| 91 | 94 | ||
| 92 | /* VARARGS1 */ | 95 | static void ATTRIBUTE_FORMAT_PRINTF (1, 2) |
| 93 | static _Noreturn void | 96 | error (char const *m, ...) |
| 94 | fatal (const char *s1, const char *s2) | ||
| 95 | { | 97 | { |
| 96 | error (s1, s2); | 98 | va_list ap; |
| 97 | exit (EXIT_FAILURE); | 99 | va_start (ap, m); |
| 100 | verror (m, ap); | ||
| 101 | va_end (ap); | ||
| 98 | } | 102 | } |
| 99 | 103 | ||
| 100 | /* Like malloc but get fatal error if memory is exhausted. */ | 104 | /* Print error message and exit. Args are like printf. */ |
| 101 | 105 | ||
| 102 | static void * | 106 | static _Noreturn void ATTRIBUTE_FORMAT_PRINTF (1, 2) |
| 103 | xmalloc (unsigned int size) | 107 | fatal (char const *m, ...) |
| 104 | { | 108 | { |
| 105 | void *result = (void *) malloc (size); | 109 | va_list ap; |
| 106 | if (result == NULL) | 110 | va_start (ap, m); |
| 107 | fatal ("virtual memory exhausted", 0); | 111 | verror (m, ap); |
| 108 | return result; | 112 | va_end (ap); |
| 113 | exit (EXIT_FAILURE); | ||
| 114 | } | ||
| 115 | |||
| 116 | static _Noreturn void | ||
| 117 | memory_exhausted (void) | ||
| 118 | { | ||
| 119 | fatal ("virtual memory exhausted"); | ||
| 109 | } | 120 | } |
| 110 | 121 | ||
| 111 | /* Like strdup, but get fatal error if memory is exhausted. */ | 122 | /* Like malloc but get fatal error if memory is exhausted. */ |
| 112 | 123 | ||
| 113 | static char * | 124 | static void * |
| 114 | xstrdup (char *s) | 125 | xmalloc (ptrdiff_t size) |
| 115 | { | 126 | { |
| 116 | char *result = strdup (s); | 127 | void *result = malloc (size); |
| 117 | if (! result) | 128 | if (result == NULL) |
| 118 | fatal ("virtual memory exhausted", 0); | 129 | memory_exhausted (); |
| 119 | return result; | 130 | return result; |
| 120 | } | 131 | } |
| 121 | 132 | ||
| 122 | /* Like realloc but get fatal error if memory is exhausted. */ | 133 | /* Like realloc but get fatal error if memory is exhausted. */ |
| 123 | 134 | ||
| 124 | static void * | 135 | static void * |
| 125 | xrealloc (void *arg, unsigned int size) | 136 | xrealloc (void *arg, ptrdiff_t size) |
| 126 | { | 137 | { |
| 127 | void *result = (void *) realloc (arg, size); | 138 | void *result = realloc (arg, size); |
| 128 | if (result == NULL) | 139 | if (result == NULL) |
| 129 | fatal ("virtual memory exhausted", 0); | 140 | memory_exhausted (); |
| 130 | return result; | 141 | return result; |
| 131 | } | 142 | } |
| 132 | 143 | ||
| @@ -135,7 +146,6 @@ int | |||
| 135 | main (int argc, char **argv) | 146 | main (int argc, char **argv) |
| 136 | { | 147 | { |
| 137 | int i; | 148 | int i; |
| 138 | int err_count = 0; | ||
| 139 | 149 | ||
| 140 | progname = argv[0]; | 150 | progname = argv[0]; |
| 141 | 151 | ||
| @@ -170,7 +180,7 @@ main (int argc, char **argv) | |||
| 170 | } | 180 | } |
| 171 | if (argc > i && !strcmp (argv[i], "-g")) | 181 | if (argc > i && !strcmp (argv[i], "-g")) |
| 172 | { | 182 | { |
| 173 | generate_globals = 1; | 183 | generate_globals = true; |
| 174 | ++i; | 184 | ++i; |
| 175 | } | 185 | } |
| 176 | 186 | ||
| @@ -192,14 +202,17 @@ main (int argc, char **argv) | |||
| 192 | if (strcmp (argv[i], argv[j]) == 0) | 202 | if (strcmp (argv[i], argv[j]) == 0) |
| 193 | break; | 203 | break; |
| 194 | if (j == i) | 204 | if (j == i) |
| 195 | err_count += scan_file (argv[i]); | 205 | scan_file (argv[i]); |
| 196 | } | 206 | } |
| 197 | } | 207 | } |
| 198 | 208 | ||
| 199 | if (err_count == 0 && generate_globals) | 209 | if (generate_globals) |
| 200 | write_globals (); | 210 | write_globals (); |
| 201 | 211 | ||
| 202 | return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS); | 212 | if (ferror (stdout) || fclose (stdout) != 0) |
| 213 | fatal ("write error"); | ||
| 214 | |||
| 215 | return EXIT_SUCCESS; | ||
| 203 | } | 216 | } |
| 204 | 217 | ||
| 205 | /* Add a source file name boundary marker in the output file. */ | 218 | /* Add a source file name boundary marker in the output file. */ |
| @@ -218,22 +231,21 @@ put_filename (char *filename) | |||
| 218 | } | 231 | } |
| 219 | 232 | ||
| 220 | /* Read file FILENAME and output its doc strings to stdout. | 233 | /* Read file FILENAME and output its doc strings to stdout. |
| 221 | Return 1 if file is not found, 0 if it is found. */ | 234 | Return true if file is found, false otherwise. */ |
| 222 | 235 | ||
| 223 | static int | 236 | static void |
| 224 | scan_file (char *filename) | 237 | scan_file (char *filename) |
| 225 | { | 238 | { |
| 226 | 239 | ptrdiff_t len = strlen (filename); | |
| 227 | size_t len = strlen (filename); | ||
| 228 | 240 | ||
| 229 | if (!generate_globals) | 241 | if (!generate_globals) |
| 230 | put_filename (filename); | 242 | put_filename (filename); |
| 231 | if (len > 4 && !strcmp (filename + len - 4, ".elc")) | 243 | if (len > 4 && !strcmp (filename + len - 4, ".elc")) |
| 232 | return scan_lisp_file (filename, "rb"); | 244 | scan_lisp_file (filename, "rb"); |
| 233 | else if (len > 3 && !strcmp (filename + len - 3, ".el")) | 245 | else if (len > 3 && !strcmp (filename + len - 3, ".el")) |
| 234 | return scan_lisp_file (filename, "r"); | 246 | scan_lisp_file (filename, "r"); |
| 235 | else | 247 | else |
| 236 | return scan_c_file (filename, "r"); | 248 | scan_c_file (filename, "r"); |
| 237 | } | 249 | } |
| 238 | 250 | ||
| 239 | static void | 251 | static void |
| @@ -250,7 +262,7 @@ static char input_buffer[128]; | |||
| 250 | struct rcsoc_state | 262 | struct rcsoc_state |
| 251 | { | 263 | { |
| 252 | /* A count of spaces and newlines that have been read, but not output. */ | 264 | /* A count of spaces and newlines that have been read, but not output. */ |
| 253 | unsigned pending_spaces, pending_newlines; | 265 | intmax_t pending_spaces, pending_newlines; |
| 254 | 266 | ||
| 255 | /* Where we're reading from. */ | 267 | /* Where we're reading from. */ |
| 256 | FILE *in_file; | 268 | FILE *in_file; |
| @@ -267,16 +279,16 @@ struct rcsoc_state | |||
| 267 | the input stream. */ | 279 | the input stream. */ |
| 268 | const char *cur_keyword_ptr; | 280 | const char *cur_keyword_ptr; |
| 269 | /* Set to true if we saw an occurrence of KEYWORD. */ | 281 | /* Set to true if we saw an occurrence of KEYWORD. */ |
| 270 | int saw_keyword; | 282 | bool saw_keyword; |
| 271 | }; | 283 | }; |
| 272 | 284 | ||
| 273 | /* Output CH to the file or buffer in STATE. Any pending newlines or | 285 | /* Output CH to the file or buffer in STATE. Any pending newlines or |
| 274 | spaces are output first. */ | 286 | spaces are output first. */ |
| 275 | 287 | ||
| 276 | static void | 288 | static void |
| 277 | put_char (int ch, struct rcsoc_state *state) | 289 | put_char (char ch, struct rcsoc_state *state) |
| 278 | { | 290 | { |
| 279 | int out_ch; | 291 | char out_ch; |
| 280 | do | 292 | do |
| 281 | { | 293 | { |
| 282 | if (state->pending_newlines > 0) | 294 | if (state->pending_newlines > 0) |
| @@ -307,7 +319,7 @@ put_char (int ch, struct rcsoc_state *state) | |||
| 307 | keyword, but were in fact not. */ | 319 | keyword, but were in fact not. */ |
| 308 | 320 | ||
| 309 | static void | 321 | static void |
| 310 | scan_keyword_or_put_char (int ch, struct rcsoc_state *state) | 322 | scan_keyword_or_put_char (char ch, struct rcsoc_state *state) |
| 311 | { | 323 | { |
| 312 | if (state->keyword | 324 | if (state->keyword |
| 313 | && *state->cur_keyword_ptr == ch | 325 | && *state->cur_keyword_ptr == ch |
| @@ -319,7 +331,7 @@ scan_keyword_or_put_char (int ch, struct rcsoc_state *state) | |||
| 319 | if (*++state->cur_keyword_ptr == '\0') | 331 | if (*++state->cur_keyword_ptr == '\0') |
| 320 | /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */ | 332 | /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */ |
| 321 | { | 333 | { |
| 322 | state->saw_keyword = 1; | 334 | state->saw_keyword = true; |
| 323 | 335 | ||
| 324 | /* Reset the scanning pointer. */ | 336 | /* Reset the scanning pointer. */ |
| 325 | state->cur_keyword_ptr = state->keyword; | 337 | state->cur_keyword_ptr = state->keyword; |
| @@ -330,22 +342,29 @@ scan_keyword_or_put_char (int ch, struct rcsoc_state *state) | |||
| 330 | 342 | ||
| 331 | /* Skip any whitespace between the keyword and the | 343 | /* Skip any whitespace between the keyword and the |
| 332 | usage string. */ | 344 | usage string. */ |
| 345 | int c; | ||
| 333 | do | 346 | do |
| 334 | ch = getc (state->in_file); | 347 | c = getc (state->in_file); |
| 335 | while (ch == ' ' || ch == '\n'); | 348 | while (c == ' ' || c == '\n'); |
| 336 | 349 | ||
| 337 | /* Output the open-paren we just read. */ | 350 | /* Output the open-paren we just read. */ |
| 338 | put_char (ch, state); | 351 | if (c != '(') |
| 352 | fatal ("Missing '(' after keyword"); | ||
| 353 | put_char (c, state); | ||
| 339 | 354 | ||
| 340 | /* Skip the function name and replace it with `fn'. */ | 355 | /* Skip the function name and replace it with `fn'. */ |
| 341 | do | 356 | do |
| 342 | ch = getc (state->in_file); | 357 | { |
| 343 | while (ch != ' ' && ch != ')'); | 358 | c = getc (state->in_file); |
| 359 | if (c == EOF) | ||
| 360 | fatal ("Unexpected EOF after keyword"); | ||
| 361 | } | ||
| 362 | while (c != ' ' && c != ')'); | ||
| 344 | put_char ('f', state); | 363 | put_char ('f', state); |
| 345 | put_char ('n', state); | 364 | put_char ('n', state); |
| 346 | 365 | ||
| 347 | /* Put back the last character. */ | 366 | /* Put back the last character. */ |
| 348 | ungetc (ch, state->in_file); | 367 | ungetc (c, state->in_file); |
| 349 | } | 368 | } |
| 350 | } | 369 | } |
| 351 | else | 370 | else |
| @@ -369,18 +388,19 @@ scan_keyword_or_put_char (int ch, struct rcsoc_state *state) | |||
| 369 | 388 | ||
| 370 | 389 | ||
| 371 | /* Skip a C string or C-style comment from INFILE, and return the | 390 | /* Skip a C string or C-style comment from INFILE, and return the |
| 372 | character that follows. COMMENT non-zero means skip a comment. If | 391 | byte that follows, or EOF. COMMENT means skip a comment. If |
| 373 | PRINTFLAG is positive, output string contents to stdout. If it is | 392 | PRINTFLAG is positive, output string contents to stdout. If it is |
| 374 | negative, store contents in buf. Convert escape sequences \n and | 393 | negative, store contents in buf. Convert escape sequences \n and |
| 375 | \t to newline and tab; discard \ followed by newline. | 394 | \t to newline and tab; discard \ followed by newline. |
| 376 | If SAW_USAGE is non-zero, then any occurrences of the string `usage:' | 395 | If SAW_USAGE is non-null, then any occurrences of the string "usage:" |
| 377 | at the beginning of a line will be removed, and *SAW_USAGE set to | 396 | at the beginning of a line will be removed, and *SAW_USAGE set to |
| 378 | true if any were encountered. */ | 397 | true if any were encountered. */ |
| 379 | 398 | ||
| 380 | static int | 399 | static int |
| 381 | read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usage) | 400 | read_c_string_or_comment (FILE *infile, int printflag, bool comment, |
| 401 | bool *saw_usage) | ||
| 382 | { | 402 | { |
| 383 | register int c; | 403 | int c; |
| 384 | struct rcsoc_state state; | 404 | struct rcsoc_state state; |
| 385 | 405 | ||
| 386 | state.in_file = infile; | 406 | state.in_file = infile; |
| @@ -390,7 +410,7 @@ read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usa | |||
| 390 | state.pending_newlines = 0; | 410 | state.pending_newlines = 0; |
| 391 | state.keyword = (saw_usage ? "usage:" : 0); | 411 | state.keyword = (saw_usage ? "usage:" : 0); |
| 392 | state.cur_keyword_ptr = state.keyword; | 412 | state.cur_keyword_ptr = state.keyword; |
| 393 | state.saw_keyword = 0; | 413 | state.saw_keyword = false; |
| 394 | 414 | ||
| 395 | c = getc (infile); | 415 | c = getc (infile); |
| 396 | if (comment) | 416 | if (comment) |
| @@ -468,10 +488,10 @@ read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usa | |||
| 468 | static void | 488 | static void |
| 469 | write_c_args (char *func, char *buf, int minargs, int maxargs) | 489 | write_c_args (char *func, char *buf, int minargs, int maxargs) |
| 470 | { | 490 | { |
| 471 | register char *p; | 491 | char *p; |
| 472 | int in_ident = 0; | 492 | bool in_ident = false; |
| 473 | char *ident_start IF_LINT (= NULL); | 493 | char *ident_start IF_LINT (= NULL); |
| 474 | size_t ident_length = 0; | 494 | ptrdiff_t ident_length = 0; |
| 475 | 495 | ||
| 476 | fputs ("(fn", stdout); | 496 | fputs ("(fn", stdout); |
| 477 | 497 | ||
| @@ -491,12 +511,12 @@ write_c_args (char *func, char *buf, int minargs, int maxargs) | |||
| 491 | { | 511 | { |
| 492 | if (!in_ident) | 512 | if (!in_ident) |
| 493 | { | 513 | { |
| 494 | in_ident = 1; | 514 | in_ident = true; |
| 495 | ident_start = p; | 515 | ident_start = p; |
| 496 | } | 516 | } |
| 497 | else | 517 | else |
| 498 | { | 518 | { |
| 499 | in_ident = 0; | 519 | in_ident = false; |
| 500 | ident_length = p - ident_start; | 520 | ident_length = p - ident_start; |
| 501 | } | 521 | } |
| 502 | } | 522 | } |
| @@ -575,34 +595,38 @@ enum { DEFUN_noreturn = 1, DEFUN_const = 2 }; | |||
| 575 | 595 | ||
| 576 | /* All the variable names we saw while scanning C sources in `-g' | 596 | /* All the variable names we saw while scanning C sources in `-g' |
| 577 | mode. */ | 597 | mode. */ |
| 578 | int num_globals; | 598 | static ptrdiff_t num_globals; |
| 579 | int num_globals_allocated; | 599 | static ptrdiff_t num_globals_allocated; |
| 580 | struct global *globals; | 600 | static struct global *globals; |
| 581 | 601 | ||
| 582 | static struct global * | 602 | static struct global * |
| 583 | add_global (enum global_type type, char *name, int value, char const *svalue) | 603 | add_global (enum global_type type, char const *name, int value, |
| 604 | char const *svalue) | ||
| 584 | { | 605 | { |
| 585 | /* Ignore the one non-symbol that can occur. */ | 606 | /* Ignore the one non-symbol that can occur. */ |
| 586 | if (strcmp (name, "...")) | 607 | if (strcmp (name, "...")) |
| 587 | { | 608 | { |
| 588 | ++num_globals; | 609 | if (num_globals == num_globals_allocated) |
| 589 | |||
| 590 | if (num_globals_allocated == 0) | ||
| 591 | { | 610 | { |
| 592 | num_globals_allocated = 100; | 611 | ptrdiff_t num_globals_max = (min (PTRDIFF_MAX, SIZE_MAX) |
| 593 | globals = xmalloc (num_globals_allocated * sizeof (struct global)); | 612 | / sizeof *globals); |
| 594 | } | 613 | if (num_globals_allocated == num_globals_max) |
| 595 | else if (num_globals == num_globals_allocated) | 614 | memory_exhausted (); |
| 596 | { | 615 | if (num_globals_allocated < num_globals_max / 2) |
| 597 | num_globals_allocated *= 2; | 616 | num_globals_allocated = 2 * num_globals_allocated + 1; |
| 598 | globals = xrealloc (globals, | 617 | else |
| 599 | num_globals_allocated * sizeof (struct global)); | 618 | num_globals_allocated = num_globals_max; |
| 619 | globals = xrealloc (globals, num_globals_allocated * sizeof *globals); | ||
| 600 | } | 620 | } |
| 601 | 621 | ||
| 622 | ++num_globals; | ||
| 623 | |||
| 624 | ptrdiff_t namesize = strlen (name) + 1; | ||
| 625 | char *buf = xmalloc (namesize + (svalue ? strlen (svalue) + 1 : 0)); | ||
| 602 | globals[num_globals - 1].type = type; | 626 | globals[num_globals - 1].type = type; |
| 603 | globals[num_globals - 1].name = name; | 627 | globals[num_globals - 1].name = strcpy (buf, name); |
| 604 | if (svalue) | 628 | if (svalue) |
| 605 | globals[num_globals - 1].v.svalue = svalue; | 629 | globals[num_globals - 1].v.svalue = strcpy (buf + namesize, svalue); |
| 606 | else | 630 | else |
| 607 | globals[num_globals - 1].v.value = value; | 631 | globals[num_globals - 1].v.value = value; |
| 608 | globals[num_globals - 1].flags = 0; | 632 | globals[num_globals - 1].flags = 0; |
| @@ -634,7 +658,7 @@ compare_globals (const void *a, const void *b) | |||
| 634 | } | 658 | } |
| 635 | 659 | ||
| 636 | static void | 660 | static void |
| 637 | close_emacs_globals (int num_symbols) | 661 | close_emacs_globals (ptrdiff_t num_symbols) |
| 638 | { | 662 | { |
| 639 | printf (("};\n" | 663 | printf (("};\n" |
| 640 | "extern struct emacs_globals globals;\n" | 664 | "extern struct emacs_globals globals;\n" |
| @@ -642,17 +666,17 @@ close_emacs_globals (int num_symbols) | |||
| 642 | "#ifndef DEFINE_SYMBOLS\n" | 666 | "#ifndef DEFINE_SYMBOLS\n" |
| 643 | "extern\n" | 667 | "extern\n" |
| 644 | "#endif\n" | 668 | "#endif\n" |
| 645 | "struct Lisp_Symbol alignas (GCALIGNMENT) lispsym[%d];\n"), | 669 | "struct Lisp_Symbol alignas (GCALIGNMENT) lispsym[%td];\n"), |
| 646 | num_symbols); | 670 | num_symbols); |
| 647 | } | 671 | } |
| 648 | 672 | ||
| 649 | static void | 673 | static void |
| 650 | write_globals (void) | 674 | write_globals (void) |
| 651 | { | 675 | { |
| 652 | int i, j; | 676 | ptrdiff_t i, j; |
| 653 | bool seen_defun = false; | 677 | bool seen_defun = false; |
| 654 | int symnum = 0; | 678 | ptrdiff_t symnum = 0; |
| 655 | int num_symbols = 0; | 679 | ptrdiff_t num_symbols = 0; |
| 656 | qsort (globals, num_globals, sizeof (struct global), compare_globals); | 680 | qsort (globals, num_globals, sizeof (struct global), compare_globals); |
| 657 | 681 | ||
| 658 | j = 0; | 682 | j = 0; |
| @@ -665,6 +689,7 @@ write_globals (void) | |||
| 665 | && globals[i].v.value != globals[i + 1].v.value) | 689 | && globals[i].v.value != globals[i + 1].v.value) |
| 666 | error ("function '%s' defined twice with differing signatures", | 690 | error ("function '%s' defined twice with differing signatures", |
| 667 | globals[i].name); | 691 | globals[i].name); |
| 692 | free (globals[i].name); | ||
| 668 | i++; | 693 | i++; |
| 669 | } | 694 | } |
| 670 | num_symbols += globals[i].type == SYMBOL; | 695 | num_symbols += globals[i].type == SYMBOL; |
| @@ -697,7 +722,7 @@ write_globals (void) | |||
| 697 | } | 722 | } |
| 698 | break; | 723 | break; |
| 699 | default: | 724 | default: |
| 700 | fatal ("not a recognized DEFVAR_", 0); | 725 | fatal ("not a recognized DEFVAR_"); |
| 701 | } | 726 | } |
| 702 | 727 | ||
| 703 | if (type) | 728 | if (type) |
| @@ -707,7 +732,7 @@ write_globals (void) | |||
| 707 | globals[i].name, globals[i].name); | 732 | globals[i].name, globals[i].name); |
| 708 | } | 733 | } |
| 709 | else if (globals[i].type == SYMBOL) | 734 | else if (globals[i].type == SYMBOL) |
| 710 | printf (("#define i%s %d\n" | 735 | printf (("#define i%s %td\n" |
| 711 | "DEFINE_LISP_SYMBOL (%s)\n"), | 736 | "DEFINE_LISP_SYMBOL (%s)\n"), |
| 712 | globals[i].name, symnum++, globals[i].name); | 737 | globals[i].name, symnum++, globals[i].name); |
| 713 | else | 738 | else |
| @@ -736,7 +761,7 @@ write_globals (void) | |||
| 736 | 761 | ||
| 737 | puts ("#ifdef DEFINE_SYMBOLS"); | 762 | puts ("#ifdef DEFINE_SYMBOLS"); |
| 738 | puts ("static char const *const defsym_name[] = {"); | 763 | puts ("static char const *const defsym_name[] = {"); |
| 739 | for (int i = 0; i < num_globals; i++) | 764 | for (ptrdiff_t i = 0; i < num_globals; i++) |
| 740 | if (globals[i].type == SYMBOL) | 765 | if (globals[i].type == SYMBOL) |
| 741 | printf ("\t\"%s\",\n", globals[i].v.svalue); | 766 | printf ("\t\"%s\",\n", globals[i].v.svalue); |
| 742 | puts ("};"); | 767 | puts ("};"); |
| @@ -745,9 +770,9 @@ write_globals (void) | |||
| 745 | puts ("#define Qnil builtin_lisp_symbol (0)"); | 770 | puts ("#define Qnil builtin_lisp_symbol (0)"); |
| 746 | puts ("#if DEFINE_NON_NIL_Q_SYMBOL_MACROS"); | 771 | puts ("#if DEFINE_NON_NIL_Q_SYMBOL_MACROS"); |
| 747 | num_symbols = 0; | 772 | num_symbols = 0; |
| 748 | for (int i = 0; i < num_globals; i++) | 773 | for (ptrdiff_t i = 0; i < num_globals; i++) |
| 749 | if (globals[i].type == SYMBOL && num_symbols++ != 0) | 774 | if (globals[i].type == SYMBOL && num_symbols++ != 0) |
| 750 | printf ("# define %s builtin_lisp_symbol (%d)\n", | 775 | printf ("# define %s builtin_lisp_symbol (%td)\n", |
| 751 | globals[i].name, num_symbols - 1); | 776 | globals[i].name, num_symbols - 1); |
| 752 | puts ("#endif"); | 777 | puts ("#endif"); |
| 753 | } | 778 | } |
| @@ -758,11 +783,11 @@ write_globals (void) | |||
| 758 | Looks for DEFUN constructs such as are defined in ../src/lisp.h. | 783 | Looks for DEFUN constructs such as are defined in ../src/lisp.h. |
| 759 | Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */ | 784 | Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */ |
| 760 | 785 | ||
| 761 | static int | 786 | static void |
| 762 | scan_c_file (char *filename, const char *mode) | 787 | scan_c_file (char *filename, const char *mode) |
| 763 | { | 788 | { |
| 764 | FILE *infile; | 789 | FILE *infile; |
| 765 | int extension = filename[strlen (filename) - 1]; | 790 | char extension = filename[strlen (filename) - 1]; |
| 766 | 791 | ||
| 767 | if (extension == 'o') | 792 | if (extension == 'o') |
| 768 | filename[strlen (filename) - 1] = 'c'; | 793 | filename[strlen (filename) - 1] = 'c'; |
| @@ -778,16 +803,15 @@ scan_c_file (char *filename, const char *mode) | |||
| 778 | filename[strlen (filename) - 1] = 'c'; /* Don't confuse people. */ | 803 | filename[strlen (filename) - 1] = 'c'; /* Don't confuse people. */ |
| 779 | } | 804 | } |
| 780 | 805 | ||
| 781 | /* No error if non-ex input file. */ | ||
| 782 | if (infile == NULL) | 806 | if (infile == NULL) |
| 783 | { | 807 | { |
| 784 | perror (filename); | 808 | perror (filename); |
| 785 | return 0; | 809 | exit (EXIT_FAILURE); |
| 786 | } | 810 | } |
| 787 | 811 | ||
| 788 | /* Reset extension to be able to detect duplicate files. */ | 812 | /* Reset extension to be able to detect duplicate files. */ |
| 789 | filename[strlen (filename) - 1] = extension; | 813 | filename[strlen (filename) - 1] = extension; |
| 790 | return scan_c_stream (infile); | 814 | scan_c_stream (infile); |
| 791 | } | 815 | } |
| 792 | 816 | ||
| 793 | /* Return 1 if next input from INFILE is equal to P, -1 if EOF, | 817 | /* Return 1 if next input from INFILE is equal to P, -1 if EOF, |
| @@ -807,7 +831,7 @@ stream_match (FILE *infile, const char *p) | |||
| 807 | return 1; | 831 | return 1; |
| 808 | } | 832 | } |
| 809 | 833 | ||
| 810 | static int | 834 | static void |
| 811 | scan_c_stream (FILE *infile) | 835 | scan_c_stream (FILE *infile) |
| 812 | { | 836 | { |
| 813 | int commas, minargs, maxargs; | 837 | int commas, minargs, maxargs; |
| @@ -815,12 +839,13 @@ scan_c_stream (FILE *infile) | |||
| 815 | 839 | ||
| 816 | while (!feof (infile)) | 840 | while (!feof (infile)) |
| 817 | { | 841 | { |
| 818 | int doc_keyword = 0; | 842 | bool doc_keyword = false; |
| 819 | int defunflag = 0; | 843 | bool defunflag = false; |
| 820 | int defvarperbufferflag = 0; | 844 | bool defvarperbufferflag = false; |
| 821 | int defvarflag = 0; | 845 | bool defvarflag = false; |
| 822 | enum global_type type = INVALID; | 846 | enum global_type type = INVALID; |
| 823 | char *name IF_LINT (= 0); | 847 | static char *name; |
| 848 | static ptrdiff_t name_size; | ||
| 824 | 849 | ||
| 825 | if (c != '\n' && c != '\r') | 850 | if (c != '\n' && c != '\r') |
| 826 | { | 851 | { |
| @@ -866,7 +891,7 @@ scan_c_stream (FILE *infile) | |||
| 866 | if (c != '_') | 891 | if (c != '_') |
| 867 | continue; | 892 | continue; |
| 868 | 893 | ||
| 869 | defvarflag = 1; | 894 | defvarflag = true; |
| 870 | 895 | ||
| 871 | c = getc (infile); | 896 | c = getc (infile); |
| 872 | defvarperbufferflag = (c == 'P'); | 897 | defvarperbufferflag = (c == 'P'); |
| @@ -920,12 +945,12 @@ scan_c_stream (FILE *infile) | |||
| 920 | c = getc (infile); | 945 | c = getc (infile); |
| 921 | if (c != '"') | 946 | if (c != '"') |
| 922 | continue; | 947 | continue; |
| 923 | c = read_c_string_or_comment (infile, -1, 0, 0); | 948 | c = read_c_string_or_comment (infile, -1, false, 0); |
| 924 | } | 949 | } |
| 925 | 950 | ||
| 926 | if (generate_globals) | 951 | if (generate_globals) |
| 927 | { | 952 | { |
| 928 | int i = 0; | 953 | ptrdiff_t i = 0; |
| 929 | char const *svalue = 0; | 954 | char const *svalue = 0; |
| 930 | 955 | ||
| 931 | /* Skip "," and whitespace. */ | 956 | /* Skip "," and whitespace. */ |
| @@ -947,7 +972,16 @@ scan_c_stream (FILE *infile) | |||
| 947 | || c == '\n' || c == '\r')); | 972 | || c == '\n' || c == '\r')); |
| 948 | input_buffer[i] = '\0'; | 973 | input_buffer[i] = '\0'; |
| 949 | 974 | ||
| 950 | name = xmalloc (i + 1); | 975 | if (name_size <= i) |
| 976 | { | ||
| 977 | free (name); | ||
| 978 | name_size = i + 1; | ||
| 979 | ptrdiff_t doubled; | ||
| 980 | if (! INT_MULTIPLY_WRAPV (name_size, 2, &doubled) | ||
| 981 | && doubled <= SIZE_MAX) | ||
| 982 | name_size = doubled; | ||
| 983 | name = xmalloc (name_size); | ||
| 984 | } | ||
| 951 | memcpy (name, input_buffer, i + 1); | 985 | memcpy (name, input_buffer, i + 1); |
| 952 | 986 | ||
| 953 | if (type == SYMBOL) | 987 | if (type == SYMBOL) |
| @@ -957,8 +991,8 @@ scan_c_stream (FILE *infile) | |||
| 957 | while (c == ' ' || c == '\t' || c == '\n' || c == '\r'); | 991 | while (c == ' ' || c == '\t' || c == '\n' || c == '\r'); |
| 958 | if (c != '"') | 992 | if (c != '"') |
| 959 | continue; | 993 | continue; |
| 960 | c = read_c_string_or_comment (infile, -1, 0, 0); | 994 | c = read_c_string_or_comment (infile, -1, false, 0); |
| 961 | svalue = xstrdup (input_buffer); | 995 | svalue = input_buffer; |
| 962 | } | 996 | } |
| 963 | 997 | ||
| 964 | if (!defunflag) | 998 | if (!defunflag) |
| @@ -1024,6 +1058,8 @@ scan_c_stream (FILE *infile) | |||
| 1024 | if (generate_globals) | 1058 | if (generate_globals) |
| 1025 | { | 1059 | { |
| 1026 | struct global *g = add_global (FUNCTION, name, maxargs, 0); | 1060 | struct global *g = add_global (FUNCTION, name, maxargs, 0); |
| 1061 | if (!g) | ||
| 1062 | continue; | ||
| 1027 | 1063 | ||
| 1028 | /* The following code tries to recognize function attributes | 1064 | /* The following code tries to recognize function attributes |
| 1029 | specified after the docstring, e.g.: | 1065 | specified after the docstring, e.g.: |
| @@ -1087,7 +1123,7 @@ scan_c_stream (FILE *infile) | |||
| 1087 | c = getc (infile); | 1123 | c = getc (infile); |
| 1088 | 1124 | ||
| 1089 | if (c == '"') | 1125 | if (c == '"') |
| 1090 | c = read_c_string_or_comment (infile, 0, 0, 0); | 1126 | c = read_c_string_or_comment (infile, 0, false, 0); |
| 1091 | 1127 | ||
| 1092 | while (c != EOF && c != ',' && c != '/') | 1128 | while (c != EOF && c != ',' && c != '/') |
| 1093 | c = getc (infile); | 1129 | c = getc (infile); |
| @@ -1100,7 +1136,7 @@ scan_c_stream (FILE *infile) | |||
| 1100 | c = getc (infile); | 1136 | c = getc (infile); |
| 1101 | if (c == ':') | 1137 | if (c == ':') |
| 1102 | { | 1138 | { |
| 1103 | doc_keyword = 1; | 1139 | doc_keyword = true; |
| 1104 | c = getc (infile); | 1140 | c = getc (infile); |
| 1105 | while (c == ' ' || c == '\n' || c == '\r' || c == '\t') | 1141 | while (c == ' ' || c == '\n' || c == '\r' || c == '\t') |
| 1106 | c = getc (infile); | 1142 | c = getc (infile); |
| @@ -1113,8 +1149,8 @@ scan_c_stream (FILE *infile) | |||
| 1113 | ungetc (c, infile), | 1149 | ungetc (c, infile), |
| 1114 | c == '*'))) | 1150 | c == '*'))) |
| 1115 | { | 1151 | { |
| 1116 | int comment = c != '"'; | 1152 | bool comment = c != '"'; |
| 1117 | int saw_usage; | 1153 | bool saw_usage; |
| 1118 | 1154 | ||
| 1119 | printf ("\037%c%s\n", defvarflag ? 'V' : 'F', input_buffer); | 1155 | printf ("\037%c%s\n", defvarflag ? 'V' : 'F', input_buffer); |
| 1120 | 1156 | ||
| @@ -1168,8 +1204,8 @@ scan_c_stream (FILE *infile) | |||
| 1168 | } | 1204 | } |
| 1169 | } | 1205 | } |
| 1170 | eof: | 1206 | eof: |
| 1171 | fclose (infile); | 1207 | if (ferror (infile) || fclose (infile) != 0) |
| 1172 | return 0; | 1208 | fatal ("read error"); |
| 1173 | } | 1209 | } |
| 1174 | 1210 | ||
| 1175 | /* Read a file of Lisp code, compiled or interpreted. | 1211 | /* Read a file of Lisp code, compiled or interpreted. |
| @@ -1245,7 +1281,7 @@ read_lisp_symbol (FILE *infile, char *buffer) | |||
| 1245 | skip_white (infile); | 1281 | skip_white (infile); |
| 1246 | } | 1282 | } |
| 1247 | 1283 | ||
| 1248 | static int | 1284 | static bool |
| 1249 | search_lisp_doc_at_eol (FILE *infile) | 1285 | search_lisp_doc_at_eol (FILE *infile) |
| 1250 | { | 1286 | { |
| 1251 | int c = 0, c1 = 0, c2 = 0; | 1287 | int c = 0, c1 = 0, c2 = 0; |
| @@ -1265,20 +1301,19 @@ search_lisp_doc_at_eol (FILE *infile) | |||
| 1265 | #ifdef DEBUG | 1301 | #ifdef DEBUG |
| 1266 | fprintf (stderr, "## non-docstring found\n"); | 1302 | fprintf (stderr, "## non-docstring found\n"); |
| 1267 | #endif | 1303 | #endif |
| 1268 | if (c != EOF) | 1304 | ungetc (c, infile); |
| 1269 | ungetc (c, infile); | 1305 | return false; |
| 1270 | return 0; | ||
| 1271 | } | 1306 | } |
| 1272 | return 1; | 1307 | return true; |
| 1273 | } | 1308 | } |
| 1274 | 1309 | ||
| 1275 | #define DEF_ELISP_FILE(fn) { #fn, sizeof(#fn) - 1 } | 1310 | #define DEF_ELISP_FILE(fn) { #fn, sizeof(#fn) - 1 } |
| 1276 | 1311 | ||
| 1277 | static int | 1312 | static void |
| 1278 | scan_lisp_file (const char *filename, const char *mode) | 1313 | scan_lisp_file (const char *filename, const char *mode) |
| 1279 | { | 1314 | { |
| 1280 | FILE *infile; | 1315 | FILE *infile; |
| 1281 | register int c; | 1316 | int c; |
| 1282 | char *saved_string = 0; | 1317 | char *saved_string = 0; |
| 1283 | /* These are the only files that are loaded uncompiled, and must | 1318 | /* These are the only files that are loaded uncompiled, and must |
| 1284 | follow the conventions of the doc strings expected by this | 1319 | follow the conventions of the doc strings expected by this |
| @@ -1286,7 +1321,7 @@ scan_lisp_file (const char *filename, const char *mode) | |||
| 1286 | byte compiler when it produces the .elc files. */ | 1321 | byte compiler when it produces the .elc files. */ |
| 1287 | static struct { | 1322 | static struct { |
| 1288 | const char *fn; | 1323 | const char *fn; |
| 1289 | size_t fl; | 1324 | int fl; |
| 1290 | } const uncompiled[] = { | 1325 | } const uncompiled[] = { |
| 1291 | DEF_ELISP_FILE (loaddefs.el), | 1326 | DEF_ELISP_FILE (loaddefs.el), |
| 1292 | DEF_ELISP_FILE (loadup.el), | 1327 | DEF_ELISP_FILE (loadup.el), |
| @@ -1294,22 +1329,22 @@ scan_lisp_file (const char *filename, const char *mode) | |||
| 1294 | DEF_ELISP_FILE (cp51932.el), | 1329 | DEF_ELISP_FILE (cp51932.el), |
| 1295 | DEF_ELISP_FILE (eucjp-ms.el) | 1330 | DEF_ELISP_FILE (eucjp-ms.el) |
| 1296 | }; | 1331 | }; |
| 1297 | int i, match; | 1332 | int i; |
| 1298 | size_t flen = strlen (filename); | 1333 | int flen = strlen (filename); |
| 1299 | 1334 | ||
| 1300 | if (generate_globals) | 1335 | if (generate_globals) |
| 1301 | fatal ("scanning lisp file when -g specified", 0); | 1336 | fatal ("scanning lisp file when -g specified"); |
| 1302 | if (flen > 3 && !strcmp (filename + flen - 3, ".el")) | 1337 | if (flen > 3 && !strcmp (filename + flen - 3, ".el")) |
| 1303 | { | 1338 | { |
| 1304 | for (i = 0, match = 0; i < sizeof (uncompiled) / sizeof (uncompiled[0]); | 1339 | bool match = false; |
| 1305 | i++) | 1340 | for (i = 0; i < sizeof (uncompiled) / sizeof (uncompiled[0]); i++) |
| 1306 | { | 1341 | { |
| 1307 | if (uncompiled[i].fl <= flen | 1342 | if (uncompiled[i].fl <= flen |
| 1308 | && !strcmp (filename + flen - uncompiled[i].fl, uncompiled[i].fn) | 1343 | && !strcmp (filename + flen - uncompiled[i].fl, uncompiled[i].fn) |
| 1309 | && (flen == uncompiled[i].fl | 1344 | && (flen == uncompiled[i].fl |
| 1310 | || IS_SLASH (filename[flen - uncompiled[i].fl - 1]))) | 1345 | || IS_SLASH (filename[flen - uncompiled[i].fl - 1]))) |
| 1311 | { | 1346 | { |
| 1312 | match = 1; | 1347 | match = true; |
| 1313 | break; | 1348 | break; |
| 1314 | } | 1349 | } |
| 1315 | } | 1350 | } |
| @@ -1321,7 +1356,7 @@ scan_lisp_file (const char *filename, const char *mode) | |||
| 1321 | if (infile == NULL) | 1356 | if (infile == NULL) |
| 1322 | { | 1357 | { |
| 1323 | perror (filename); | 1358 | perror (filename); |
| 1324 | return 0; /* No error. */ | 1359 | exit (EXIT_FAILURE); |
| 1325 | } | 1360 | } |
| 1326 | 1361 | ||
| 1327 | c = '\n'; | 1362 | c = '\n'; |
| @@ -1345,22 +1380,24 @@ scan_lisp_file (const char *filename, const char *mode) | |||
| 1345 | c = getc (infile); | 1380 | c = getc (infile); |
| 1346 | if (c == '@') | 1381 | if (c == '@') |
| 1347 | { | 1382 | { |
| 1348 | size_t length = 0; | 1383 | ptrdiff_t length = 0; |
| 1349 | size_t i; | 1384 | ptrdiff_t i; |
| 1350 | 1385 | ||
| 1351 | /* Read the length. */ | 1386 | /* Read the length. */ |
| 1352 | while ((c = getc (infile), | 1387 | while ((c = getc (infile), |
| 1353 | c >= '0' && c <= '9')) | 1388 | c >= '0' && c <= '9')) |
| 1354 | { | 1389 | { |
| 1355 | length *= 10; | 1390 | if (INT_MULTIPLY_WRAPV (length, 10, &length) |
| 1356 | length += c - '0'; | 1391 | || INT_ADD_WRAPV (length, c - '0', &length) |
| 1392 | || SIZE_MAX < length) | ||
| 1393 | memory_exhausted (); | ||
| 1357 | } | 1394 | } |
| 1358 | 1395 | ||
| 1359 | if (length <= 1) | 1396 | if (length <= 1) |
| 1360 | fatal ("invalid dynamic doc string length", ""); | 1397 | fatal ("invalid dynamic doc string length"); |
| 1361 | 1398 | ||
| 1362 | if (c != ' ') | 1399 | if (c != ' ') |
| 1363 | fatal ("space not found after dynamic doc string length", ""); | 1400 | fatal ("space not found after dynamic doc string length"); |
| 1364 | 1401 | ||
| 1365 | /* The next character is a space that is counted in the length | 1402 | /* The next character is a space that is counted in the length |
| 1366 | but not part of the doc string. | 1403 | but not part of the doc string. |
| @@ -1369,7 +1406,7 @@ scan_lisp_file (const char *filename, const char *mode) | |||
| 1369 | 1406 | ||
| 1370 | /* Read in the contents. */ | 1407 | /* Read in the contents. */ |
| 1371 | free (saved_string); | 1408 | free (saved_string); |
| 1372 | saved_string = (char *) xmalloc (length); | 1409 | saved_string = xmalloc (length); |
| 1373 | for (i = 0; i < length; i++) | 1410 | for (i = 0; i < length; i++) |
| 1374 | saved_string[i] = getc (infile); | 1411 | saved_string[i] = getc (infile); |
| 1375 | /* The last character is a ^_. | 1412 | /* The last character is a ^_. |
| @@ -1568,7 +1605,7 @@ scan_lisp_file (const char *filename, const char *mode) | |||
| 1568 | buffer, filename); | 1605 | buffer, filename); |
| 1569 | continue; | 1606 | continue; |
| 1570 | } | 1607 | } |
| 1571 | read_c_string_or_comment (infile, 0, 0, 0); | 1608 | read_c_string_or_comment (infile, 0, false, 0); |
| 1572 | 1609 | ||
| 1573 | if (saved_string == 0) | 1610 | if (saved_string == 0) |
| 1574 | if (!search_lisp_doc_at_eol (infile)) | 1611 | if (!search_lisp_doc_at_eol (infile)) |
| @@ -1604,10 +1641,11 @@ scan_lisp_file (const char *filename, const char *mode) | |||
| 1604 | saved_string = 0; | 1641 | saved_string = 0; |
| 1605 | } | 1642 | } |
| 1606 | else | 1643 | else |
| 1607 | read_c_string_or_comment (infile, 1, 0, 0); | 1644 | read_c_string_or_comment (infile, 1, false, 0); |
| 1608 | } | 1645 | } |
| 1609 | fclose (infile); | 1646 | free (saved_string); |
| 1610 | return 0; | 1647 | if (ferror (infile) || fclose (infile) != 0) |
| 1648 | fatal ("%s: read error", filename); | ||
| 1611 | } | 1649 | } |
| 1612 | 1650 | ||
| 1613 | 1651 | ||