aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2017-07-07 18:12:16 -0700
committerPaul Eggert2017-07-07 18:54:42 -0700
commit1628305811247bd652099dad92f6498fc244d8dc (patch)
tree3cd6708a814fbf9684574704ee088edf4b659952 /src
parentd2832063c3c5490c931da2f395b8b56116b0192b (diff)
downloademacs-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.c90
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
412static unsigned 415static unsigned
413read_hex (FILE *fp, bool *eof, bool *overflow) 416read_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;