emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 1628305 1/2: Avoid ungetc when loading charset maps


From: Paul Eggert
Subject: [Emacs-diffs] master 1628305 1/2: Avoid ungetc when loading charset maps from files
Date: Fri, 7 Jul 2017 21:54:47 -0400 (EDT)

branch: master
commit 1628305811247bd652099dad92f6498fc244d8dc
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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.
---
 src/charset.c | 90 ++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 49 insertions(+), 41 deletions(-)

diff --git a/src/charset.c b/src/charset.c
index 9c3b8db..6ce2f90 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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]