]> git.eshelyaron.com Git - emacs.git/commitdiff
Avoid ungetc when loading charset maps from files
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 8 Jul 2017 01:12:16 +0000 (18:12 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 8 Jul 2017 01:54:42 +0000 (18:54 -0700)
* src/charset.c (read_hex): New args LOOKAHEAD and TERMINATOR,
replacing the old EOF.  All callers changed.  This avoids the
need to call ungetc.

src/charset.c

index 9c3b8db2a538b8340784754adaed0b78c05d7b01..6ce2f902c8169282f99605557a42489b52e0d131 100644 (file)
@@ -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;