changeset 61914:f658c441541a

(resolve_face_name): Add arg SIGNAL_P. Calls changed. Fix cyclic alias check. If alias loop is detected, signal circular-list error if SIGNAL_P, and return Qdefault if !SIGNAL_P.
author Kim F. Storm <storm@cua.dk>
date Thu, 28 Apr 2005 13:14:06 +0000
parents caa98288a9da
children ff74381ed0cd
files src/xfaces.c
diffstat 1 files changed, 37 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/xfaces.c	Thu Apr 28 11:54:11 2005 +0000
+++ b/src/xfaces.c	Thu Apr 28 13:14:06 2005 +0000
@@ -333,6 +333,8 @@
 
 Lisp_Object Qface_alias;
 
+extern Lisp_Object Qcircular_list;
+
 /* Default stipple pattern used on monochrome displays.  This stipple
    pattern is used on monochrome displays instead of shades of gray
    for a face background color.  See `set-face-stipple' for possible
@@ -468,7 +470,7 @@
 
 static void map_tty_color P_ ((struct frame *, struct face *,
 			       enum lface_attribute_index, int *));
-static Lisp_Object resolve_face_name P_ ((Lisp_Object));
+static Lisp_Object resolve_face_name P_ ((Lisp_Object, int));
 static int may_use_scalable_font_p P_ ((const char *));
 static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object));
 static int better_font_p P_ ((int *, struct font_name *, struct font_name *,
@@ -3203,27 +3205,47 @@
 
 
 /* Resolve face name FACE_NAME.  If FACE_NAME is a string, intern it
-   to make it a symvol.  If FACE_NAME is an alias for another face,
-   return that face's name.  */
+   to make it a symbol.  If FACE_NAME is an alias for another face,
+   return that face's name.
+
+   Return default face in case of errors.  */
 
 static Lisp_Object
-resolve_face_name (face_name)
+resolve_face_name (face_name, signal_p)
      Lisp_Object face_name;
-{
-  Lisp_Object aliased;
-  int alias_loop_max = 10;
+     int signal_p;
+{
+  Lisp_Object orig_face;
+  Lisp_Object tortoise, hare;
 
   if (STRINGP (face_name))
     face_name = intern (SDATA (face_name));
 
-  while (SYMBOLP (face_name))
-    {
-      aliased = Fget (face_name, Qface_alias);
-      if (NILP (aliased))
+  if (NILP (face_name) || !SYMBOLP (face_name))
+    return face_name;
+
+  orig_face = face_name;
+  tortoise = hare = face_name;
+
+  while (1)
+    {
+      face_name = hare;
+      hare = Fget (hare, Qface_alias);
+      if (NILP (hare) || !SYMBOLP (hare))
 	break;
-      if (--alias_loop_max == 0)
+
+      face_name = hare;
+      hare = Fget (hare, Qface_alias);
+      if (NILP (hare) || !SYMBOLP (hare))
 	break;
-      face_name = aliased;
+
+      tortoise = Fget (tortoise, Qface_alias);
+      if (EQ (hare, tortoise))
+	{
+	  if (signal_p)
+	    Fsignal (Qcircular_list, Fcons (orig_face, Qnil));
+	  return Qdefault;
+	}
     }
 
   return face_name;
@@ -3247,7 +3269,7 @@
 {
   Lisp_Object lface;
 
-  face_name = resolve_face_name (face_name);
+  face_name = resolve_face_name (face_name, signal_p);
 
   if (f)
     lface = assq_no_quit (face_name, f->face_alist);
@@ -3982,7 +4004,7 @@
   CHECK_SYMBOL (face);
   CHECK_SYMBOL (attr);
 
-  face = resolve_face_name (face);
+  face = resolve_face_name (face, 1);
 
   /* If FRAME is 0, change face on all frames, and change the
      default for new frames.  */