/* 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;
}
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)
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;