changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate lisp/lib/net/codec/punycode.lisp

changeset 698: 96958d3eb5b0
parent: 524dfb768c7a
author: Richard Westhaver <ellis@rwest.io>
date: Fri, 04 Oct 2024 22:04:59 -0400
permissions: -rw-r--r--
description: fixes
105
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
1
 ;;; lib/net/codec/punycode.lisp --- RFC 3492 Punycode strings
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
2
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
3
 ;; This library was written by Yukari Hafner <shinmera@tymoon.eu>: https://github.com/Shinmera/punycode.git
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
4
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
5
 ;;; Code:
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
6
 (in-package :net/codec/punycode)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
7
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
8
 (defconstant INITIAL-N #x80)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
9
 (defconstant INITIAL-BIAS 72)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
10
 (defconstant BASE 36)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
11
 (defconstant TMAX 26)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
12
 (defconstant TMIN 1)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
13
 (defconstant SKEW 38)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
14
 (defconstant DAMP 700)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
15
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
16
 (defun encode-digit (code)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
17
   (code-char (+ code (if (< code 26) 97 22))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
18
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
19
 (defun adapt (delta num-points first-time-p)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
20
   (setf delta (if first-time-p 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
21
                   (truncate delta DAMP)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
22
                   (ash delta -1)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
23
   (incf delta (truncate delta num-points))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
24
   (loop for k from 0 by BASE
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
25
         while (< (ash (* TMAX (- BASE TMIN)) -1) delta)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
26
         do (setf delta (truncate delta (- BASE TMIN)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
27
         finally (return (+ k (truncate (* delta (+ 1 (- BASE TMIN))) (+ delta SKEW))))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
28
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
29
 (defmacro with-stream (stream-ish &body body)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
30
   (let ((thunk (gensym "THUNK")))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
31
     `(flet ((,thunk (,stream-ish)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
32
               ,@body))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
33
        (etypecase out
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
34
          (null
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
35
           (with-output-to-string (,stream-ish)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
36
             (,thunk ,stream-ish)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
37
          ((eql T)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
38
           (,thunk *standard-output*))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
39
          (stream
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
40
           (,thunk ,stream-ish))))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
41
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
42
 (defun encode-punycode (string &optional out)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
43
   (with-stream out
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
44
     (let ((n INITIAL-N)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
45
           (bias INITIAL-BIAS)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
46
           (delta 0)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
47
           (basic 0))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
48
       (loop for i from 0 below (length string)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
49
             for char = (char string i)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
50
             for code = (char-code char)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
51
             do (when (< code 128)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
52
                  (write-char char out)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
53
                  (incf basic)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
54
       (unless (= 0 basic)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
55
         (write-char #\- out))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
56
       (loop with handled = basic
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
57
             for m = most-positive-fixnum
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
58
             for handled+1 = (1+ handled)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
59
             while (< handled (length string))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
60
             do (loop for char across string
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
61
                      for code = (char-code char)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
62
                      do (when (<= n code (1- m))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
63
                           (setf m code)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
64
                (incf delta (* (- m n) handled+1))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
65
                (setf n m)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
66
                (loop for char across string
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
67
                      for code = (char-code char)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
68
                      do (let ((q delta))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
69
                           (when (< code n)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
70
                             (incf delta))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
71
                           (when (= n code)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
72
                             (loop for k from BASE by BASE
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
73
                                   for tt = (cond ((<= k bias) TMIN)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
74
                                                  ((<= (+ bias TMAX) k) TMAX)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
75
                                                  (T (- k bias)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
76
                                   do (when (< q tt) (return))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
77
                                      (write-char (encode-digit (+ tt (mod (- q tt) (- BASE tt)))) out)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
78
                                      (setf q (truncate (- q tt) (- BASE tt))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
79
                             (write-char (encode-digit q) out)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
80
                             (setf bias (adapt delta handled+1 (= handled basic)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
81
                             (setf delta 0)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
82
                             (incf handled))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
83
                (incf delta)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
84
                (incf n)))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
85
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
86
 (defun decode-digit (char)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
87
   (let ((code (char-code char)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
88
     (cond ((<= #x30 code #x39) (+ 26 (- code #x30)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
89
           ((<= #x41 code #x5A) (- code #x41))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
90
           ((<= #x61 code #x7A) (- code #x61))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
91
           (T BASE))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
92
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
93
 (defun decode-punycode (string &optional out)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
94
   (let* ((i 0)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
95
          (n INITIAL-N)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
96
          (bias INITIAL-BIAS)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
97
          (basic (or (position #\- string :from-end T) 0))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
98
          (written basic)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
99
          (uni (make-array (length string) :element-type 'character)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
100
     ;; This is gross, I know. But we can't stream things out nicely because
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
101
     ;; later mixed codepoints can have the same target index, causing earlier
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
102
     ;; codepoints to be shifted downwards, which we obviously cannot do if we
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
103
     ;; already emitted the codepoint to stream. So we instead copy to a string
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
104
     ;; first.
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
105
     (loop for i from 0 below basic
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
106
           do (setf (char uni i) (char string i)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
107
     (flet ((insert (pos char)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
108
              (loop for i downfrom written above pos
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
109
                    do (setf (char uni i) (char uni (1- i))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
110
              (setf (char uni pos) char)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
111
       (loop with in = (if (< 0 basic) (1+ basic) 0)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
112
             for old-i = i
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
113
             while (< in (length string))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
114
             do (loop with w = 1
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
115
                      for k from BASE by BASE
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
116
                      for digit = (decode-digit (char string in))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
117
                      do (incf in)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
118
                         (incf i (* digit w))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
119
                         (let ((tt (cond ((<= k bias) TMIN)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
120
                                         ((<= (+ bias TMAX) k) TMAX)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
121
                                         (T (- k bias)))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
122
                           (when (< digit tt) (return))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
123
                           (setf w (* w (- base tt)))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
124
                (incf written)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
125
                (setf bias (adapt (- i old-i) written (= old-i 0)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
126
                (incf n (truncate i written))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
127
                (setf i (mod i written))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
128
                (insert i (code-char n))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
129
                (incf i)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
130
     (with-stream out
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
131
       (write-string uni out :end written))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
132
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
133
 (defun encode-domain (string &optional out)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
134
   (with-stream out
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
135
     (loop for start = 0 then (1+ end)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
136
           for end = (or (position #\. string :start start) (length string))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
137
           do (cond ((loop for i from start below end
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
138
                           thereis (< 127 (char-code (char string i))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
139
                     (write-string "xn--" out)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
140
                     (encode-punycode (subseq string start end) out))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
141
                    (T
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
142
                     (write-string string out :start start :end end)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
143
              (if (< end (length string))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
144
                  (write-char #\. out)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
145
                  (return)))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
146
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
147
 (defun decode-domain (string &optional out)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
148
   (with-stream out
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
149
     (loop for start = 0 then (1+ end)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
150
           for end = (or (position #\. string :start start) (length string))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
151
           do (cond ((and (< (length "xn--") (- end start))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
152
                          (string= "xn--" string :start2 start :end2 (+ start (length "xn--"))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
153
                     (decode-punycode (subseq string (+ start (length "xn--")) end) out))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
154
                    (T
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
155
                     (write-string string out :start start :end end)))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
156
              (if (< end (length string))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
157
                  (write-char #\. out)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
158
                  (return)))))
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
159
 
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
160
 (eval-when (:load-toplevel)
524dfb768c7a added PWN, NET, OBJ/URI
ellis <ellis@rwest.io>
parents:
diff changeset
161
   (push :rfc3492 *features*))