summaryrefslogtreecommitdiff
path: root/src/charset.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2017-07-07 18:12:16 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2017-07-07 18:54:42 -0700
commit1628305811247bd652099dad92f6498fc244d8dc (patch)
tree3cd6708a814fbf9684574704ee088edf4b659952 /src/charset.c
parentd2832063c3c5490c931da2f395b8b56116b0192b (diff)
downloademacs-1628305811247bd652099dad92f6498fc244d8dc.tar.gz
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/charset.c')
-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,
/* Read a hexadecimal number (preceded by "0x") from the file FP while
- paying attention to comment character '#'. */
+ paying attention to comment character '#'. LOOKAHEAD is the
+ lookahead byte if it is nonnegative. Store into *TERMINATOR the
+ input byte after the number, or EOF if an end-of-file or input
+ error occurred. Set *OVERFLOW if the number overflows. */
static unsigned
-read_hex (FILE *fp, bool *eof, bool *overflow)
+read_hex (FILE *fp, int lookahead, int *terminator, bool *overflow)
{
- int c;
- unsigned n;
+ int c = lookahead < 0 ? getc_unlocked (fp) : lookahead;
- while ((c = getc_unlocked (fp)) != EOF)
+ while (true)
{
if (c == '#')
- {
- while ((c = getc_unlocked (fp)) != EOF && c != '\n');
- }
+ do
+ c = getc_unlocked (fp);
+ while (0 <= c && c != '\n');
else if (c == '0')
{
- if ((c = getc_unlocked (fp)) == EOF || c == 'x')
+ c = getc_unlocked (fp);
+ if (c < 0 || c == 'x')
break;
}
- }
- if (c == EOF)
- {
- *eof = 1;
- return 0;
- }
- n = 0;
- while (true)
- {
- c = getc_unlocked (fp);
- int digit = char_hexdigit (c);
- if (digit < 0)
+ if (c < 0)
break;
- if (INT_LEFT_SHIFT_OVERFLOW (n, 4))
- *overflow = 1;
- n = (n << 4) + digit;
+ c = getc_unlocked (fp);
}
- if (c != EOF)
- ungetc (c, fp);
+
+ unsigned n = 0;
+ bool v = false;
+
+ if (0 <= c)
+ while (true)
+ {
+ c = getc_unlocked (fp);
+ int digit = char_hexdigit (c);
+ if (digit < 0)
+ break;
+ v |= INT_LEFT_SHIFT_OVERFLOW (n, 4);
+ n = (n << 4) + digit;
+ }
+
+ *terminator = c;
+ *overflow |= v;
return n;
}
@@ -499,23 +504,26 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile,
memset (entries, 0, sizeof (struct charset_map_entries));
n_entries = 0;
- while (1)
+ int ch = -1;
+ while (true)
{
- unsigned from, to, c;
- int idx;
- bool eof = 0, overflow = 0;
-
- from = read_hex (fp, &eof, &overflow);
- if (eof)
+ bool overflow = false;
+ unsigned from = read_hex (fp, ch, &ch, &overflow), to;
+ if (ch < 0)
break;
- if (getc_unlocked (fp) == '-')
- to = read_hex (fp, &eof, &overflow);
+ if (ch == '-')
+ {
+ to = read_hex (fp, -1, &ch, &overflow);
+ if (ch < 0)
+ break;
+ }
else
- to = from;
- if (eof)
- break;
- c = read_hex (fp, &eof, &overflow);
- if (eof)
+ {
+ to = from;
+ ch = -1;
+ }
+ unsigned c = read_hex (fp, ch, &ch, &overflow);
+ if (ch < 0)
break;
if (overflow)
@@ -530,7 +538,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile,
memset (entries, 0, sizeof (struct charset_map_entries));
n_entries = 0;
}
- idx = n_entries;
+ int idx = n_entries;
entries->entry[idx].from = from;
entries->entry[idx].to = to;
entries->entry[idx].c = c;