summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2008-06-25 21:24:53 (UTC)
committer Michael Krelin <hacker@klever.net>2008-06-25 21:24:53 (UTC)
commit2744ea9808c3a6c50f8be78a9a71f6d3b2ba7e00 (patch) (unidiff)
treea9c124efee2b4edbeaeb646f1b94928bdc4e8c4c
parent04aac0e097992df01e17fbbb62a5a7d9682bcea9 (diff)
downloadlibopkele-2744ea9808c3a6c50f8be78a9a71f6d3b2ba7e00.zip
libopkele-2744ea9808c3a6c50f8be78a9a71f6d3b2ba7e00.tar.gz
libopkele-2744ea9808c3a6c50f8be78a9a71f6d3b2ba7e00.tar.bz2
improved detection of htmltidy for debian and co.
Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--configure.ac5
-rw-r--r--include/opkele/tidy.h11
-rw-r--r--lib/discovery.cc3
3 files changed, 14 insertions, 5 deletions
diff --git a/configure.ac b/configure.ac
index 0aa1272..a66e53d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,257 +1,258 @@
1AC_INIT([libopkele], [1.1.99.0], [libopkele-bugs@klever.net]) 1AC_INIT([libopkele], [1.1.99.0], [libopkele-bugs@klever.net])
2AC_CONFIG_SRCDIR([include/opkele/opkele-config.h]) 2AC_CONFIG_SRCDIR([include/opkele/opkele-config.h])
3AC_CONFIG_HEADERS([config.h include/opkele/acconfig.h]) 3AC_CONFIG_HEADERS([config.h include/opkele/acconfig.h])
4AM_INIT_AUTOMAKE([dist-bzip2]) 4AM_INIT_AUTOMAKE([dist-bzip2])
5 5
6AC_PROG_INSTALL 6AC_PROG_INSTALL
7AC_PROG_CXX 7AC_PROG_CXX
8AC_PROG_CC 8AC_PROG_CC
9AC_PROG_LIBTOOL 9AC_PROG_LIBTOOL
10PKG_PROG_PKG_CONFIG 10PKG_PROG_PKG_CONFIG
11 11
12AC_HEADER_STDC 12AC_HEADER_STDC
13 13
14AC_PATH_PROG([XSLTPROC],[xsltproc],[true]) 14AC_PATH_PROG([XSLTPROC],[xsltproc],[true])
15 15
16AC_MSG_CHECKING([for source tree version]) 16AC_MSG_CHECKING([for source tree version])
17if headrev=$(cd $srcdir && git rev-parse --verify HEAD 2>/dev/null) ; then 17if headrev=$(cd $srcdir && git rev-parse --verify HEAD 2>/dev/null) ; then
18 PACKAGE_SRC_VERSION="$(cd $srcdir && git describe --tags $headrev)" 18 PACKAGE_SRC_VERSION="$(cd $srcdir && git describe --tags $headrev)"
19 test "$PACKAGE_SRC_VERSION" = "$PACKAGE_VERSION" \ 19 test "$PACKAGE_SRC_VERSION" = "$PACKAGE_VERSION" \
20 -o "${PACKAGE_SRC_VERSION#${PACKAGE_VERSION}-}" != "$PACKAGE_SRC_VERSION" || PACKAGE_SRC_VERSION="${PACKAGE_VERSION}:${PACKAGE_SRC_VERSION}" 20 -o "${PACKAGE_SRC_VERSION#${PACKAGE_VERSION}-}" != "$PACKAGE_SRC_VERSION" || PACKAGE_SRC_VERSION="${PACKAGE_VERSION}:${PACKAGE_SRC_VERSION}"
21 ( cd $srcdir && git diff-index $headrev | read dirt ) && PACKAGE_SRC_VERSION="${PACKAGE_SRC_VERSION}-dirty" 21 ( cd $srcdir && git diff-index $headrev | read dirt ) && PACKAGE_SRC_VERSION="${PACKAGE_SRC_VERSION}-dirty"
22else 22else
23 PACKAGE_SRC_VERSION="$PACKAGE_VERSION" 23 PACKAGE_SRC_VERSION="$PACKAGE_VERSION"
24fi 24fi
25AC_MSG_RESULT([$PACKAGE_SRC_VERSION]) 25AC_MSG_RESULT([$PACKAGE_SRC_VERSION])
26AC_SUBST([PACKAGE_SRC_VERSION]) 26AC_SUBST([PACKAGE_SRC_VERSION])
27AC_DEFINE_UNQUOTED([PACKAGE_SRC_VERSION],["$PACKAGE_SRC_VERSION"],[more or less precise source tree version]) 27AC_DEFINE_UNQUOTED([PACKAGE_SRC_VERSION],["$PACKAGE_SRC_VERSION"],[more or less precise source tree version])
28 28
29tr1_mem_std="false" 29tr1_mem_std="false"
30tr1_mem_boost="false" 30tr1_mem_boost="false"
31AC_CHECK_SHAREDPTR(std::tr1,tr1/memory,[ tr1_mem_std=true ]) 31AC_CHECK_SHAREDPTR(std::tr1,tr1/memory,[ tr1_mem_std=true ])
32AC_CHECK_SHAREDPTR(boost,boost/shared_ptr.hpp,[ tr1_mem_boost=true ]) 32AC_CHECK_SHAREDPTR(boost,boost/shared_ptr.hpp,[ tr1_mem_boost=true ])
33tr1_mem="" 33tr1_mem=""
34AC_ARG_WITH([tr1-memory], 34AC_ARG_WITH([tr1-memory],
35 AC_HELP_STRING([--with-tr1-memory=<boost|std>],[select tr1/memory (shared_ptr<>) implementation to use]), 35 AC_HELP_STRING([--with-tr1-memory=<boost|std>],[select tr1/memory (shared_ptr<>) implementation to use]),
36 [ tr1_mem="$withval" ] 36 [ tr1_mem="$withval" ]
37) 37)
38AC_MSG_CHECKING([for tr1/memory implementation to use]) 38AC_MSG_CHECKING([for tr1/memory implementation to use])
39test -z "$tr1_mem" && $tr1_mem_std && tr1_mem=std 39test -z "$tr1_mem" && $tr1_mem_std && tr1_mem=std
40test -z "$tr1_mem" && $tr1_mem_boost && tr1_mem=boost 40test -z "$tr1_mem" && $tr1_mem_boost && tr1_mem=boost
41if test -z "$tr1_mem" ; then 41if test -z "$tr1_mem" ; then
42 AC_MSG_RESULT([none found]) 42 AC_MSG_RESULT([none found])
43else 43else
44 AC_MSG_RESULT([$tr1_mem]) 44 AC_MSG_RESULT([$tr1_mem])
45fi 45fi
46case "$tr1_mem" in 46case "$tr1_mem" in
47 std) 47 std)
48 $tr1_mem_std || AC_MSG_ERROR([std implementation requested, but not found]) 48 $tr1_mem_std || AC_MSG_ERROR([std implementation requested, but not found])
49 OPKELE_TR1_MEM_NS=std::tr1 49 OPKELE_TR1_MEM_NS=std::tr1
50 OPKELE_TR1_MEM_HEADER=tr1/memory 50 OPKELE_TR1_MEM_HEADER=tr1/memory
51 ;; 51 ;;
52 boost) 52 boost)
53 $tr1_mem_boost || AC_MSG_ERROR([boost implementation requested, but not found]) 53 $tr1_mem_boost || AC_MSG_ERROR([boost implementation requested, but not found])
54 OPKELE_TR1_MEM_NS=boost 54 OPKELE_TR1_MEM_NS=boost
55 OPKELE_TR1_MEM_HEADER=boost/shared_ptr.hpp 55 OPKELE_TR1_MEM_HEADER=boost/shared_ptr.hpp
56 ;; 56 ;;
57 *) 57 *)
58 AC_MSG_ERROR([no shared_ptr<> implementation found]) 58 AC_MSG_ERROR([no shared_ptr<> implementation found])
59 ;; 59 ;;
60esac 60esac
61AC_SUBST([OPKELE_TR1_MEM_NS]) 61AC_SUBST([OPKELE_TR1_MEM_NS])
62AC_SUBST([OPKELE_TR1_MEM_HEADER]) 62AC_SUBST([OPKELE_TR1_MEM_HEADER])
63 63
64AC_MSG_CHECKING([for deprecated attribute support]) 64AC_MSG_CHECKING([for deprecated attribute support])
65AC_COMPILE_IFELSE([ 65AC_COMPILE_IFELSE([
66 int __attribute__((deprecated)) deprecated_function(); 66 int __attribute__((deprecated)) deprecated_function();
67 ],[ 67 ],[
68 AC_MSG_RESULT([yes]) 68 AC_MSG_RESULT([yes])
69 AC_DEFINE([OPKELE_DEPRECATE],[__attribute__((deprecated))],[deprecated function attribute]) 69 AC_DEFINE([OPKELE_DEPRECATE],[__attribute__((deprecated))],[deprecated function attribute])
70 ],[ 70 ],[
71 AC_MSG_RESULT([no]) 71 AC_MSG_RESULT([no])
72 AC_DEFINE([OPKELE_DEPRECATE],,[deprecated function attribute]) 72 AC_DEFINE([OPKELE_DEPRECATE],,[deprecated function attribute])
73 ] 73 ]
74) 74)
75 75
76AC_LANG_PUSH([C++]) 76AC_LANG_PUSH([C++])
77AC_MSG_CHECKING([for abi::__cxa_demangle]) 77AC_MSG_CHECKING([for abi::__cxa_demangle])
78AC_COMPILE_IFELSE([ 78AC_COMPILE_IFELSE([
79 #include <typeinfo> 79 #include <typeinfo>
80 using namespace std; 80 using namespace std;
81 #include <cxxabi.h> 81 #include <cxxabi.h>
82 int main(int c,char **v) { 82 int main(int c,char **v) {
83 int dstat; 83 int dstat;
84 char *demangled = abi::__cxa_demangle(typeid(dstat).name(),0,0,&dstat); 84 char *demangled = abi::__cxa_demangle(typeid(dstat).name(),0,0,&dstat);
85 return 0; 85 return 0;
86 } 86 }
87 ],[ 87 ],[
88 AC_MSG_RESULT([yes]) 88 AC_MSG_RESULT([yes])
89 AC_DEFINE([HAVE_DEMANGLE],,[defined if abi::__cxa_demangle is available]) 89 AC_DEFINE([HAVE_DEMANGLE],,[defined if abi::__cxa_demangle is available])
90 ],[ 90 ],[
91 AC_MSG_RESULT([no]) 91 AC_MSG_RESULT([no])
92 ] 92 ]
93) 93)
94AC_LANG_POP([C++]) 94AC_LANG_POP([C++])
95 95
96 96
97 97
98 98
99PKG_CHECK_MODULES([OPENSSL],[openssl],,[ 99PKG_CHECK_MODULES([OPENSSL],[openssl],,[
100 AC_MSG_ERROR([no openssl library found. get one from http://www.openssl.org/]) 100 AC_MSG_ERROR([no openssl library found. get one from http://www.openssl.org/])
101]) 101])
102 102
103WANT_KONFORKA="yes" 103WANT_KONFORKA="yes"
104AC_ARG_ENABLE([konforka], 104AC_ARG_ENABLE([konforka],
105 AC_HELP_STRING([--disable-konforka],[do not use konforka library (default: use if found)]), 105 AC_HELP_STRING([--disable-konforka],[do not use konforka library (default: use if found)]),
106 [ 106 [
107 test "${enableval}" = "no" && WANT_KONFORKA="no" 107 test "${enableval}" = "no" && WANT_KONFORKA="no"
108 ] 108 ]
109) 109)
110if test "${WANT_KONFORKA}" = "yes" ; then 110if test "${WANT_KONFORKA}" = "yes" ; then
111 PKG_CHECK_MODULES([KONFORKA],[konforka],[ 111 PKG_CHECK_MODULES([KONFORKA],[konforka],[
112 AC_SUBST([KONFORKA_CFLAGS]) 112 AC_SUBST([KONFORKA_CFLAGS])
113 AC_SUBST([KONFORKA_LIBS]) 113 AC_SUBST([KONFORKA_LIBS])
114 AC_DEFINE([HAVE_KONFORKA],,[defined in presence of konforka library]) 114 AC_DEFINE([HAVE_KONFORKA],,[defined in presence of konforka library])
115 AC_DEFINE([OPKELE_HAVE_KONFORKA],,[defined in presence of konforka library]) 115 AC_DEFINE([OPKELE_HAVE_KONFORKA],,[defined in presence of konforka library])
116 AC_SUBST([KONFORKA_KONFORKA],[konforka]) 116 AC_SUBST([KONFORKA_KONFORKA],[konforka])
117 ],[true]) 117 ],[true])
118fi 118fi
119 119
120WANT_DOXYGEN="yes" 120WANT_DOXYGEN="yes"
121AC_ARG_ENABLE([doxygen], 121AC_ARG_ENABLE([doxygen],
122 AC_HELP_STRING([--disable-doxygen],[do not generate documentation]), 122 AC_HELP_STRING([--disable-doxygen],[do not generate documentation]),
123 [ 123 [
124 test "${enableval}" = "no" && WANT_DOXYGEN="no" 124 test "${enableval}" = "no" && WANT_DOXYGEN="no"
125 ] 125 ]
126) 126)
127if test "${WANT_DOXYGEN}" = "yes" ; then 127if test "${WANT_DOXYGEN}" = "yes" ; then
128 AC_WITH_DOXYGEN 128 AC_WITH_DOXYGEN
129 AC_WITH_DOT 129 AC_WITH_DOT
130else 130else
131 AM_CONDITIONAL([HAVE_DOXYGEN],[false]) 131 AM_CONDITIONAL([HAVE_DOXYGEN],[false])
132 AM_CONDITIONAL([HAVE_DOT],[false]) 132 AM_CONDITIONAL([HAVE_DOT],[false])
133fi 133fi
134 134
135LIBCURL_CHECK_CONFIG(,,,[ 135LIBCURL_CHECK_CONFIG(,,,[
136 AC_MSG_ERROR([no required libcurl library. get one from http://curl.haxx.se/]) 136 AC_MSG_ERROR([no required libcurl library. get one from http://curl.haxx.se/])
137]) 137])
138 138
139AC_CHECK_HEADER([expat.h],[ 139AC_CHECK_HEADER([expat.h],[
140 AC_CHECK_LIB([expat],[XML_ParserCreate],[ 140 AC_CHECK_LIB([expat],[XML_ParserCreate],[
141 EXPAT_LIBS=-lexpat 141 EXPAT_LIBS=-lexpat
142 EXPAT_CFLAGS= 142 EXPAT_CFLAGS=
143 AC_SUBST([EXPAT_LIBS]) 143 AC_SUBST([EXPAT_LIBS])
144 AC_SUBST([EXPAT_CFLAGS]) 144 AC_SUBST([EXPAT_CFLAGS])
145 ],[ 145 ],[
146 AC_MSG_ERROR([no required expat library. get one from http://expat.sourceforge.net/]) 146 AC_MSG_ERROR([no required expat library. get one from http://expat.sourceforge.net/])
147 ]) 147 ])
148],[ 148],[
149 AC_MSG_ERROR([no required expat library. get one from http://expat.sourceforge.net/]) 149 AC_MSG_ERROR([no required expat library. get one from http://expat.sourceforge.net/])
150]) 150])
151 151
152AC_CHECK_HEADER([tidy.h],[ 152AC_CHECK_HEADERS([tidy.h tidy/tidy.h],[
153 AC_CHECK_LIB([tidy],[tidyParseBuffer],[ 153 AC_CHECK_LIB([tidy],[tidyParseBuffer],[
154 TIDY_LIBS=-ltidy 154 TIDY_LIBS=-ltidy
155 TIDY_CFLAGS= 155 TIDY_CFLAGS=
156 AC_SUBST([TIDY_LIBS]) 156 AC_SUBST([TIDY_LIBS])
157 AC_SUBST([TIDY_CFLAGS]) 157 AC_SUBST([TIDY_CFLAGS])
158 ],[ 158 ],[
159 AC_MSG_ERROR([no required htmltidy library found. get one from http://tidy.sourceforge.net/]) 159 AC_MSG_ERROR([no required htmltidy library found. get one from http://tidy.sourceforge.net/])
160 ]) 160 ])
161],[ 161],[
162 AC_MSG_ERROR([no required htmltidy library found. get one from http://tidy.sourceforge.net/]) 162 test "$ac_header" = "tidy/tidy.h" \
163 && AC_MSG_ERROR([no required htmltidy library found. get one from http://tidy.sourceforge.net/])
163]) 164])
164 165
165if test -n "$PCRE_LIBS" -a -n "$PCRE_CFLAGS" ; then 166if test -n "$PCRE_LIBS" -a -n "$PCRE_CFLAGS" ; then
166 AC_SUBST([PCRE_CFLAGS]) 167 AC_SUBST([PCRE_CFLAGS])
167 AC_SUBST([PCRE_LIBS]) 168 AC_SUBST([PCRE_LIBS])
168 : 169 :
169else 170else
170 PKG_CHECK_MODULES([PCRE],[libpcre],,[ 171 PKG_CHECK_MODULES([PCRE],[libpcre],,[
171 AC_MSG_ERROR([no libpcre found, go get it at http://www.pcre.org/]) 172 AC_MSG_ERROR([no libpcre found, go get it at http://www.pcre.org/])
172 ]) 173 ])
173fi 174fi
174 175
175PKG_CHECK_MODULES([SQLITE3],[sqlite3],[have_sqlite3=true],[have_sqlite3=false]) 176PKG_CHECK_MODULES([SQLITE3],[sqlite3],[have_sqlite3=true],[have_sqlite3=false])
176AM_CONDITIONAL([HAVE_SQLITE3],[$have_sqlite3]) 177AM_CONDITIONAL([HAVE_SQLITE3],[$have_sqlite3])
177PKG_CHECK_MODULES([KINGATE],[kingate-plaincgi],[have_kingate=true],[have_kingate=false]) 178PKG_CHECK_MODULES([KINGATE],[kingate-plaincgi],[have_kingate=true],[have_kingate=false])
178AM_CONDITIONAL([HAVE_KINGATE],[$have_kingate]) 179AM_CONDITIONAL([HAVE_KINGATE],[$have_kingate])
179PKG_CHECK_MODULES([UUID],[uuid],[have_uuid=true],[have_uuid=false]) 180PKG_CHECK_MODULES([UUID],[uuid],[have_uuid=true],[have_uuid=false])
180AM_CONDITIONAL([HAVE_UUID],[$have_uuid]) 181AM_CONDITIONAL([HAVE_UUID],[$have_uuid])
181if $have_uuid ; then 182if $have_uuid ; then
182 AC_DEFINE([HAVE_LIBUUID],,[defined in presence of libuuid]) 183 AC_DEFINE([HAVE_LIBUUID],,[defined in presence of libuuid])
183 AC_SUBST([UUID_UUID],[uuid]) 184 AC_SUBST([UUID_UUID],[uuid])
184fi 185fi
185 186
186curl_ssl_verify_host="true" 187curl_ssl_verify_host="true"
187AC_ARG_ENABLE([ssl-verify-host], 188AC_ARG_ENABLE([ssl-verify-host],
188 AC_HELP_STRING([--disable-ssl-verify-host],[disable cURL cert/host relationships verification]), 189 AC_HELP_STRING([--disable-ssl-verify-host],[disable cURL cert/host relationships verification]),
189 [ test "${enableval}" = "no" && curl_ssl_verify_host="false" ] 190 [ test "${enableval}" = "no" && curl_ssl_verify_host="false" ]
190) 191)
191${curl_ssl_verify_host} || AC_DEFINE([DISABLE_CURL_SSL_VERIFYHOST],,[defined if cURL is not to verify cert/host]) 192${curl_ssl_verify_host} || AC_DEFINE([DISABLE_CURL_SSL_VERIFYHOST],,[defined if cURL is not to verify cert/host])
192 193
193curl_ssl_verify_peer="true" 194curl_ssl_verify_peer="true"
194AC_ARG_ENABLE([ssl-verify-peer], 195AC_ARG_ENABLE([ssl-verify-peer],
195 AC_HELP_STRING([--disable-ssl-verify-peer],[disable cURL cert validity verification]), 196 AC_HELP_STRING([--disable-ssl-verify-peer],[disable cURL cert validity verification]),
196 [ test "${enableval}" = "no" && curl_ssl_verify_peer="false" ] 197 [ test "${enableval}" = "no" && curl_ssl_verify_peer="false" ]
197) 198)
198${curl_ssl_verify_peer} || AC_DEFINE([DISABLE_CURL_SSL_VERIFYPEER],,[defined if cURL is not to verify cert validity]) 199${curl_ssl_verify_peer} || AC_DEFINE([DISABLE_CURL_SSL_VERIFYPEER],,[defined if cURL is not to verify cert validity])
199 200
200postels_law=true 201postels_law=true
201AC_ARG_ENABLE([postels-law], 202AC_ARG_ENABLE([postels-law],
202 AC_HELP_STRING([--disable-postels-law],[Be strict, do not adhere to Postel's Law ("be conservative in what you do, be liberal in what you accept from others", RFC 793)]), 203 AC_HELP_STRING([--disable-postels-law],[Be strict, do not adhere to Postel's Law ("be conservative in what you do, be liberal in what you accept from others", RFC 793)]),
203 [ test "${enableval}" = "no" && postels_law=false ] 204 [ test "${enableval}" = "no" && postels_law=false ]
204) 205)
205$postels_law && AC_DEFINE([POSTELS_LAW],,[defined if we want to adhere to Postel's Law]) 206$postels_law && AC_DEFINE([POSTELS_LAW],,[defined if we want to adhere to Postel's Law])
206 207
207AC_DEFINE_UNQUOTED([OPKELE_SRC_DIR],["$PWD"],[source directory]) 208AC_DEFINE_UNQUOTED([OPKELE_SRC_DIR],["$PWD"],[source directory])
208 209
209nitpick=false 210nitpick=false
210AC_ARG_ENABLE([nitpicking], 211AC_ARG_ENABLE([nitpicking],
211 AC_HELP_STRING([--enable-nitpicking],[make compiler somewhat overly fastidious about the code it deals with]), 212 AC_HELP_STRING([--enable-nitpicking],[make compiler somewhat overly fastidious about the code it deals with]),
212 [ test "$enableval" = "no" || nitpick=true ] 213 [ test "$enableval" = "no" || nitpick=true ]
213) 214)
214if $nitpick ; then 215if $nitpick ; then
215 CPP_NITPICK="-pedantic -Wall -Wextra -Wundef -Wshadow \ 216 CPP_NITPICK="-pedantic -Wall -Wextra -Wundef -Wshadow \
216 -Wunsafe-loop-optimizations -Wconversion -Wmissing-format-attribute \ 217 -Wunsafe-loop-optimizations -Wconversion -Wmissing-format-attribute \
217 -Wredundant-decls -ansi" 218 -Wredundant-decls -ansi"
218 # -Wlogical-op -Wmissing-noreturn 219 # -Wlogical-op -Wmissing-noreturn
219 C_NITPICK="$CPP_NITPICK" 220 C_NITPICK="$CPP_NITPICK"
220 CXX_NITPICK="$C_NITPICK" 221 CXX_NITPICK="$C_NITPICK"
221 222
222 CPPFLAGS="$CPPFLAGS $CPP_NITPICK" 223 CPPFLAGS="$CPPFLAGS $CPP_NITPICK"
223 CFLAGS="$CFLAGS $C_NITPICK" 224 CFLAGS="$CFLAGS $C_NITPICK"
224 CXXFLAGS="$CXXFLAGS $CXX_NITPICK" 225 CXXFLAGS="$CXXFLAGS $CXX_NITPICK"
225fi 226fi
226 227
227ndebug=true 228ndebug=true
228AC_ARG_ENABLE([debug], 229AC_ARG_ENABLE([debug],
229 AC_HELP_STRING([--enable-debug],[enable debugging code]), 230 AC_HELP_STRING([--enable-debug],[enable debugging code]),
230 [ test "$enableval" = "no" || ndebug=false ] 231 [ test "$enableval" = "no" || ndebug=false ]
231) 232)
232if $ndebug ; then 233if $ndebug ; then
233 CPPFLAGS_DEBUG="-DNDEBUG" 234 CPPFLAGS_DEBUG="-DNDEBUG"
234else 235else
235 CPPFLAGS_DEBUG="" 236 CPPFLAGS_DEBUG=""
236fi 237fi
237AC_SUBST([CPPFLAGS_DEBUG]) 238AC_SUBST([CPPFLAGS_DEBUG])
238 239
239xri_proxy_url="https://xri.net/" 240xri_proxy_url="https://xri.net/"
240AC_MSG_CHECKING([for XRI resolver proxy]) 241AC_MSG_CHECKING([for XRI resolver proxy])
241AC_ARG_ENABLE([xri-proxy], 242AC_ARG_ENABLE([xri-proxy],
242 AC_HELP_STRING([--with-xri-proxy=url],[set xri proxy for use when resolving xri identities, default is https://xri.net/]), 243 AC_HELP_STRING([--with-xri-proxy=url],[set xri proxy for use when resolving xri identities, default is https://xri.net/]),
243 [ xri_proxy_url="$withval" ] 244 [ xri_proxy_url="$withval" ]
244) 245)
245AC_MSG_RESULT([$xri_proxy_url]) 246AC_MSG_RESULT([$xri_proxy_url])
246AC_DEFINE_UNQUOTED([XRI_PROXY_URL],["$xri_proxy_url"],[XRI proxy resolver URL]) 247AC_DEFINE_UNQUOTED([XRI_PROXY_URL],["$xri_proxy_url"],[XRI proxy resolver URL])
247 248
248AC_CONFIG_FILES([ 249AC_CONFIG_FILES([
249 Makefile 250 Makefile
250 libopkele.pc 251 libopkele.pc
251 Doxyfile 252 Doxyfile
252 include/Makefile 253 include/Makefile
253 include/opkele/tr1-mem.h 254 include/opkele/tr1-mem.h
254 lib/Makefile 255 lib/Makefile
255 test/Makefile 256 test/Makefile
256]) 257])
257AC_OUTPUT 258AC_OUTPUT
diff --git a/include/opkele/tidy.h b/include/opkele/tidy.h
index 888e7d4..059656d 100644
--- a/include/opkele/tidy.h
+++ b/include/opkele/tidy.h
@@ -1,73 +1,80 @@
1#ifndef __OPKELE_TIDY_H 1#ifndef __OPKELE_TIDY_H
2#define __OPKELE_TIDY_H 2#define __OPKELE_TIDY_H
3 3
4#include <cassert> 4#include <cassert>
5#include <tidy.h> 5#ifdef HAVE_TIDY_H
6#include <buffio.h> 6# include <tidy.h>
7# include <buffio.h>
8#elif HAVE_TIDY_TIDY_H
9# include <tidy/tidy.h>
10# include <tidy/buffio.h>
11#else
12# error "Don't know where to look for htmltidy headers"
13#endif
7 14
8namespace opkele { 15namespace opkele {
9 namespace util { 16 namespace util {
10 17
11 class tidy_buf_t { 18 class tidy_buf_t {
12 public: 19 public:
13 TidyBuffer _x; 20 TidyBuffer _x;
14 21
15 tidy_buf_t() { tidyBufInit(&_x); } 22 tidy_buf_t() { tidyBufInit(&_x); }
16 virtual ~tidy_buf_t() throw() { 23 virtual ~tidy_buf_t() throw() {
17 tidyBufFree(&_x); } 24 tidyBufFree(&_x); }
18 25
19 inline operator const TidyBuffer&(void) const { return _x; } 26 inline operator const TidyBuffer&(void) const { return _x; }
20 inline operator TidyBuffer&(void) { return _x; } 27 inline operator TidyBuffer&(void) { return _x; }
21 28
22 inline operator const char*(void) const { return (const char*)_x.bp; } 29 inline operator const char*(void) const { return (const char*)_x.bp; }
23 inline operator char*(void) { return (char*)_x.bp; } 30 inline operator char*(void) { return (char*)_x.bp; }
24 31
25 inline const char *c_str() const { 32 inline const char *c_str() const {
26 return (const char*)_x.bp; } 33 return (const char*)_x.bp; }
27 inline size_t size() const { 34 inline size_t size() const {
28 return _x.size; } 35 return _x.size; }
29 }; 36 };
30 37
31 class tidy_doc_t { 38 class tidy_doc_t {
32 public: 39 public:
33 TidyDoc _x; 40 TidyDoc _x;
34 41
35 tidy_doc_t() : _x(0) { } 42 tidy_doc_t() : _x(0) { }
36 tidy_doc_t(TidyDoc x) : _x(x) { } 43 tidy_doc_t(TidyDoc x) : _x(x) { }
37 virtual ~tidy_doc_t() throw() { 44 virtual ~tidy_doc_t() throw() {
38 if(_x) tidyRelease(_x); } 45 if(_x) tidyRelease(_x); }
39 46
40 tidy_doc_t& operator=(TidyDoc x) { 47 tidy_doc_t& operator=(TidyDoc x) {
41 if(_x) tidyRelease(_x); 48 if(_x) tidyRelease(_x);
42 _x = x; 49 _x = x;
43 return *this; 50 return *this;
44 } 51 }
45 52
46 operator const TidyDoc(void) const { return _x; } 53 operator const TidyDoc(void) const { return _x; }
47 operator TidyDoc(void) { return _x; } 54 operator TidyDoc(void) { return _x; }
48 55
49 inline bool opt_set(TidyOptionId o,bool v) { 56 inline bool opt_set(TidyOptionId o,bool v) {
50 assert(_x); 57 assert(_x);
51 return tidyOptSetBool(_x,o,v?yes:no); } 58 return tidyOptSetBool(_x,o,v?yes:no); }
52 inline bool opt_set(TidyOptionId o,int v) { 59 inline bool opt_set(TidyOptionId o,int v) {
53 assert(_x); 60 assert(_x);
54 return tidyOptSetInt(_x,o,v); } 61 return tidyOptSetInt(_x,o,v); }
55 62
56 inline int parse_string(const string& s) { 63 inline int parse_string(const string& s) {
57 assert(_x); 64 assert(_x);
58 return tidyParseString(_x,s.c_str()); } 65 return tidyParseString(_x,s.c_str()); }
59 inline int clean_and_repair() { 66 inline int clean_and_repair() {
60 assert(_x); 67 assert(_x);
61 return tidyCleanAndRepair(_x); } 68 return tidyCleanAndRepair(_x); }
62 inline int save_buffer(TidyBuffer& ob) { 69 inline int save_buffer(TidyBuffer& ob) {
63 assert(_x); 70 assert(_x);
64 return tidySaveBuffer(_x,&ob); } 71 return tidySaveBuffer(_x,&ob); }
65 72
66 static inline TidyDoc create() { 73 static inline TidyDoc create() {
67 return tidyCreate(); } 74 return tidyCreate(); }
68 }; 75 };
69 76
70 } 77 }
71} 78}
72 79
73#endif /* __OPKELE_TIDY_H */ 80#endif /* __OPKELE_TIDY_H */
diff --git a/lib/discovery.cc b/lib/discovery.cc
index 3b90977..d1989ec 100644
--- a/lib/discovery.cc
+++ b/lib/discovery.cc
@@ -1,269 +1,270 @@
1#include <list> 1#include <list>
2#include <opkele/curl.h> 2#include <opkele/curl.h>
3#include <opkele/expat.h> 3#include <opkele/expat.h>
4#include <opkele/uris.h> 4#include <opkele/uris.h>
5#include <opkele/discovery.h> 5#include <opkele/discovery.h>
6#include <opkele/exception.h> 6#include <opkele/exception.h>
7#include <opkele/util.h> 7#include <opkele/util.h>
8#include <opkele/tidy.h>
9#include <opkele/data.h> 8#include <opkele/data.h>
10#include <opkele/debug.h> 9#include <opkele/debug.h>
11 10
12#include "config.h" 11#include "config.h"
13 12
13#include <opkele/tidy.h>
14
14#define XRDS_HEADER "X-XRDS-Location" 15#define XRDS_HEADER "X-XRDS-Location"
15#define CT_HEADER "Content-Type" 16#define CT_HEADER "Content-Type"
16 17
17namespace opkele { 18namespace opkele {
18 using std::list; 19 using std::list;
19 using xrd::XRD_t; 20 using xrd::XRD_t;
20 using xrd::service_t; 21 using xrd::service_t;
21 22
22 /* TODO: the whole discovery thing needs cleanup and optimization due to 23 /* TODO: the whole discovery thing needs cleanup and optimization due to
23 * many changes of concept. */ 24 * many changes of concept. */
24 25
25 static const size_t max_html = 16384; 26 static const size_t max_html = 16384;
26 27
27 static const struct service_type_t { 28 static const struct service_type_t {
28 const char *uri; 29 const char *uri;
29 const char *forceid; 30 const char *forceid;
30 } op_service_types[] = { 31 } op_service_types[] = {
31 { STURI_OPENID20_OP, IDURI_SELECT20 }, 32 { STURI_OPENID20_OP, IDURI_SELECT20 },
32 { STURI_OPENID20, 0 }, 33 { STURI_OPENID20, 0 },
33 { STURI_OPENID11, 0 }, 34 { STURI_OPENID11, 0 },
34 { STURI_OPENID10, 0 } 35 { STURI_OPENID10, 0 }
35 }; 36 };
36 enum { 37 enum {
37 st_index_1 = 2, st_index_2 = 1 38 st_index_1 = 2, st_index_2 = 1
38 }; 39 };
39 40
40 41
41 static inline bool is_qelement(const XML_Char *n,const char *qen) { 42 static inline bool is_qelement(const XML_Char *n,const char *qen) {
42 return !strcasecmp(n,qen); 43 return !strcasecmp(n,qen);
43 } 44 }
44 static inline bool is_element(const XML_Char *n,const char *en) { 45 static inline bool is_element(const XML_Char *n,const char *en) {
45 if(!strcasecmp(n,en)) return true; 46 if(!strcasecmp(n,en)) return true;
46 int nl = strlen(n), enl = strlen(en); 47 int nl = strlen(n), enl = strlen(en);
47 if( (nl>=(enl+1)) && n[nl-enl-1]=='\t' 48 if( (nl>=(enl+1)) && n[nl-enl-1]=='\t'
48 && !strcasecmp(&n[nl-enl],en) ) 49 && !strcasecmp(&n[nl-enl],en) )
49 return true; 50 return true;
50 return false; 51 return false;
51 } 52 }
52 53
53 static long element_priority(const XML_Char **a) { 54 static long element_priority(const XML_Char **a) {
54 for(;*a;++a) 55 for(;*a;++a)
55 if(!strcasecmp(*(a++),"priority")) { 56 if(!strcasecmp(*(a++),"priority")) {
56 long rv; 57 long rv;
57 return (sscanf(*a,"%ld",&rv)==1)?rv:-1; 58 return (sscanf(*a,"%ld",&rv)==1)?rv:-1;
58 } 59 }
59 return -1; 60 return -1;
60 } 61 }
61 /* TODO: ideally all attributes should be 62 /* TODO: ideally all attributes should be
62 * retrieved in one run */ 63 * retrieved in one run */
63 static const char *element_attr(const XML_Char **a, const char *at) { 64 static const char *element_attr(const XML_Char **a, const char *at) {
64 for(;*a;++a) 65 for(;*a;++a)
65 if(!strcasecmp(*(a++),at)) { 66 if(!strcasecmp(*(a++),at)) {
66 return *a; 67 return *a;
67 } 68 }
68 return 0; 69 return 0;
69 } 70 }
70 71
71 class idigger_t : public util::curl_t, public util::expat_t { 72 class idigger_t : public util::curl_t, public util::expat_t {
72 public: 73 public:
73 string xri_proxy; 74 string xri_proxy;
74 75
75 enum { 76 enum {
76 xmode_html = 1, xmode_xrd = 2, xmode_cid = 4, 77 xmode_html = 1, xmode_xrd = 2, xmode_cid = 4,
77 xmode_noredirs = 8 78 xmode_noredirs = 8
78 }; 79 };
79 int xmode; 80 int xmode;
80 81
81 string xrds_location; 82 string xrds_location;
82 string http_content_type; 83 string http_content_type;
83 service_t html_openid1; 84 service_t html_openid1;
84 service_t html_openid2; 85 service_t html_openid2;
85 string cdata_buf; 86 string cdata_buf;
86 long status_code; 87 long status_code;
87 string status_string; 88 string status_string;
88 89
89 typedef list<string> pt_stack_t; 90 typedef list<string> pt_stack_t;
90 pt_stack_t pt_stack; 91 pt_stack_t pt_stack;
91 int skipping; 92 int skipping;
92 bool parser_choked; 93 bool parser_choked;
93 string save_html; 94 string save_html;
94 95
95 XRD_t *xrd; 96 XRD_t *xrd;
96 service_t *xrd_service; 97 service_t *xrd_service;
97 string* cdata; 98 string* cdata;
98 99
99 idigger_t() 100 idigger_t()
100 : util::curl_t(easy_init()), 101 : util::curl_t(easy_init()),
101 util::expat_t(0), 102 util::expat_t(0),
102 xri_proxy(XRI_PROXY_URL) { 103 xri_proxy(XRI_PROXY_URL) {
103 CURLcode r; 104 CURLcode r;
104 (r=misc_sets()) 105 (r=misc_sets())
105 || (r=set_write()) 106 || (r=set_write())
106 || (r=set_header()) 107 || (r=set_header())
107 ; 108 ;
108 if(r) 109 if(r)
109 throw exception_curl(OPKELE_CP_ "failed to set curly options",r); 110 throw exception_curl(OPKELE_CP_ "failed to set curly options",r);
110 } 111 }
111 ~idigger_t() throw() { } 112 ~idigger_t() throw() { }
112 113
113 void yadiscover(endpoint_discovery_iterator oi,const string& yurl,const char **types,bool redirs) { 114 void yadiscover(endpoint_discovery_iterator oi,const string& yurl,const char **types,bool redirs) {
114 idiscovery_t idis; 115 idiscovery_t idis;
115 idis.xri_identity = false; 116 idis.xri_identity = false;
116 discover_at(idis,yurl,xmode_html|xmode_xrd|(redirs?0:xmode_noredirs)); 117 discover_at(idis,yurl,xmode_html|xmode_xrd|(redirs?0:xmode_noredirs));
117 if(!xrds_location.empty()) { 118 if(!xrds_location.empty()) {
118 idis.clear(); 119 idis.clear();
119 discover_at(idis,xrds_location,xmode_xrd); 120 discover_at(idis,xrds_location,xmode_xrd);
120 } 121 }
121 idis.normalized_id = idis.canonicalized_id = yurl; 122 idis.normalized_id = idis.canonicalized_id = yurl;
122 service_type_t st; 123 service_type_t st;
123 for(st.uri=*types;*types;st.uri=*(++types)) 124 for(st.uri=*types;*types;st.uri=*(++types))
124 queue_endpoints(oi,idis,&st); 125 queue_endpoints(oi,idis,&st);
125 } 126 }
126 127
127 string discover(endpoint_discovery_iterator& oi,const string& identity) { 128 string discover(endpoint_discovery_iterator& oi,const string& identity) {
128 string rv; 129 string rv;
129 idiscovery_t idis; 130 idiscovery_t idis;
130 string::size_type fsc = identity.find_first_not_of(data::_whitespace_chars); 131 string::size_type fsc = identity.find_first_not_of(data::_whitespace_chars);
131 if(fsc==string::npos) 132 if(fsc==string::npos)
132 throw bad_input(OPKELE_CP_ "whitespace-only identity"); 133 throw bad_input(OPKELE_CP_ "whitespace-only identity");
133 string::size_type lsc = identity.find_last_not_of(data::_whitespace_chars); 134 string::size_type lsc = identity.find_last_not_of(data::_whitespace_chars);
134 assert(lsc!=string::npos); 135 assert(lsc!=string::npos);
135 if(!strncasecmp(identity.c_str()+fsc,"xri://",sizeof("xri://")-1)) 136 if(!strncasecmp(identity.c_str()+fsc,"xri://",sizeof("xri://")-1))
136 fsc += sizeof("xri://")-1; 137 fsc += sizeof("xri://")-1;
137 if((fsc+1)>=lsc) 138 if((fsc+1)>=lsc)
138 throw bad_input(OPKELE_CP_ "not a character of importance in identity"); 139 throw bad_input(OPKELE_CP_ "not a character of importance in identity");
139 string id(identity,fsc,lsc-fsc+1); 140 string id(identity,fsc,lsc-fsc+1);
140 idis.clear(); 141 idis.clear();
141 if(strchr(data::_iname_leaders,id[0])) { 142 if(strchr(data::_iname_leaders,id[0])) {
142 /* TODO: further normalize xri identity? Like folding case 143 /* TODO: further normalize xri identity? Like folding case
143 * or whatever... */ 144 * or whatever... */
144 rv = id; 145 rv = id;
145 set<string> cids; 146 set<string> cids;
146 for(const struct service_type_t *st=op_service_types; 147 for(const struct service_type_t *st=op_service_types;
147 st<&op_service_types[sizeof(op_service_types)/sizeof(*op_service_types)];++st) { 148 st<&op_service_types[sizeof(op_service_types)/sizeof(*op_service_types)];++st) {
148 idis.clear(); 149 idis.clear();
149 discover_at( idis, 150 discover_at( idis,
150 xri_proxy + util::url_encode(id)+ 151 xri_proxy + util::url_encode(id)+
151 "?_xrd_t="+util::url_encode(st->uri)+ 152 "?_xrd_t="+util::url_encode(st->uri)+
152 "&_xrd_r=application/xrd%2Bxml" 153 "&_xrd_r=application/xrd%2Bxml"
153 ";sep=true;refs=true", 154 ";sep=true;refs=true",
154 xmode_xrd ); 155 xmode_xrd );
155 if(status_code==241) continue; 156 if(status_code==241) continue;
156 if(status_code!=100) 157 if(status_code!=100)
157 throw failed_xri_resolution(OPKELE_CP_ 158 throw failed_xri_resolution(OPKELE_CP_
158 "XRI resolution failed with '"+status_string+"' message" 159 "XRI resolution failed with '"+status_string+"' message"
159 ", while looking for SEP with type '"+st->uri+"'", status_code); 160 ", while looking for SEP with type '"+st->uri+"'", status_code);
160 if(idis.xrd.canonical_ids.empty()) 161 if(idis.xrd.canonical_ids.empty())
161 throw opkele::failed_discovery(OPKELE_CP_ "No CanonicalID for XRI identity found"); 162 throw opkele::failed_discovery(OPKELE_CP_ "No CanonicalID for XRI identity found");
162 string cid = idis.xrd.canonical_ids.begin()->second; 163 string cid = idis.xrd.canonical_ids.begin()->second;
163 if(cids.find(cid)==cids.end()) { 164 if(cids.find(cid)==cids.end()) {
164 cids.insert(cid); 165 cids.insert(cid);
165 idis.clear(); 166 idis.clear();
166 discover_at( idis, 167 discover_at( idis,
167 xri_proxy + util::url_encode(id)+ 168 xri_proxy + util::url_encode(id)+
168 "?_xrd_t="+util::url_encode(st->uri)+ 169 "?_xrd_t="+util::url_encode(st->uri)+
169 "&_xrd_r=application/xrd%2Bxml" 170 "&_xrd_r=application/xrd%2Bxml"
170 ";sep=true;refs=true", 171 ";sep=true;refs=true",
171 xmode_xrd ); 172 xmode_xrd );
172 if(status_code==241) continue; 173 if(status_code==241) continue;
173 if(status_code!=100) 174 if(status_code!=100)
174 throw failed_xri_resolution(OPKELE_CP_ 175 throw failed_xri_resolution(OPKELE_CP_
175 "XRI resolution failed with '"+status_string+"' message" 176 "XRI resolution failed with '"+status_string+"' message"
176 ", while looking for SEP with type '"+st->uri+"'" 177 ", while looking for SEP with type '"+st->uri+"'"
177 " on canonical id", status_code); 178 " on canonical id", status_code);
178 } 179 }
179 idis.canonicalized_id = cid; 180 idis.canonicalized_id = cid;
180 idis.normalized_id = rv; idis.xri_identity = true; 181 idis.normalized_id = rv; idis.xri_identity = true;
181 queue_endpoints(oi,idis,st); 182 queue_endpoints(oi,idis,st);
182 } 183 }
183 }else{ 184 }else{
184 idis.xri_identity = false; 185 idis.xri_identity = false;
185 if(id.find("://")==string::npos) 186 if(id.find("://")==string::npos)
186 id.insert(0,"http://"); 187 id.insert(0,"http://");
187 string::size_type fp = id.find('#'); 188 string::size_type fp = id.find('#');
188 if(fp!=string::npos) { 189 if(fp!=string::npos) {
189 string::size_type qp = id.find('?'); 190 string::size_type qp = id.find('?');
190 if(qp==string::npos || qp<fp) 191 if(qp==string::npos || qp<fp)
191 id.erase(fp); 192 id.erase(fp);
192 else if(qp>fp) 193 else if(qp>fp)
193 id.erase(fp,qp-fp); 194 id.erase(fp,qp-fp);
194 } 195 }
195 rv = idis.normalized_id = util::rfc_3986_normalize_uri(id); 196 rv = idis.normalized_id = util::rfc_3986_normalize_uri(id);
196 discover_at(idis,id,xmode_html|xmode_xrd); 197 discover_at(idis,id,xmode_html|xmode_xrd);
197 const char * eu = 0; 198 const char * eu = 0;
198 CURLcode r = easy_getinfo(CURLINFO_EFFECTIVE_URL,&eu); 199 CURLcode r = easy_getinfo(CURLINFO_EFFECTIVE_URL,&eu);
199 if(r) 200 if(r)
200 throw exception_curl(OPKELE_CP_ "failed to get CURLINFO_EFFECTIVE_URL",r); 201 throw exception_curl(OPKELE_CP_ "failed to get CURLINFO_EFFECTIVE_URL",r);
201 string cid = util::strip_uri_fragment_part( idis.canonicalized_id = util::rfc_3986_normalize_uri(eu) ); 202 string cid = util::strip_uri_fragment_part( idis.canonicalized_id = util::rfc_3986_normalize_uri(eu) );
202 if(xrds_location.empty()) { 203 if(xrds_location.empty()) {
203 if(idis.xrd.empty()) 204 if(idis.xrd.empty())
204 html2xrd(oi,idis); 205 html2xrd(oi,idis);
205 else{ 206 else{
206 for(const service_type_t *st=op_service_types; 207 for(const service_type_t *st=op_service_types;
207 st<&op_service_types[sizeof(op_service_types)/sizeof(*op_service_types)];++st) 208 st<&op_service_types[sizeof(op_service_types)/sizeof(*op_service_types)];++st)
208 queue_endpoints(oi,idis,st); 209 queue_endpoints(oi,idis,st);
209 } 210 }
210 }else{ 211 }else{
211 idis.clear(); 212 idis.clear();
212 idis.canonicalized_id = cid; 213 idis.canonicalized_id = cid;
213 discover_at(idis,xrds_location,xmode_xrd); 214 discover_at(idis,xrds_location,xmode_xrd);
214 if(idis.xrd.empty()) 215 if(idis.xrd.empty())
215 html2xrd(oi,idis); 216 html2xrd(oi,idis);
216 else{ 217 else{
217 for(const service_type_t *st=op_service_types; 218 for(const service_type_t *st=op_service_types;
218 st<&op_service_types[sizeof(op_service_types)/sizeof(*op_service_types)];++st) 219 st<&op_service_types[sizeof(op_service_types)/sizeof(*op_service_types)];++st)
219 queue_endpoints(oi,idis,st); 220 queue_endpoints(oi,idis,st);
220 } 221 }
221 } 222 }
222 } 223 }
223 return rv; 224 return rv;
224 } 225 }
225 226
226 void discover_at(idiscovery_t& idis,const string& url,int xm) { 227 void discover_at(idiscovery_t& idis,const string& url,int xm) {
227 CURLcode r = easy_setopt(CURLOPT_MAXREDIRS, (xm&xmode_noredirs)?0:5); 228 CURLcode r = easy_setopt(CURLOPT_MAXREDIRS, (xm&xmode_noredirs)?0:5);
228 if(r) 229 if(r)
229 throw exception_curl(OPKELE_CP_ "failed to set curly maxredirs option"); 230 throw exception_curl(OPKELE_CP_ "failed to set curly maxredirs option");
230 if( (r=easy_setopt(CURLOPT_URL,url.c_str())) ) 231 if( (r=easy_setopt(CURLOPT_URL,url.c_str())) )
231 throw exception_curl(OPKELE_CP_ "failed to set curly urlie",r); 232 throw exception_curl(OPKELE_CP_ "failed to set curly urlie",r);
232 233
233 http_content_type.clear(); 234 http_content_type.clear();
234 xmode = xm; 235 xmode = xm;
235 prepare_to_parse(); 236 prepare_to_parse();
236 if(xmode&xmode_html) { 237 if(xmode&xmode_html) {
237 xrds_location.clear(); 238 xrds_location.clear();
238 save_html.clear(); 239 save_html.clear();
239 save_html.reserve(max_html); 240 save_html.reserve(max_html);
240 } 241 }
241 xrd = &idis.xrd; 242 xrd = &idis.xrd;
242 243
243 r = easy_perform(); 244 r = easy_perform();
244 if(r && r!=CURLE_WRITE_ERROR) 245 if(r && r!=CURLE_WRITE_ERROR)
245 throw exception_curl(OPKELE_CP_ "failed to perform curly request",r); 246 throw exception_curl(OPKELE_CP_ "failed to perform curly request",r);
246 247
247 if(!parser_choked) { 248 if(!parser_choked) {
248 parse(0,0,true); 249 parse(0,0,true);
249 }else if(xmode&xmode_html){ 250 }else if(xmode&xmode_html){
250 /* TODO: do not bother if we've seen xml */ 251 /* TODO: do not bother if we've seen xml */
251 try { 252 try {
252 util::tidy_doc_t td = util::tidy_doc_t::create(); 253 util::tidy_doc_t td = util::tidy_doc_t::create();
253 if(!td) 254 if(!td)
254 throw exception_tidy(OPKELE_CP_ "failed to create htmltidy document"); 255 throw exception_tidy(OPKELE_CP_ "failed to create htmltidy document");
255#ifndef NDEBUG 256#ifndef NDEBUG
256 td.opt_set(TidyQuiet,false); 257 td.opt_set(TidyQuiet,false);
257 td.opt_set(TidyShowWarnings,false); 258 td.opt_set(TidyShowWarnings,false);
258#endif /* NDEBUG */ 259#endif /* NDEBUG */
259 td.opt_set(TidyForceOutput,true); 260 td.opt_set(TidyForceOutput,true);
260 td.opt_set(TidyXhtmlOut,true); 261 td.opt_set(TidyXhtmlOut,true);
261 td.opt_set(TidyDoctypeMode,TidyDoctypeOmit); 262 td.opt_set(TidyDoctypeMode,TidyDoctypeOmit);
262 td.opt_set(TidyMark,false); 263 td.opt_set(TidyMark,false);
263 td.opt_set(TidyNumEntities,true); 264 td.opt_set(TidyNumEntities,true);
264 if(td.parse_string(save_html)<=0) 265 if(td.parse_string(save_html)<=0)
265 throw exception_tidy(OPKELE_CP_ "tidy failed to parse document"); 266 throw exception_tidy(OPKELE_CP_ "tidy failed to parse document");
266 if(td.clean_and_repair()<=0) 267 if(td.clean_and_repair()<=0)
267 throw exception_tidy(OPKELE_CP_ "tidy failed to clean and repair"); 268 throw exception_tidy(OPKELE_CP_ "tidy failed to clean and repair");
268 util::tidy_buf_t tide; 269 util::tidy_buf_t tide;
269 if(td.save_buffer(tide)<=0) 270 if(td.save_buffer(tide)<=0)