25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-22 16:20:52 +01:00

Delete expat_erl, stringprep, xml and xml_stream; replaced by exmpp (EJAB-991)

SVN Revision: 2409
This commit is contained in:
Badlop 2009-07-30 17:57:56 +00:00
parent 35c1c3774c
commit f5868a0952
20 changed files with 124 additions and 7363 deletions

1
README
View File

@ -8,7 +8,6 @@ Quickstart guide
To compile ejabberd you need: To compile ejabberd you need:
- GNU Make - GNU Make
- GCC - GCC
- Libexpat 1.95 or higher
- Erlang/OTP R12B-5. Support for R13 or higher is experimental. - Erlang/OTP R12B-5. Support for R13 or higher is experimental.
- exmpp 0.9.1 or higher - exmpp 0.9.1 or higher
- OpenSSL 0.9.6 or higher, for STARTTLS, SASL and SSL - OpenSSL 0.9.6 or higher, for STARTTLS, SASL and SSL

View File

@ -335,7 +335,6 @@ as long as your system have all the dependencies.</P><P> <A NAME="installreq"></
</P><UL CLASS="itemize"><LI CLASS="li-itemize"> </P><UL CLASS="itemize"><LI CLASS="li-itemize">
GNU Make GNU Make
</LI><LI CLASS="li-itemize">GCC </LI><LI CLASS="li-itemize">GCC
</LI><LI CLASS="li-itemize">Libexpat 1.95 or higher
</LI><LI CLASS="li-itemize">Erlang/OTP R12B-5. Support for R13 or higher is experimental. </LI><LI CLASS="li-itemize">Erlang/OTP R12B-5. Support for R13 or higher is experimental.
</LI><LI CLASS="li-itemize">exmpp 0.9.1 or higher </LI><LI CLASS="li-itemize">exmpp 0.9.1 or higher
</LI><LI CLASS="li-itemize">OpenSSL 0.9.6 or higher, for STARTTLS, SASL and SSL encryption. Optional, highly recommended. </LI><LI CLASS="li-itemize">OpenSSL 0.9.6 or higher, for STARTTLS, SASL and SSL encryption. Optional, highly recommended.

View File

@ -299,7 +299,6 @@ To compile \ejabberd{} on a `Unix-like' operating system, you need:
\begin{itemize} \begin{itemize}
\item GNU Make \item GNU Make
\item GCC \item GCC
\item Libexpat 1.95 or higher
\item Erlang/OTP R12B-5. Support for R13 or higher is experimental. \item Erlang/OTP R12B-5. Support for R13 or higher is experimental.
\item exmpp 0.9.1 or higher \item exmpp 0.9.1 or higher
\item OpenSSL 0.9.6 or higher, for STARTTLS, SASL and SSL encryption. Optional, highly recommended. \item OpenSSL 0.9.6 or higher, for STARTTLS, SASL and SSL encryption. Optional, highly recommended.

View File

@ -63,8 +63,8 @@ endif
prefix = @prefix@ prefix = @prefix@
exec_prefix = @exec_prefix@ exec_prefix = @exec_prefix@
SUBDIRS = @mod_pubsub@ @mod_muc@ @mod_proxy65@ @eldap@ @pam@ @web@ stringprep @tls@ @odbc@ @ejabberd_zlib@ SUBDIRS = @mod_pubsub@ @mod_muc@ @mod_proxy65@ @eldap@ @pam@ @web@ @tls@ @odbc@ @ejabberd_zlib@
ERLSHLIBS = expat_erl.so ERLSHLIBS =
ERLBEHAVS = cyrsasl.erl gen_mod.erl p1_fsm.erl ERLBEHAVS = cyrsasl.erl gen_mod.erl p1_fsm.erl
SOURCES_ALL = $(wildcard *.erl) SOURCES_ALL = $(wildcard *.erl)
SOURCES = $(filter-out $(ERLBEHAVS),$(SOURCES_ALL)) SOURCES = $(filter-out $(ERLBEHAVS),$(SOURCES_ALL))

494
src/configure vendored
View File

@ -578,6 +578,7 @@ PACKAGE_VERSION='version'
PACKAGE_STRING='ejabberd.erl version' PACKAGE_STRING='ejabberd.erl version'
PACKAGE_BUGREPORT='ejabberd@process-one.net' PACKAGE_BUGREPORT='ejabberd@process-one.net'
ac_default_prefix=/
# Factoring default headers for most tests. # Factoring default headers for most tests.
ac_includes_default="\ ac_includes_default="\
#include <stdio.h> #include <stdio.h>
@ -614,7 +615,6 @@ ac_includes_default="\
# include <unistd.h> # include <unistd.h>
#endif" #endif"
ac_default_prefix=/
ac_subst_vars='SHELL ac_subst_vars='SHELL
PATH_SEPARATOR PATH_SEPARATOR
PACKAGE_NAME PACKAGE_NAME
@ -669,8 +669,6 @@ ERLANG_EXMPP
CPP CPP
GREP GREP
EGREP EGREP
EXPAT_CFLAGS
EXPAT_LIBS
LIBOBJS LIBOBJS
mod_muc mod_muc
make_mod_muc make_mod_muc
@ -1311,7 +1309,6 @@ Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-erlang=PREFIX path to erlc and erl --with-erlang=PREFIX path to erlc and erl
--with-expat=PREFIX prefix where EXPAT is installed
--with-zlib=PREFIX prefix where zlib is installed --with-zlib=PREFIX prefix where zlib is installed
--with-pam=PREFIX prefix where PAM is installed --with-pam=PREFIX prefix where PAM is installed
--with-openssl=PREFIX prefix where OPENSSL is installed --with-openssl=PREFIX prefix where OPENSSL is installed
@ -3034,8 +3031,123 @@ echo "$as_me: error: erlang program was not properly executed, (conftest.out was
#locating libexpat
# Checks for typedefs, structures, and compiler characteristics.
{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; }
if test "${ac_cv_c_const+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
int
main ()
{
/* FIXME: Include the comments suggested by Paul. */
#ifndef __cplusplus
/* Ultrix mips cc rejects this. */
typedef int charset[2];
const charset cs;
/* SunOS 4.1.1 cc rejects this. */
char const *const *pcpcc;
char **ppc;
/* NEC SVR4.0.2 mips cc rejects this. */
struct point {int x, y;};
static struct point const zero = {0,0};
/* AIX XL C 1.02.0.0 rejects this.
It does not let you subtract one const X* pointer from another in
an arm of an if-expression whose if-part is not a constant
expression */
const char *g = "string";
pcpcc = &g + (g ? g-g : 0);
/* HPUX 7.0 cc rejects these. */
++pcpcc;
ppc = (char**) pcpcc;
pcpcc = (char const *const *) ppc;
{ /* SCO 3.2v4 cc rejects this. */
char *t;
char const *s = 0 ? (char *) 0 : (char const *) 0;
*t++ = 0;
if (s) return 0;
}
{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
int x[] = {25, 17};
const int *foo = &x[0];
++foo;
}
{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
typedef const int *iptr;
iptr p = 0;
++p;
}
{ /* AIX XL C 1.02.0.0 rejects this saying
"k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
struct s { int j; const int *ap[3]; };
struct s *b; b->j = 5;
}
{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
const int foo = 10;
if (!foo) return 0;
}
return !cs[0] && !zero.x;
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
ac_cv_c_const=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_c_const=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
echo "${ECHO_T}$ac_cv_c_const" >&6; }
if test $ac_cv_c_const = no; then
cat >>confdefs.h <<\_ACEOF
#define const
_ACEOF
fi
# Check Erlang headers are installed
#AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])])
# Change default prefix
# Checks for library functions.
ac_ext=c ac_ext=c
ac_cpp='$CPP $CPPFLAGS' ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@ -3673,371 +3785,6 @@ done
# Check whether --with-expat was given.
if test "${with_expat+set}" = set; then
withval=$with_expat;
fi
EXPAT_CFLAGS=
EXPAT_LIBS=
if test x"$with_expat" != x; then
EXPAT_CFLAGS="-I$with_expat/include"
EXPAT_LIBS="-L$with_expat/lib"
fi
{ echo "$as_me:$LINENO: checking for XML_ParserCreate in -lexpat" >&5
echo $ECHO_N "checking for XML_ParserCreate in -lexpat... $ECHO_C" >&6; }
if test "${ac_cv_lib_expat_XML_ParserCreate+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lexpat "$EXPAT_LIBS" $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* 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 XML_ParserCreate ();
int
main ()
{
return XML_ParserCreate ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
ac_cv_lib_expat_XML_ParserCreate=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_expat_XML_ParserCreate=no
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_expat_XML_ParserCreate" >&5
echo "${ECHO_T}$ac_cv_lib_expat_XML_ParserCreate" >&6; }
if test $ac_cv_lib_expat_XML_ParserCreate = yes; then
EXPAT_LIBS="$EXPAT_LIBS -lexpat"
expat_found=yes
else
expat_found=no
fi
if test $expat_found = no; then
{ { echo "$as_me:$LINENO: error: Could not find development files of Expat library" >&5
echo "$as_me: error: Could not find development files of Expat library" >&2;}
{ (exit 1); exit 1; }; }
fi
expat_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $EXPAT_CFLAGS"
expat_save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $EXPAT_CFLAGS"
for ac_header in expat.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
ac_res=`eval echo '${'$as_ac_Header'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
else
# Is the header compilable?
{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6; }
# Is the header present?
{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (ac_try="$ac_cpp conftest.$ac_ext"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null && {
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
test ! -s conftest.err
}; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6; }
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
( cat <<\_ASBOX
## --------------------------------------- ##
## Report this to ejabberd@process-one.net ##
## --------------------------------------- ##
_ASBOX
) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
eval "$as_ac_Header=\$ac_header_preproc"
fi
ac_res=`eval echo '${'$as_ac_Header'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
fi
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
else
expat_found=no
fi
done
if test $expat_found = no; then
{ { echo "$as_me:$LINENO: error: Could not find expat.h" >&5
echo "$as_me: error: Could not find expat.h" >&2;}
{ (exit 1); exit 1; }; }
fi
CFLAGS="$expat_save_CFLAGS"
CPPFLAGS="$expat_save_CPPFLAGS"
# Checks for typedefs, structures, and compiler characteristics.
{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; }
if test "${ac_cv_c_const+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
int
main ()
{
/* FIXME: Include the comments suggested by Paul. */
#ifndef __cplusplus
/* Ultrix mips cc rejects this. */
typedef int charset[2];
const charset cs;
/* SunOS 4.1.1 cc rejects this. */
char const *const *pcpcc;
char **ppc;
/* NEC SVR4.0.2 mips cc rejects this. */
struct point {int x, y;};
static struct point const zero = {0,0};
/* AIX XL C 1.02.0.0 rejects this.
It does not let you subtract one const X* pointer from another in
an arm of an if-expression whose if-part is not a constant
expression */
const char *g = "string";
pcpcc = &g + (g ? g-g : 0);
/* HPUX 7.0 cc rejects these. */
++pcpcc;
ppc = (char**) pcpcc;
pcpcc = (char const *const *) ppc;
{ /* SCO 3.2v4 cc rejects this. */
char *t;
char const *s = 0 ? (char *) 0 : (char const *) 0;
*t++ = 0;
if (s) return 0;
}
{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
int x[] = {25, 17};
const int *foo = &x[0];
++foo;
}
{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
typedef const int *iptr;
iptr p = 0;
++p;
}
{ /* AIX XL C 1.02.0.0 rejects this saying
"k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
struct s { int j; const int *ap[3]; };
struct s *b; b->j = 5;
}
{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
const int foo = 10;
if (!foo) return 0;
}
return !cs[0] && !zero.x;
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
ac_cv_c_const=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_c_const=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
echo "${ECHO_T}$ac_cv_c_const" >&6; }
if test $ac_cv_c_const = no; then
cat >>confdefs.h <<\_ACEOF
#define const
_ACEOF
fi
# Check Erlang headers are installed
#AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])])
# Change default prefix
# Checks for library functions.
for ac_header in stdlib.h for ac_header in stdlib.h
do do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
@ -5226,7 +4973,7 @@ fi
ac_config_files="$ac_config_files Makefile $make_mod_muc $make_mod_pubsub $make_mod_proxy65 $make_eldap $make_pam $make_web stringprep/Makefile $make_tls $make_odbc $make_ejabberd_zlib" ac_config_files="$ac_config_files Makefile $make_mod_muc $make_mod_pubsub $make_mod_proxy65 $make_eldap $make_pam $make_web $make_tls $make_odbc $make_ejabberd_zlib"
#openssl #openssl
@ -6219,7 +5966,6 @@ do
"$make_eldap") CONFIG_FILES="$CONFIG_FILES $make_eldap" ;; "$make_eldap") CONFIG_FILES="$CONFIG_FILES $make_eldap" ;;
"$make_pam") CONFIG_FILES="$CONFIG_FILES $make_pam" ;; "$make_pam") CONFIG_FILES="$CONFIG_FILES $make_pam" ;;
"$make_web") CONFIG_FILES="$CONFIG_FILES $make_web" ;; "$make_web") CONFIG_FILES="$CONFIG_FILES $make_web" ;;
"stringprep/Makefile") CONFIG_FILES="$CONFIG_FILES stringprep/Makefile" ;;
"$make_tls") CONFIG_FILES="$CONFIG_FILES $make_tls" ;; "$make_tls") CONFIG_FILES="$CONFIG_FILES $make_tls" ;;
"$make_odbc") CONFIG_FILES="$CONFIG_FILES $make_odbc" ;; "$make_odbc") CONFIG_FILES="$CONFIG_FILES $make_odbc" ;;
"$make_ejabberd_zlib") CONFIG_FILES="$CONFIG_FILES $make_ejabberd_zlib" ;; "$make_ejabberd_zlib") CONFIG_FILES="$CONFIG_FILES $make_ejabberd_zlib" ;;
@ -6337,8 +6083,6 @@ ERLANG_EXMPP!$ERLANG_EXMPP$ac_delim
CPP!$CPP$ac_delim CPP!$CPP$ac_delim
GREP!$GREP$ac_delim GREP!$GREP$ac_delim
EGREP!$EGREP$ac_delim EGREP!$EGREP$ac_delim
EXPAT_CFLAGS!$EXPAT_CFLAGS$ac_delim
EXPAT_LIBS!$EXPAT_LIBS$ac_delim
LIBOBJS!$LIBOBJS$ac_delim LIBOBJS!$LIBOBJS$ac_delim
mod_muc!$mod_muc$ac_delim mod_muc!$mod_muc$ac_delim
make_mod_muc!$make_mod_muc$ac_delim make_mod_muc!$make_mod_muc$ac_delim
@ -6373,7 +6117,7 @@ INSTALLUSER!$INSTALLUSER$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF _ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 88; then if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 86; then
break break
elif $ac_last_try; then elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5

View File

@ -14,8 +14,6 @@ fi
#locating erlang #locating erlang
AM_WITH_ERLANG AM_WITH_ERLANG
#locating libexpat
AM_WITH_EXPAT
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST AC_C_CONST
@ -98,7 +96,6 @@ AC_CONFIG_FILES([Makefile
$make_eldap $make_eldap
$make_pam $make_pam
$make_web $make_web
stringprep/Makefile
$make_tls $make_tls
$make_odbc $make_odbc
$make_ejabberd_zlib]) $make_ejabberd_zlib])

View File

@ -99,19 +99,7 @@ init() ->
LogPath = get_log_path(), LogPath = get_log_path(),
error_logger:add_report_handler(ejabberd_logger_h, LogPath), error_logger:add_report_handler(ejabberd_logger_h, LogPath),
erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv), erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv),
case erl_ddll:load_driver(ejabberd:get_so_path(), expat_erl) of ok.
ok -> ok;
{error, already_loaded} -> ok
end,
Port = open_port({spawn, expat_erl}, [binary]),
loop(Port).
loop(Port) ->
receive
_ ->
loop(Port)
end.
db_init() -> db_init() ->
case mnesia:system_info(extra_db_nodes) of case mnesia:system_info(extra_db_nodes) of

View File

@ -1,190 +0,0 @@
/*
* ejabberd, Copyright (C) 2002-2009 ProcessOne
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*
*/
#include <stdio.h>
#include <string.h>
#include <erl_driver.h>
#include <ei.h>
#include <expat.h>
#define XML_START 0
#define XML_END 1
#define XML_CDATA 2
#define XML_ERROR 3
#define PARSE_COMMAND 0
#define PARSE_FINAL_COMMAND 1
ei_x_buff event_buf;
typedef struct {
ErlDrvPort port;
XML_Parser parser;
} expat_data;
void *erlXML_StartElementHandler(expat_data *d,
const XML_Char *name,
const XML_Char **atts)
{
int i;
ei_x_encode_list_header(&event_buf, 1);
ei_x_encode_tuple_header(&event_buf, 2);
ei_x_encode_long(&event_buf, XML_START);
ei_x_encode_tuple_header(&event_buf, 2);
ei_x_encode_string(&event_buf, name);
for (i = 0; atts[i]; i += 2) {}
if (i > 0)
{
ei_x_encode_list_header(&event_buf, i/2);
for (i = 0; atts[i]; i += 2)
{
ei_x_encode_tuple_header(&event_buf, 2);
ei_x_encode_string(&event_buf, atts[i]);
ei_x_encode_string(&event_buf, atts[i+1]);
}
}
ei_x_encode_empty_list(&event_buf);
return NULL;
}
void *erlXML_EndElementHandler(expat_data *d,
const XML_Char *name)
{
ei_x_encode_list_header(&event_buf, 1);
ei_x_encode_tuple_header(&event_buf, 2);
ei_x_encode_long(&event_buf, XML_END);
ei_x_encode_string(&event_buf, name);
return NULL;
}
void *erlXML_CharacterDataHandler(expat_data *d,
const XML_Char *s,
int len)
{
ei_x_encode_list_header(&event_buf, 1);
ei_x_encode_tuple_header(&event_buf, 2);
ei_x_encode_long(&event_buf, XML_CDATA);
ei_x_encode_binary(&event_buf, s, len);
return NULL;
}
static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
{
expat_data* d = (expat_data*)driver_alloc(sizeof(expat_data));
d->port = port;
d->parser = XML_ParserCreate("UTF-8");
XML_SetUserData(d->parser, d);
set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
XML_SetStartElementHandler(
d->parser, (XML_StartElementHandler)erlXML_StartElementHandler);
XML_SetEndElementHandler(
d->parser, (XML_EndElementHandler)erlXML_EndElementHandler);
XML_SetCharacterDataHandler(
d->parser, (XML_CharacterDataHandler)erlXML_CharacterDataHandler);
return (ErlDrvData)d;
}
static void expat_erl_stop(ErlDrvData handle)
{
XML_ParserFree(((expat_data *)handle)->parser);
driver_free((char*)handle);
}
static int expat_erl_control(ErlDrvData drv_data,
unsigned int command,
char *buf, int len,
char **rbuf, int rlen)
{
expat_data* d = (expat_data*)drv_data;
int res, errcode;
char *errstring;
ErlDrvBinary *b;
size_t size;
switch (command)
{
case PARSE_COMMAND:
case PARSE_FINAL_COMMAND:
ei_x_new_with_version(&event_buf);
res = XML_Parse(d->parser, buf, len, command == PARSE_FINAL_COMMAND);
if(!res)
{
errcode = XML_GetErrorCode(d->parser);
errstring = (char *)XML_ErrorString(errcode);
ei_x_encode_list_header(&event_buf, 1);
ei_x_encode_tuple_header(&event_buf, 2);
ei_x_encode_long(&event_buf, XML_ERROR);
ei_x_encode_tuple_header(&event_buf, 2);
ei_x_encode_long(&event_buf, errcode);
ei_x_encode_string(&event_buf, errstring);
}
ei_x_encode_empty_list(&event_buf);
size = event_buf.index;
b = driver_alloc_binary(size);
memcpy(b->orig_bytes, event_buf.buff, size);
ei_x_free(&event_buf);
*rbuf = (char *)b;
return size;
default:
return 0;
}
}
ErlDrvEntry expat_driver_entry = {
NULL, /* F_PTR init, N/A */
expat_erl_start, /* L_PTR start, called when port is opened */
expat_erl_stop, /* F_PTR stop, called when port is closed */
NULL, /* F_PTR output, called when erlang has sent */
NULL, /* F_PTR ready_input, called when input descriptor ready */
NULL, /* F_PTR ready_output, called when output descriptor ready */
"expat_erl", /* char *driver_name, the argument to open_port */
NULL, /* F_PTR finish, called when unloaded */
NULL, /* handle */
expat_erl_control, /* F_PTR control, port_command callback */
NULL, /* F_PTR timeout, reserved */
NULL /* F_PTR outputv, reserved */
};
DRIVER_INIT(expat_erl) /* must match name in driver_entry */
{
return &expat_driver_entry;
}

View File

@ -566,7 +566,7 @@ get_user_list(_, User, Server)
%% If Dir = in, User@Server is the destination account (To). %% If Dir = in, User@Server is the destination account (To).
check_packet(_, User, Server, check_packet(_, User, Server,
#userlist{list = List, needdb = NeedDb}, #userlist{list = List, needdb = NeedDb},
{From, To, #xmlel{name = PName, attrs = Attrs}}, {From, To, #xmlel{name = PName} = El},
Dir) when Dir) when
PName =:= message ; PName =:= message ;
PName =:= iq ; PName =:= iq ;
@ -579,7 +579,7 @@ check_packet(_, User, Server,
'message' -> message; 'message' -> message;
'iq' -> iq; 'iq' -> iq;
'presence' -> 'presence' ->
case xml:get_attr_s("type", Attrs) of case exmpp_xml:get_attribute(El, type, '') of
%% notification %% notification
'' -> presence; '' -> presence;
'unavailable' -> presence; 'unavailable' -> presence;

View File

@ -1,60 +0,0 @@
# $Id$
CC = @CC@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
# Assume Linux-style dynamic library flags
DYNAMIC_LIB_CFLAGS = -fpic -shared
ifeq ($(shell uname),Darwin)
DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
endif
ifeq ($(shell uname),SunOs)
DYNAMIC_LIB_CFLAGS = -KPIC -G -z text
endif
EFLAGS += -I ..
EFLAGS += -pz ..
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
endif
ERLSHLIBS = ../stringprep_drv.so
OUTDIR = ..
SOURCES = $(wildcard *.erl)
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
all: $(BEAMS) $(ERLSHLIBS)
$(OUTDIR)/%.beam: %.erl
@ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
#all: $(ERLSHLIBS)
# erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt
$(ERLSHLIBS): ../%.so: %.c uni_data.c uni_norm.c
$(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDES) \
$(subst ../,,$(subst .so,.c,$@)) $(LIBS) \
$(ERLANG_LIBS) \
$(ERLANG_CFLAGS) \
-o $@ \
$(DYNAMIC_LIB_CFLAGS)
clean:
rm -f $(BEAMS) $(ERLSHLIBS)
distclean: clean
rm -f Makefile
TAGS:
etags *.erl

View File

@ -1,40 +0,0 @@
include ..\Makefile.inc
EFLAGS = -I .. -pz ..
OUTDIR = ..
BEAMS = ..\stringprep.beam ..\stringprep_sup.beam
SOURCE = stringprep_drv.c
AUXIL = uni_data.c uni_norm.c
OBJECT = stringprep_drv.o
DLL = $(OUTDIR)\stringprep_drv.dll
ALL : $(DLL) $(BEAMS)
CLEAN :
-@erase $(DLL)
-@erase $(OUTDIR)\stringprep_drv.exp
-@erase $(OUTDIR)\stringprep_drv.lib
-@erase $(OBJECT)
-@erase $(BEAMS)
$(OUTDIR)\stringprep.beam : stringprep.erl
erlc -W $(EFLAGS) -o $(OUTDIR) stringprep.erl
$(OUTDIR)\stringprep_sup.beam : stringprep_sup.erl
erlc -W $(EFLAGS) -o $(OUTDIR) stringprep_sup.erl
CC=cl.exe
CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include"
LD=link.exe
LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib
$(DLL) : $(OBJECT)
$(LD) $(LD_FLAGS) -out:$(DLL) $(OBJECT)
$(OBJECT) : $(SOURCE) $(AUXIL)
$(CC) $(CC_FLAGS) -c -Fo$(OBJECT) $(SOURCE)

View File

@ -1,113 +0,0 @@
%%%----------------------------------------------------------------------
%%% File : stringprep.erl
%%% Author : Alexey Shchepin <alexey@process-one.net>
%%% Purpose : Interface to stringprep_drv
%%% Created : 16 Feb 2003 by Alexey Shchepin <alexey@proces-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%%
%%% 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 2 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, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%%
%%%----------------------------------------------------------------------
-module(stringprep).
-author('alexey@process-one.net').
-behaviour(gen_server).
-export([start/0, start_link/0,
tolower/1,
nameprep/1,
nodeprep/1,
resourceprep/1]).
%% Internal exports, call-back functions.
-export([init/1,
handle_call/3,
handle_cast/2,
handle_info/2,
code_change/3,
terminate/2]).
-define(STRINGPREP_PORT, stringprep_port).
-define(NAMEPREP_COMMAND, 1).
-define(NODEPREP_COMMAND, 2).
-define(RESOURCEPREP_COMMAND, 3).
start() ->
gen_server:start({local, ?MODULE}, ?MODULE, [], []).
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
init([]) ->
case erl_ddll:load_driver(ejabberd:get_so_path(), stringprep_drv) of
ok -> ok;
{error, already_loaded} -> ok
end,
Port = open_port({spawn, stringprep_drv}, []),
register(?STRINGPREP_PORT, Port),
{ok, Port}.
%%% --------------------------------------------------------
%%% The call-back functions.
%%% --------------------------------------------------------
handle_call(_, _, State) ->
{noreply, State}.
handle_cast(_, State) ->
{noreply, State}.
handle_info({'EXIT', Port, Reason}, Port) ->
{stop, {port_died, Reason}, Port};
handle_info({'EXIT', _Pid, _Reason}, Port) ->
{noreply, Port};
handle_info(_, State) ->
{noreply, State}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
terminate(_Reason, Port) ->
Port ! {self, close},
ok.
tolower(String) ->
control(0, String).
nameprep(String) ->
control(?NAMEPREP_COMMAND, String).
nodeprep(String) ->
control(?NODEPREP_COMMAND, String).
resourceprep(String) ->
control(?RESOURCEPREP_COMMAND, String).
control(Command, String) ->
case port_control(?STRINGPREP_PORT, Command, String) of
[0 | _] -> error;
[1 | Res] -> Res
end.

View File

@ -1,410 +0,0 @@
/*
* ejabberd, Copyright (C) 2002-2009 ProcessOne
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*
*/
#include <stdio.h>
#include <string.h>
#include <erl_driver.h>
#include <ei.h>
#include "uni_data.c"
#include "uni_norm.c"
#define NAMEPREP_COMMAND 1
#define NODEPREP_COMMAND 2
#define RESOURCEPREP_COMMAND 3
typedef struct {
ErlDrvPort port;
} stringprep_data;
static ErlDrvData stringprep_erl_start(ErlDrvPort port, char *buff)
{
stringprep_data* d = (stringprep_data*)driver_alloc(sizeof(stringprep_data));
d->port = port;
//set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
return (ErlDrvData)d;
}
static void stringprep_erl_stop(ErlDrvData handle)
{
driver_free((char*)handle);
}
/* Hangul constants */
#define SBase 0xAC00
#define LBase 0x1100
#define VBase 0x1161
#define TBase 0x11A7
#define LCount 19
#define VCount 21
#define TCount 28
#define NCount (VCount * TCount)
#define SCount (LCount * NCount)
/*
* "canonical_ordering" and "compose" functions are based on nfkc.c from Gnome
* library
*/
static void canonical_ordering(int *str, int len)
{
int i, j, t;
int last, next;
last = GetUniCharCClass(str[0]);
for (i = 0; i < len - 1; i++)
{
next = GetUniCharCClass(str[i + 1]);
if (next != 0 && last > next)
{
for (j = i; j >= 0; j--)
{
if (GetUniCharCClass(str[j]) <= next)
break;
t = str[j + 1];
str[j + 1] = str[j];
str[j] = t;
}
next = last;
}
last = next;
}
}
static int compose(int ch1, int ch2)
{
int info1, info2;
if (LBase <= ch1 && ch1 < LBase + LCount &&
VBase <= ch2 && ch2 < VBase + VCount) {
return SBase + ((ch1 - LBase) * VCount + (ch2 - VBase)) * TCount;
}
if (SBase <= ch1 && ch1 < SBase + SCount && ((ch1 - SBase) % TCount) == 0 &&
TBase <= ch2 && ch2 < TBase + TCount) {
return ch1 + ch2 - TBase;
}
info1 = GetUniCharCompInfo(ch1);
if (info1 != -1 && info1 & CompSingleMask) {
if (!(info1 & CompSecondMask) &&
ch2 == compFirstList[info1 & CompMask][0]) {
return compFirstList[info1 & CompMask][1];
} else
return 0;
}
info2 = GetUniCharCompInfo(ch2);
if (info2 != -1 && info2 & CompSingleMask) {
if ((info2 & CompSecondMask) &&
ch1 == compSecondList[info2 & CompMask][0]) {
return compSecondList[info2 & CompMask][1];
} else
return 0;
}
if (info1 != -1 && info2 != -1 &&
!(info1 & CompSecondMask) && (info2 & CompSecondMask))
return compBothList[info1][info2 & CompMask];
else
return 0;
}
#define ADD_UCHAR(ruc) \
if (ruc <= 0x7F) { \
if (pos >= size) { \
size = 2*size + 1; \
rstring = driver_realloc(rstring, size); \
} \
rstring[pos] = (char) ruc; \
pos++; \
} else if (ruc <= 0x7FF) { \
if (pos + 1 >= size) { \
size = 2*size + 2; \
rstring = driver_realloc(rstring, size); \
} \
rstring[pos] = (char) ((ruc >> 6) | 0xC0); \
rstring[pos+1] = (char) ((ruc | 0x80) & 0xBF); \
pos += 2; \
} else if (ruc <= 0xFFFF) { \
if (pos + 2 >= size) { \
size = 2*size + 3; \
rstring = driver_realloc(rstring, size); \
} \
rstring[pos] = (char) ((ruc >> 12) | 0xE0); \
rstring[pos+1] = (char) (((ruc >> 6) | 0x80) & 0xBF); \
rstring[pos+2] = (char) ((ruc | 0x80) & 0xBF); \
pos += 3; \
} else if (ruc <= 0x1FFFFF) { \
if (pos + 3 >= size) { \
size = 2*size + 4; \
rstring = driver_realloc(rstring, size); \
} \
rstring[pos] = (char) ((ruc >> 18) | 0xF0); \
rstring[pos+1] = (char) (((ruc >> 12) | 0x80) & 0xBF); \
rstring[pos+2] = (char) (((ruc >> 6) | 0x80) & 0xBF); \
rstring[pos+3] = (char) ((ruc | 0x80) & 0xBF); \
pos += 4; \
}
#define ADD_UCHAR32(str, pos, len, ch) \
if (pos >= len) { \
len = 2*len + 1; \
str = driver_realloc(str, len * sizeof(int)); \
} \
str[pos] = ch; \
pos++;
#define ADD_DECOMP(ruc) \
info = GetUniCharDecompInfo(ruc); \
if (info >= 0) { \
decomp_len = GetDecompLen(info); \
decomp_shift = GetDecompShift(info); \
for (j = 0; j < decomp_len; j++) { \
ADD_UCHAR32(str32, str32pos, str32len, \
decompList[decomp_shift + j]); \
} \
} else { \
ADD_UCHAR32(str32, str32pos, str32len, ruc); \
}
static int stringprep_erl_control(ErlDrvData drv_data,
unsigned int command,
char *buf, int len,
char **rbuf, int rlen)
{
int i, j, pos=1;
unsigned char c;
int bad = 0;
int uc = 0, ruc;
int size;
int info;
int prohibit = 0, tolower = 0;
char *rstring;
int *mc;
int *str32;
int str32len, str32pos = 0;
int decomp_len, decomp_shift;
int comp_pos, comp_starter_pos;
int cclass_prev, cclass2;
int ch1, ch2;
int first_ral, last_ral, have_ral, have_l;
size = len + 1;
rstring = driver_alloc(size);
rstring[0] = 0;
str32len = len + 1;
str32 = driver_alloc(str32len * sizeof(int));
switch (command)
{
case 0:
prohibit = ACMask;
tolower = 1;
break;
case NAMEPREP_COMMAND:
prohibit = ACMask;
tolower = 1;
break;
case NODEPREP_COMMAND:
prohibit = ACMask | C11Mask | C21Mask | XNPMask;
tolower = 1;
break;
case RESOURCEPREP_COMMAND:
prohibit = ACMask | C21Mask;
tolower = 0;
break;
}
for (i = 0; i < len; i++)
{
c = buf[i];
if (c < 0x80) {
uc = c;
} else if (c < 0xC0) {
bad = 1;
} else if (c < 0xE0) {
if (i+1 < len && (buf[i+1] & 0xC0) == 0x80) {
uc = ((c & 0x1F) << 6) | (buf[i+1] & 0x3F);
i++;
} else {
bad = 1;
}
} else if (c < 0xF0) {
if (i+2 < len && (buf[i+1] & 0xC0) == 0x80 &&
(buf[i+2] & 0xC0) == 0x80) {
uc = ((c & 0x0F) << 12)
| ((buf[i+1] & 0x3F) << 6)
| (buf[i+2] & 0x3F);
i += 2;
} else {
bad = 1;
}
} else if (c < 0xF8) {
if (i+3 < len &&
(buf[i+1] & 0xC0) == 0x80 &&
(buf[i+2] & 0xC0) == 0x80 &&
(buf[i+3] & 0xC0) == 0x80) {
uc = ((c & 0x07) << 18)
| ((buf[i+1] & 0x3F) << 12)
| ((buf[i+2] & 0x3F) << 6)
| (buf[i+3] & 0x3F);
i += 3;
if (uc > 0x10FFFF)
bad = 1;
} else {
bad = 1;
}
} else {
bad = 1;
}
if (bad) {
*rbuf = rstring;
driver_free(str32);
return 1;
}
info = GetUniCharInfo(uc);
if (!(info & B1Mask))
{
if (tolower) {
if (!(info & MCMask))
{
ruc = uc + GetDelta(info);
ADD_DECOMP(ruc);
} else {
mc = GetMC(info);
for (j = 1; j <= mc[0]; j++) {
ruc = mc[j];
ADD_DECOMP(ruc);
}
}
} else {
ruc = uc;
ADD_DECOMP(ruc);
}
}
}
if (str32pos == 0) {
rstring[0] = 1;
*rbuf = rstring;
driver_free(str32);
return 1;
}
canonical_ordering(str32, str32pos);
comp_pos = 1;
comp_starter_pos = 0;
ch1 = str32[0];
cclass_prev = GetUniCharCClass(ch1);
for (i = 1; i < str32pos; i++)
{
ch2 = str32[i];
cclass2 = GetUniCharCClass(ch2);
if ((cclass_prev == 0 || cclass2 > cclass_prev) &&
(ruc = compose(ch1, ch2))) {
ch1 = ruc;
} else {
if (cclass2 == 0) {
str32[comp_starter_pos] = ch1;
comp_starter_pos = comp_pos++;
ch1 = ch2;
cclass_prev = 0;
} else {
str32[comp_pos++] = ch2;
cclass_prev = cclass2;
}
}
}
str32[comp_starter_pos] = ch1;
str32pos = comp_pos;
last_ral = have_ral = have_l = 0;
info = GetUniCharInfo(str32[0]);
first_ral = info & D1Mask;
for (i = 0; i < str32pos; i++)
{
ruc = str32[i];
info = GetUniCharInfo(ruc);
if (info & prohibit) {
*rbuf = rstring;
driver_free(str32);
return 1;
}
last_ral = info & D1Mask;
have_ral = have_ral || last_ral;
have_l = info & D2Mask;
ADD_UCHAR(ruc);
}
if (have_ral && (!first_ral || !last_ral || have_l)) {
*rbuf = rstring;
driver_free(str32);
return 1;
}
rstring[0] = 1;
*rbuf = rstring;
driver_free(str32);
return pos;
}
ErlDrvEntry stringprep_driver_entry = {
NULL, /* F_PTR init, N/A */
stringprep_erl_start, /* L_PTR start, called when port is opened */
stringprep_erl_stop, /* F_PTR stop, called when port is closed */
NULL, /* F_PTR output, called when erlang has sent */
NULL, /* F_PTR ready_input, called when input descriptor ready */
NULL, /* F_PTR ready_output, called when output descriptor ready */
"stringprep_drv", /* char *driver_name, the argument to open_port */
NULL, /* F_PTR finish, called when unloaded */
NULL, /* handle */
stringprep_erl_control, /* F_PTR control, port_command callback */
NULL, /* F_PTR timeout, reserved */
NULL /* F_PTR outputv, reserved */
};
DRIVER_INIT(stringprep_erl) /* must match name in driver_entry */
{
return &stringprep_driver_entry;
}

View File

@ -1,68 +0,0 @@
%%%-------------------------------------------------------------------
%%% File : stringprep_sup.erl
%%% Author : Mickael Remond <mremond@process-one.net>
%%% Description : Supervisor for the Stringprep worker.
%%% Created : 29 Jun 2007 by Mickael Remond <mremond@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%%
%%% 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 2 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, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%%
%%%-------------------------------------------------------------------
-module(stringprep_sup).
-behaviour(supervisor).
%% API
-export([start_link/0]).
%% Supervisor callbacks
-export([init/1]).
-define(SERVER, ?MODULE).
%%====================================================================
%% API functions
%%====================================================================
%%--------------------------------------------------------------------
%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
%% Description: Starts the supervisor
%%--------------------------------------------------------------------
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
%%====================================================================
%% Supervisor callbacks
%%====================================================================
%%--------------------------------------------------------------------
%% Func: init(Args) -> {ok, {SupFlags, [ChildSpec]}} |
%% ignore |
%% {error, Reason}
%% Description: Whenever a supervisor is started using
%% supervisor:start_link/[2,3], this function is called by the new process
%% to find out about restart strategy, maximum restart frequency and child
%% specifications.
%%--------------------------------------------------------------------
init([]) ->
StringPrep = {stringprep,
{stringprep, start_link, []},
permanent,
brutal_kill,
worker,
[stringprep]},
{ok,{{one_for_all,10,1}, [StringPrep]}}.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,437 +0,0 @@
# uni_parse.tcl --
#
# This program parses the UnicodeData file and generates the
# corresponding uni_data.c file with compressed character
# data tables. The input to this program should be rfc3454.txt
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
# Modified for ejabberd by Alexey Shchepin
#
# RCS: @(#) $Id$
namespace eval uni {
set shift 8; # number of bits of data within a page
# This value can be adjusted to find the
# best split to minimize table size
variable pMap; # map from page to page index, each entry is
# an index into the pages table, indexed by
# page number
variable pages; # map from page index to page info, each
# entry is a list of indices into the groups
# table, the list is indexed by the offset
variable groups; # list of character info values, indexed by
# group number, initialized with the
# unassigned character group
}
proc uni::getValue {i} {
variable casemap
variable casemap2
variable tablemap
if {[info exists tablemap($i)]} {
set tables $tablemap($i)
} else {
set tables {}
}
if {[info exists casemap2($i)]} {
set multicase 1
set delta $casemap2($i)
} else {
set multicase 0
if {[info exists casemap($i)]} {
set delta $casemap($i)
} else {
set delta 0
}
}
if {abs($delta) > 0xFFFFF} {
puts "delta must be less than 22 bits wide"
exit
}
set ac 0
set c11 0
set c21 0
set b1 0
set d1 0
set d2 0
set xnp 0
foreach tab $tables {
switch -glob -- $tab {
C.1.1 {set c11 1}
C.2.1 {set c21 1}
C.* {set ac 1}
A.1 {set ac 1}
B.1 {set b1 1}
D.1 {set d1 1}
D.2 {set d2 1}
XNP {set xnp 1}
}
}
set val [expr {($ac << 0) |
($c11 << 1) |
($c21 << 2) |
($b1 << 3) |
($d1 << 4) |
($d2 << 5) |
($xnp << 6) |
($multicase << 7) |
($delta << 11)}]
return $val
}
proc uni::getGroup {value} {
variable groups
set gIndex [lsearch -exact $groups $value]
if {$gIndex == -1} {
set gIndex [llength $groups]
lappend groups $value
}
return $gIndex
}
proc uni::addPage {info} {
variable pMap
variable pages
variable pages_map
if {[info exists pages_map($info)]} {
lappend pMap $pages_map($info)
} else {
set pIndex [llength $pages]
lappend pages $info
set pages_map($info) $pIndex
lappend pMap $pIndex
}
return
}
proc uni::load_tables {data} {
variable casemap
variable casemap2
variable multicasemap
variable tablemap
set multicasemap {}
set table ""
foreach line [split $data \n] {
if {$table == ""} {
if {[regexp { ----- Start Table (.*) -----} $line temp table]} {
#puts "Start table '$table'"
}
} else {
if {[regexp { ----- End Table (.*) -----} $line temp table1]} {
set table ""
} else {
if {$table == "B.1"} {
if {[regexp {^ ([[:xdigit:]]+); ;} $line \
temp val]} {
scan $val %x val
if {$val <= 0x10ffff} {
lappend tablemap($val) $table
}
}
} elseif {$table == "B.2"} {
if {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+);} $line \
temp from to]} {
scan $from %x from
scan $to %x to
if {$from <= 0x10ffff && $to <= 0x10ffff} {
set casemap($from) [expr {$to - $from}]
}
} elseif {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+) ([[:xdigit:]]+);} $line \
temp from to1 to2]} {
scan $from %x from
scan $to1 %x to1
scan $to2 %x to2
if {$from <= 0x10ffff && \
$to1 <= 0x10ffff && $to2 <= 0x10ffff} {
set casemap2($from) [llength $multicasemap]
lappend multicasemap [list $to1 $to2]
}
} elseif {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+) ([[:xdigit:]]+) ([[:xdigit:]]+);} $line \
temp from to1 to2 to3]} {
scan $from %x from
scan $to1 %x to1
scan $to2 %x to2
scan $to3 %x to3
if {$from <= 0x10ffff && \
$to1 <= 0x10ffff && $to2 <= 0x10ffff && \
$to3 <= 0x10ffff} {
set casemap2($from) [llength $multicasemap]
lappend multicasemap [list $to1 $to2 $to3]
}
} else {
#puts "missed: $line"
}
} elseif {$table != "B.3"} {
if {[regexp {^ ([[:xdigit:]]+)-([[:xdigit:]]+)} $line \
temp from to]} {
scan $from %x from
scan $to %x to
for {set i $from} {$i <= $to && $i <= 0x10ffff} {incr i} {
lappend tablemap($i) $table
}
} elseif {[regexp {^ ([[:xdigit:]]+)} $line \
temp val]} {
scan $val %x val
if {$val <= 0x10ffff} {
lappend tablemap($val) $table
}
}
}
}
}
}
# XMPP nodeprep prohibited
foreach val {22 26 27 2f 3a 3c 3e 40} {
scan $val %x val
lappend tablemap($val) XNP
}
}
proc uni::buildTables {} {
variable shift
variable casemap
variable tablemap
variable pMap {}
variable pages {}
variable groups {}
set info {} ;# temporary page info
set mask [expr {(1 << $shift) - 1}]
set next 0
for {set i 0} {$i <= 0x10ffff} {incr i} {
set gIndex [getGroup [getValue $i]]
# Split character index into offset and page number
set offset [expr {$i & $mask}]
set page [expr {($i >> $shift)}]
# Add the group index to the info for the current page
lappend info $gIndex
# If this is the last entry in the page, add the page
if {$offset == $mask} {
addPage $info
set info {}
}
}
return
}
proc uni::main {} {
global argc argv0 argv
variable pMap
variable pages
variable groups
variable shift
variable multicasemap
if {$argc != 2} {
puts stderr "\nusage: $argv0 <datafile> <outdir>\n"
exit 1
}
set f [open [lindex $argv 0] r]
set data [read $f]
close $f
load_tables $data
buildTables
puts "X = [llength $pMap] Y= [llength $pages] A= [llength $groups]"
set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}]
puts "shift = $shift, space = $size"
set f [open [file join [lindex $argv 1] uni_data.c] w]
fconfigure $f -translation lf
puts $f "/*
* uni_data.c --
*
* Declarations of Unicode character information tables. This file is
* automatically generated by the uni_parse.tcl script. Do not
* modify this file by hand.
*
* Copyright (c) 1998 by Scriptics Corporation.
* All rights reserved.
*
* Modified for ejabberd by Alexey Shchepin
*
* RCS: @(#) \$Id\$
*/
/*
* A 16-bit Unicode character is split into two parts in order to index
* into the following tables. The lower OFFSET_BITS comprise an offset
* into a page of characters. The upper bits comprise the page number.
*/
#define OFFSET_BITS $shift
/*
* The pageMap is indexed by page number and returns an alternate page number
* that identifies a unique page of characters. Many Unicode characters map
* to the same alternate page number.
*/
static unsigned char pageMap\[\] = {"
set line " "
set last [expr {[llength $pMap] - 1}]
for {set i 0} {$i <= $last} {incr i} {
append line [lindex $pMap $i]
if {$i != $last} {
append line ", "
}
if {[string length $line] > 70} {
puts $f $line
set line " "
}
}
puts $f $line
puts $f "};
/*
* The groupMap is indexed by combining the alternate page number with
* the page offset and returns a group number that identifies a unique
* set of character attributes.
*/
static unsigned short int groupMap\[\] = {"
set line " "
set lasti [expr {[llength $pages] - 1}]
for {set i 0} {$i <= $lasti} {incr i} {
set page [lindex $pages $i]
set lastj [expr {[llength $page] - 1}]
for {set j 0} {$j <= $lastj} {incr j} {
append line [lindex $page $j]
if {$j != $lastj || $i != $lasti} {
append line ", "
}
if {[string length $line] > 70} {
puts $f $line
set line " "
}
}
}
puts $f $line
puts $f "};
/*
* Each group represents a unique set of character attributes. The attributes
* are encoded into a 32-bit value as follows:
*
* Bit 0 A.1 | C.1.2 | C.2.2 | C.3 -- C.9
*
* Bit 1 C.1.1
*
* Bit 2 C.2.1
*
* Bit 3 B.1
*
* Bit 4 D.1
*
* Bit 5 D.2
*
* Bit 6 XNP
*
* Bit 7 Case maps to several characters
*
* Bits 8-10 Reserved for future use.
*
* Bits 11-31 Case delta: delta for case conversions. This should be the
* highest field so we can easily sign extend.
*/
static int groups\[\] = {"
set line " "
set last [expr {[llength $groups] - 1}]
for {set i 0} {$i <= $last} {incr i} {
set val [lindex $groups $i]
append line [format "%d" $val]
if {$i != $last} {
append line ", "
}
if {[string length $line] > 65} {
puts $f $line
set line " "
}
}
puts $f $line
puts $f "};
/*
* Table for characters that lowercased to multiple ones
*/
static int multiCaseTable\[\]\[4\] = {"
set last [expr {[llength $multicasemap] - 1}]
for {set i 0} {$i <= $last} {incr i} {
set val [lindex $multicasemap $i]
set line " "
append line [format "{%d, %s}" [llength $val] [join $val ", "]]
if {$i != $last} {
append line ", "
}
puts $f $line
}
puts $f "};
/*
* The following constants are used to determine the category of a
* Unicode character.
*/
#define ACMask (1 << 0)
#define C11Mask (1 << 1)
#define C21Mask (1 << 2)
#define B1Mask (1 << 3)
#define D1Mask (1 << 4)
#define D2Mask (1 << 5)
#define XNPMask (1 << 6)
#define MCMask (1 << 7)
/*
* The following macros extract the fields of the character info. The
* GetDelta() macro is complicated because we can't rely on the C compiler
* to do sign extension on right shifts.
*/
#define GetCaseType(info) (((info) & 0xE0) >> 5)
#define GetCategory(info) ((info) & 0x1F)
#define GetDelta(info) (((info) > 0) ? ((info) >> 11) : (~(~((info)) >> 11)))
#define GetMC(info) (multiCaseTable\[GetDelta(info)\])
/*
* This macro extracts the information about a character from the
* Unicode character tables.
*/
#define GetUniCharInfo(ch) (groups\[groupMap\[(pageMap\[(((int)(ch)) & 0x1fffff) >> OFFSET_BITS\] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))\]\])
"
close $f
}
uni::main
return

View File

@ -1,702 +0,0 @@
# uni_parse2.tcl --
#
# This program parses the UnicodeData file and generates the
# corresponding uni_norm.c file with compressed character
# data tables. The input to this program should be
# UnicodeData-3.2.0.txt and CompositionExclusions-3.2.0.txt files from:
# ftp://ftp.unicode.org/Public/UNIDATA/
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
# Modified for ejabberd by Alexey Shchepin
#
# RCS: @(#) $Id$
namespace eval uni {
set cclass_shift 8
set decomp_shift 8
set comp_shift 8
set shift 5; # number of bits of data within a page
# This value can be adjusted to find the
# best split to minimize table size
variable pMap; # map from page to page index, each entry is
# an index into the pages table, indexed by
# page number
variable pages; # map from page index to page info, each
# entry is a list of indices into the groups
# table, the list is indexed by the offset
variable groups; # list of character info values, indexed by
# group number, initialized with the
# unassigned character group
variable categories {
Cn Lu Ll Lt Lm Lo Mn Me Mc Nd Nl No Zs Zl Zp
Cc Cf Co Cs Pc Pd Ps Pe Pi Pf Po Sm Sc Sk So
}; # Ordered list of character categories, must
# match the enumeration in the header file.
variable titleCount 0; # Count of the number of title case
# characters. This value is used in the
# regular expression code to allocate enough
# space for the title case variants.
}
proc uni::getValue {items index} {
variable categories
variable titleCount
# Extract character info
set category [lindex $items 2]
if {[scan [lindex $items 12] %4x toupper] == 1} {
set toupper [expr {$index - $toupper}]
} else {
set toupper {}
}
if {[scan [lindex $items 13] %4x tolower] == 1} {
set tolower [expr {$tolower - $index}]
} else {
set tolower {}
}
if {[scan [lindex $items 14] %4x totitle] == 1} {
set totitle [expr {$index - $totitle}]
} else {
set totitle {}
}
set categoryIndex [lsearch -exact $categories $category]
if {$categoryIndex < 0} {
puts "Unexpected character category: $index($category)"
set categoryIndex 0
} elseif {$category == "Lt"} {
incr titleCount
}
return "$categoryIndex,$toupper,$tolower,$totitle"
}
proc uni::getGroup {value} {
variable groups
set gIndex [lsearch -exact $groups $value]
if {$gIndex == -1} {
set gIndex [llength $groups]
lappend groups $value
}
return $gIndex
}
proc uni::addPage {info} {
variable pMap
variable pages
set pIndex [lsearch -exact $pages $info]
if {$pIndex == -1} {
set pIndex [llength $pages]
lappend pages $info
}
lappend pMap $pIndex
return
}
proc uni::addPage {map_var pages_var info} {
variable $map_var
variable $pages_var
set pIndex [lsearch -exact [set $pages_var] $info]
if {$pIndex == -1} {
set pIndex [llength [set $pages_var]]
lappend $pages_var $info
}
lappend $map_var $pIndex
return
}
proc uni::load_exclusions {data} {
variable exclusions
foreach line [split $data \n] {
if {$line == ""} continue
set items [split $line " "]
if {[lindex $items 0] == "#"} continue
scan [lindex $items 0] %x index
set exclusions($index) ""
}
}
proc uni::load_tables {data} {
variable cclass_map
variable decomp_map
variable comp_map
variable comp_first
variable comp_second
variable exclusions
foreach line [split $data \n] {
if {$line == ""} continue
set items [split $line \;]
scan [lindex $items 0] %x index
set cclass [lindex $items 3]
set decomp [lindex $items 5]
set cclass_map($index) $cclass
#set decomp_map($index) $cclass
if {$decomp != ""} {
if {[string index [lindex $decomp 0] 0] == "<"} {
set decomp1 [lreplace $decomp 0 0]
set decomp {}
foreach ch $decomp1 {
scan $ch %x ch
lappend decomp $ch
}
set decomp_map($index) $decomp
} else {
switch -- [llength $decomp] {
1 {
scan $decomp %x ch
set decomp_map($index) $ch
}
2 {
scan $decomp "%x %x" ch1 ch2
set decomp [list $ch1 $ch2]
set decomp_map($index) $decomp
# hackish
if {(![info exists cclass_map($ch1)] || \
$cclass_map($ch1) == 0) && \
![info exists exclusions($index)]} {
if {[info exists comp_first($ch1)]} {
incr comp_first($ch1)
} else {
set comp_first($ch1) 1
}
if {[info exists comp_second($ch2)]} {
incr comp_second($ch2)
} else {
set comp_second($ch2) 1
}
set comp_map($decomp) $index
} else {
puts "Excluded $index"
}
}
default {
puts "Bad canonical decomposition: $line"
}
}
}
#puts "[format 0x%0.4x $index]\t$cclass\t$decomp_map($index)"
}
}
#puts [array get comp_first]
#puts [array get comp_second]
}
proc uni::buildTables {} {
variable cclass_shift
variable decomp_shift
variable comp_shift
variable cclass_map
variable cclass_pmap {}
variable cclass_pages {}
variable decomp_map
variable decomp_pmap {}
variable decomp_pages {}
variable decomp_list {}
variable comp_map
variable comp_pmap {}
variable comp_pages {}
variable comp_first
variable comp_second
variable comp_first_list {}
variable comp_second_list {}
variable comp_x_list {}
variable comp_y_list {}
variable comp_both_map {}
set cclass_info {}
set decomp_info {}
set comp_info {}
set cclass_mask [expr {(1 << $cclass_shift) - 1}]
set decomp_mask [expr {(1 << $decomp_shift) - 1}]
set comp_mask [expr {(1 << $comp_shift) - 1}]
foreach comp [array names comp_map] {
set ch1 [lindex $comp 0]
if {[info exists comp_first($ch1)] && $comp_first($ch1) > 0 && \
[info exists comp_second($ch1)] && $comp_second($ch1) > 0} {
if {[lsearch -exact $comp_x_list $ch1] < 0} {
set i [llength $comp_x_list]
lappend comp_x_list $ch1
set comp_info_map($ch1) $i
lappend comp_y_list $ch1
set comp_info_map($ch1) $i
puts "There should be no symbols which appears on"
puts "both first and second place in composition"
exit
}
}
}
foreach comp [array names comp_map] {
set ch1 [lindex $comp 0]
set ch2 [lindex $comp 1]
if {$comp_first($ch1) == 1 && ![info exists comp_second($ch1)]} {
set i [llength $comp_first_list]
lappend comp_first_list [list $ch2 $comp_map($comp)]
set comp_info_map($ch1) [expr {$i | (1 << 16)}]
} elseif {$comp_second($ch2) == 1 && ![info exists comp_first($ch2)]} {
set i [llength $comp_second_list]
lappend comp_second_list [list $ch1 $comp_map($comp)]
set comp_info_map($ch2) [expr {$i | (1 << 16) | (1 << 17)}]
} else {
if {[lsearch -exact $comp_x_list $ch1] < 0} {
set i [llength $comp_x_list]
lappend comp_x_list $ch1
set comp_info_map($ch1) $i
}
if {[lsearch -exact $comp_y_list $ch2] < 0} {
set i [llength $comp_y_list]
lappend comp_y_list $ch2
set comp_info_map($ch2) [expr {$i | (1 << 17)}]
}
}
}
set next 0
for {set i 0} {$i <= 0x10ffff} {incr i} {
#set gIndex [getGroup [getValue $i]]
set cclass_offset [expr {$i & $cclass_mask}]
if {[info exists cclass_map($i)]} {
set cclass $cclass_map($i)
} else {
set cclass 0
}
lappend cclass_info $cclass
if {$cclass_offset == $cclass_mask} {
addPage cclass_pmap cclass_pages $cclass_info
set cclass_info {}
}
set decomp_offset [expr {$i & $decomp_mask}]
if {[info exists decomp_map($i)]} {
set decomp $decomp_map($i)
set b 1
while {$b} {
set b 0
for {set j 0} {$j < [llength $decomp]} {incr j} {
if {[info exists \
decomp_map([set ch1 [lindex $decomp $j]])]} {
#puts -$decomp
set decomp [eval [list lreplace $decomp $j $j] \
$decomp_map($ch1)]
#puts +$decomp
set b 1
}
}
}
if {[info exists decomp_used($decomp)]} {
lappend decomp_info $decomp_used($decomp)
} else {
set val [expr {([llength $decomp] << 16) + \
[llength $decomp_list]}]
#set val [expr {[llength $decomp_list]}]
lappend decomp_info $val
set decomp_used($decomp) $val
#puts "$val $decomp"
foreach d $decomp {
lappend decomp_list $d
}
}
} else {
lappend decomp_info -1
}
if {$decomp_offset == $decomp_mask} {
addPage decomp_pmap decomp_pages $decomp_info
set decomp_info {}
}
set comp_offset [expr {$i & $comp_mask}]
if {[info exists comp_info_map($i)]} {
set comp $comp_info_map($i)
} else {
set comp -1
}
lappend comp_info $comp
if {$comp_offset == $comp_mask} {
addPage comp_pmap comp_pages $comp_info
set comp_info {}
}
}
#puts [array get decomp_map]
#puts $decomp_list
return
}
proc uni::main {} {
global argc argv0 argv
variable cclass_shift
variable cclass_pmap
variable cclass_pages
variable decomp_shift
variable decomp_pmap
variable decomp_pages
variable decomp_list
variable comp_shift
variable comp_map
variable comp_pmap
variable comp_pages
variable comp_first_list
variable comp_second_list
variable comp_x_list
variable comp_y_list
variable pages
variable groups {}
variable titleCount
if {$argc != 3} {
puts stderr "\nusage: $argv0 <datafile> <exclusionsfile> <outdir>\n"
exit 1
}
set f [open [lindex $argv 1] r]
set data [read $f]
close $f
load_exclusions $data
set f [open [lindex $argv 0] r]
set data [read $f]
close $f
load_tables $data
buildTables
#puts "X = [llength $pMap] Y= [llength $pages] A= [llength $groups]"
#set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}]
#puts "shift = 6, space = $size"
#puts "title case count = $titleCount"
set f [open [file join [lindex $argv 2] uni_norm.c] w]
fconfigure $f -translation lf
puts $f "/*
* uni_norm.c --
*
* Declarations of Unicode character information tables. This file is
* automatically generated by the uni_parse2.tcl script. Do not
* modify this file by hand.
*
* Copyright (c) 1998 by Scriptics Corporation.
* All rights reserved.
*
* Modified for ejabberd by Alexey Shchepin
*
* RCS: @(#) \$Id\$
*/
/*
* A 16-bit Unicode character is split into two parts in order to index
* into the following tables. The lower CCLASS_OFFSET_BITS comprise an offset
* into a page of characters. The upper bits comprise the page number.
*/
#define CCLASS_OFFSET_BITS $cclass_shift
/*
* The pageMap is indexed by page number and returns an alternate page number
* that identifies a unique page of characters. Many Unicode characters map
* to the same alternate page number.
*/
static unsigned char cclassPageMap\[\] = {"
set line " "
set last [expr {[llength $cclass_pmap] - 1}]
for {set i 0} {$i <= $last} {incr i} {
append line [lindex $cclass_pmap $i]
if {$i != $last} {
append line ", "
}
if {[string length $line] > 70} {
puts $f $line
set line " "
}
}
puts $f $line
puts $f "};
/*
* The cclassGroupMap is indexed by combining the alternate page number with
* the page offset and returns a combining class number.
*/
static unsigned char cclassGroupMap\[\] = {"
set line " "
set lasti [expr {[llength $cclass_pages] - 1}]
for {set i 0} {$i <= $lasti} {incr i} {
set page [lindex $cclass_pages $i]
set lastj [expr {[llength $page] - 1}]
for {set j 0} {$j <= $lastj} {incr j} {
append line [lindex $page $j]
if {$j != $lastj || $i != $lasti} {
append line ", "
}
if {[string length $line] > 70} {
puts $f $line
set line " "
}
}
}
puts $f $line
puts $f "};
#define GetUniCharCClass(ch) (cclassGroupMap\[(cclassPageMap\[(((int)(ch)) & 0x1fffff) >> CCLASS_OFFSET_BITS\] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))\])
#define DECOMP_OFFSET_BITS $decomp_shift
/*
* The pageMap is indexed by page number and returns an alternate page number
* that identifies a unique page of characters. Many Unicode characters map
* to the same alternate page number.
*/
static unsigned char decompPageMap\[\] = {"
set line " "
set last [expr {[llength $decomp_pmap] - 1}]
for {set i 0} {$i <= $last} {incr i} {
append line [lindex $decomp_pmap $i]
if {$i != $last} {
append line ", "
}
if {[string length $line] > 70} {
puts $f $line
set line " "
}
}
puts $f $line
puts $f "};
/*
* The decompGroupMap is indexed by combining the alternate page number with
* the page offset and returns a group number that identifies a length and
* shift of decomposition sequence in decompList
*/
static int decompGroupMap\[\] = {"
set line " "
set lasti [expr {[llength $decomp_pages] - 1}]
for {set i 0} {$i <= $lasti} {incr i} {
set page [lindex $decomp_pages $i]
set lastj [expr {[llength $page] - 1}]
for {set j 0} {$j <= $lastj} {incr j} {
append line [lindex $page $j]
if {$j != $lastj || $i != $lasti} {
append line ", "
}
if {[string length $line] > 70} {
puts $f $line
set line " "
}
}
}
puts $f $line
puts $f "};
/*
* List of decomposition sequences
*/
static int decompList\[\] = {"
set line " "
set last [expr {[llength $decomp_list] - 1}]
for {set i 0} {$i <= $last} {incr i} {
set val [lindex $decomp_list $i]
append line [format "%d" $val]
if {$i != $last} {
append line ", "
}
if {[string length $line] > 70} {
puts $f $line
set line " "
}
}
puts $f $line
puts $f "};
/*
* This macro extracts the information about a character from the
* Unicode character tables.
*/
#define GetUniCharDecompInfo(ch) (decompGroupMap\[(decompPageMap\[(((int)(ch)) & 0x1fffff) >> DECOMP_OFFSET_BITS\] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))\])
#define GetDecompShift(info) ((info) & 0xffff)
#define GetDecompLen(info) ((info) >> 16)
#define COMP_OFFSET_BITS $comp_shift
/*
* The pageMap is indexed by page number and returns an alternate page number
* that identifies a unique page of characters. Many Unicode characters map
* to the same alternate page number.
*/
static unsigned char compPageMap\[\] = {"
set line " "
set last [expr {[llength $comp_pmap] - 1}]
for {set i 0} {$i <= $last} {incr i} {
append line [lindex $comp_pmap $i]
if {$i != $last} {
append line ", "
}
if {[string length $line] > 70} {
puts $f $line
set line " "
}
}
puts $f $line
puts $f "};
/*
* The groupMap is indexed by combining the alternate page number with
* the page offset and returns a group number that identifies a unique
* set of character attributes.
*/
static int compGroupMap\[\] = {"
set line " "
set lasti [expr {[llength $comp_pages] - 1}]
for {set i 0} {$i <= $lasti} {incr i} {
set page [lindex $comp_pages $i]
set lastj [expr {[llength $page] - 1}]
for {set j 0} {$j <= $lastj} {incr j} {
append line [lindex $page $j]
if {$j != $lastj || $i != $lasti} {
append line ", "
}
if {[string length $line] > 70} {
puts $f $line
set line " "
}
}
}
puts $f $line
puts $f "};
/*
* Lists of compositions for characters that appears only in one composition
*/
static int compFirstList\[\]\[2\] = {"
set line " "
set last [expr {[llength $comp_first_list] - 1}]
for {set i 0} {$i <= $last} {incr i} {
set val [lindex $comp_first_list $i]
append line [format "{%d, %d}" [lindex $val 0] [lindex $val 1]]
if {$i != $last} {
append line ", "
}
if {[string length $line] > 60} {
puts $f $line
set line " "
}
}
puts $f $line
puts $f "};
static int compSecondList\[\]\[2\] = {"
set line " "
set last [expr {[llength $comp_second_list] - 1}]
for {set i 0} {$i <= $last} {incr i} {
set val [lindex $comp_second_list $i]
append line [format "{%d, %d}" [lindex $val 0] [lindex $val 1]]
if {$i != $last} {
append line ", "
}
if {[string length $line] > 60} {
puts $f $line
set line " "
}
}
puts $f $line
puts $f "};
/*
* Compositions matrix
*/
static int compBothList\[[llength $comp_x_list]\]\[[llength $comp_y_list]\] = {"
set lastx [expr {[llength $comp_x_list] - 1}]
set lasty [expr {[llength $comp_y_list] - 1}]
for {set i 0} {$i <= $lastx} {incr i} {
puts $f " \{"
set line " "
for {set j 0} {$j <= $lasty} {incr j} {
set comp [list [lindex $comp_x_list $i] [lindex $comp_y_list $j]]
if {[info exists comp_map($comp)]} {
set val $comp_map($comp)
} else {
set val 0
}
append line [format "%d" $val]
if {$j != $lasty} {
append line ", "
}
if {[string length $line] > 70} {
puts $f $line
set line " "
}
}
puts $f $line
if {$j != $lasty} {
puts $f " \},"
} else {
puts $f " \}"
}
}
puts $f "};
#define GetUniCharCompInfo(ch) (compGroupMap\[(compPageMap\[(((int)(ch)) & 0x1fffff) >> COMP_OFFSET_BITS\] << COMP_OFFSET_BITS) | ((ch) & ((1 << COMP_OFFSET_BITS)-1))\])
#define CompSingleMask (1 << 16)
#define CompMask ((1 << 16) - 1)
#define CompSecondMask (1 << 17)
"
close $f
}
uni::main
return

View File

@ -1,234 +0,0 @@
%%%----------------------------------------------------------------------
%%% File : xml.erl
%%% Author : Alexey Shchepin <alexey@process-one.net>
%%% Purpose : XML utils
%%% Created : 20 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%%
%%% 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 2 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, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%%
%%%----------------------------------------------------------------------
-module(xml).
-author('alexey@process-one.net').
-export([element_to_string/1,
crypt/1, make_text_node/1,
remove_cdata/1,
get_cdata/1, get_tag_cdata/1,
get_attr/2, get_attr_s/2,
get_tag_attr/2, get_tag_attr_s/2,
get_subtag/2, get_subtag_cdata/2,
get_path_s/2,
replace_tag_attr/3]).
%% Select at compile time how to escape characters in binary text
%% nodes.
%% Can be choosen with ./configure --enable-full-xml
-ifdef(FULL_XML_SUPPORT).
-define(ESCAPE_BINARY(CData), make_text_node(CData)).
-else.
-define(ESCAPE_BINARY(CData), crypt(CData)).
-endif.
element_to_string(El) ->
case El of
{xmlelement, Name, Attrs, Els} ->
if
Els /= [] ->
[$<, Name, attrs_to_list(Attrs), $>,
[element_to_string(E) || E <- Els],
$<, $/, Name, $>];
true ->
[$<, Name, attrs_to_list(Attrs), $/, $>]
end;
%% We do not crypt CDATA binary, but we enclose it in XML CDATA
{xmlcdata, CData} when is_binary(CData) ->
?ESCAPE_BINARY(CData);
%% We crypt list and possibly binaries if full XML usage is
%% disabled unsupported (implies a conversion to list).
{xmlcdata, CData} ->
crypt(CData)
end.
attrs_to_list(Attrs) ->
[attr_to_list(A) || A <- Attrs].
attr_to_list({Name, Value}) ->
[$\s, crypt(Name), $=, $', crypt(Value), $'].
crypt(S) when is_list(S) ->
[case C of
$& -> "&amp;";
$< -> "&lt;";
$> -> "&gt;";
$" -> "&quot;";
$' -> "&apos;";
_ -> C
end || C <- S];
crypt(S) when is_binary(S) ->
crypt(binary_to_list(S)).
%% Make a cdata_binary depending on what characters it contains
make_text_node(CData) ->
case cdata_need_escape(CData) of
cdata ->
CDATA1 = <<"<![CDATA[">>,
CDATA2 = <<"]]>">>,
concat_binary([CDATA1, CData, CDATA2]);
none ->
CData;
{cdata, EndTokens} ->
EscapedCData = escape_cdata(CData, EndTokens),
concat_binary(EscapedCData)
end.
%% Returns escape type needed for the text node
%% none, cdata, {cdata, [Positions]}
%% Positions is a list a integer containing positions of CDATA end
%% tokens, so that they can be escaped
cdata_need_escape(CData) ->
cdata_need_escape(CData, 0, false, []).
cdata_need_escape(<<>>, _, false, _) ->
none;
cdata_need_escape(<<>>, _, true, []) ->
cdata;
cdata_need_escape(<<>>, _, true, CDataEndTokens) ->
{cdata, lists:reverse(CDataEndTokens)};
cdata_need_escape(<<$],$],$>,Rest/binary>>, CurrentPosition,
_XMLEscape, CDataEndTokens) ->
NewPosition = CurrentPosition + 3,
cdata_need_escape(Rest, NewPosition, true,
[CurrentPosition+1|CDataEndTokens]);
%% Only <, & need to be escaped in XML text node
%% See reference: http://www.w3.org/TR/xml11/#syntax
cdata_need_escape(<<$<,Rest/binary>>, CurrentPosition,
_XMLEscape, CDataEndTokens) ->
cdata_need_escape(Rest, CurrentPosition+1, true, CDataEndTokens);
cdata_need_escape(<<$&,Rest/binary>>, CurrentPosition,
_XMLEscape, CDataEndTokens) ->
cdata_need_escape(Rest, CurrentPosition+1, true, CDataEndTokens);
cdata_need_escape(<<_:8,Rest/binary>>, CurrentPosition,
XMLEscape, CDataEndTokens) ->
cdata_need_escape(Rest, CurrentPosition+1, XMLEscape,
CDataEndTokens).
%% escape cdata that contain CDATA end tokens
%% EndTokens is a list of position of end tokens (integer)
%% This is supposed to be a very rare case: You need to generate several
%% fields, splitting it in the middle of the end token.
%% See example: http://en.wikipedia.org/wiki/CDATA#Uses_of_CDATA_sections
escape_cdata(CData, EndTokens) ->
escape_cdata(CData, 0, EndTokens, []).
escape_cdata(<<>>, _CurrentPosition, [], Acc) ->
lists:reverse(Acc);
escape_cdata(Rest, CurrentPosition, [], Acc) ->
CDATA1 = <<"<![CDATA[">>,
CDATA2 = <<"]]>">>,
escape_cdata(<<>>, CurrentPosition, [], [CDATA2, Rest, CDATA1|Acc]);
escape_cdata(CData, Index, [Pos|Positions], Acc) ->
CDATA1 = <<"<![CDATA[">>,
CDATA2 = <<"]]>">>,
Split = Pos-Index,
{Part, Rest} = split_binary(CData, Split+1),
%% Note: We build the list in reverse to optimize construction
escape_cdata(Rest, Pos+1, Positions, [CDATA2, Part, CDATA1|Acc]).
remove_cdata_p({xmlelement, _Name, _Attrs, _Els}) -> true;
remove_cdata_p(_) -> false.
remove_cdata(L) -> [E || E <- L, remove_cdata_p(E)].
get_cdata(L) ->
binary_to_list(list_to_binary(get_cdata(L, ""))).
get_cdata([{xmlcdata, CData} | L], S) ->
get_cdata(L, [S, CData]);
get_cdata([_ | L], S) ->
get_cdata(L, S);
get_cdata([], S) ->
S.
get_tag_cdata({xmlelement, _Name, _Attrs, Els}) ->
get_cdata(Els).
get_attr(AttrName, Attrs) ->
case lists:keysearch(AttrName, 1, Attrs) of
{value, {_, Val}} ->
{value, Val};
_ ->
false
end.
get_attr_s(AttrName, Attrs) ->
case lists:keysearch(AttrName, 1, Attrs) of
{value, {_, Val}} ->
Val;
_ ->
""
end.
get_tag_attr(AttrName, {xmlelement, _Name, Attrs, _Els}) ->
get_attr(AttrName, Attrs).
get_tag_attr_s(AttrName, {xmlelement, _Name, Attrs, _Els}) ->
get_attr_s(AttrName, Attrs).
get_subtag({xmlelement, _, _, Els}, Name) ->
get_subtag1(Els, Name).
get_subtag1([El | Els], Name) ->
case El of
{xmlelement, Name, _, _} ->
El;
_ ->
get_subtag1(Els, Name)
end;
get_subtag1([], _) ->
false.
get_subtag_cdata(Tag, Name) ->
case get_subtag(Tag, Name) of
false ->
"";
Subtag ->
get_tag_cdata(Subtag)
end.
get_path_s(El, []) ->
El;
get_path_s(El, [{elem, Name} | Path]) ->
case get_subtag(El, Name) of
false ->
"";
SubEl ->
get_path_s(SubEl, Path)
end;
get_path_s(El, [{attr, Name}]) ->
get_tag_attr_s(Name, El);
get_path_s(El, [cdata]) ->
get_tag_cdata(El).
replace_tag_attr(Attr, Value, {xmlelement, Name, Attrs, Els}) ->
Attrs1 = lists:keydelete(Attr, 1, Attrs),
Attrs2 = [{Attr, Value} | Attrs1],
{xmlelement, Name, Attrs2, Els}.

View File

@ -1,190 +0,0 @@
%%%----------------------------------------------------------------------
%%% File : xml_stream.erl
%%% Author : Alexey Shchepin <alexey@process-one.net>
%%% Purpose : Parse XML streams
%%% Created : 17 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%%
%%% 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 2 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, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%%
%%%----------------------------------------------------------------------
-module(xml_stream).
-author('alexey@process-one.net').
-export([new/1,
new/2,
parse/2,
close/1,
parse_element/1]).
-define(XML_START, 0).
-define(XML_END, 1).
-define(XML_CDATA, 2).
-define(XML_ERROR, 3).
-define(PARSE_COMMAND, 0).
-define(PARSE_FINAL_COMMAND, 1).
-record(xml_stream_state, {callback_pid, port, stack, size, maxsize}).
process_data(CallbackPid, Stack, Data) ->
case Data of
{?XML_START, {Name, Attrs}} ->
if
Stack == [] ->
catch gen_fsm:send_event(CallbackPid,
{xmlstreamstart, Name, Attrs});
true ->
ok
end,
[{xmlelement, Name, Attrs, []} | Stack];
{?XML_END, EndName} ->
case Stack of
[{xmlelement, Name, Attrs, Els} | Tail] ->
NewEl = {xmlelement, Name, Attrs, lists:reverse(Els)},
case Tail of
[] ->
catch gen_fsm:send_event(CallbackPid,
{xmlstreamend, EndName}),
Tail;
[_] ->
catch gen_fsm:send_event(CallbackPid,
{xmlstreamelement, NewEl}),
Tail;
[{xmlelement, Name1, Attrs1, Els1} | Tail1] ->
[{xmlelement, Name1, Attrs1, [NewEl | Els1]} |
Tail1]
end
end;
{?XML_CDATA, CData} ->
case Stack of
[El] ->
[El];
%% Merge CDATA nodes if they are contiguous
%% This does not change the semantic: the split in
%% several CDATA nodes depends on the TCP/IP packet
%% fragmentation
[{xmlelement, Name, Attrs,
[{xmlcdata, PreviousCData}|Els]} | Tail] ->
[{xmlelement, Name, Attrs,
[{xmlcdata, concat_binary([PreviousCData, CData])} | Els]} | Tail];
%% No previous CDATA
[{xmlelement, Name, Attrs, Els} | Tail] ->
[{xmlelement, Name, Attrs, [{xmlcdata, CData} | Els]} |
Tail];
[] -> []
end;
{?XML_ERROR, Err} ->
catch gen_fsm:send_event(CallbackPid, {xmlstreamerror, Err})
end.
new(CallbackPid) ->
new(CallbackPid, infinity).
new(CallbackPid, MaxSize) ->
Port = open_port({spawn, expat_erl}, [binary]),
#xml_stream_state{callback_pid = CallbackPid,
port = Port,
stack = [],
size = 0,
maxsize = MaxSize}.
parse(#xml_stream_state{callback_pid = CallbackPid,
port = Port,
stack = Stack,
size = Size,
maxsize = MaxSize} = State, Str) ->
StrSize = if
is_list(Str) -> length(Str);
is_binary(Str) -> size(Str)
end,
Res = port_control(Port, ?PARSE_COMMAND, Str),
{NewStack, NewSize} =
lists:foldl(
fun(Data, {St, Sz}) ->
NewSt = process_data(CallbackPid, St, Data),
case NewSt of
[_] -> {NewSt, 0};
_ -> {NewSt, Sz}
end
end, {Stack, Size + StrSize}, binary_to_term(Res)),
if
NewSize > MaxSize ->
catch gen_fsm:send_event(CallbackPid,
{xmlstreamerror, "XML stanza is too big"});
true ->
ok
end,
State#xml_stream_state{stack = NewStack, size = NewSize}.
close(#xml_stream_state{port = Port}) ->
port_close(Port).
parse_element(Str) ->
Port = open_port({spawn, expat_erl}, [binary]),
Res = port_control(Port, ?PARSE_FINAL_COMMAND, Str),
port_close(Port),
process_element_events(binary_to_term(Res)).
process_element_events(Events) ->
process_element_events(Events, []).
process_element_events([], _Stack) ->
{error, parse_error};
process_element_events([Event | Events], Stack) ->
case Event of
{?XML_START, {Name, Attrs}} ->
process_element_events(
Events, [{xmlelement, Name, Attrs, []} | Stack]);
{?XML_END, _EndName} ->
case Stack of
[{xmlelement, Name, Attrs, Els} | Tail] ->
NewEl = {xmlelement, Name, Attrs, lists:reverse(Els)},
case Tail of
[] ->
if
Events == [] ->
NewEl;
true ->
{error, parse_error}
end;
[{xmlelement, Name1, Attrs1, Els1} | Tail1] ->
process_element_events(
Events,
[{xmlelement, Name1, Attrs1, [NewEl | Els1]} |
Tail1])
end
end;
{?XML_CDATA, CData} ->
case Stack of
[{xmlelement, Name, Attrs, Els} | Tail] ->
process_element_events(
Events,
[{xmlelement, Name, Attrs, [{xmlcdata, CData} | Els]} |
Tail]);
[] ->
process_element_events(Events, [])
end;
{?XML_ERROR, Err} ->
{error, Err}
end.