Merge from trunk.
[bpt/emacs.git] / src / font.c
index 5aff20b..16d09af 100644 (file)
@@ -1,6 +1,6 @@
 /* font.c -- "Font" primitives.
 
 /* font.c -- "Font" primitives.
 
-Copyright (C) 2006-2011  Free Software Foundation, Inc.
+Copyright (C) 2006-2012  Free Software Foundation, Inc.
 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
   National Institute of Advanced Industrial Science and Technology (AIST)
   Registration Number H13PRO009
 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
   National Institute of Advanced Industrial Science and Technology (AIST)
   Registration Number H13PRO009
@@ -21,6 +21,7 @@ You should have received a copy of the GNU General Public License
 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
+#include <float.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <setjmp.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <setjmp.h>
@@ -161,7 +162,7 @@ static struct font_driver_list *font_driver_list;
 
 \f
 
 
 \f
 
-/* Creaters of font-related Lisp object.  */
+/* Creators of font-related Lisp object.  */
 
 static Lisp_Object
 font_make_spec (void)
 
 static Lisp_Object
 font_make_spec (void)
@@ -237,7 +238,7 @@ font_intern_prop (const char *str, ptrdiff_t len, int force_symbol)
   ptrdiff_t i;
   Lisp_Object tem;
   Lisp_Object obarray;
   ptrdiff_t i;
   Lisp_Object tem;
   Lisp_Object obarray;
-  EMACS_INT nbytes, nchars;
+  ptrdiff_t nbytes, nchars;
 
   if (len == 1 && *str == '*')
     return Qnil;
 
   if (len == 1 && *str == '*')
     return Qnil;
@@ -363,7 +364,7 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val, int noerror
   else
     {
       int i, last_n;
   else
     {
       int i, last_n;
-      int numeric = XINT (val);
+      EMACS_INT numeric = XINT (val);
 
       for (i = 0, last_n = -1; i < len; i++)
        {
 
       for (i = 0, last_n = -1; i < len; i++)
        {
@@ -517,7 +518,7 @@ font_prop_validate_style (Lisp_Object style, Lisp_Object val)
                                   : FONT_WIDTH_INDEX);
   if (INTEGERP (val))
     {
                                   : FONT_WIDTH_INDEX);
   if (INTEGERP (val))
     {
-      int n = XINT (val);
+      EMACS_INT n = XINT (val);
       if (((n >> 4) & 0xF)
          >= ASIZE (AREF (font_style_table, prop - FONT_WEIGHT_INDEX)))
        val = Qerror;
       if (((n >> 4) & 0xF)
          >= ASIZE (AREF (font_style_table, prop - FONT_WEIGHT_INDEX)))
        val = Qerror;
@@ -613,7 +614,7 @@ static const struct
   /* Function to validate PROP's value VAL, or NULL if any value is
      ok.  The value is VAL or its regularized value if VAL is valid,
      and Qerror if not.  */
   /* Function to validate PROP's value VAL, or NULL if any value is
      ok.  The value is VAL or its regularized value if VAL is valid,
      and Qerror if not.  */
-  Lisp_Object (*validater) (Lisp_Object prop, Lisp_Object val);
+  Lisp_Object (*validator) (Lisp_Object prop, Lisp_Object val);
 } font_property_table[] =
   { { &QCtype, font_prop_validate_symbol },
     { &QCfoundry, font_prop_validate_symbol },
 } font_property_table[] =
   { { &QCtype, font_prop_validate_symbol },
     { &QCfoundry, font_prop_validate_symbol },
@@ -671,7 +672,7 @@ font_prop_validate (int idx, Lisp_Object prop, Lisp_Object val)
       if (idx < 0)
        return val;
     }
       if (idx < 0)
        return val;
     }
-  validated = (font_property_table[idx].validater) (prop, val);
+  validated = (font_property_table[idx].validator) (prop, val);
   if (EQ (validated, Qerror))
     signal_error ("invalid font property", Fcons (prop, val));
   return validated;
   if (EQ (validated, Qerror))
     signal_error ("invalid font property", Fcons (prop, val));
   return validated;
@@ -801,7 +802,7 @@ font_expand_wildcards (Lisp_Object *field, int n)
   struct {
     /* Minimum possible field.  */
     int from;
   struct {
     /* Minimum possible field.  */
     int from;
-    /* Maxinum possible field.  */
+    /* Maximum possible field.  */
     int to;
     /* Bit mask of possible field.  Nth bit corresponds to Nth field.  */
     int mask;
     int to;
     /* Bit mask of possible field.  Nth bit corresponds to Nth field.  */
     int mask;
@@ -824,7 +825,7 @@ font_expand_wildcards (Lisp_Object *field, int n)
     range_mask = (range_mask << 1) | 1;
 
   /* The triplet RANGE_FROM, RANGE_TO, and RANGE_MASK is a
     range_mask = (range_mask << 1) | 1;
 
   /* The triplet RANGE_FROM, RANGE_TO, and RANGE_MASK is a
-     position-based retriction for FIELD[I].  */
+     position-based restriction for FIELD[I].  */
   for (i = 0, range_from = 0, range_to = 14 - n; i < n;
        i++, range_from++, range_to++, range_mask <<= 1)
     {
   for (i = 0, range_from = 0, range_to = 14 - n; i < n;
        i++, range_from++, range_to++, range_mask <<= 1)
     {
@@ -841,13 +842,13 @@ font_expand_wildcards (Lisp_Object *field, int n)
       else
        {
          /* The triplet FROM, TO, and MASK is a value-based
       else
        {
          /* The triplet FROM, TO, and MASK is a value-based
-            retriction for FIELD[I].  */
+            restriction for FIELD[I].  */
          int from, to;
          unsigned mask;
 
          if (INTEGERP (val))
            {
          int from, to;
          unsigned mask;
 
          if (INTEGERP (val))
            {
-             int numeric = XINT (val);
+             EMACS_INT numeric = XINT (val);
 
              if (i + 1 == n)
                from = to = XLFD_ENCODING_INDEX,
 
              if (i + 1 == n)
                from = to = XLFD_ENCODING_INDEX,
@@ -953,7 +954,7 @@ font_expand_wildcards (Lisp_Object *field, int n)
        }
     }
 
        }
     }
 
-  /* Decide all fileds from restrictions in RANGE.  */
+  /* Decide all fields from restrictions in RANGE.  */
   for (i = j = 0; i < n ; i++)
     {
       if (j < range[i].from)
   for (i = j = 0; i < n ; i++)
     {
       if (j < range[i].from)
@@ -1180,7 +1181,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
   char *p;
   const char *f[XLFD_REGISTRY_INDEX + 1];
   Lisp_Object val;
   char *p;
   const char *f[XLFD_REGISTRY_INDEX + 1];
   Lisp_Object val;
-  int i, j, len = 0;
+  int i, j, len;
 
   font_assert (FONTP (font));
 
 
   font_assert (FONTP (font));
 
@@ -1195,9 +1196,9 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
       if (NILP (val))
        {
          if (j == XLFD_REGISTRY_INDEX)
       if (NILP (val))
        {
          if (j == XLFD_REGISTRY_INDEX)
-           f[j] = "*-*", len += 4;
+           f[j] = "*-*";
          else
          else
-           f[j] = "*", len += 2;
+           f[j] = "*";
        }
       else
        {
        }
       else
        {
@@ -1207,21 +1208,15 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
              && ! strchr (SSDATA (val), '-'))
            {
              /* Change "jisx0208*" and "jisx0208" to "jisx0208*-*".  */
              && ! strchr (SSDATA (val), '-'))
            {
              /* Change "jisx0208*" and "jisx0208" to "jisx0208*-*".  */
-             if (SDATA (val)[SBYTES (val) - 1] == '*')
-               {
-                 f[j] = p = alloca (SBYTES (val) + 3);
-                 sprintf (p, "%s-*", SDATA (val));
-                 len += SBYTES (val) + 3;
-               }
-             else
-               {
-                 f[j] = p = alloca (SBYTES (val) + 4);
-                 sprintf (p, "%s*-*", SDATA (val));
-                 len += SBYTES (val) + 4;
-               }
+             ptrdiff_t alloc = SBYTES (val) + 4;
+             if (nbytes <= alloc)
+               return -1;
+             f[j] = p = alloca (alloc);
+             sprintf (p, "%s%s-*", SDATA (val),
+                      "*" + (SDATA (val)[SBYTES (val) - 1] == '*'));
            }
          else
            }
          else
-           f[j] = SSDATA (val), len += SBYTES (val) + 1;
+           f[j] = SSDATA (val);
        }
     }
 
        }
     }
 
@@ -1230,11 +1225,11 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
     {
       val = font_style_symbolic (font, i, 0);
       if (NILP (val))
     {
       val = font_style_symbolic (font, i, 0);
       if (NILP (val))
-       f[j] = "*", len += 2;
+       f[j] = "*";
       else
        {
          val = SYMBOL_NAME (val);
       else
        {
          val = SYMBOL_NAME (val);
-         f[j] = SSDATA (val), len += SBYTES (val) + 1;
+         f[j] = SSDATA (val);
        }
     }
 
        }
     }
 
@@ -1242,64 +1237,62 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
   font_assert (NUMBERP (val) || NILP (val));
   if (INTEGERP (val))
     {
   font_assert (NUMBERP (val) || NILP (val));
   if (INTEGERP (val))
     {
-      i = XINT (val);
-      if (i <= 0)
-       i = pixel_size;
-      if (i > 0)
+      EMACS_INT v = XINT (val);
+      if (v <= 0)
+       v = pixel_size;
+      if (v > 0)
        {
        {
-         f[XLFD_PIXEL_INDEX] = p = alloca (22);
-         len += sprintf (p, "%d-*", i) + 1;
+         f[XLFD_PIXEL_INDEX] = p =
+           alloca (sizeof "-*" + INT_STRLEN_BOUND (EMACS_INT));
+         sprintf (p, "%"pI"d-*", v);
        }
       else
        }
       else
-       f[XLFD_PIXEL_INDEX] = "*-*", len += 4;
+       f[XLFD_PIXEL_INDEX] = "*-*";
     }
   else if (FLOATP (val))
     {
     }
   else if (FLOATP (val))
     {
-      i = XFLOAT_DATA (val) * 10;
-      f[XLFD_PIXEL_INDEX] = p = alloca (12);
-      len += sprintf (p, "*-%d", i) + 1;
+      double v = XFLOAT_DATA (val) * 10;
+      f[XLFD_PIXEL_INDEX] = p = alloca (sizeof "*-" + 1 + DBL_MAX_10_EXP + 1);
+      sprintf (p, "*-%.0f", v);
     }
   else
     }
   else
-    f[XLFD_PIXEL_INDEX] = "*-*", len += 4;
+    f[XLFD_PIXEL_INDEX] = "*-*";
 
   if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
     {
 
   if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
     {
-      i = XINT (AREF (font, FONT_DPI_INDEX));
-      f[XLFD_RESX_INDEX] = p = alloca (22);
-      len += sprintf (p, "%d-%d", i, i) + 1;
+      EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX));
+      f[XLFD_RESX_INDEX] = p =
+       alloca (sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT));
+      sprintf (p, "%"pI"d-%"pI"d", v, v);
     }
   else
     }
   else
-    f[XLFD_RESX_INDEX] = "*-*", len += 4;
+    f[XLFD_RESX_INDEX] = "*-*";
   if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
     {
   if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
     {
-      int spacing = XINT (AREF (font, FONT_SPACING_INDEX));
+      EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX));
 
       f[XLFD_SPACING_INDEX] = (spacing <= FONT_SPACING_PROPORTIONAL ? "p"
                               : spacing <= FONT_SPACING_DUAL ? "d"
                               : spacing <= FONT_SPACING_MONO ? "m"
                               : "c");
 
       f[XLFD_SPACING_INDEX] = (spacing <= FONT_SPACING_PROPORTIONAL ? "p"
                               : spacing <= FONT_SPACING_DUAL ? "d"
                               : spacing <= FONT_SPACING_MONO ? "m"
                               : "c");
-      len += 2;
     }
   else
     }
   else
-    f[XLFD_SPACING_INDEX] = "*", len += 2;
+    f[XLFD_SPACING_INDEX] = "*";
   if (INTEGERP (AREF (font,  FONT_AVGWIDTH_INDEX)))
     {
   if (INTEGERP (AREF (font,  FONT_AVGWIDTH_INDEX)))
     {
-      f[XLFD_AVGWIDTH_INDEX] = p = alloca (22);
-      len += sprintf (p, "%"pI"d",
-                     XINT (AREF (font, FONT_AVGWIDTH_INDEX))) + 1;
+      f[XLFD_AVGWIDTH_INDEX] = p = alloca (INT_BUFSIZE_BOUND (EMACS_INT));
+      sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX)));
     }
   else
     }
   else
-    f[XLFD_AVGWIDTH_INDEX] = "*", len += 2;
-  len++;       /* for terminating '\0'.  */
-  if (len >= nbytes)
-    return -1;
-  return sprintf (name, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
+    f[XLFD_AVGWIDTH_INDEX] = "*";
+  len = snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
                  f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX],
                  f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX],
                  f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX],
                  f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX],
                  f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX],
                  f[XLFD_REGISTRY_INDEX]);
                  f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX],
                  f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX],
                  f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX],
                  f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX],
                  f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX],
                  f[XLFD_REGISTRY_INDEX]);
+  return len < nbytes ? len : -1;
 }
 
 /* Parse NAME (null terminated) and store information in FONT
 }
 
 /* Parse NAME (null terminated) and store information in FONT
@@ -1341,7 +1334,7 @@ font_parse_fcname (char *name, Lisp_Object font)
        {
          int decimal = 0, size_found = 1;
          for (q = p + 1; *q && *q != ':'; q++)
        {
          int decimal = 0, size_found = 1;
          for (q = p + 1; *q && *q != ':'; q++)
-           if (! isdigit(*q))
+           if (! isdigit (*q))
              {
                if (*q != '.' || decimal)
                  {
              {
                if (*q != '.' || decimal)
                  {
@@ -1553,23 +1546,19 @@ int
 font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
 {
   Lisp_Object family, foundry;
 font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
 {
   Lisp_Object family, foundry;
-  Lisp_Object tail, val;
+  Lisp_Object val;
   int point_size;
   int i;
   int point_size;
   int i;
-  ptrdiff_t len = 1;
   char *p;
   char *p;
+  char *lim;
   Lisp_Object styles[3];
   const char *style_names[3] = { "weight", "slant", "width" };
   Lisp_Object styles[3];
   const char *style_names[3] = { "weight", "slant", "width" };
-  char work[256];
 
   family = AREF (font, FONT_FAMILY_INDEX);
   if (! NILP (family))
     {
       if (SYMBOLP (family))
 
   family = AREF (font, FONT_FAMILY_INDEX);
   if (! NILP (family))
     {
       if (SYMBOLP (family))
-       {
-         family = SYMBOL_NAME (family);
-         len += SBYTES (family);
-       }
+       family = SYMBOL_NAME (family);
       else
        family = Qnil;
     }
       else
        family = Qnil;
     }
@@ -1580,7 +1569,6 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
       if (XINT (val) != 0)
        pixel_size = XINT (val);
       point_size = -1;
       if (XINT (val) != 0)
        pixel_size = XINT (val);
       point_size = -1;
-      len += 21;               /* for ":pixelsize=NUM" */
     }
   else
     {
     }
   else
     {
@@ -1588,80 +1576,91 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes)
        abort ();
       pixel_size = -1;
       point_size = (int) XFLOAT_DATA (val);
        abort ();
       pixel_size = -1;
       point_size = (int) XFLOAT_DATA (val);
-      len += 11;               /* for "-NUM" */
     }
 
   foundry = AREF (font, FONT_FOUNDRY_INDEX);
   if (! NILP (foundry))
     {
       if (SYMBOLP (foundry))
     }
 
   foundry = AREF (font, FONT_FOUNDRY_INDEX);
   if (! NILP (foundry))
     {
       if (SYMBOLP (foundry))
-       {
-         foundry = SYMBOL_NAME (foundry);
-         len += 9 + SBYTES (foundry); /* ":foundry=NAME" */
-       }
+       foundry = SYMBOL_NAME (foundry);
       else
        foundry = Qnil;
     }
 
   for (i = 0; i < 3; i++)
       else
        foundry = Qnil;
     }
 
   for (i = 0; i < 3; i++)
-    {
-      styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
-      if (! NILP (styles[i]))
-       len += sprintf (work, ":%s=%s", style_names[i],
-                       SDATA (SYMBOL_NAME (styles[i])));
-    }
-
-  if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
-    len += sprintf (work, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX)));
-  if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
-    len += strlen (":spacing=100");
-  if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
-    len += strlen (":scalable=false"); /* or ":scalable=true" */
-  for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
-    {
-      Lisp_Object key = XCAR (XCAR (tail)), value = XCDR (XCAR (tail));
+    styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0);
 
 
-      len += SBYTES (SYMBOL_NAME (key)) + 1; /* for :KEY= */
-      if (STRINGP (value))
-       len += SBYTES (value);
-      else if (INTEGERP (value))
-       len += sprintf (work, "%"pI"d", XINT (value));
-      else if (SYMBOLP (value))
-       len += (NILP (value) ? 5 : 4); /* for "false" or "true" */
-    }
-
-  if (len > nbytes)
-    return -1;
   p = name;
   p = name;
+  lim = name + nbytes;
   if (! NILP (family))
   if (! NILP (family))
-    p += sprintf (p, "%s", SDATA (family));
+    {
+      int len = snprintf (p, lim - p, "%s", SSDATA (family));
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
   if (point_size > 0)
     {
   if (point_size > 0)
     {
-      if (p == name)
-       p += sprintf (p, "%d", point_size);
-      else
-       p += sprintf (p, "-%d", point_size);
+      int len = snprintf (p, lim - p, "-%d" + (p == name), point_size);
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
     }
   else if (pixel_size > 0)
     }
   else if (pixel_size > 0)
-    p += sprintf (p, ":pixelsize=%d", pixel_size);
+    {
+      int len = snprintf (p, lim - p, ":pixelsize=%d", pixel_size);
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
   if (! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
   if (! NILP (AREF (font, FONT_FOUNDRY_INDEX)))
-    p += sprintf (p, ":foundry=%s",
-                 SDATA (SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX))));
+    {
+      int len = snprintf (p, lim - p, ":foundry=%s",
+                         SSDATA (SYMBOL_NAME (AREF (font,
+                                                    FONT_FOUNDRY_INDEX))));
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
   for (i = 0; i < 3; i++)
     if (! NILP (styles[i]))
   for (i = 0; i < 3; i++)
     if (! NILP (styles[i]))
-      p += sprintf (p, ":%s=%s", style_names[i],
-                   SDATA (SYMBOL_NAME (styles[i])));
+      {
+       int len = snprintf (p, lim - p, ":%s=%s", style_names[i],
+                           SSDATA (SYMBOL_NAME (styles[i])));
+       if (! (0 <= len && len < lim - p))
+         return -1;
+       p += len;
+      }
+
   if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
   if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
-    p += sprintf (p, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX)));
+    {
+      int len = snprintf (p, lim - p, ":dpi=%"pI"d",
+                         XINT (AREF (font, FONT_DPI_INDEX)));
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
+
   if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
   if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
-    p += sprintf (p, ":spacing=%"pI"d", XINT (AREF (font, FONT_SPACING_INDEX)));
+    {
+      int len = snprintf (p, lim - p, ":spacing=%"pI"d",
+                         XINT (AREF (font, FONT_SPACING_INDEX)));
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
+    }
+
   if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
     {
   if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
     {
-      if (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0)
-       p += sprintf (p, ":scalable=true");
-      else
-       p += sprintf (p, ":scalable=false");
+      int len = snprintf (p, lim - p,
+                         (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0
+                          ? ":scalable=true"
+                          : ":scalable=false"));
+      if (! (0 <= len && len < lim - p))
+       return -1;
+      p += len;
     }
     }
+
   return (p - name);
 }
 
   return (p - name);
 }
 
@@ -1738,11 +1737,11 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec
 #define LGSTRING_GLYPH_SIZE 8
 
 static int
 #define LGSTRING_GLYPH_SIZE 8
 
 static int
-check_gstring (gstring)
-     Lisp_Object gstring;
+check_gstring (Lisp_Object gstring)
 {
   Lisp_Object val;
 {
   Lisp_Object val;
-  int i, j;
+  ptrdiff_t i;
+  int j;
 
   CHECK_VECTOR (gstring);
   val = AREF (gstring, 0);
 
   CHECK_VECTOR (gstring);
   val = AREF (gstring, 0);
@@ -1793,8 +1792,7 @@ check_gstring (gstring)
 }
 
 static void
 }
 
 static void
-check_otf_features (otf_features)
-     Lisp_Object otf_features;
+check_otf_features (Lisp_Object otf_features)
 {
   Lisp_Object val;
 
 {
   Lisp_Object val;
 
@@ -1827,8 +1825,7 @@ check_otf_features (otf_features)
 Lisp_Object otf_list;
 
 static Lisp_Object
 Lisp_Object otf_list;
 
 static Lisp_Object
-otf_tag_symbol (tag)
-     OTF_Tag tag;
+otf_tag_symbol (OTF_Tag tag)
 {
   char name[5];
 
 {
   char name[5];
 
@@ -1837,8 +1834,7 @@ otf_tag_symbol (tag)
 }
 
 static OTF *
 }
 
 static OTF *
-otf_open (file)
-     Lisp_Object file;
+otf_open (Lisp_Object file)
 {
   Lisp_Object val = Fassoc (file, otf_list);
   OTF *otf;
 {
   Lisp_Object val = Fassoc (file, otf_list);
   OTF *otf;
@@ -1860,8 +1856,7 @@ otf_open (file)
    (struct font_driver).otf_capability.  */
 
 Lisp_Object
    (struct font_driver).otf_capability.  */
 
 Lisp_Object
-font_otf_capability (font)
-     struct font *font;
+font_otf_capability (struct font *font)
 {
   OTF *otf;
   Lisp_Object capability = Fcons (Qnil, Qnil);
 {
   OTF *otf;
   Lisp_Object capability = Fcons (Qnil, Qnil);
@@ -1935,9 +1930,7 @@ font_otf_capability (font)
    FEATURES.  */
 
 static void
    FEATURES.  */
 
 static void
-generate_otf_features (spec, features)
-     Lisp_Object spec;
-     char *features;
+generate_otf_features (Lisp_Object spec, char *features)
 {
   Lisp_Object val;
   char *p;
 {
   Lisp_Object val;
   char *p;
@@ -1959,12 +1952,12 @@ generate_otf_features (spec, features)
       else if (! asterisk)
        {
          val = SYMBOL_NAME (val);
       else if (! asterisk)
        {
          val = SYMBOL_NAME (val);
-         p += sprintf (p, "%s", SDATA (val));
+         p += esprintf (p, "%s", SDATA (val));
        }
       else
        {
          val = SYMBOL_NAME (val);
        }
       else
        {
          val = SYMBOL_NAME (val);
-         p += sprintf (p, "~%s", SDATA (val));
+         p += esprintf (p, "~%s", SDATA (val));
        }
     }
   if (CONSP (spec))
        }
     }
   if (CONSP (spec))
@@ -1972,8 +1965,7 @@ generate_otf_features (spec, features)
 }
 
 Lisp_Object
 }
 
 Lisp_Object
-font_otf_DeviceTable (device_table)
-     OTF_DeviceTable *device_table;
+font_otf_DeviceTable (OTF_DeviceTable *device_table)
 {
   int len = device_table->StartSize - device_table->EndSize + 1;
 
 {
   int len = device_table->StartSize - device_table->EndSize + 1;
 
@@ -1982,9 +1974,7 @@ font_otf_DeviceTable (device_table)
 }
 
 Lisp_Object
 }
 
 Lisp_Object
-font_otf_ValueRecord (value_format, value_record)
-     int value_format;
-     OTF_ValueRecord *value_record;
+font_otf_ValueRecord (int value_format, OTF_ValueRecord *value_record)
 {
   Lisp_Object val = Fmake_vector (make_number (8), Qnil);
 
 {
   Lisp_Object val = Fmake_vector (make_number (8), Qnil);
 
@@ -2008,8 +1998,7 @@ font_otf_ValueRecord (value_format, value_record)
 }
 
 Lisp_Object
 }
 
 Lisp_Object
-font_otf_Anchor (anchor)
-     OTF_Anchor *anchor;
+font_otf_Anchor (OTF_Anchor *anchor)
 {
   Lisp_Object val;
 
 {
   Lisp_Object val;
 
@@ -2445,7 +2434,7 @@ font_match_p (Lisp_Object spec, Lisp_Object font)
                  /* All characters in the list must be supported.  */
                  for (; CONSP (val2); val2 = XCDR (val2))
                    {
                  /* All characters in the list must be supported.  */
                  for (; CONSP (val2); val2 = XCDR (val2))
                    {
-                     if (! NATNUMP (XCAR (val2)))
+                     if (! CHARACTERP (XCAR (val2)))
                        continue;
                      if (font_encode_char (font, XFASTINT (XCAR (val2)))
                          == FONT_INVALID_CODE)
                        continue;
                      if (font_encode_char (font, XFASTINT (XCAR (val2)))
                          == FONT_INVALID_CODE)
@@ -2457,7 +2446,7 @@ font_match_p (Lisp_Object spec, Lisp_Object font)
                  /* At most one character in the vector must be supported.  */
                  for (i = 0; i < ASIZE (val2); i++)
                    {
                  /* At most one character in the vector must be supported.  */
                  for (i = 0; i < ASIZE (val2); i++)
                    {
-                     if (! NATNUMP (AREF (val2, i)))
+                     if (! CHARACTERP (AREF (val2, i)))
                        continue;
                      if (font_encode_char (font, XFASTINT (AREF (val2, i)))
                          != FONT_INVALID_CODE)
                        continue;
                      if (font_encode_char (font, XFASTINT (AREF (val2, i)))
                          != FONT_INVALID_CODE)
@@ -3088,6 +3077,7 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
   Lisp_Object foundry[3], *family, registry[3], adstyle[3];
   int pixel_size;
   int i, j, k, l;
   Lisp_Object foundry[3], *family, registry[3], adstyle[3];
   int pixel_size;
   int i, j, k, l;
+  USE_SAFE_ALLOCA;
 
   registry[0] = AREF (spec, FONT_REGISTRY_INDEX);
   if (NILP (registry[0]))
 
   registry[0] = AREF (spec, FONT_REGISTRY_INDEX);
   if (NILP (registry[0]))
@@ -3172,18 +3162,12 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
   else
     {
       Lisp_Object alters
   else
     {
       Lisp_Object alters
-       = Fassoc_string (val, Vface_alternative_font_family_alist,
-                         /* Font family names are case-sensitive under NS. */
-#ifndef HAVE_NS
-                        Qt
-#else
-                        Qnil
-#endif
-                        );
+       = Fassoc_string (val, Vface_alternative_font_family_alist, Qt);
 
       if (! NILP (alters))
        {
 
       if (! NILP (alters))
        {
-         family = alloca ((sizeof family[0]) * (XINT (Flength (alters)) + 2));
+         EMACS_INT alterslen = XFASTINT (Flength (alters));
+         SAFE_ALLOCA_LISP (family, alterslen + 2);
          for (i = 0; CONSP (alters); i++, alters = XCDR (alters))
            family[i] = XCAR (alters);
          if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
          for (i = 0; CONSP (alters); i++, alters = XCDR (alters))
            family[i] = XCAR (alters);
          if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
@@ -3225,6 +3209,8 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
            }
        }
     }
            }
        }
     }
+
+  SAFE_FREE ();
   return Qnil;
 }
 
   return Qnil;
 }
 
@@ -3251,7 +3237,7 @@ font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_O
          if (INTEGERP (height))
            pt = XINT (height);
          else
          if (INTEGERP (height))
            pt = XINT (height);
          else
-           abort(); /* We should never end up here.  */
+           abort (); /* We should never end up here.  */
        }
 
       pt /= 10;
        }
 
       pt /= 10;
@@ -3259,7 +3245,7 @@ font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_O
 #ifdef HAVE_NS
       if (size == 0)
         {
 #ifdef HAVE_NS
       if (size == 0)
         {
-          Lisp_Object ffsize = get_frame_param(f, Qfontsize);
+          Lisp_Object ffsize = get_frame_param (f, Qfontsize);
           size = NUMBERP (ffsize) ? POINT_TO_PIXEL (XINT (ffsize), f->resy) : 0;
         }
 #endif
           size = NUMBERP (ffsize) ? POINT_TO_PIXEL (XINT (ffsize), f->resy) : 0;
         }
 #endif
@@ -3623,7 +3609,7 @@ font_filter_properties (Lisp_Object font,
    STRING.  */
 
 static Lisp_Object
    STRING.  */
 
 static Lisp_Object
-font_at (int c, EMACS_INT pos, struct face *face, struct window *w,
+font_at (int c, ptrdiff_t pos, struct face *face, struct window *w,
         Lisp_Object string)
 {
   FRAME_PTR f;
         Lisp_Object string)
 {
   FRAME_PTR f;
@@ -3639,7 +3625,7 @@ font_at (int c, EMACS_INT pos, struct face *face, struct window *w,
        {
          if (multibyte)
            {
        {
          if (multibyte)
            {
-             EMACS_INT pos_byte = CHAR_TO_BYTE (pos);
+             ptrdiff_t pos_byte = CHAR_TO_BYTE (pos);
 
              c = FETCH_CHAR (pos_byte);
            }
 
              c = FETCH_CHAR (pos_byte);
            }
@@ -3653,7 +3639,7 @@ font_at (int c, EMACS_INT pos, struct face *face, struct window *w,
          multibyte = STRING_MULTIBYTE (string);
          if (multibyte)
            {
          multibyte = STRING_MULTIBYTE (string);
          if (multibyte)
            {
-             EMACS_INT pos_byte = string_char_to_byte (string, pos);
+             ptrdiff_t pos_byte = string_char_to_byte (string, pos);
 
              str = SDATA (string) + pos_byte;
              c = STRING_CHAR (str);
 
              str = SDATA (string) + pos_byte;
              c = STRING_CHAR (str);
@@ -3669,7 +3655,7 @@ font_at (int c, EMACS_INT pos, struct face *face, struct window *w,
   if (! face)
     {
       int face_id;
   if (! face)
     {
       int face_id;
-      EMACS_INT endptr;
+      ptrdiff_t endptr;
 
       if (STRINGP (string))
        face_id = face_at_string_position (w, string, pos, 0, -1, -1, &endptr,
 
       if (STRINGP (string))
        face_id = face_at_string_position (w, string, pos, 0, -1, -1, &endptr,
@@ -3706,9 +3692,9 @@ font_at (int c, EMACS_INT pos, struct face *face, struct window *w,
    It is assured that the current buffer (or STRING) is multibyte.  */
 
 Lisp_Object
    It is assured that the current buffer (or STRING) is multibyte.  */
 
 Lisp_Object
-font_range (EMACS_INT pos, EMACS_INT *limit, struct window *w, struct face *face, Lisp_Object string)
+font_range (ptrdiff_t pos, ptrdiff_t *limit, struct window *w, struct face *face, Lisp_Object string)
 {
 {
-  EMACS_INT pos_byte, ignore;
+  ptrdiff_t pos_byte, ignore;
   int c;
   Lisp_Object font_object = Qnil;
 
   int c;
   Lisp_Object font_object = Qnil;
 
@@ -4114,7 +4100,7 @@ how close they are to PREFER.  */)
   (Lisp_Object font_spec, Lisp_Object frame, Lisp_Object num, Lisp_Object prefer)
 {
   Lisp_Object vec, list;
   (Lisp_Object font_spec, Lisp_Object frame, Lisp_Object num, Lisp_Object prefer)
 {
   Lisp_Object vec, list;
-  int n = 0;
+  EMACS_INT n = 0;
 
   if (NILP (frame))
     frame = selected_frame;
 
   if (NILP (frame))
     frame = selected_frame;
@@ -4281,13 +4267,10 @@ void
 font_fill_lglyph_metrics (Lisp_Object glyph, Lisp_Object font_object)
 {
   struct font *font = XFONT_OBJECT (font_object);
 font_fill_lglyph_metrics (Lisp_Object glyph, Lisp_Object font_object)
 {
   struct font *font = XFONT_OBJECT (font_object);
-  unsigned code;
-  /* ecode used in LGLYPH_SET_CODE to avoid compiler warnings.  */
-  EMACS_INT ecode = font->driver->encode_char (font, LGLYPH_CHAR (glyph));
+  unsigned code = font->driver->encode_char (font, LGLYPH_CHAR (glyph));
   struct font_metrics metrics;
 
   struct font_metrics metrics;
 
-  LGLYPH_SET_CODE (glyph, ecode);
-  code = ecode;
+  LGLYPH_SET_CODE (glyph, code);
   font->driver->text_extents (font, &code, 1, &metrics);
   LGLYPH_SET_LBEARING (glyph, metrics.lbearing);
   LGLYPH_SET_RBEARING (glyph, metrics.rbearing);
   font->driver->text_extents (font, &code, 1, &metrics);
   LGLYPH_SET_LBEARING (glyph, metrics.lbearing);
   LGLYPH_SET_RBEARING (glyph, metrics.rbearing);
@@ -4309,7 +4292,7 @@ created glyph-string.  Otherwise, the value is nil.  */)
 {
   struct font *font;
   Lisp_Object font_object, n, glyph;
 {
   struct font *font;
   Lisp_Object font_object, n, glyph;
-  EMACS_INT i, j, from, to;
+  ptrdiff_t i, j, from, to;
 
   if (! composition_gstring_p (gstring))
     signal_error ("Invalid glyph-string: ", gstring);
 
   if (! composition_gstring_p (gstring))
     signal_error ("Invalid glyph-string: ", gstring);
@@ -4328,8 +4311,7 @@ created glyph-string.  Otherwise, the value is nil.  */)
       if (INTEGERP (n))
        break;
       gstring = larger_vector (gstring,
       if (INTEGERP (n))
        break;
       gstring = larger_vector (gstring,
-                              ASIZE (gstring) + LGSTRING_GLYPH_LEN (gstring),
-                              Qnil);
+                              LGSTRING_GLYPH_LEN (gstring), -1);
     }
   if (i == 3 || XINT (n) == 0)
     return Qnil;
     }
   if (i == 3 || XINT (n) == 0)
     return Qnil;
@@ -4537,7 +4519,7 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
        doc: /* Open FONT-ENTITY.  */)
   (Lisp_Object font_entity, Lisp_Object size, Lisp_Object frame)
 {
        doc: /* Open FONT-ENTITY.  */)
   (Lisp_Object font_entity, Lisp_Object size, Lisp_Object frame)
 {
-  int isize;
+  EMACS_INT isize;
 
   CHECK_FONT_ENTITY (font_entity);
   if (NILP (frame))
 
   CHECK_FONT_ENTITY (font_entity);
   if (NILP (frame))
@@ -4553,6 +4535,8 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
        isize = POINT_TO_PIXEL (XFLOAT_DATA (size), XFRAME (frame)->resy);
       else
        isize = XINT (size);
        isize = POINT_TO_PIXEL (XFLOAT_DATA (size), XFRAME (frame)->resy);
       else
        isize = XINT (size);
+      if (! (INT_MIN <= isize && isize <= INT_MAX))
+       args_out_of_range (font_entity, size);
       if (isize == 0)
        isize = 120;
     }
       if (isize == 0)
        isize = 120;
     }
@@ -4656,14 +4640,14 @@ the corresponding element is nil.  */)
    Lisp_Object object)
 {
   struct font *font;
    Lisp_Object object)
 {
   struct font *font;
-  int i, len;
+  ptrdiff_t i, len;
   Lisp_Object *chars, vec;
   USE_SAFE_ALLOCA;
 
   CHECK_FONT_GET_OBJECT (font_object, font);
   if (NILP (object))
     {
   Lisp_Object *chars, vec;
   USE_SAFE_ALLOCA;
 
   CHECK_FONT_GET_OBJECT (font_object, font);
   if (NILP (object))
     {
-      EMACS_INT charpos, bytepos;
+      ptrdiff_t charpos, bytepos;
 
       validate_region (&from, &to);
       if (EQ (from, to))
 
       validate_region (&from, &to);
       if (EQ (from, to))
@@ -4769,22 +4753,22 @@ the current buffer.  It defaults to the currently selected window.  */)
   (Lisp_Object position, Lisp_Object window, Lisp_Object string)
 {
   struct window *w;
   (Lisp_Object position, Lisp_Object window, Lisp_Object string)
 {
   struct window *w;
-  EMACS_INT pos;
+  ptrdiff_t pos;
 
   if (NILP (string))
     {
       CHECK_NUMBER_COERCE_MARKER (position);
 
   if (NILP (string))
     {
       CHECK_NUMBER_COERCE_MARKER (position);
-      pos = XINT (position);
-      if (pos < BEGV || pos >= ZV)
+      if (! (BEGV <= XINT (position) && XINT (position) < ZV))
        args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
        args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
+      pos = XINT (position);
     }
   else
     {
       CHECK_NUMBER (position);
       CHECK_STRING (string);
     }
   else
     {
       CHECK_NUMBER (position);
       CHECK_STRING (string);
-      pos = XINT (position);
-      if (pos < 0 || pos >= SCHARS (string))
+      if (! (0 < XINT (position) && XINT (position) < SCHARS (string)))
        args_out_of_range (string, position);
        args_out_of_range (string, position);
+      pos = XINT (position);
     }
   if (NILP (window))
     window = selected_window;
     }
   if (NILP (window))
     window = selected_window;
@@ -5156,7 +5140,7 @@ the corresponding glyph code.  If ENCODING is a char-table, looking up
 the table by a character gives the corresponding glyph code.
 
 REPERTORY specifies a repertory of characters supported by the font.
 the table by a character gives the corresponding glyph code.
 
 REPERTORY specifies a repertory of characters supported by the font.
-If REPERTORY is a charset, all characters beloging to the charset are
+If REPERTORY is a charset, all characters belonging to the charset are
 supported.  If REPERTORY is a char-table, all characters who have a
 non-nil value in the table are supported.  If REPERTORY is nil, Emacs
 gets the repertory information by an opened font and ENCODING.  */);
 supported.  If REPERTORY is a char-table, all characters who have a
 non-nil value in the table are supported.  If REPERTORY is nil, Emacs
 gets the repertory information by an opened font and ENCODING.  */);