Function: rng-normalize-choice-list

rng-normalize-choice-list is a byte-compiled function defined in rng-match.el.gz.

Signature

(rng-normalize-choice-list IPATTERNS)

Documentation

Normalize a list of choices.

Expands nested choices, removes not-allowed members, sorts by index and removes duplicates. Return a pair whose car says whether the list is nullable and whose cdr is the normalized list.

Source Code

;; Defined in /usr/src/emacs/lisp/nxml/rng-match.el.gz
(defun rng-normalize-choice-list (ipatterns)
  "Normalize a list of choices.
Expands nested choices, removes not-allowed members, sorts by index
and removes duplicates.  Return a pair whose car says whether the
list is nullable and whose cdr is the normalized list."
  (let ((sorted t)
	(nullable nil)
	(head (cons nil ipatterns)))
    (let ((tail head)
	  (final-tail nil)
	  (prev-index -100)
	  (cur ipatterns)
	  member)
      ;; the cdr of tail is always cur
      (while cur
	(setq member (car cur))
	(or nullable
	    (setq nullable (rng--ipattern-nullable member)))
	(cond ((eq (rng--ipattern-type member) 'choice)
	       (setq final-tail
		     (append (rng--ipattern-child member)
			     final-tail))
	       (setq cur (cdr cur))
	       (setq sorted nil)
	       (setcdr tail cur))
	      ((eq member rng-not-allowed-ipattern)
	       (setq cur (cdr cur))
	       (setcdr tail cur))
	      (t
	       (if (and sorted
			(let ((cur-index (rng--ipattern-index member)))
			  (if (>= prev-index cur-index)
			      (or (= prev-index cur-index) ; will remove it
				  (setq sorted nil)) ; won't remove it
			    (setq prev-index cur-index)
			    ;; won't remove it
			    nil)))
		   (progn
		     ;; remove it
		     (setq cur (cdr cur))
		     (setcdr tail cur))
		 ;; don't remove it
		 (setq tail cur)
		 (setq cur (cdr cur))))))
      (setcdr tail final-tail))
    (setq head (cdr head))
    (cons nullable
	  (if sorted
	      head
            (seq-uniq (sort head 'rng-compare-ipattern) #'eq)))))