(defconst po-content-type-charset-alist
'(("ASCII" . undecided)
("ANSI_X3.4-1968" . undecided)
("US-ASCII" . undecided))
"Alist of coding system versus GNU libc/libiconv canonical charset name.
Contains canonical charset names that don't correspond to coding systems.")
(defun po-find-charset (filename)
"Return PO charset value for FILENAME.
If FILENAME is a cons cell, its CDR is a buffer that already contains
the PO file (but not yet decoded)."
(let ((charset-regexp
"^\"Content-Type:[ \t]*text/plain;[ \t]*charset=\\(.*\\)\\\\n\"")
(buf (and (consp filename) (cdr filename)))
(short-read nil))
(when buf
(set-buffer buf)
(goto-char (point-min)))
(while (not (or short-read (re-search-forward "^msgid" nil t) buf))
(save-excursion
(goto-char (point-max))
(let ((pair (insert-file-contents-literally filename nil
(1- (point))
(1- (+ (point) 4096)))))
(setq short-read (< (nth 1 pair) 4096)))))
(cond ((re-search-forward charset-regexp nil t) (match-string 1))
((or short-read buf) nil)
(t (save-excursion
(goto-char (point-max))
(insert-file-contents-literally filename nil
(1- (point))
(1- (+ (point) 1024))))
(if (re-search-forward charset-regexp nil t)
(match-string 1))))))
(defun po-find-file-coding-system-guts (operation filename)
"Return a (DECODING . ENCODING) pair for OPERATION on PO file FILENAME.
Do so according to FILENAME's declared charset.
FILENAME may be a cons (NAME . BUFFER). In that case, detect charset
in BUFFER."
(and
(eq operation 'insert-file-contents)
(or (if (consp filename) (buffer-live-p (cdr filename)))
(file-exists-p filename))
(with-temp-buffer
(let* ((coding-system-for-read 'no-conversion)
(charset (or (po-find-charset filename) "ascii"))
assoc)
(list (cond
((setq assoc
(assoc-string charset
po-content-type-charset-alist
t))
(cdr assoc))
((or (setq assoc (assoc-string charset coding-system-alist t))
(setq assoc
(assoc-string (subst-char-in-string ?_ ?-
charset)
coding-system-alist t)))
(intern (car assoc)))
((featurep 'code-pages)
'raw-text)
(t
(require 'code-pages nil t)
(if (or
(setq assoc (assoc-string charset coding-system-alist t))
(setq assoc (assoc-string (subst-char-in-string
?_ ?- charset)
coding-system-alist t)))
(intern (car assoc))
'raw-text))))))))
(defun po-find-file-coding-system (arg-list)
"Return a (DECODING . ENCODING) pair, according to PO file's charset.
Called through `file-coding-system-alist', before the file is visited for real."
(po-find-file-coding-system-guts (car arg-list) (car (cdr arg-list))))
(provide 'po)