use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / lread.c
index e1bde2e..e02a91f 100644 (file)
@@ -1046,10 +1046,9 @@ Return t if the file exists and loads successfully.  */)
   (Lisp_Object file, Lisp_Object noerror, Lisp_Object nomessage,
    Lisp_Object nosuffix, Lisp_Object must_suffix)
 {
-  FILE *stream;
+  FILE *stream = NULL;
   int fd;
-  int fd_index;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   struct gcpro gcpro1, gcpro2, gcpro3;
   Lisp_Object found, efound, hist_file_name;
   /* True means we printed the ".el is newer" message.  */
@@ -1085,8 +1084,10 @@ Return t if the file exists and loads successfully.  */)
     {
       file = internal_condition_case_1 (Fsubstitute_in_file_name, file,
                                        Qt, load_error_handler);
-      if (NILP (file))
-       return Qnil;
+      if (NILP (file)) {
+        dynwind_end ();
+        return Qnil;
+      }
     }
   else
     file = Fsubstitute_in_file_name (file);
@@ -1142,6 +1143,7 @@ Return t if the file exists and loads successfully.  */)
     {
       if (NILP (noerror))
        report_file_error ("Cannot open load file", file);
+      dynwind_end ();
       return Qnil;
     }
 
@@ -1159,8 +1161,10 @@ Return t if the file exists and loads successfully.  */)
        handler = Ffind_file_name_handler (found, Qt);
       else
        handler = Ffind_file_name_handler (found, Qload);
-      if (! NILP (handler))
-       return call5 (handler, Qload, found, noerror, nomessage, Qt);
+      if (! NILP (handler)) {
+        dynwind_end ();
+        return call5 (handler, Qload, found, noerror, nomessage, Qt);
+      }
 #ifdef DOS_NT
       /* Tramp has to deal with semi-broken packages that prepend
         drive letters to remote files.  For that reason, Tramp
@@ -1179,15 +1183,10 @@ Return t if the file exists and loads successfully.  */)
 #endif
     }
 
-  if (fd < 0)
+  if (fd >= 0)
     {
-      /* Pacify older GCC with --enable-gcc-warnings.  */
-      IF_LINT (fd_index = 0);
-    }
-  else
-    {
-      fd_index = SPECPDL_INDEX ();
-      record_unwind_protect_int (close_file_unwind, fd);
+      record_unwind_protect_ptr (close_file_ptr_unwind, &fd);
+      record_unwind_protect_ptr (fclose_ptr_unwind, &stream);
     }
 
   /* Check if we're stuck in a recursive load cycle.
@@ -1300,12 +1299,13 @@ Return t if the file exists and loads successfully.  */)
          if (fd >= 0)
            {
              emacs_close (fd);
-             clear_unwind_protect (fd_index);
+              fd = -1;
            }
          val = call4 (Vload_source_file_function, found, hist_file_name,
                       NILP (noerror) ? Qnil : Qt,
                       (NILP (nomessage) || force_load_messages) ? Qnil : Qt);
-         return unbind_to (count, val);
+         dynwind_end ();
+         return val;
        }
     }
 
@@ -1323,7 +1323,7 @@ Return t if the file exists and loads successfully.  */)
     {
 #ifdef WINDOWSNT
       emacs_close (fd);
-      clear_unwind_protect (fd_index);
+      fd = -1;
       efound = ENCODE_FILE (found);
       stream = emacs_fopen (SSDATA (efound), fmode);
 #else
@@ -1332,7 +1332,6 @@ Return t if the file exists and loads successfully.  */)
     }
   if (! stream)
     report_file_error ("Opening stdio stream", file);
-  set_unwind_protect_ptr (fd_index, fclose_unwind, stream);
 
   if (! NILP (Vpurify_flag))
     Vpreloaded_file_list = Fcons (Fpurecopy (file), Vpreloaded_file_list);
@@ -1370,7 +1369,7 @@ Return t if the file exists and loads successfully.  */)
       readevalloop (Qget_emacs_mule_file_char, stream, hist_file_name,
                    0, Qnil, Qnil, Qnil, Qnil);
     }
-  unbind_to (count, Qnil);
+  dynwind_end ();
 
   /* Run any eval-after-load forms for this file.  */
   if (!NILP (Ffboundp (Qdo_after_load_evaluation)))
@@ -1803,7 +1802,7 @@ readevalloop (Lisp_Object readcharfun,
 {
   register int c;
   register Lisp_Object val;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   struct buffer *b = 0;
   bool continue_reading_p;
@@ -1865,7 +1864,7 @@ readevalloop (Lisp_Object readcharfun,
   continue_reading_p = 1;
   while (continue_reading_p)
     {
-      ptrdiff_t count1 = SPECPDL_INDEX ();
+      dynwind_begin ();
 
       if (b != 0 && !BUFFER_LIVE_P (b))
        error ("Reading from killed buffer");
@@ -1908,7 +1907,7 @@ readevalloop (Lisp_Object readcharfun,
        }
       if (c < 0)
        {
-         unbind_to (count1, Qnil);
+         dynwind_end ();
          break;
        }
 
@@ -1949,7 +1948,7 @@ readevalloop (Lisp_Object readcharfun,
        start = Fpoint_marker ();
 
       /* Restore saved point and BEGV.  */
-      unbind_to (count1, Qnil);
+      dynwind_end ();
 
       /* Now eval what we just read.  */
       if (!NILP (macroexpand))
@@ -1974,7 +1973,7 @@ readevalloop (Lisp_Object readcharfun,
 
   UNGCPRO;
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
 }
 
 DEFUN ("eval-buffer", Feval_buffer, Seval_buffer, 0, 5, "",
@@ -1993,7 +1992,7 @@ DO-ALLOW-PRINT, if non-nil, specifies that `print' and related
 This function preserves the position of point.  */)
   (Lisp_Object buffer, Lisp_Object printflag, Lisp_Object filename, Lisp_Object unibyte, Lisp_Object do_allow_print)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   Lisp_Object tem, buf;
 
   if (NILP (buffer))
@@ -2018,7 +2017,7 @@ This function preserves the position of point.  */)
   specbind (Qlexical_binding, lisp_file_lexically_bound_p (buf) ? Qt : Qnil);
   readevalloop (buf, 0, filename,
                !NILP (printflag), unibyte, Qnil, Qnil, Qnil);
-  unbind_to (count, Qnil);
+  dynwind_end ();
 
   return Qnil;
 }
@@ -2038,7 +2037,7 @@ This function does not move point.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object printflag, Lisp_Object read_function)
 {
   /* FIXME: Do the eval-sexp-add-defvars dance!  */
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   Lisp_Object tem, cbuf;
 
   cbuf = Fcurrent_buffer ();
@@ -2055,7 +2054,8 @@ This function does not move point.  */)
                !NILP (printflag), Qnil, read_function,
                start, end);
 
-  return unbind_to (count, Qnil);
+  dynwind_end ();
+  return Qnil;
 }
 
 \f
@@ -3307,58 +3307,52 @@ substitute_object_recurse (Lisp_Object object, Lisp_Object placeholder, Lisp_Obj
 
   /* Recurse according to subtree's type.
      Every branch must return a Lisp_Object.  */
-  switch (XTYPE (subtree))
+  if (VECTORLIKEP (subtree))
     {
-    case Lisp_Vectorlike:
-      {
-       ptrdiff_t i, length = 0;
-       if (BOOL_VECTOR_P (subtree))
-         return subtree;               /* No sub-objects anyway.  */
-       else if (CHAR_TABLE_P (subtree) || SUB_CHAR_TABLE_P (subtree)
-                || COMPILEDP (subtree) || HASH_TABLE_P (subtree))
-         length = ASIZE (subtree) & PSEUDOVECTOR_SIZE_MASK;
-       else if (VECTORP (subtree))
-         length = ASIZE (subtree);
-       else
-         /* An unknown pseudovector may contain non-Lisp fields, so we
-            can't just blindly traverse all its fields.  We used to call
-            `Flength' which signaled `sequencep', so I just preserved this
-            behavior.  */
-         wrong_type_argument (Qsequencep, subtree);
-
-       for (i = 0; i < length; i++)
-         SUBSTITUTE (AREF (subtree, i),
-                     ASET (subtree, i, true_value));
-       return subtree;
-      }
-
-    case Lisp_Cons:
-      {
-       SUBSTITUTE (XCAR (subtree),
-                   XSETCAR (subtree, true_value));
-       SUBSTITUTE (XCDR (subtree),
-                   XSETCDR (subtree, true_value));
-       return subtree;
-      }
-
-    case Lisp_String:
-      {
-       /* Check for text properties in each interval.
-          substitute_in_interval contains part of the logic.  */
-
-       INTERVAL root_interval = string_intervals (subtree);
-       Lisp_Object arg = Fcons (object, placeholder);
+      ptrdiff_t i, length = 0;
+      if (BOOL_VECTOR_P (subtree))
+        return subtree;                /* No sub-objects anyway.  */
+      else if (CHAR_TABLE_P (subtree) || SUB_CHAR_TABLE_P (subtree)
+               || COMPILEDP (subtree) || HASH_TABLE_P (subtree))
+        length = ASIZE (subtree) & PSEUDOVECTOR_SIZE_MASK;
+      else if (VECTORP (subtree))
+        length = ASIZE (subtree);
+      else
+        /* An unknown pseudovector may contain non-Lisp fields, so we
+           can't just blindly traverse all its fields.  We used to call
+           `Flength' which signaled `sequencep', so I just preserved this
+           behavior.  */
+        wrong_type_argument (Qsequencep, subtree);
+
+      for (i = 0; i < length; i++)
+        SUBSTITUTE (AREF (subtree, i),
+                    ASET (subtree, i, true_value));
+      return subtree;
+    }
+  else if (CONSP (subtree))
+    {
+      SUBSTITUTE (XCAR (subtree),
+                  XSETCAR (subtree, true_value));
+      SUBSTITUTE (XCDR (subtree),
+                  XSETCDR (subtree, true_value));
+      return subtree;
+    }
+  else if (STRINGP (subtree))
+    {
+      /* Check for text properties in each interval.
+         substitute_in_interval contains part of the logic.  */
 
-       traverse_intervals_noorder (root_interval,
-                                   &substitute_in_interval, arg);
+      INTERVAL root_interval = string_intervals (subtree);
+      Lisp_Object arg = Fcons (object, placeholder);
 
-       return subtree;
-      }
+      traverse_intervals_noorder (root_interval,
+                                  &substitute_in_interval, arg);
 
-      /* Other types don't recurse any further.  */
-    default:
       return subtree;
     }
+  else
+    /* Other types don't recurse any further.  */
+    return subtree;
 }
 
 /*  Helper function for substitute_object_recurse.  */