mirror of
https://codeberg.org/cage/tinmop/
synced 2025-01-29 04:09:19 +01:00
- added minimal wrapping of libidn2;
- added library checks (libidn2 and libssl) to configure scripts; - removed commented reference to quri.
This commit is contained in:
parent
2205ab5152
commit
5f8c9d422e
@ -75,7 +75,8 @@
|
||||
|
||||
** Foreign (C language) library
|
||||
|
||||
- libssl
|
||||
- libssl (TLS socket)
|
||||
- linidn2 (i18n domain name aka idna)
|
||||
|
||||
* Install
|
||||
|
||||
|
@ -119,7 +119,8 @@ Table of Contents
|
||||
3.3 Foreign (C language) library
|
||||
────────────────────────────────
|
||||
|
||||
• libssl
|
||||
• libssl (TLS socket)
|
||||
• linidn2 (i18n domain name aka idna)
|
||||
|
||||
|
||||
4 Install
|
||||
@ -266,7 +267,7 @@ Table of Contents
|
||||
Any help is appreciated. If you intend to contribute please point your
|
||||
browser to the [issue tracker] or file a [pull request].
|
||||
|
||||
But, please take a minute to read the file <file:./CONTRIBUTING.org>
|
||||
But, please take a minute to read the file <./CONTRIBUTING.org>
|
||||
|
||||
|
||||
[issue tracker] <https://notabug.org/cage/tinmop/issues>
|
||||
|
89
configure
vendored
89
configure
vendored
@ -6127,6 +6127,95 @@ $as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h
|
||||
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for idn2_to_ascii_8z in -lidn2" >&5
|
||||
$as_echo_n "checking for idn2_to_ascii_8z in -lidn2... " >&6; }
|
||||
if ${ac_cv_lib_idn2_idn2_to_ascii_8z+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lidn2 $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char idn2_to_ascii_8z ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return idn2_to_ascii_8z ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_idn2_idn2_to_ascii_8z=yes
|
||||
else
|
||||
ac_cv_lib_idn2_idn2_to_ascii_8z=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_idn2_idn2_to_ascii_8z" >&5
|
||||
$as_echo "$ac_cv_lib_idn2_idn2_to_ascii_8z" >&6; }
|
||||
if test "x$ac_cv_lib_idn2_idn2_to_ascii_8z" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBIDN2 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-lidn2 $LIBS"
|
||||
|
||||
else
|
||||
as_fn_error $? "Can not this function find libidn2." "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_get_version in -lssl" >&5
|
||||
$as_echo_n "checking for SSL_get_version in -lssl... " >&6; }
|
||||
if ${ac_cv_lib_ssl_SSL_get_version+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lssl $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char SSL_get_version ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return SSL_get_version ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_ssl_SSL_get_version=yes
|
||||
else
|
||||
ac_cv_lib_ssl_SSL_get_version=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_get_version" >&5
|
||||
$as_echo "$ac_cv_lib_ssl_SSL_get_version" >&6; }
|
||||
if test "x$ac_cv_lib_ssl_SSL_get_version" = xyes; then :
|
||||
as_fn_error $? "Can not find libssl." "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
# Extract the first word of "sbcl", so it can be a program name with args.
|
||||
set dummy sbcl; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
|
@ -21,6 +21,10 @@ AM_INIT_AUTOMAKE([-Wall foreign])
|
||||
|
||||
AM_GNU_GETTEXT([external])
|
||||
|
||||
AC_CHECK_LIB([idn2], [idn2_to_ascii_8z], [], AC_MSG_ERROR([Can not this function find libidn2.]))
|
||||
|
||||
AC_CHECK_LIB([ssl], [SSL_get_version], AC_MSG_ERROR([Can not find libssl.]))
|
||||
|
||||
AC_PATH_PROG([LISP_COMPILER],[sbcl],[no])
|
||||
|
||||
if test "$LISP_COMPILER" = "no" ; then
|
||||
|
44
src/grovel-idn.lisp
Normal file
44
src/grovel-idn.lisp
Normal file
@ -0,0 +1,44 @@
|
||||
(in-package :idn)
|
||||
|
||||
(include "idn2.h")
|
||||
|
||||
(cenum (idn2-rc :define-constants t)
|
||||
((:ok "IDN2_OK"))
|
||||
((:malloc "IDN2_MALLOC"))
|
||||
((:no-codeset "IDN2_NO_CODESET"))
|
||||
((:iconv-fail "IDN2_ICONV_FAIL"))
|
||||
((:encoding-error "IDN2_ENCODING_ERROR"))
|
||||
((:nfc "IDN2_NFC"))
|
||||
((:punycode-bad-input "IDN2_PUNYCODE_BAD_INPUT"))
|
||||
((:punycode-big-output "IDN2_PUNYCODE_BIG_OUTPUT"))
|
||||
((:punycode-overflow "IDN2_PUNYCODE_OVERFLOW"))
|
||||
((:too-big-domain "IDN2_TOO_BIG_DOMAIN"))
|
||||
((:too-big-label "IDN2_TOO_BIG_LABEL"))
|
||||
((:invalid-alabel "IDN2_INVALID_ALABEL"))
|
||||
((:ualabel-mismatch "IDN2_UALABEL_MISMATCH"))
|
||||
((:invalid-flags "IDN2_INVALID_FLAGS"))
|
||||
((:not-nfc "IDN2_NOT_NFC"))
|
||||
((:2hyphen "IDN2_2HYPHEN"))
|
||||
((:hyphen-startend "IDN2_HYPHEN_STARTEND"))
|
||||
((:leading-combining "IDN2_LEADING_COMBINING"))
|
||||
((:disallowed "IDN2_DISALLOWED"))
|
||||
((:contextj "IDN2_CONTEXTJ"))
|
||||
((:contextj-no-rule "IDN2_CONTEXTJ_NO_RULE"))
|
||||
((:contexto "IDN2_CONTEXTO"))
|
||||
((:contexto-no-rule "IDN2_CONTEXTO_NO_RULE"))
|
||||
((:unassigned "IDN2_UNASSIGNED"))
|
||||
((:bidi "IDN2_BIDI"))
|
||||
((:dot-in-label "IDN2_DOT_IN_LABEL"))
|
||||
((:invalid-transitional "IDN2_INVALID_TRANSITIONAL"))
|
||||
((:invalid-nontransitional "IDN2_INVALID_NONTRANSITIONAL"))
|
||||
((:alabel-roundtrip-failed "IDN2_ALABEL_ROUNDTRIP_FAILED")))
|
||||
|
||||
(cenum (flags :define-constants t)
|
||||
((:nfc-input "IDN2_NFC_INPUT"))
|
||||
((:alabel-roundtrip "IDN2_ALABEL_ROUNDTRIP"))
|
||||
((:transitional "IDN2_TRANSITIONAL"))
|
||||
((:nontransitional "IDN2_NONTRANSITIONAL"))
|
||||
((:allow-unassigned "IDN2_ALLOW_UNASSIGNED"))
|
||||
((:use-std3-ascii-rules "IDN2_USE_STD3_ASCII_RULES"))
|
||||
((:no-tr46 "IDN2_NO_TR46"))
|
||||
((:no-alabel-roundtrip "IDN2_NO_ALABEL_ROUNDTRIP")))
|
89
src/idn.lisp
Normal file
89
src/idn.lisp
Normal file
@ -0,0 +1,89 @@
|
||||
(in-package :idn)
|
||||
|
||||
(cffi:define-foreign-library libidn2
|
||||
(:unix (:or "libidn2.so.0" "libidn2.so"))
|
||||
(t (:default "libmagic")))
|
||||
|
||||
(cffi:use-foreign-library libidn2)
|
||||
|
||||
;; int idn2_to_ascii_8z (const char * input, char ** output, int flags)
|
||||
|
||||
(cffi:defcfun (idn2-to-ascii-8z "idn2_to_ascii_8z")
|
||||
:int
|
||||
(input :pointer)
|
||||
(output :pointer)
|
||||
(flags :int))
|
||||
|
||||
;; int idn2_to_unicode_8z8z (const char *input, char **output, int flags)
|
||||
|
||||
(cffi:defcfun (idn2-to-unicode-8z8z "idn2_to_unicode_8z8z")
|
||||
:int
|
||||
(input :pointer)
|
||||
(output :pointer)
|
||||
(flags :int)) ; unused
|
||||
|
||||
(define-condition punycode-conversion-error (error)
|
||||
((host
|
||||
:initarg :host
|
||||
:reader host)
|
||||
(error-code
|
||||
:initarg :error-code
|
||||
:reader error-code))
|
||||
(:report (lambda (condition stream)
|
||||
(format stream
|
||||
"error converting ~a to ASCII (code: ~a)"
|
||||
(host condition)
|
||||
(error-code condition))))
|
||||
(:documentation "Error conversion unicode -> ASCII"))
|
||||
|
||||
(defun ->ascii-default-flags ()
|
||||
(logior (cffi:foreign-enum-value 'flags :nontransitional)
|
||||
(cffi:foreign-enum-value 'flags :nfc-input)))
|
||||
|
||||
(defun unicode->ascii (host &optional (flags (->ascii-default-flags)))
|
||||
(labels ((deref (ptr** index)
|
||||
(cffi:mem-aref (cffi:mem-aref ptr** :pointer)
|
||||
:char index)))
|
||||
(cffi:with-foreign-string (input host)
|
||||
(cffi:with-foreign-object (buf* :unsigned-char)
|
||||
(cffi:with-foreign-object (buf** :pointer)
|
||||
(setf (cffi:mem-ref buf** :pointer) buf*)
|
||||
(let ((results (idn2-to-ascii-8z input buf** flags)))
|
||||
(unwind-protect
|
||||
(if (= (cffi:foreign-enum-value 'idn2-rc :ok)
|
||||
results)
|
||||
(with-output-to-string (punycode)
|
||||
(loop for i from 0 while (/= (deref buf** i)
|
||||
0)
|
||||
do
|
||||
(let ((octect (deref buf** i)))
|
||||
(write-char (code-char octect) punycode))))
|
||||
(error 'punycode-conversion-error
|
||||
:host host
|
||||
:error-code (cffi:foreign-enum-keyword 'idn2-rc results)))
|
||||
(cffi:foreign-free (cffi:mem-aref buf** :pointer)))))))))
|
||||
|
||||
|
||||
(defun ascii->unicode (host)
|
||||
(labels ((deref (ptr** index)
|
||||
(cffi:mem-aref (cffi:mem-aref ptr** :pointer)
|
||||
:char index)))
|
||||
(cffi:with-foreign-string (input host)
|
||||
(cffi:with-foreign-object (buf* :unsigned-char)
|
||||
(cffi:with-foreign-object (buf** :pointer)
|
||||
(setf (cffi:mem-ref buf** :pointer) buf*)
|
||||
(let ((results (idn2-to-unicode-8z8z input buf** 0)))
|
||||
(unwind-protect
|
||||
(if (= (cffi:foreign-enum-value 'idn2-rc :ok)
|
||||
results)
|
||||
(let ((octects (misc:make-array-frame 0 0 '(unsigned-byte 8))))
|
||||
(loop for i from 0 while (/= (deref buf** i)
|
||||
0)
|
||||
do
|
||||
(vector-push-extend (logand (deref buf** i) 255)
|
||||
octects))
|
||||
(babel:octets-to-string octects))
|
||||
(error 'punycode-conversion-error
|
||||
:host host
|
||||
:error-code (cffi:foreign-enum-keyword 'idn2-rc results)))
|
||||
(cffi:foreign-free (cffi:mem-aref buf** :pointer)))))))))
|
@ -14,6 +14,12 @@
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
(defpackage :idn
|
||||
(:use :cl)
|
||||
(:export
|
||||
:unicode->ascii
|
||||
:ascii->unicode))
|
||||
|
||||
(defpackage :config
|
||||
(:use :cl)
|
||||
(:export
|
||||
|
@ -21,6 +21,7 @@
|
||||
:version "0.3.2"
|
||||
:pathname "src"
|
||||
:serial t
|
||||
:defsystem-depends-on ("cffi-grovel")
|
||||
:depends-on (:alexandria
|
||||
:cl-ppcre
|
||||
:tooter
|
||||
@ -49,10 +50,11 @@
|
||||
:drakma
|
||||
:usocket
|
||||
:babel
|
||||
; :quri
|
||||
:percent-encoding
|
||||
:uiop)
|
||||
:components ((:file "package")
|
||||
(:cffi-grovel-file "grovel-idn")
|
||||
(:file "idn")
|
||||
(:file "config")
|
||||
(:file "constants")
|
||||
(:file "conditions")
|
||||
|
Loading…
x
Reference in New Issue
Block a user