emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r110996: Fix dependency sorting in cu


From: Chong Yidong
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r110996: Fix dependency sorting in custom-theme-set-variables.
Date: Sat, 24 Nov 2012 11:46:29 +0800
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 110996
fixes bug: http://debbugs.gnu.org/12952
committer: Chong Yidong <address@hidden>
branch nick: trunk
timestamp: Sat 2012-11-24 11:46:29 +0800
message:
  Fix dependency sorting in custom-theme-set-variables.
  
  * lisp/custom.el (custom-theme-set-variables): Use a topological sort
  for ordering by custom dependencies.
  (custom--sort-vars, custom--sort-vars-1): New functions.
modified:
  lisp/ChangeLog
  lisp/custom.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-11-24 01:57:09 +0000
+++ b/lisp/ChangeLog    2012-11-24 03:46:29 +0000
@@ -1,3 +1,9 @@
+2012-11-24  Chong Yidong  <address@hidden>
+
+       * custom.el (custom-theme-set-variables): Use a topological sort
+       for ordering by custom dependencies (Bug#12952).
+       (custom--sort-vars, custom--sort-vars-1): New functions.
+
 2012-11-24  Stefan Monnier  <address@hidden>
 
        * emacs-lisp/bytecomp.el (byte-compile-file): Setup default value for

=== modified file 'lisp/custom.el'
--- a/lisp/custom.el    2012-09-28 12:18:38 +0000
+++ b/lisp/custom.el    2012-11-24 03:46:29 +0000
@@ -948,7 +948,6 @@
 
 COMMENT is a comment string about SYMBOL."
   (custom-check-theme theme)
-
   ;; Process all the needed autoloads before anything else, so that the
   ;; subsequent code has all the info it needs (e.g. which var corresponds
   ;; to a minor mode), regardless of the ordering of the variables.
@@ -958,29 +957,7 @@
                   (memq (get symbol 'custom-autoload) '(nil noset)))
         ;; This symbol needs to be autoloaded, even just for a `set'.
         (custom-load-symbol symbol))))
-
-  ;; Move minor modes and variables with explicit requires to the end.
-  (setq args
-       (sort args
-             (lambda (a1 a2)
-               (let* ((sym1 (car a1))
-                      (sym2 (car a2))
-                      (1-then-2 (memq sym1 (get sym2 'custom-dependencies)))
-                      (2-then-1 (memq sym2 (get sym1 'custom-dependencies))))
-                 (cond ((and 1-then-2 2-then-1)
-                        (error "Circular custom dependency between `%s' and 
`%s'"
-                               sym1 sym2))
-                       (2-then-1 nil)
-                       ;; 1 is a dependency of 2, so needs to be set first.
-                       (1-then-2)
-                       ;; Put minor modes and symbols with :require last.
-                       ;; Putting minor modes last ensures that the mode
-                       ;; function will see other customized values rather
-                       ;; than default values.
-                       (t (or (nth 3 a2)
-                               (eq (get sym2 'custom-set)
-                                   'custom-set-minor-mode))))))))
-
+  (setq args (custom--sort-vars args))
   (dolist (entry args)
     (unless (listp entry)
       (error "Incompatible Custom theme spec"))
@@ -1014,6 +991,60 @@
          (and (or now (default-boundp symbol))
               (put symbol 'variable-comment comment)))))))
 
+(defvar custom--sort-vars-table)
+(defvar custom--sort-vars-result)
+
+(defun custom--sort-vars (vars)
+  "Sort VARS based on custom dependencies.
+VARS is a list whose elements have the same form as the ARGS
+arguments to `custom-theme-set-variables'.  Return the sorted
+list, in which A occurs before B if B was defined with a
+`:set-after' keyword specifying A (see `defcustom')."
+  (let ((custom--sort-vars-table (make-hash-table))
+       (dependants (make-hash-table))
+       (custom--sort-vars-result nil)
+       last)
+    ;; Construct a pair of tables keyed with the symbols of VARS.
+    (dolist (var vars)
+      (puthash (car var) (cons t var) custom--sort-vars-table)
+      (puthash (car var) var dependants))
+    ;; From the second table, remove symbols that are depended-on.
+    (dolist (var vars)
+      (dolist (dep (get (car var) 'custom-dependencies))
+       (remhash dep dependants)))
+    ;; If a variable is "stand-alone", put it last if it's a minor
+    ;; mode or has a :require flag.  This is not really necessary, but
+    ;; putting minor modes last helps ensure that the mode function
+    ;; sees other customized values rather than default values.
+    (maphash (lambda (sym var)
+              (when (and (null (get sym 'custom-dependencies))
+                         (or (nth 3 var)
+                             (eq (get sym 'custom-set)
+                                 'custom-set-minor-mode)))
+                (remhash sym dependants)
+                (push var last)))
+            dependants)
+    ;; The remaining symbols depend on others but are not
+    ;; depended-upon.  Do a depth-first topological sort.
+    (maphash #'custom--sort-vars-1 dependants)
+    (nreverse (append last custom--sort-vars-result))))
+
+(defun custom--sort-vars-1 (sym &optional _ignored)
+  (let ((elt (gethash sym custom--sort-vars-table)))
+    ;; The car of the hash table value is nil if the variable has
+    ;; already been processed, `dependant' if it is a dependant in the
+    ;; current graph descent, and t otherwise.
+    (when elt
+      (cond
+       ((eq (car elt) 'dependant)
+       (error "Circular custom dependency on `%s'" sym))
+       ((car elt)
+       (setcar elt 'dependant)
+       (dolist (dep (get sym 'custom-dependencies))
+         (custom--sort-vars-1 dep))
+       (setcar elt nil)
+       (push (cdr elt) custom--sort-vars-result))))))
+
 
 ;;; Defining themes.
 


reply via email to

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