Commits

Mats Lidell committed e6d6b99

New files from Libidn: idna.el and punycode.el

Changelog addition:

2014-08-06 Mats Lidell <matsl@xemacs.org>

* idna.el: New file from GNU Libidn. Added Coding cookie and load
protection if utf-8 support is missing.
* punycode.el: Ditto.

Comments (0)

Files changed (3)

+2014-08-06  Mats Lidell  <matsl@xemacs.org>
+
+	* idna.el: New file from GNU Libidn. Added Coding cookie and load
+	protection if utf-8 support is missing.
+	* punycode.el: Ditto.
+
 2014-05-15  Norbert Koch  <viteno@xemacs.org>
 
 	* Makefile (VERSION): XEmacs package 1.60 released.
+;;; idna.el --- Internationalizing Domain Names in Applications. -*- coding: iso-8859-1 -*-
+
+;; Copyright (C) 2003-2013 Simon Josefsson
+;; Keywords: idna, idn, domain name, internationalization
+
+;; This file is part of GNU Libidn.
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A simple wrapper around the command line "idn" utility in GNU
+;; Libidn to make IDNA ToASCII and ToUnicode operations available in
+;; Emacs.
+
+;; Example:
+;;
+;; (idna-to-ascii "r�ksm�rg�s.gnu.org")
+;; => "xn--rksmrgs-5wao1o.gnu.org"
+;;
+;; (idna-to-ascii "www.gnu.org")
+;; => "www.gnu.org"
+;;
+;; (idna-to-unicode "xn--rksmrgs-5wao1o.gnu.org")
+;; => "r�ksm�rg�s.gnu.org"
+;;
+;; (idna-to-unicode "www.gnu.org")
+;; => "www.gnu.org"
+
+;; Todo: Support AllowUnassigned and UseSTD3ASCIIRules somehow?
+
+;; This package is useless unless your emacs has at least partial
+;; support for the UTF-8 coding system.
+
+;; Report bugs to bug-libidn@gnu.org.
+
+;;; Code:
+
+(eval-when (load eval)
+  (unless (find-coding-system 'utf-8)
+    (error 'invalid-operation "`idna.el' requires support for the utf-8 coding system")))
+
+(defgroup idna nil
+  "Internationalizing Domain Names in Applications.")
+
+(defcustom idna-program "idn"
+  "Name of the GNU Libidn \"idn\" application."
+  :type 'string
+  :group 'idna)
+
+(defcustom idna-environment '("CHARSET=UTF-8")
+  "List of environment variable definitions prepended to `process-environment'."
+  :type '(repeat string)
+  :group 'idna)
+
+(defcustom idna-to-ascii-parameters '("--quiet"
+				      "--idna-to-ascii"
+				      "--usestd3asciirules")
+  "Parameters passed to `idna-program' to invoke IDNA ToASCII mode."
+  :type '(repeat string)
+  :group 'idna)
+
+(defcustom idna-to-unicode-parameters '("--quiet"
+					"--idna-to-unicode"
+					"--usestd3asciirules")
+  "Parameters passed `idna-program' to invoke IDNA ToUnicode mode."
+  :type '(repeat string)
+  :group 'idna)
+
+;; Internal process handling:
+
+(defvar idna-to-ascii-process nil
+  "Internal variable holding process for ToASCII.")
+(defvar idna-to-ascii-response nil
+  "Internal variable holding response data received from ToASCII process.")
+
+(defun idna-to-ascii-response-clear ()
+  (setq idna-to-ascii-response nil))
+
+(defun idna-to-ascii-response ()
+  (while (and (eq (process-status idna-to-ascii-process) 'run)
+	      (null idna-to-ascii-response))
+    (accept-process-output idna-to-ascii-process 1))
+  idna-to-ascii-response)
+
+(defun idna-to-ascii-filter (process string)
+  (setq idna-to-ascii-response (concat idna-to-ascii-response string)))
+
+(defun idna-to-ascii-process ()
+  (if (and idna-to-ascii-process
+	   (eq (process-status idna-to-ascii-process) 'run))
+      idna-to-ascii-process
+    (if idna-to-ascii-process
+	(condition-case ()
+	    (kill-process idna-to-ascii-process)
+	  (error)))
+    (when (setq idna-to-ascii-process
+		(let ((process-environment (append idna-environment
+						   process-environment)))
+		  (apply 'start-process "idna" nil idna-program
+			 idna-to-ascii-parameters)))
+      (set-process-filter idna-to-ascii-process 'idna-to-ascii-filter)
+      (set-process-coding-system idna-to-ascii-process 'utf-8 'utf-8)
+      (process-kill-without-query idna-to-ascii-process))
+    idna-to-ascii-process))
+
+(defvar idna-to-unicode-process nil
+  "Internal variable holding process for ToASCII.")
+(defvar idna-to-unicode-response nil
+  "Internal variable holding response data received from ToASCII process.")
+
+(defun idna-to-unicode-response-clear ()
+  (setq idna-to-unicode-response nil))
+
+(defun idna-to-unicode-response ()
+  (while (and (eq (process-status idna-to-unicode-process) 'run)
+	      (null idna-to-unicode-response))
+    (accept-process-output idna-to-unicode-process 1))
+  idna-to-unicode-response)
+
+(defun idna-to-unicode-filter (process string)
+  (setq idna-to-unicode-response (concat idna-to-unicode-response string)))
+
+(defun idna-to-unicode-process ()
+  (if (and idna-to-unicode-process
+	   (eq (process-status idna-to-unicode-process) 'run))
+      idna-to-unicode-process
+    (if idna-to-unicode-process
+	(condition-case ()
+	    (kill-process idna-to-unicode-process)
+	  (error)))
+    (when (setq idna-to-unicode-process
+		(let ((process-environment (append idna-environment
+						   process-environment)))
+		  (apply 'start-process "idna" nil idna-program
+			 idna-to-unicode-parameters)))
+      (set-process-filter idna-to-unicode-process 'idna-to-unicode-filter)
+      (set-process-coding-system idna-to-unicode-process 'utf-8 'utf-8)
+      (process-kill-without-query idna-to-unicode-process))
+    idna-to-unicode-process))
+
+;; IDNA Elisp API:
+
+(defun idna-to-ascii (str)
+  "Returns an ASCII Compatible Encoding (ACE) of STR.
+It is computed by the IDNA ToASCII operation, after converting the
+input to UTF-8."
+  (let ((proc (idna-to-ascii-process))
+	string)
+    (if (null proc)
+	(error "Cannot start idn application (to-ascii)")
+      (idna-to-ascii-response-clear)
+      (process-send-string proc (concat str "\n"))
+      (setq string (idna-to-ascii-response))
+      (if (and string (string= (substring string (1- (length string))) "\n"))
+	  (substring string 0 (1- (length string)))
+	string))))
+
+(defun idna-to-unicode (str)
+  "Returns a possibly multibyte string after decoding STR.
+It is computed by the IDNA ToUnicode operation."
+  (let ((proc (idna-to-unicode-process))
+	string)
+    (if (null proc)
+	(error "Cannot start idn application (to-unicode)")
+      (idna-to-unicode-response-clear)
+      (process-send-string proc (concat str "\n"))
+      (setq string (idna-to-unicode-response))
+      (if (and string (string= (substring string (1- (length string))) "\n"))
+	  (substring string 0 (1- (length string)))
+	string))))
+
+(defun idna-shutdown ()
+  "Kill the IDNA related processes."
+  (interactive)
+  (if (and idna-to-ascii-process
+	   (eq (process-status idna-to-ascii-process) 'run))
+      (kill-process idna-to-ascii-process))
+  (if (and idna-to-unicode-process
+	   (eq (process-status idna-to-unicode-process) 'run))
+      (kill-process idna-to-unicode-process)))
+
+(provide 'idna)
+
+;;; idna.el ends here
+;;; punycode.el --- An ASCII compatible Unicode encoding format. -*- coding: iso-8859-1 -*-
+
+;; Copyright (C) 2003-2013 Simon Josefsson
+;; Keywords: punycode, idna, idn, unicode, encoding
+
+;; This file is part of GNU Libidn.
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A simple wrapper around the command line "idn" utility in GNU
+;; Libidn to make punycode operations available in Emacs.
+
+;; Example:
+;;
+;; (punycode-encode "r�ksm�rg�s")
+;; => "rksmrgs-5wao1o"
+;;
+;; (punycode-encode "foo")
+;; => "foo-"
+;;
+;; (punycode-decode "rksmrgs-5wao1o")
+;; => "r�ksm�rg�s"
+;;
+;; (punycode-decode "foo-")
+;; => "foo"
+
+;; This package is useless unless your emacs has at least partial
+;; support for the UTF-8 coding system.
+
+;; Report bugs to bug-libidn@gnu.org.
+
+;;; Code:
+
+(eval-when (load eval)
+  (unless (find-coding-system 'utf-8)
+    (error 'invalid-operation "`punycode.el' requires support for the utf-8 coding system")))
+
+(defgroup punycode nil
+  "Punycode: An ASCII compatible Unicode encoding format.")
+
+(defcustom punycode-program "idn"
+  "Name of the GNU Libidn \"idn\" application."
+  :type 'string
+  :group 'punycode)
+
+(defcustom punycode-environment '("CHARSET=UTF-8")
+  "List of environment variable definitions prepended to `process-environment'."
+  :type '(repeat string)
+  :group 'punycode)
+
+(defcustom punycode-encode-parameters '("--quiet" "--punycode-encode")
+  "Parameters passed to `punycode-program' to invoke punycode encoding mode."
+  :type '(repeat string)
+  :group 'punycode)
+
+(defcustom punycode-decode-parameters '("--quiet" "--punycode-decode")
+  "Parameters passed to `punycode-program' to invoke punycode decoding mode."
+  :type '(repeat string)
+  :group 'punycode)
+
+;; Internal process handling:
+
+(defvar punycode-encode-process nil
+  "Internal variable holding process for punycode encoding.")
+(defvar punycode-encode-response nil
+  "Internal variable holding response data received from punycode process.")
+
+(defun punycode-encode-response-clear ()
+  (setq punycode-encode-response nil))
+
+(defun punycode-encode-response ()
+  (while (and (eq (process-status punycode-encode-process) 'run)
+	      (null punycode-encode-response))
+    (accept-process-output punycode-encode-process 1))
+  punycode-encode-response)
+
+(defun punycode-encode-filter (process string)
+  (setq punycode-encode-response (concat punycode-encode-response string)))
+
+(defun punycode-encode-process ()
+  (if (and punycode-encode-process
+	   (eq (process-status punycode-encode-process) 'run))
+      punycode-encode-process
+    (if punycode-encode-process
+	(condition-case ()
+	    (kill-process punycode-encode-process)
+	  (error)))
+    (when (setq punycode-encode-process
+		(let ((process-environment (append punycode-environment
+						   process-environment)))
+		  (apply 'start-process "punycode" nil punycode-program
+			 punycode-encode-parameters)))
+      (set-process-filter punycode-encode-process 'punycode-encode-filter)
+      (set-process-coding-system punycode-encode-process 'utf-8 'utf-8)
+      (process-kill-without-query punycode-encode-process))
+    punycode-encode-process))
+
+(defvar punycode-decode-process nil
+  "Internal variable holding process for punycode encoding.")
+(defvar punycode-decode-response nil
+  "Internal variable holding response data received from punycode process.")
+
+(defun punycode-decode-response-clear ()
+  (setq punycode-decode-response nil))
+
+(defun punycode-decode-response ()
+  (while (and (eq (process-status punycode-decode-process) 'run)
+	      (null punycode-decode-response))
+    (accept-process-output punycode-decode-process 1))
+  punycode-decode-response)
+
+(defun punycode-decode-filter (process string)
+  (setq punycode-decode-response (concat punycode-decode-response string)))
+
+(defun punycode-decode-process ()
+  (if (and punycode-decode-process
+	   (eq (process-status punycode-decode-process) 'run))
+      punycode-decode-process
+    (if punycode-decode-process
+	(condition-case ()
+	    (kill-process punycode-decode-process)
+	  (error)))
+    (when (setq punycode-decode-process
+		(let ((process-environment (append punycode-environment
+						   process-environment)))
+		  (apply 'start-process "punycode" nil punycode-program
+			 punycode-decode-parameters)))
+      (set-process-filter punycode-decode-process 'punycode-decode-filter)
+      (set-process-coding-system punycode-decode-process 'utf-8 'utf-8)
+      (process-kill-without-query punycode-decode-process))
+    punycode-decode-process))
+
+;; Punycode Elisp API:
+
+(defun punycode-encode (str)
+  "Returns a Punycode encoding of STR."
+  (let ((proc (punycode-encode-process))
+	string)
+    (if (null proc)
+	(error "Cannot start idn application")
+      (punycode-encode-response-clear)
+      (process-send-string proc (concat str "\n"))
+      (setq string (punycode-encode-response))
+      (if (and string (string= (substring string (1- (length string))) "\n"))
+	  (substring string 0 (1- (length string)))
+	string))))
+
+(defun punycode-decode (str)
+  "Returns a possibly multibyte string which is the punycode decoding of STR."
+  (let ((proc (punycode-decode-process))
+	string)
+    (if (null proc)
+	(error "Cannot start idn application")
+      (punycode-decode-response-clear)
+      (process-send-string proc (concat str "\n"))
+      (setq string (punycode-decode-response))
+      (if (and string (string= (substring string (1- (length string))) "\n"))
+	  (substring string 0 (1- (length string)))
+	string))))
+
+(defun punycode-shutdown ()
+  "Kill the punycode related process."
+  (interactive)
+  (if (and punycode-decode-process
+	   (eq (process-status punycode-decode-process) 'run))
+      (kill-process punycode-decode-process))
+  (if (and punycode-encode-process
+	   (eq (process-status punycode-encode-process) 'run))
+      (kill-process punycode-encode-process)))
+
+(provide 'punycode)
+
+;;; punycode.el ends here