Source

mule-base / mule-util.el

Diff from to

mule-util.el

 ;; That code is pointless in XEmacs/Mule, since our multibyte
 ;; representation doesn't leak to Lisp.
 
+;;; Following functions are defined in obsolete.el of kernel.
+
+;; ;;;###autoload
+;; (defun string-to-sequence (string type)
+;;   "Convert STRING to a sequence of TYPE which contains characters in STRING.
+;; TYPE should be `list' or `vector'."
+;;   (let ((len (length string))
+;;         (i 0)
+;;         val)
+;;     (cond ((eq type 'list)
+;;            (setq val (make-list len 0))
+;;            (let ((l val))
+;;              (while (< i len)
+;;                (setcar l (aref string i))
+;;                (setq l (cdr l) i (1+ i)))))
+;;           ((eq type 'vector)
+;;            (setq val (make-vector len 0))
+;;            (while (< i len)
+;;              (aset val i (aref string i))
+;;              (setq i (1+ i))))
+;;           (t
+;;            (error "Invalid type: %s" type)))
+;;     val))
+
 ;; string-to-sequence, string-to-list, string-to-vector, store-substring,
 ;; truncate-string-to-width
 
+;; ;;;###autoload
+;; (defsubst string-to-list (string)
+;;   "Return a list of characters in STRING."
+;;   (string-to-sequence string 'list))
+
+;; ;;;###autoload
+;; (defsubst string-to-vector (string)
+;;   "Return a vector of characters in STRING."
+;;   (string-to-sequence string 'vector))
+
+;;;###autoload
+(defun store-substring (string idx obj)
+  "Embed OBJ (string or character) at index IDX of STRING."
+  (if (characterp obj)
+      (aset string idx obj)
+    (let ((len1 (length obj))
+	  (len2 (length string))
+	  (i 0))
+      (while (< i len1)
+	(aset string (+ idx i) (aref obj i))
+	(setq i (1+ i)))))
+  string)
+
+;;;###autoload
+(defun truncate-string-to-width (str end-column &optional start-column padding)
+  "Truncate string STR to end at column END-COLUMN.
+The optional 2nd arg START-COLUMN, if non-nil, specifies
+the starting column; that means to return the characters occupying
+columns START-COLUMN ... END-COLUMN of STR.
+
+The optional 3rd arg PADDING, if non-nil, specifies a padding character
+to add at the end of the result if STR doesn't reach column END-COLUMN,
+or if END-COLUMN comes in the middle of a character in STR.
+PADDING is also added at the beginning of the result
+if column START-COLUMN appears in the middle of a character in STR.
+
+If PADDING is nil, no padding is added in these cases, so
+the resulting string may be narrower than END-COLUMN."
+  (or start-column
+      (setq start-column 0))
+  (let ((len (length str))
+	(idx 0)
+	(column 0)
+	(head-padding "") (tail-padding "")
+	ch last-column last-idx from-idx)
+    (condition-case nil
+	(while (< column start-column)
+	  (setq ch (aref str idx)
+		column (+ column (char-width ch))
+		idx (1+ idx)))
+      (args-out-of-range (setq idx len)))
+    (if (< column start-column)
+	(if padding (make-string end-column padding) "")
+      (if (and padding (> column start-column))
+	  (setq head-padding (make-string (- column start-column) padding)))
+      (setq from-idx idx)
+      (if (< end-column column)
+	  (setq idx from-idx)
+	(condition-case nil
+	    (while (< column end-column)
+	      (setq last-column column
+		    last-idx idx
+		    ch (aref str idx)
+		    column (+ column (char-width ch))
+		    idx (1+ idx)))
+	  (args-out-of-range (setq idx len)))
+	(if (> column end-column)
+	    (setq column last-column idx last-idx))
+	(if (and padding (< column end-column))
+	    (setq tail-padding (make-string (- end-column column) padding))))
+      (setq str (substring str from-idx idx))
+      (if padding
+	  (concat head-padding str tail-padding)
+	str))))
+
+;;; For backward compatibility ...
+;;;###autoload
+(defalias 'truncate-string 'truncate-string-to-width)
+(make-obsolete 'truncate-string 'truncate-string-to-width)
 
 ;;; Nested alist handler.  Nested alist is alist whose elements are
 ;;; also nested alist.
 ;; [Was defsubst]
 ;;;###autoload
 (defun nested-alist-p (obj)
-  "Return t if OBJ is a nesetd alist.
+  "Return t if OBJ is a nested alist.
 
 Nested alist is a list of the form (ENTRY . BRANCHES), where ENTRY is
 any Lisp object, and BRANCHES is a list of cons cells of the form
 ;;;###autoload
 (defun set-nested-alist (keyseq entry alist &optional len branches)
   "Set ENTRY for KEYSEQ in a nested alist ALIST.
-Optional 4th arg LEN non-nil means the firlst LEN elements in KEYSEQ
+Optional 4th arg LEN non-nil means the first LEN elements in KEYSEQ
  is considered.
 Optional argument BRANCHES if non-nil is branches for a keyseq
 longer than KEYSEQ.
 See the documentation of `nested-alist-p' for more detail."
   (or (nested-alist-p alist)
-      (error "Invalid arguement %s" alist))
+      (error "Invalid argument %s" alist))
   (let ((islist (listp keyseq))
 	(len (or len (length keyseq)))
 	(i 0)
 Optional 3rd argument NIL-FOR-TOO-LONG non-nil means return nil
  even if ALIST is not deep enough."
   (or (nested-alist-p alist)
-      (error "invalid arguement %s" alist))
+      (error "invalid argument %s" alist))
   (or len
       (setq len (length keyseq)))
   (let ((i (or start 0)))
 ;; Coding system related functions.
 
 ;;;###autoload
-(defun set-coding-system-alist (target-type regexp coding-system
-					    &optional operation)
-  "Update `coding-system-alist' according to the arguments.
-TARGET-TYPE specifies a type of the target: `file', `process', or `network'.
-  TARGET-TYPE tells which slots of coding-system-alist should be affected.
-  If `file', it affects slots for insert-file-contents and write-region.
-  If `process', it affects slots for call-process, call-process-region, and
-    start-process.
-  If `network', it affects a slot for open-network-process.
-REGEXP is a regular expression matching a target of I/O operation.
-CODING-SYSTEM is a coding system to perform code conversion
-  on the I/O operation, or a cons of coding systems for decoding and
-  encoding respectively, or a function symbol which returns the cons.
-Optional arg OPERATION if non-nil specifies directly one of slots above.
-  The valid value is: insert-file-contents, write-region,
-  call-process, call-process-region, start-process, or open-network-stream.
-If OPERATION is specified, TARGET-TYPE is ignored.
-See the documentation of `coding-system-alist' for more detail."
-  (or (stringp regexp)
-      (error "Invalid regular expression: %s" regexp))
-  (or (memq target-type '(file process network))
-      (error "Invalid target type: %s" target-type))
-  (if (symbolp coding-system)
-      (if (not (fboundp coding-system))
-	  (progn
-	    (check-coding-system coding-system)
-	    (setq coding-system (cons coding-system coding-system))))
-    (check-coding-system (car coding-system))
-    (check-coding-system (cdr coding-system)))
-  (let ((op-list (if operation (list operation)
-		   (cond ((eq target-type 'file)
-			  '(insert-file-contents write-region))
-			 ((eq target-type 'process)
-			  '(call-process call-process-region start-process))
-			 (t		; i.e. (eq target-type network)
-			  '(open-network-stream)))))
-	slot)
-    (while op-list
-      (setq slot (assq (car op-list) coding-system-alist))
-      (if slot
-	  (let ((chain (cdr slot)))
-	    (if (catch 'tag
-		  (while chain
-		    (if (string= regexp (car (car chain)))
-			(progn
-			  (setcdr (car chain) coding-system)
-			  (throw 'tag nil)))
-		    (setq chain (cdr chain)))
-		  t)
-	      (setcdr slot (cons (cons regexp coding-system) (cdr slot)))))
-	(setq coding-system-alist
-	      (cons (cons (car op-list) (list (cons regexp coding-system)))
-		    coding-system-alist)))
-      (setq op-list (cdr op-list)))))
+(define-obsolete-function-alias
+  'set-coding-system-alist 'modify-coding-system-alist)
+
+(defvar eol-mnemonic-undecided ":")
+(defvar eol-mnemonic-lf "(LF)")
+(defvar eol-mnemonic-crlf "(CRLF)")
+(defvar eol-mnemonic-cr "(CR)")
+
+;;;###autoload
+(defun coding-system-eol-type-mnemonic (coding-system)
+  "Return the string indicating end-of-line format of CODING-SYSTEM."
+  (let* ((eol-type (coding-system-eol-type coding-system))
+	 (val (symbol-value
+	       (intern (format "eol-mnemonic-%s"
+			       (or eol-type
+				   "undecided"))))))
+    (if (stringp val)
+	val
+      (char-to-string val))))
+
+;;; Following functions are defined in coding.el of kernel
+
+;; ;;;###autoload
+;; (defun coding-system-post-read-conversion (coding-system)
+;;   "Return the value of CODING-SYSTEM's post-read-conversion property."
+;;   (coding-system-get coding-system 'post-read-conversion))
+
+;; ;;;###autoload
+;; (defun coding-system-pre-write-conversion (coding-system)
+;;   "Return the value of CODING-SYSTEM's pre-write-conversion property."
+;;   (coding-system-get coding-system 'pre-write-conversion))
+
+;;; Following functions are not implemented yet.
+
+;; ;;;###autoload
+;; (defun coding-system-translation-table-for-decode (coding-system)
+;;   "Return the value of CODING-SYSTEM's translation-table-for-decode property."
+;;   (coding-system-get coding-system 'translation-table-for-decode))
+
+;; ;;;###autoload
+;; (defun coding-system-translation-table-for-encode (coding-system)
+;;   "Return the value of CODING-SYSTEM's translation-table-for-encode property."
+;;   (coding-system-get coding-system 'translation-table-for-encode))
+
+;; ;;;###autoload
+;; (defun coding-system-equal (coding-system-1 coding-system-2)
+;;   "Return t if and only if CODING-SYSTEM-1 and CODING-SYSTEM-2 are identical.
+;; Two coding systems are identical if two symbols are equal
+;; or one is an alias of the other."
+;;   (or (eq coding-system-1 coding-system-2)
+;;       (and (equal (coding-system-spec coding-system-1)
+;;                   (coding-system-spec coding-system-2))
+;;            (let ((eol-type-1 (coding-system-eol-type coding-system-1))
+;;                  (eol-type-2 (coding-system-eol-type coding-system-2)))
+;;              (or (eq eol-type-1 eol-type-2)
+;;                  (and (vectorp eol-type-1) (vectorp eol-type-2)))))))
+
+;;;###autoload
+(defsubst detect-coding-with-priority (from to priority-list)
+  "Detect a coding system of the text between FROM and TO with PRIORITY-LIST.
+PRIORITY-LIST is an alist of coding categories vs the corresponding
+coding systems ordered by priority."
+  (let* ((orig-category-list (coding-priority-list))
+	 (orig-category-systems (mapcar (function coding-category-system)
+					orig-category-list)))
+    (unwind-protect
+	(let ((prio-list priority-list)
+	      categories x)
+	  (while prio-list
+	    (setq x (car prio-list))
+	    (unless (memq (car x) categories)
+	      (set-coding-category-system (car x) (cdr x))
+	      (setq categories (cons (car x) categories)))
+	    (setq prio-list (cdr prio-list)))
+	  (set-coding-priority-list (nreverse categories))
+	  (detect-coding-region from to))
+      ;; We must restore...
+      (set-coding-priority-list orig-category-list)
+      (while orig-category-list
+	(set-coding-category-system (car orig-category-list)
+				    (car orig-category-systems))
+	(setq orig-category-list (cdr orig-category-list)
+	      orig-category-systems (cdr orig-category-systems))))))
+
+;;;###autoload
+(defun detect-coding-with-language-environment (from to lang-env)
+  "Detect a coding system of the text between FROM and TO with LANG-ENV.
+The detection takes into account the coding system priorities for the
+language environment LANG-ENV."
+  (let ((coding-priority (get-language-info lang-env 'coding-priority)))
+    (if coding-priority
+	(detect-coding-with-priority
+	 from to
+	 (mapcar (function (lambda (x)
+			     (cons (coding-system-category x) x)))
+		 coding-priority))
+      (detect-coding-region from to))))
 
 
-;;; Composite charcater manipulations.
+;;; Composite character manipulations.
 
-;;;###autoload
-(defun compose-region (start end &optional buffer)
-  "Compose characters in the current region into one composite character.
-From a Lisp program, pass two arguments, START to END.
-The composite character replaces the composed characters.
-BUFFER defaults to the current buffer if omitted."
-  (interactive "r")
-  (let ((ch (make-composite-char (buffer-substring start end buffer))))
-    (delete-region start end buffer)
-    (insert-char ch nil nil buffer)))
+;; ;;;###autoload
+;; (defun compose-region (start end &optional buffer)
+;;   "Compose characters in the current region into one composite character.
+;; From a Lisp program, pass two arguments, START to END.
+;; The composite character replaces the composed characters.
+;; BUFFER defaults to the current buffer if omitted."
+;;   (interactive "r")
+;;   (save-excursion
+;;     (let ((str (buffer-substring start end)))
+;;       (goto-char start)
+;;       (insert (compose-string str))
+;;       (delete-char (- end start)))))
 
-;;;###autoload
-(defun decompose-region (start end &optional buffer)
-  "Decompose any composite characters in the current region.
-From a Lisp program, pass two arguments, START to END.
-This converts each composite character into one or more characters,
-the individual characters out of which the composite character was formed.
-Non-composite characters are left as-is.  BUFFER defaults to the current
-buffer if omitted."
-  (interactive "r")
-  (save-excursion
-    (set-buffer buffer)
-    (save-restriction
-      (narrow-to-region start end)
-      (goto-char (point-min))
-      (let ((compcharset (get-charset 'composite)))
-	(while (< (point) (point-max))
-	  (let ((ch (char-after (point))))
-	    (if (eq compcharset (char-charset ch))
-		(progn
-		  (delete-char 1)
-		  (insert (composite-char-string ch))))))))))
+;; ;;;###autoload
+;; (defun decompose-region (start end &optional buffer)
+;;   "Decompose any composite characters in the current region.
+;; From a Lisp program, pass two arguments, START to END.
+;; This converts each composite character into one or more characters,
+;; the individual characters out of which the composite character was formed.
+;; Non-composite characters are left as-is.  BUFFER defaults to the current
+;; buffer if omitted."
+;;   (interactive "r")
+;;   (let ((buf (current-buffer))
+;;         (cmpchar-head (char-to-string leading-code-composition)))
+;;     (with-temp-buffer
+;;       (insert-buffer-substring buf start end)
+;;       (set-buffer-multibyte nil)
+;;       (goto-char (point-min))
+;;       (while (search-forward cmpchar-head nil t)
+;;         (if (looking-at "[\240-\377][\240-\377][\240-\377][\240-\377]+")
+;;             (let* ((from (1- (point)))
+;;                    (to (match-end 0))
+;;                    (str (string-as-multibyte (buffer-substring from to))))
+;;               (if (cmpcharp (string-to-char str))
+;;                   (progn
+;;                     (delete-region from to)
+;;                     (insert (string-as-unibyte (decompose-string str))))
+;;                 (goto-char to)))))
+;;       (set-buffer-multibyte t)
+;;       (let ((tempbuf (current-buffer)))
+;;         (save-excursion
+;;           (set-buffer buf)
+;;           (goto-char start)
+;;           (delete-region start end)
+;;           (insert-buffer-substring tempbuf))))))
 
-;;;###autoload
-(defconst reference-point-alist
-  '((tl . 0) (tc . 1) (tr . 2)
-    (ml . 3) (mc . 4) (mr . 5)
-    (bl . 6) (bc . 7) (br . 8)
-    (top-left . 0) (top-center . 1) (top-right . 2)
-    (mid-left . 3) (mid-center . 4) (mid-right . 5)
-    (bottom-left . 6) (bottom-center . 7) (bottom-right . 8)
-    (0 . 0) (1 . 1) (2 . 2)
-    (3 . 3) (4 . 4) (5 . 5)
-    (6 . 6) (7 . 7) (8 . 8))
-  "Alist of reference point symbols vs reference point codes.
-Meanings of reference point codes are as follows:
+;; ;;;###autoload
+;; (defun decompose-string (string)
+;;   "Decompose all composite characters in STRING."
+;;   (let ((len (length string))
+;;         (idx 0)
+;;         (i 0)
+;;         (str-list nil)
+;;         ch)
+;;     (while (< idx len)
+;;       (setq ch (aref string idx))
+;;       (if (>= ch min-composite-char)
+;;           (progn
+;;             (if (> idx i)
+;;                 (setq str-list (cons (substring string i idx) str-list)))
+;;             (setq str-list (cons (decompose-composite-char ch) str-list))
+;;             (setq i (1+ idx))))
+;;       (setq idx (1+ idx)))
+;;     (if (not str-list)
+;;         (copy-sequence string)
+;;       (if (> idx i)
+;;           (setq str-list (cons (substring string i idx) str-list)))
+;;       (apply 'concat (nreverse str-list)))))
 
-    0----1----2 <-- ascent	0:tl or top-left
-    |         |			1:tc or top-center
-    |         |			2:tr or top-right
-    |         |			3:ml or mid-left
-    |    4 <--+---- center	4:mc or mid-center
-    |         |			5:mr or mid-right
---- 3         5 <-- baseline	6:bl or bottom-left
-    |         |			7:bc or bottom-center
-    6----7----8 <-- descent	8:br or bottom-right
-
-Reference point symbols are to be used to specify composition rule of
-the form \(GLOBAL-REF-POINT . NEW-REF-POINT), where GLOBAL-REF-POINT
-is a reference point in the overall glyphs already composed, and
-NEW-REF-POINT is a reference point in the new glyph to be added.
-
-For instance, if GLOBAL-REF-POINT is 8 and NEW-REF-POINT is 1, the
-overall glyph is updated as follows:
-
-    +-------+--+ <--- new ascent
-    |       |  |
-    | global|  |
-    | glyph |  |
---- |       |  | <--- baseline (doesn't change)
-    +----+--+--+
-    |    | new |
-    |    |glyph|
-    +----+-----+ <--- new descent
-")
+;; ;;;###autoload
+;; (defconst reference-point-alist
+;;   '((tl . 0) (tc . 1) (tr . 2)
+;;     (ml . 3) (mc . 4) (mr . 5)
+;;     (bl . 6) (bc . 7) (br . 8)
+;;     (top-left . 0) (top-center . 1) (top-right . 2)
+;;     (mid-left . 3) (mid-center . 4) (mid-right . 5)
+;;     (bottom-left . 6) (bottom-center . 7) (bottom-right . 8)
+;;     (0 . 0) (1 . 1) (2 . 2)
+;;     (3 . 3) (4 . 4) (5 . 5)
+;;     (6 . 6) (7 . 7) (8 . 8))
+;;   "Alist of reference point symbols vs reference point codes.
+;; Meanings of reference point codes are as follows:
+;; 
+;;     0----1----2 <-- ascent      0:tl or top-left
+;;     |         |                 1:tc or top-center
+;;     |         |                 2:tr or top-right
+;;     |         |                 3:ml or mid-left
+;;     |    4 <--+---- center      4:mc or mid-center
+;;     |         |                 5:mr or mid-right
+;; --- 3         5 <-- baseline    6:bl or bottom-left
+;;     |         |                 7:bc or bottom-center
+;;     6----7----8 <-- descent     8:br or bottom-right
+;; 
+;; Reference point symbols are to be used to specify composition rule of
+;; the form \(GLOBAL-REF-POINT . NEW-REF-POINT), where GLOBAL-REF-POINT
+;; is a reference point in the overall glyphs already composed, and
+;; NEW-REF-POINT is a reference point in the new glyph to be added.
+;; 
+;; For instance, if GLOBAL-REF-POINT is 8 and NEW-REF-POINT is 1, the
+;; overall glyph is updated as follows:
+;; 
+;;     +-------+--+ <--- new ascent
+;;     |       |  |
+;;     | global|  |
+;;     | glyph |  |
+;; --- |       |  | <--- baseline (doesn't change)
+;;     +----+--+--+
+;;     |    | new |
+;;     |    |glyph|
+;;     +----+-----+ <--- new descent
+;; ")
 
 ;; Return a string for char CH to be embedded in multibyte form of
 ;; composite character.
-(defun compose-chars-component (ch)
-  (if (< ch 128)
-      (format "\240%c" (+ ch 128))
-    (let ((str (char-to-string ch)))
-      (if (cmpcharp ch)
-	  (if (/= (aref str 1) ?\xFF)
-	      (error "Char %c can't be composed" ch)
-	    (substring str 2))
-	(aset str 0 (+ (aref str 0) ?\x20))
-	str))))
+;; ;;;###autoload
+;; (defun compose-chars-component (ch)
+;;   (if (< ch 128)
+;;       (format "\240%c" (+ ch 128))
+;;     (let ((str (string-as-unibyte (char-to-string ch))))
+;;       (if (cmpcharp ch)
+;;           (if (= (aref str 1) ?\xFF)
+;;               (error "Can't compose a rule-based composition character")
+;;             (substring str (if (= (aref str 1) ?\xFF) 2 1)))
+;;         (aset str 0 (+ (aref str 0) ?\x20))
+;;         str))))
 
-;; Return a string for composition rule RULE to be embedded in
-;; multibyte form of composite character.
-(defsubst compose-chars-rule (rule)
-  (char-to-string (+ ?\xA0
-		     (* (cdr (assq (car rule) reference-point-alist)) 9)
-		     (cdr (assq (cdr rule) reference-point-alist)))))
+;; ;; Return a string for composition rule RULE to be embedded in
+;; ;; multibyte form of composite character.
+;; (defsubst compose-chars-rule (rule)
+;;   (char-to-string (+ ?\xA0
+;;                      (* (cdr (assq (car rule) reference-point-alist)) 9)
+;;                      (cdr (assq (cdr rule) reference-point-alist)))))
 
-;;;###autoload
-(defun compose-chars (first-component &rest args)
-  "Return one char string composed from the arguments.
-Each argument is a character (including a composite chararacter)
-or a composition rule.
-A composition rule has the form \(GLOBAL-REF-POINT . NEW-REF-POINT).
-See the documentation of `reference-point-alist' for more detail."
-  (if (= (length args) 0)
-      (char-to-string first-component)
-    (let* ((with-rule (consp (car args)))
-	   (str (if with-rule (concat (vector leading-code-composition ?\xFF))
-		  (char-to-string leading-code-composition))))
-      (setq str (concat str (compose-chars-component first-component)))
-      (while args
-	(if with-rule
-	    (progn
-	      (if (not (consp (car args)))
-		  (error "Invalid composition rule: %s" (car args)))
-	      (setq str (concat str (compose-chars-rule (car args))
-				(compose-chars-component (car (cdr args))))
-		    args (cdr (cdr args))))
-	  (setq str (concat str (compose-chars-component (car args)))
-		args (cdr args))))
-      str)))
+;; ;;;###autoload
+;; (defun compose-chars (first-component &rest args)
+;;   "Return one char string composed from the arguments.
+;; For relative composition, each argument should be a non-composition character
+;; or a relative-composition character.
+;; For rule-based composition, Nth (where N is odd) argument should be
+;; a non-composition character or a rule-based-composition character,
+;; and Mth (where M is even) argument should be a composition rule.
+;; A composition rule has the form \(GLOBAL-REF-POINT . NEW-REF-POINT).
+;; See the documentation of `reference-point-alist' for more detail."
+;;   (if (= (length args) 0)
+;;       (char-to-string first-component)
+;;     (let* ((with-rule (consp (car args)))
+;;            (str (if (cmpcharp first-component)
+;;                     (string-as-unibyte (char-to-string first-component))
+;;                   (if with-rule
+;;                       (concat (vector leading-code-composition ?\xFF)
+;;                               (compose-chars-component first-component))
+;;                     (concat (char-to-string leading-code-composition)
+;;                             (compose-chars-component first-component))))))
+;;       (if (and (cmpcharp first-component)
+;;                (eq with-rule (/= (aref str 1) ?\xFF)))
+;;           (error "%s-compostion-character is not allowed in %s composition: %c"
+;;                  (if with-rule "relative" "rule-based")
+;;                  (if with-rule "rule-based" "relative")
+;;                  first-component))
+;;       (while args
+;;         (if with-rule
+;;             (setq str (concat str (compose-chars-rule (car args)))
+;;                   args (cdr args)))
+;;         (if (cmpcharp (car args))
+;;             (let ((cmp-str (string-as-unibyte (char-to-string (car args)))))
+;;               (if (eq with-rule (/= (aref cmp-str 1) ?\xFF))
+;;                   (error "%s-compostion-character is not allowed in %s composition: %c"
+;;                          (if with-rule "relative" "rule-based")
+;;                          (if with-rule "rule-based" "relative")
+;;                          (car args)))
+;;               (setq str (concat str (substring cmp-str
+;;                                                (if with-rule 2 1)))))
+;;           (setq str (concat str (compose-chars-component (car args)))))
+;;         (setq args (cdr args)))
+;;       (string-as-multibyte str))))
 
-;;;###autoload
-(defun decompose-composite-char (char &optional type with-composition-rule)
-  "Convert composite character CHAR to a string containing components of CHAR.
-Optional 1st arg TYPE specifies the type of sequence returned.
-It should be `string' (default), `list', or `vector'.
-Optional 2nd arg WITH-COMPOSITION-RULE non-nil means the returned
-sequence contains embedded composition rules if any.  In this case, the
-order of elements in the sequence is the same as arguments for
-`compose-chars' to create CHAR.
-If TYPE is omitted or is `string', composition rules are omitted
-even if WITH-COMPOSITION-RULE is t."
-  (or type
-      (setq type 'string))
-  (let* ((len (composite-char-component-count char))
-	 (i (1- len))
-	 l)
-    (setq with-composition-rule (and with-composition-rule
-				    (not (eq type 'string))
-				    (composite-char-composition-rule-p char)))
-    (while (> i 0)
-      (setq l (cons (composite-char-component char i) l))
-      (if  with-composition-rule
-	  (let ((rule (- (composite-char-composition-rule char i) ?\xA0)))
-	    (setq l (cons (cons (/ rule 9) (% rule 9)) l))))
-      (setq i (1- i)))
-    (setq l (cons (composite-char-component char 0) l))
-    (cond ((eq type 'string)
-	   (apply 'concat-chars l))
-	  ((eq type 'list)
-	   l)
-	  (t				; i.e. TYPE is vector
-	   (vconcat l)))))
+;; ;;;###autoload
+;; (defun decompose-composite-char (char &optional type with-composition-rule)
+;;   "Convert composite character CHAR to a sequence of the components.
+;; Optional 1st arg TYPE specifies the type of sequence returned.
+;; It should be `string' (default), `list', or `vector'.
+;; Optional 2nd arg WITH-COMPOSITION-RULE non-nil means the returned
+;; sequence contains embedded composition rules if any.  In this case, the
+;; order of elements in the sequence is the same as arguments for
+;; `compose-chars' to create CHAR.
+;; If TYPE is omitted or is `string', composition rules are omitted
+;; even if WITH-COMPOSITION-RULE is t."
+;;   (or type
+;;       (setq type 'string))
+;;   (let* ((len (composite-char-component-count char))
+;;          (i (1- len))
+;;          l)
+;;     (setq with-composition-rule (and with-composition-rule
+;;                                     (not (eq type 'string))
+;;                                     (composite-char-composition-rule-p char)))
+;;     (while (> i 0)
+;;       (setq l (cons (composite-char-component char i) l))
+;;       (if  with-composition-rule
+;;           (let ((rule (- (composite-char-composition-rule char i) ?\xA0)))
+;;             (setq l (cons (cons (/ rule 9) (% rule 9)) l))))
+;;       (setq i (1- i)))
+;;     (setq l (cons (composite-char-component char 0) l))
+;;     (cond ((eq type 'string)
+;;            (apply 'string l))
+;;           ((eq type 'list)
+;;            l)
+;;           (t                            ; i.e. TYPE is vector
+;;            (vconcat l)))))
 
 ;;; mule-util.el ends here