diff options
| author | Paul Eggert | 2017-07-07 18:12:16 -0700 |
|---|---|---|
| committer | Paul Eggert | 2017-07-07 18:54:42 -0700 |
| commit | 1628305811247bd652099dad92f6498fc244d8dc (patch) | |
| tree | 3cd6708a814fbf9684574704ee088edf4b659952 /src | |
| parent | d2832063c3c5490c931da2f395b8b56116b0192b (diff) | |
| download | emacs-1628305811247bd652099dad92f6498fc244d8dc.tar.gz emacs-1628305811247bd652099dad92f6498fc244d8dc.zip | |
Avoid ungetc when loading charset maps from files
* src/charset.c (read_hex): New args LOOKAHEAD and TERMINATOR,
replacing the old EOF. All callers changed. This avoids the
need to call ungetc.
Diffstat (limited to 'src')
| -rw-r--r-- | src/charset.c | 90 |
1 files changed, 49 insertions, 41 deletions
diff --git a/src/charset.c b/src/charset.c index 9c3b8db2a53..6ce2f902c81 100644 --- a/src/charset.c +++ b/src/charset.c | |||
| @@ -407,44 +407,49 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries, | |||
| 407 | 407 | ||
| 408 | 408 | ||
| 409 | /* Read a hexadecimal number (preceded by "0x") from the file FP while | 409 | /* Read a hexadecimal number (preceded by "0x") from the file FP while |
| 410 | paying attention to comment character '#'. */ | 410 | paying attention to comment character '#'. LOOKAHEAD is the |
| 411 | lookahead byte if it is nonnegative. Store into *TERMINATOR the | ||
| 412 | input byte after the number, or EOF if an end-of-file or input | ||
| 413 | error occurred. Set *OVERFLOW if the number overflows. */ | ||
| 411 | 414 | ||
| 412 | static unsigned | 415 | static unsigned |
| 413 | read_hex (FILE *fp, bool *eof, bool *overflow) | 416 | read_hex (FILE *fp, int lookahead, int *terminator, bool *overflow) |
| 414 | { | 417 | { |
| 415 | int c; | 418 | int c = lookahead < 0 ? getc_unlocked (fp) : lookahead; |
| 416 | unsigned n; | ||
| 417 | 419 | ||
| 418 | while ((c = getc_unlocked (fp)) != EOF) | 420 | while (true) |
| 419 | { | 421 | { |
| 420 | if (c == '#') | 422 | if (c == '#') |
| 421 | { | 423 | do |
| 422 | while ((c = getc_unlocked (fp)) != EOF && c != '\n'); | 424 | c = getc_unlocked (fp); |
| 423 | } | 425 | while (0 <= c && c != '\n'); |
| 424 | else if (c == '0') | 426 | else if (c == '0') |
| 425 | { | 427 | { |
| 426 | if ((c = getc_unlocked (fp)) == EOF || c == 'x') | 428 | c = getc_unlocked (fp); |
| 429 | if (c < 0 || c == 'x') | ||
| 427 | break; | 430 | break; |
| 428 | } | 431 | } |
| 429 | } | 432 | if (c < 0) |
| 430 | if (c == EOF) | ||
| 431 | { | ||
| 432 | *eof = 1; | ||
| 433 | return 0; | ||
| 434 | } | ||
| 435 | n = 0; | ||
| 436 | while (true) | ||
| 437 | { | ||
| 438 | c = getc_unlocked (fp); | ||
| 439 | int digit = char_hexdigit (c); | ||
| 440 | if (digit < 0) | ||
| 441 | break; | 433 | break; |
| 442 | if (INT_LEFT_SHIFT_OVERFLOW (n, 4)) | 434 | c = getc_unlocked (fp); |
| 443 | *overflow = 1; | ||
| 444 | n = (n << 4) + digit; | ||
| 445 | } | 435 | } |
| 446 | if (c != EOF) | 436 | |
| 447 | ungetc (c, fp); | 437 | unsigned n = 0; |
| 438 | bool v = false; | ||
| 439 | |||
| 440 | if (0 <= c) | ||
| 441 | while (true) | ||
| 442 | { | ||
| 443 | c = getc_unlocked (fp); | ||
| 444 | int digit = char_hexdigit (c); | ||
| 445 | if (digit < 0) | ||
| 446 | break; | ||
| 447 | v |= INT_LEFT_SHIFT_OVERFLOW (n, 4); | ||
| 448 | n = (n << 4) + digit; | ||
| 449 | } | ||
| 450 | |||
| 451 | *terminator = c; | ||
| 452 | *overflow |= v; | ||
| 448 | return n; | 453 | return n; |
| 449 | } | 454 | } |
| 450 | 455 | ||
| @@ -499,23 +504,26 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, | |||
| 499 | memset (entries, 0, sizeof (struct charset_map_entries)); | 504 | memset (entries, 0, sizeof (struct charset_map_entries)); |
| 500 | 505 | ||
| 501 | n_entries = 0; | 506 | n_entries = 0; |
| 502 | while (1) | 507 | int ch = -1; |
| 508 | while (true) | ||
| 503 | { | 509 | { |
| 504 | unsigned from, to, c; | 510 | bool overflow = false; |
| 505 | int idx; | 511 | unsigned from = read_hex (fp, ch, &ch, &overflow), to; |
| 506 | bool eof = 0, overflow = 0; | 512 | if (ch < 0) |
| 507 | |||
| 508 | from = read_hex (fp, &eof, &overflow); | ||
| 509 | if (eof) | ||
| 510 | break; | 513 | break; |
| 511 | if (getc_unlocked (fp) == '-') | 514 | if (ch == '-') |
| 512 | to = read_hex (fp, &eof, &overflow); | 515 | { |
| 516 | to = read_hex (fp, -1, &ch, &overflow); | ||
| 517 | if (ch < 0) | ||
| 518 | break; | ||
| 519 | } | ||
| 513 | else | 520 | else |
| 514 | to = from; | 521 | { |
| 515 | if (eof) | 522 | to = from; |
| 516 | break; | 523 | ch = -1; |
| 517 | c = read_hex (fp, &eof, &overflow); | 524 | } |
| 518 | if (eof) | 525 | unsigned c = read_hex (fp, ch, &ch, &overflow); |
| 526 | if (ch < 0) | ||
| 519 | break; | 527 | break; |
| 520 | 528 | ||
| 521 | if (overflow) | 529 | if (overflow) |
| @@ -530,7 +538,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, | |||
| 530 | memset (entries, 0, sizeof (struct charset_map_entries)); | 538 | memset (entries, 0, sizeof (struct charset_map_entries)); |
| 531 | n_entries = 0; | 539 | n_entries = 0; |
| 532 | } | 540 | } |
| 533 | idx = n_entries; | 541 | int idx = n_entries; |
| 534 | entries->entry[idx].from = from; | 542 | entries->entry[idx].from = from; |
| 535 | entries->entry[idx].to = to; | 543 | entries->entry[idx].to = to; |
| 536 | entries->entry[idx].c = c; | 544 | entries->entry[idx].c = c; |