summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--AUTHORS14
-rw-r--r--BSDmakefile10
-rw-r--r--GIT-Access7
-rw-r--r--README83
-rw-r--r--buildsys.mk.in394
-rw-r--r--configure.ac3
-rw-r--r--debian/changelog6
-rw-r--r--doc/BOOST3
-rw-r--r--doc/design-concepts.txt5
-rwxr-xr-xscripts/makerelease.sh2
-rw-r--r--src/examples/Makefile3
-rw-r--r--src/examples/async_resolver/async_resolver.c27
-rw-r--r--src/examples/echoserver/echoserver.c27
-rw-r--r--src/examples/formattertest/formattertest.c3
-rw-r--r--src/examples/futuretest/futuretest.c89
-rw-r--r--src/examples/helpertest/helpertest.c32
-rw-r--r--src/examples/jsontest/Makefile (renamed from src/examples/futuretest/Makefile)4
-rw-r--r--src/examples/jsontest/jsontest.c47
-rw-r--r--src/examples/libevent-bench/bench.c82
-rw-r--r--src/examples/linetest/linetest.c27
-rw-r--r--src/examples/listsort/listsort.c24
-rw-r--r--src/examples/memslice-bench/memslice-bench.c56
-rw-r--r--src/examples/patriciatest/patriciatest.c32
-rw-r--r--src/examples/patriciatest2/patriciatest2.c40
-rw-r--r--src/examples/randomtest/randomtest.c8
-rw-r--r--src/examples/timertest/timertest.c9
-rw-r--r--src/examples/vio-udplistener/vio-udplistener.c15
-rw-r--r--src/libmowgli/Makefile4
-rw-r--r--src/libmowgli/base/argstack.c63
-rw-r--r--src/libmowgli/base/argstack.h14
-rw-r--r--src/libmowgli/base/bitvector.c46
-rw-r--r--src/libmowgli/base/bitvector.h4
-rw-r--r--src/libmowgli/base/formatter.c20
-rw-r--r--src/libmowgli/base/hash.c46
-rw-r--r--src/libmowgli/base/hook.c5
-rw-r--r--src/libmowgli/base/hook.h23
-rw-r--r--src/libmowgli/base/memslice.c11
-rw-r--r--src/libmowgli/base/memslice.h1
-rw-r--r--src/libmowgli/base/mowgli_signal.c8
-rw-r--r--src/libmowgli/base/mowgli_signal.h2
-rw-r--r--src/libmowgli/base/random.c37
-rw-r--r--src/libmowgli/base/random.h4
-rw-r--r--src/libmowgli/container/dictionary.c97
-rw-r--r--src/libmowgli/container/dictionary.h29
-rw-r--r--src/libmowgli/container/index.c191
-rw-r--r--src/libmowgli/container/index.h40
-rw-r--r--src/libmowgli/container/list.c180
-rw-r--r--src/libmowgli/container/list.h20
-rw-r--r--src/libmowgli/container/patricia.c202
-rw-r--r--src/libmowgli/container/patricia.h29
-rw-r--r--src/libmowgli/container/queue.c15
-rw-r--r--src/libmowgli/container/queue.h1
-rw-r--r--src/libmowgli/dns/Makefile10
-rw-r--r--src/libmowgli/dns/dns.c24
-rw-r--r--src/libmowgli/dns/dns.h19
-rw-r--r--src/libmowgli/dns/dns_evloop_reslib.h112
-rw-r--r--src/libmowgli/dns/evloop_res.c (renamed from src/libmowgli/dns/dns_evloop_res.c)433
-rw-r--r--src/libmowgli/dns/evloop_res.h (renamed from src/libmowgli/dns/dns_evloop_res.h)9
-rw-r--r--src/libmowgli/dns/evloop_reslib.c (renamed from src/libmowgli/dns/dns_evloop_reslib.c)406
-rw-r--r--src/libmowgli/dns/evloop_reslib.h115
-rw-r--r--src/libmowgli/dns/evloop_reslist_win32.c (renamed from src/libmowgli/dns/dns_evloop_reslist_win32.c)45
-rw-r--r--src/libmowgli/eventloop/epoll_pollops.c46
-rw-r--r--src/libmowgli/eventloop/eventloop.c35
-rw-r--r--src/libmowgli/eventloop/eventloop.h148
-rw-r--r--src/libmowgli/eventloop/helper.c20
-rw-r--r--src/libmowgli/eventloop/kqueue_pollops.c65
-rw-r--r--src/libmowgli/eventloop/null_pollops.c43
-rw-r--r--src/libmowgli/eventloop/poll_pollops.c75
-rw-r--r--src/libmowgli/eventloop/pollable.c62
-rw-r--r--src/libmowgli/eventloop/ports_pollops.c56
-rw-r--r--src/libmowgli/eventloop/qnx_pollops.c50
-rw-r--r--src/libmowgli/eventloop/select_pollops.c59
-rw-r--r--src/libmowgli/eventloop/timer.c47
-rw-r--r--src/libmowgli/eventloop/windows_pollops.c55
-rw-r--r--src/libmowgli/ext/Makefile7
-rw-r--r--src/libmowgli/ext/confparse.c197
-rw-r--r--src/libmowgli/ext/confparse.h2
-rw-r--r--src/libmowgli/ext/error_backtrace.c8
-rw-r--r--src/libmowgli/ext/error_backtrace.h3
-rw-r--r--src/libmowgli/ext/getopt_long.c288
-rw-r--r--src/libmowgli/ext/getopt_long.h18
-rw-r--r--src/libmowgli/ext/global_storage.c8
-rw-r--r--src/libmowgli/ext/global_storage.h1
-rw-r--r--src/libmowgli/ext/json-inline.h107
-rw-r--r--src/libmowgli/ext/json.c1475
-rw-r--r--src/libmowgli/ext/json.h151
-rw-r--r--src/libmowgli/ext/proctitle.c142
-rw-r--r--src/libmowgli/ext/proctitle.h7
-rw-r--r--src/libmowgli/ext/program_opts.c27
-rw-r--r--src/libmowgli/ext/program_opts.h3
-rw-r--r--src/libmowgli/linebuf/linebuf.c175
-rw-r--r--src/libmowgli/linebuf/linebuf.h37
-rw-r--r--src/libmowgli/module/Makefile2
-rw-r--r--src/libmowgli/module/interface.c73
-rw-r--r--src/libmowgli/module/loader_posix.c29
-rw-r--r--src/libmowgli/module/loader_win32.c21
-rw-r--r--src/libmowgli/module/module.h17
-rw-r--r--src/libmowgli/mowgli.h11
-rw-r--r--src/libmowgli/object/class.c59
-rw-r--r--src/libmowgli/object/class.h34
-rw-r--r--src/libmowgli/object/message.c68
-rw-r--r--src/libmowgli/object/message.h3
-rw-r--r--src/libmowgli/object/metadata.c36
-rw-r--r--src/libmowgli/object/metadata.h3
-rw-r--r--src/libmowgli/object/object.c18
-rw-r--r--src/libmowgli/object/object.h3
-rw-r--r--src/libmowgli/platform/Makefile12
-rw-r--r--src/libmowgli/platform/attributes.h69
-rw-r--r--src/libmowgli/platform/cacheline.c72
-rw-r--r--src/libmowgli/platform/cacheline.h (renamed from src/libmowgli/platform/win32/gettimeofday.c)47
-rw-r--r--src/libmowgli/platform/constructor.h27
-rw-r--r--src/libmowgli/platform/machine.h474
-rw-r--r--src/libmowgli/platform/win32/Makefile2
-rw-r--r--src/libmowgli/platform/win32/fork.c41
-rw-r--r--src/libmowgli/platform/win32/inet.c18
-rw-r--r--src/libmowgli/platform/win32/pipe.c4
-rw-r--r--src/libmowgli/platform/win32/setenv.c4
-rw-r--r--src/libmowgli/platform/win32/socketpair.c155
-rw-r--r--src/libmowgli/platform/win32/win32_stdinc.h32
-rw-r--r--src/libmowgli/thread/mutex.c35
-rw-r--r--src/libmowgli/thread/mutex.h16
-rw-r--r--src/libmowgli/thread/null_mutexops.c18
-rw-r--r--src/libmowgli/thread/posix_mutexops.c81
-rw-r--r--src/libmowgli/thread/thread.h20
-rw-r--r--src/libmowgli/thread/win32_mutexops.c30
-rw-r--r--src/libmowgli/vio/vio.c133
-rw-r--r--src/libmowgli/vio/vio.h283
-rw-r--r--src/libmowgli/vio/vio_openssl.c200
-rw-r--r--src/libmowgli/vio/vio_sockets.c229
-rw-r--r--uncrustify.cfg1578
131 files changed, 7836 insertions, 2857 deletions
diff --git a/.gitignore b/.gitignore
index b056935..232e8f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,8 @@ src/examples/memslice-bench/memslice-bench
src/examples/vio-udplistener/vio-udplistener
src/examples/futuretest/futuretest
src/examples/async_resolver/async_resolver
+src/examples/jsontest/jsontest
+src/examples/jsontest/test.json
.deps
*.dylib
*.o
diff --git a/AUTHORS b/AUTHORS
index e96e123..868bfb1 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,6 +1,12 @@
-Patrick McFarland <pmcfarland -at- adterrasperaspera.com>
-William Pitcock <nenolod -at- sacredspiral.co.uk>
+All names are listed in alphabetical order.
+
+The following people are active contributors to libmowgli:
+Elizabeth Myers <elizabeth -at- sporksmoo.net>
+William Pitcock <nenolod -at- nenolod.net>
Jonathan Schleifer <js-libmowgli -at- webkeks.org>
-Pippijn van Steenhoven <pippijn -at- one09.net>
Jilles Tjoelker <jilles -at- stack.nl>
-Elizabeth Myers <elizabeth -at- sporksmoo.net>
+
+The following people have contributed to libmowgli in the past:
+Patrick McFarland <pmcfarland -at- adterrasperaspera.com>
+Pippijn van Steenhoven <pippijn -at- one09.net>
+Andrew Wilcox <awilcox -at- wilcox-tech.com>
diff --git a/BSDmakefile b/BSDmakefile
new file mode 100644
index 0000000..b075051
--- /dev/null
+++ b/BSDmakefile
@@ -0,0 +1,10 @@
+# This BSDmakefile redirects to GNU make.
+
+all: .DEFAULT
+.DEFAULT:
+ @case ${MAKE} in \
+ gmake|*/gmake) \
+ echo "BSDmakefile run using gmake??"; \
+ exit 1;; \
+ esac
+ gmake ${.MAKEFLAGS} ${.TARGETS}
diff --git a/GIT-Access b/GIT-Access
index e57914e..c84661b 100644
--- a/GIT-Access
+++ b/GIT-Access
@@ -1,6 +1,5 @@
The libmowgli GIT repository can be checked out using the following command:
- git clone git://git.atheme.org/libmowgli-2.git libmowgli-2
+ git clone git://github.com/atheme/libmowgli-2.git
-libmowgli's GIT repository depot can be browsed over the internet at
-the following address:
- http://git.atheme.org/
+libmowgli's GIT repository can be browsed via HTTP at the following address:
+ https://github.com/atheme/libmowgli-2
diff --git a/README b/README
index 424f23d..a76a749 100644
--- a/README
+++ b/README
@@ -19,42 +19,44 @@ libmowgli is a class library containing performance and usability oriented
extensions to C.
It contains:
- - mowgli_alloc: A safe wrapper around malloc/free.
- - mowgli_argstack: Safe serialization of valists.
- - mowgli_assert: Various assertion routines that can be used.
- - mowgli_bitvector: Bitmasks with an unlimited level of precision.
- - mowgli_patricia: A keyword-backed definition hashtable class.
- - mowgli_error_backtrace: Provide feedback to users on what caused the
- error they are recieving.
- - mowgli_exception: Assertions with user feedback.
- - mowgli_formatter: A simple token formatter which is sometimes useful.
- - mowgli_global_storage: A simple global storage library.
- - mowgli_hash: A portable implementation of the FNV-1 hash.
- - mowgli_heap: An optimistic heap-based memory allocator
- - mowgli_hook: A simple hooks API you can use for your application, which
- allows for hooks to provide both application data and user data.
- - mowgli_list: A high performance linked lists implementation with O(1) scalability
- for most common operations.
- - mowgli_logger: An internal class for handling logging of exceptions.
- - mowgli_module: A wrapper around dlopen(3) and dlsym(3).
- - mowgli_object: A simple class which provides reference counted pointers and
- polymorphism of structs.
- - mowgli_object_class: Classing and subclassing for objects.
- - mowgli_object_metadata: Metadata for objects.
- - mowgli_object_messaging: Messaging and signalling for objects.
- - mowgli_queue: A simple class which implements double-ended queues.
- - mowgli_random: A high performance psuedo-random number generator.
- - mowgli_signal: A wrapper for sigaction(2).
- - mowgli_eventloop: A portable event loop implementation.
- - mowgli_vio: An abstraction layer for I/O.
- - mowgli_linebuf: A line-buffering implementation for clients.
- - mowgli_thread: Minimal thread abstraction.
-
-More classes will be added with later releases. Please contact
-nenolod -at- atheme.org if you have suggestions on what should be
-implemented.
-
-More information is available at http://www.atheme.org/projects/mowgli.shtml.
+ - mowgli.alloc: A safe wrapper around malloc/free.
+ - mowgli.argstack: Safe serialization of valists.
+ - mowgli.assert: Various assertion routines that can be used.
+ - mowgli.bitvector: Bitmasks with an unlimited level of precision.
+ - mowgli.patricia: A dictionary implementation based on a modified
+ patricia tree algorithm (uses nibbles instead of
+ bits for branching).
+ - mowgli.error_backtrace: Provide feedback to users on what caused
+ the error they are recieving.
+ - mowgli.formatter: A simple token formatter which is sometimes useful.
+ - mowgli.global_storage: A simple global storage library.
+ - mowgli.hash: A portable implementation of the FNV-1 hash.
+ - mowgli.heap: An optimistic heap-based memory allocator
+ - mowgli.hook: A simple hooks API you can use for your application,
+ which allows for hooks to provide both application
+ data and user data.
+ - mowgli.json: A simple, flexible, reentrant JSON parser
+ - mowgli.list: A high performance linked lists implementation with
+ O(1) scalability for most common operations.
+ - mowgli.logger: An internal class for handling logging of exceptions.
+ - mowgli.module: A wrapper around dlopen(3) and dlsym(3).
+ - mowgli.object: A simple class which provides reference counted
+ pointers and polymorphism of structs.
+ - mowgli.object_class: Classing and subclassing for objects.
+ - mowgli.object_metadata: Metadata for objects.
+ - mowgli.object_messaging: Messaging and signalling for objects.
+ - mowgli.queue: A simple class which implements double-ended queues.
+ - mowgli.random: A high performance psuedo-random number generator.
+ - mowgli.signal: A wrapper for sigaction(2).
+ - mowgli.eventloop: A portable event loop implementation.
+ - mowgli.vio: An abstraction layer for I/O.
+ - mowgli.linebuf: A line-buffering implementation for clients.
+ - mowgli.thread: Minimal thread abstraction.
+
+More classes will be added with later releases. Please use GitHub's
+issue tracker if you have suggestions on what should be implemented.
+
+More information is available at http://www.atheme.org/projects/mowgli.
Installation
@@ -66,14 +68,13 @@ Installation is fairly typical:
$ make
$ sudo make install
-(If sudo isn't on your system, su to root. On GNU systems you can even
-do "su -c 'make install'", which is basically the same thing as using
-sudo.)
+(If sudo isn't on your system, su to root. On GNU systems you can even do
+"su -c 'make install'", which is basically the same thing as using sudo.)
Bug Reports
-----------
-Bugs can be reported on our tracker at http://jira.atheme.org against the
-libmowgli product.
+Bugs can be reported using the GitHub issue tracker on the libmowgli-2
+project page: https://github.com/atheme/libmowgli-2/issues
diff --git a/buildsys.mk.in b/buildsys.mk.in
index 7977b07..dc54919 100644
--- a/buildsys.mk.in
+++ b/buildsys.mk.in
@@ -21,6 +21,7 @@
# POSSIBILITY OF SUCH DAMAGE.
#
+#V=1
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
AS = @AS@
@@ -104,19 +105,13 @@ MO_FILES = ${LOCALES:.po=.mo}
.SILENT:
.SUFFIXES:
.SUFFIXES: .beam .c .c.dep .cc .cc.dep .class .cxx .cxx.dep .d .erl .lib.o .java .mo .m .m.dep .mm .mm.dep .o .plugin.o .po .py .pyc .rc .S .S.dep .xpm
-.PHONY: all subdirs pre-depend depend install install-extra uninstall uninstall-extra clean distclean locales
+.PHONY: all subdirs ${SUBDIRS} pre-depend depend install install-extra uninstall uninstall-extra clean distclean locales
-all:
- ${MAKE} ${MFLAGS} subdirs
- ${MAKE} ${MFLAGS} depend
- ${MAKE} ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${PLUGIN} ${PLUGIN_NOINST} ${PROG} ${PROG_NOINST} ${JARFILE} locales
+all: subdirs depend ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${PLUGIN} ${PLUGIN_NOINST} ${PROG} ${PROG_NOINST} ${JARFILE} locales
-subdirs:
- for i in ${SUBDIRS}; do \
- ${DIR_ENTER}; \
- ${MAKE} ${MFLAGS} || exit $$?; \
- ${DIR_LEAVE}; \
- done
+subdirs: ${SUBDIRS}
+${SUBDIRS}:
+ ${MAKE} -C $@ ${MFLAGS}
depend: pre-depend ${SRCS}
regen=0; \
@@ -142,15 +137,36 @@ depend: pre-depend ${SRCS}
fi; \
fi
-.c.c.dep .cc.cc.dep .cxx.cxx.dep .m.m.dep .mm.mm.dep .S.S.dep:
- ${CPP} ${CPPFLAGS} -M $< | \
+.c.c.dep:
+ ${CPP} ${CPPFLAGS} ${CFLAGS} -M $< | \
+ sed 's/^\([^\.]*\)\.o:/\1.o \1.lib.o \1.plugin.o:/' >$@ || \
+ { rm -f $@; false; }
+
+.cc.cc.dep .cxx.cxx.dep:
+ ${CPP} ${CPPFLAGS} ${CXXFLAGS} -M $< | \
+ sed 's/^\([^\.]*\)\.o:/\1.o \1.lib.o \1.plugin.o:/' >$@ || \
+ { rm -f $@; false; }
+
+.m.m.dep:
+ ${CPP} ${CPPFLAGS} ${OBJCFLAGS} -M $< | \
+ sed 's/^\([^\.]*\)\.o:/\1.o \1.lib.o \1.plugin.o:/' >$@ || \
+ { rm -f $@; false; }
+
+.mm.mm.dep:
+ ${CPP} ${CPPFLAGS} ${OBJCPPFLAGS} -M $< | \
+ sed 's/^\([^\.]*\)\.o:/\1.o \1.lib.o \1.plugin.o:/' >$@ || \
+ { rm -f $@; false; }
+
+.S.S.dep:
+ ${CPP} ${CPPFLAGS} ${ASFLAGS} -M $< | \
sed 's/^\([^\.]*\)\.o:/\1.o \1.lib.o \1.plugin.o:/' >$@ || \
{ rm -f $@; false; }
pre-depend:
${PROG} ${PROG_NOINST}: ${EXT_DEPS} ${OBJS} ${OBJS_EXTRA}
- ${LINK_STATUS}
+ LDOBJS="${OBJS} ${OBJS_EXTRA}"; \
+ ${LINK_STATUS}; \
if ${LD} -o $@ ${OBJS} ${OBJS_EXTRA} ${LDFLAGS} ${LIBS}; then \
${LINK_OK}; \
else \
@@ -174,6 +190,7 @@ ${JARFILE}: ${EXT_DEPS} ${JAR_MANIFEST} ${OBJS} ${OBJS_EXTRA}
fi
${SHARED_LIB} ${SHARED_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA}
+ LDOBJS="${LIB_OBJS} ${LIB_OBJS_EXTRA}"; \
${LINK_STATUS}; \
objs=""; \
ars=""; \
@@ -209,7 +226,8 @@ ${SHARED_LIB} ${SHARED_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA}
done
${PLUGIN} ${PLUGIN_NOINST}: ${EXT_DEPS} ${PLUGIN_OBJS}
- ${LINK_STATUS}
+ LDOBJS="${PLUGIN_OBJS}"; \
+ ${LINK_STATUS}; \
objs=""; \
ars=""; \
for i in ${PLUGIN_OBJS}; do \
@@ -244,8 +262,9 @@ ${PLUGIN} ${PLUGIN_NOINST}: ${EXT_DEPS} ${PLUGIN_OBJS}
done
${STATIC_LIB} ${STATIC_LIB_NOINST}: ${EXT_DEPS} ${OBJS} ${OBJS_EXTRA}
- ${LINK_STATUS}
- rm -f $@
+ LDOBJS="${OBJS} ${OBJS_EXTRA}"; \
+ ${LINK_STATUS}; \
+ rm -f $@; \
objs=""; \
ars=""; \
for i in ${OBJS} ${OBJS_EXTRA}; do \
@@ -281,7 +300,8 @@ ${STATIC_LIB} ${STATIC_LIB_NOINST}: ${EXT_DEPS} ${OBJS} ${OBJS_EXTRA}
done
${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA}
- ${LINK_STATUS}
+ LDOBJS="${LIB_OBJS} ${LIB_OBJS_EXTRA}"; \
+ ${LINK_STATUS}; \
rm -f $@
objs=""; \
ars=""; \
@@ -320,192 +340,151 @@ ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_E
locales: ${MO_FILES}
.c.o:
- ${COMPILE_STATUS}
- if ${CC} ${CFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi
+ COMPILER="${CC}"; \
+ COMPILER_FLAGS="${CFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.c.lib.o:
- ${COMPILE_LIB_STATUS}
- if ${CC} ${LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_LIB_OK}; \
- else \
- ${COMPILE_LIB_FAILED}; \
- fi
+ COMPILER="${CC}"; \
+ COMPILER_FLAGS="${LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_LIB_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.c.plugin.o:
- ${COMPILE_PLUGIN_STATUS}
- if ${CC} ${PLUGIN_CFLAGS} ${CFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_PLUGIN_OK}; \
- else \
- ${COMPILE_PLUGIN_FAILED}; \
- fi
+ COMPILER="${CC}"; \
+ COMPILER_FLAGS="${PLUGIN_CFLAGS} ${CFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_PLUGIN_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
.cc.o .cxx.o:
- ${COMPILE_STATUS}
- if ${CXX} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi
+ COMPILER="${CXX}"; \
+ COMPILER_FLAGS="${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.cc.lib.o .cxx.lib.o:
- ${COMPILE_LIB_STATUS}
- if ${CXX} ${LIB_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_LIB_OK}; \
- else \
- ${COMPILE_LIB_FAILED}; \
- fi
+ COMPILER="${CXX}"; \
+ COMPILER_FLAGS="${LIB_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_LIB_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.cc.plugin.o .cxx.plugin.o:
- ${COMPILE_PLUGIN_STATUS}
- if ${CXX} ${PLUGIN_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_PLUGIN_OK}; \
- else \
- ${COMPILE_PLUGIN_FAILED}; \
- fi
+ COMPILER="${CXX}"; \
+ COMPILER_FLAGS="${PLUGIN_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_PLUGIN_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
.d.o:
- ${COMPILE_STATUS}
- if test x"$(basename ${DC})" = x"dmd"; then \
- if ${DC} ${DFLAGS} -c -of$@ $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi \
+ COMPILER="${DC}"; \
+ ${COMPILE_STATUS}; \
+ if test x"$(basename ${COMPILER})" = x"dmd"; then \
+ $${COMPILER} ${DFLAGS} -c -of$@ $<; \
else \
- if ${DC} ${DFLAGS} -c -o $@ $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi \
+ $${COMPILER} ${DFLAGS} -c -o $@ $<; \
fi
.erl.beam:
- ${COMPILE_STATUS}
- if ${ERLC} ${ERLCFLAGS} -o $@ $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi
+ COMPILER="${ERLC}"; \
+ COMPILER_FLAGS="${ERLCFLAGS} -o $@ $<"; \
+ ${COMPILE_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
.java.class:
- ${COMPILE_STATUS}
- if ${JAVAC} ${JAVACFLAGS} $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi
+ COMPILER="${JAVAC}"; \
+ COMPILER_FLAGS="${JAVACFLAGS} $<"; \
+ ${COMPILE_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
.m.o:
- ${COMPILE_STATUS}
- if ${OBJC} ${OBJCFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi
+ COMPILER="${OBJC}"; \
+ COMPILER_FLAGS="${OBJCFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.m.lib.o:
- ${COMPILE_LIB_STATUS}
- if ${OBJC} ${LIB_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_LIB_OK}; \
- else \
- ${COMPILE_LIB_FAILED}; \
- fi
+ COMPILER="${OBJC}"; \
+ COMPILER_FLAGS="${LIB_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_LIB_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.m.plugin.o:
- ${COMPILE_PLUGIN_STATUS}
- if ${OBJC} ${PLUGIN_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_PLUGIN_OK}; \
- else \
- ${COMPILE_PLUGIN_FAILED}; \
- fi
+ COMPILER="${OBJC}"; \
+ COMPILER_FLAGS="${PLUGIN_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_PLUGIN_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
.mm.o:
- ${COMPILE_STATUS}
- if ${OBJCXX} ${OBJCXXFLAGS} ${OBJCFLAGS} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi
+ COMPILER="${OBJCXX}"; \
+ COMPILER_FLAGS="${OBJCXXFLAGS} ${OBJCFLAGS} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.mm.lib.o:
- ${COMPILE_LIB_STATUS}
- if ${OBJCXX} ${LIB_CFLAGS} ${OBJCXXFLAGS} ${OBJCFLAGS} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_LIB_OK}; \
- else \
- ${COMPILE_LIB_FAILED}; \
- fi
+ COMPILER="${OBJCXX}"; \
+ COMPILER_FLAGS="${LIB_CFLAGS} ${OBJCXXFLAGS} ${OBJCFLAGS} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_LIB_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.mm.plugin.o:
- ${COMPILE_PLUGIN_STATUS}
- if ${OBJCXX} ${PLUGIN_CFLAGS} ${OBJCXXFLAGS} ${OBJCFLAGS} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_PLUGIN_OK}; \
- else \
- ${COMPILE_PLUGIN_FAILED}; \
- fi
+ COMPILER="${OBJCXX}"; \
+ COMPILER_FLAGS="${PLUGIN_CFLAGS} ${OBJCXXFLAGS} ${OBJCFLAGS} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_PLUGIN_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
.po.mo:
- ${COMPILE_STATUS}
- if ${MSGFMT} -c -o $@ $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi
+ COMPILER="${MSGFMT}"; \
+ COMPILER_FLAGS="-c -o $@ $<"; \
+ ${COMPILE_RESOURCE_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
.py.pyc:
- ${COMPILE_STATUS}
- if ${PYTHON} ${PYTHON_FLAGS} -c "import py_compile; py_compile.compile('$<')"; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi
+ COMPILER="${PYTHON}"; \
+ COMPILER_FLAGS="${PYTHON_FLAGS}"; \
+ ${COMPILE_RESOURCE_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS} -c "import py_compile; py_compile.compile('$<')"
.rc.o .rc.lib.o .rc.plugin.o:
- ${COMPILE_STATUS}
- if ${WINDRES} ${CPPFLAGS} -J rc -O coff -o $@ $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi
+ COMPILER="${WINDRES}"; \
+ COMPILER_FLAGS="${CPPFLAGS} -J rc -O coff -o $@ $<"; \
+ ${COMPILE_RESOURCE_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
.S.o:
- ${COMPILE_STATUS}
- if ${AS} ${ASFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi
+ COMPILER="${AS}"; \
+ COMPILER_FLAGS="${ASFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.S.lib.o:
- ${COMPILE_LIB_STATUS}
- if ${AS} ${LIB_CFLAGS} ${ASFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_LIB_OK}; \
- else \
- ${COMPILE_LIB_FAILED}; \
- fi
+ COMPILER="${AS}"; \
+ COMPILER_FLAGS="${LIB_CFLAGS} ${ASFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_LIB_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.S.plugin.o:
- ${COMPILE_PLUGIN_STATUS}
- if ${AS} ${PLUGIN_CFLAGS} ${ASFLAGS} ${CPPFLAGS} -c -o $@ $<; then \
- ${COMPILE_PLUGIN_OK}; \
- else \
- ${COMPILE_PLUGIN_FAILED}; \
- fi
+ COMPILER="${AS}"; \
+ COMPILER_FLAGS="${PLUGIN_CFLAGS} ${ASFLAGS} ${CPPFLAGS} -c -o $@ $<"; \
+ ${COMPILE_PLUGIN_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
.xpm.o:
- ${COMPILE_STATUS}
- if ${CC} ${CFLAGS} ${CPPFLAGS} -x c -c -o $@ $<; then \
- ${COMPILE_OK}; \
- else \
- ${COMPILE_FAILED}; \
- fi
+ COMPILER="${CC}"; \
+ COMPILER_FLAGS="${CFLAGS} ${CPPFLAGS} -x c -c -o $@ $<"; \
+ ${COMPILE_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.xpm.lib.o:
- ${COMPILE_LIB_STATUS}
- if ${CC} ${LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} -x c -c -o $@ $<; then \
- ${COMPILE_LIB_OK}; \
- else \
- ${COMPILE_LIB_FAILED}; \
- fi
+ COMPILER="${CC}"; \
+ COMPILER_FLAGS="${LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} -x c -c -o $@ $<"; \
+ ${COMPILE_LIB_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
+
.xpm.plugin.o:
- ${COMPILE_PLUGIN_STATUS}
- if ${CC} ${PLUGIN_CFLAGS} ${CFLAGS} ${CPPFLAGS} -x c -c -o $@ $<; then \
- ${COMPILE_PLUGIN_OK}; \
- else \
- ${COMPILE_PLUGIN_FAILED}; \
- fi
+ COMPILER="${CC}"; \
+ COMPILER_FLAGS="${PLUGIN_CFLAGS} ${CFLAGS} ${CPPFLAGS} -x c -c -o $@ $<"; \
+ ${COMPILE_PLUGIN_STATUS}; \
+ $${COMPILER} $${COMPILER_FLAGS}
install: ${SHARED_LIB} ${STATIC_LIB} ${STATIC_PIC_LIB} ${PLUGIN} ${PROG} install-extra
for i in ${SUBDIRS}; do \
@@ -715,27 +694,62 @@ distclean: clean
fi \
done
-DIR_ENTER = printf "@TERM_EL@@TERM_SETAF6@Entering directory @TERM_BOLD@$$i@TERM_SGR0@@TERM_SETAF6@.@TERM_SGR0@\n"; cd $$i || exit $$?
-DIR_LEAVE = printf "@TERM_EL@@TERM_SETAF6@Leaving directory @TERM_BOLD@$$i@TERM_SGR0@@TERM_SETAF6@.@TERM_SGR0@\n"; cd .. || exit $$?
-DEPEND_STATUS = printf "@TERM_EL@@TERM_SETAF3@Generating dependencies...@TERM_SGR0@\r"
-DEPEND_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully generated dependencies.@TERM_SGR0@\n"
-DEPEND_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to generate dependencies!@TERM_SGR0@\n"; exit $$err
-COMPILE_STATUS = printf "@TERM_EL@@TERM_SETAF3@Compiling @TERM_BOLD@$<@TERM_SGR0@@TERM_SETAF3@...@TERM_SGR0@\r"
-COMPILE_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully compiled @TERM_BOLD@$<@TERM_SGR0@@TERM_SETAF2@.@TERM_SGR0@\n"
-COMPILE_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to compile @TERM_BOLD@$<@TERM_SGR0@@TERM_SETAF1@!@TERM_SGR0@\n"; exit $$err
-COMPILE_LIB_STATUS = printf "@TERM_EL@@TERM_SETAF3@Compiling @TERM_BOLD@$<@TERM_SGR0@@TERM_SETAF3@ (lib)...@TERM_SGR0@\r"
-COMPILE_LIB_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully compiled @TERM_BOLD@$<@TERM_SGR0@@TERM_SETAF2@ (lib).@TERM_SGR0@\n"
-COMPILE_LIB_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to compile @TERM_BOLD@$<@TERM_SGR0@@TERM_SETAF1@ (lib)!@TERM_SGR0@\n"; exit $$err
-COMPILE_PLUGIN_STATUS = printf "@TERM_EL@@TERM_SETAF3@Compiling @TERM_BOLD@$<@TERM_SGR0@@TERM_SETAF3@ (plugin)...@TERM_SGR0@\r"
-COMPILE_PLUGIN_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully compiled @TERM_BOLD@$<@TERM_SGR0@@TERM_SETAF2@ (plugin).@TERM_SGR0@\n"
-COMPILE_PLUGIN_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to compile @TERM_BOLD@$<@TERM_SGR0@@TERM_SETAF1@ (plugin)!@TERM_SGR0@\n"; exit $$err
-LINK_STATUS = printf "@TERM_EL@@TERM_SETAF3@Linking @TERM_BOLD@$@@TERM_SGR0@@TERM_SETAF3@...@TERM_SGR0@\r"
-LINK_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully linked @TERM_BOLD@$@@TERM_SGR0@@TERM_SETAF2@.@TERM_SGR0@\n"
-LINK_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to link @TERM_BOLD@$@@TERM_SGR0@@TERM_SETAF1@!@TERM_SGR0@\n"; exit $$err
-INSTALL_STATUS = printf "@TERM_EL@@TERM_SETAF3@Installing @TERM_BOLD@$$i@TERM_SGR0@@TERM_SETAF3@...@TERM_SGR0@\r"
-INSTALL_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully installed @TERM_BOLD@$$i@TERM_SGR0@@TERM_SETAF2@.@TERM_SGR0@\n"
-INSTALL_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to install @TERM_BOLD@$$i@TERM_SGR0@@TERM_SETAF1@!@TERM_SGR0@\n"; exit $$err
-DELETE_OK = printf "@TERM_EL@@TERM_SETAF4@Deleted @TERM_BOLD@$$i@TERM_SGR0@@TERM_SETAF4@.@TERM_SGR0@\n"
-DELETE_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to delete @TERM_BOLD@$$i@TERM_SGR0@@TERM_SETAF1@!@TERM_SGR0@\n"; exit $$err
+ifndef V
+
+DIR_ENTER = cd $$i || exit $$?
+DIR_LEAVE = cd .. || exit $$?
+DEPEND_STATUS = true
+DEPEND_OK = true
+DEPEND_FAILED = exit $$?
+COMPILE_STATUS = printf "CompileExe: $@\n"
+COMPILE_OK = true
+COMPILE_FAILED = exit $$?
+COMPILE_LIB_STATUS = printf "CompileLib: $@\n"
+COMPILE_LIB_OK = true
+COMPILE_LIB_FAILED = exit $$?
+COMPILE_PLUGIN_STATUS = printf "CompilePlugin: $@\n"
+COMPILE_PLUGIN_OK = true
+COMPILE_PLUGIN_FAILED = exit $$?
+COMPILE_RESOURCE_STATUS = printf "CompileResource: $@\n"
+COMPILE_RESOURCE_OK = true
+COMPILE_RESOURCE_FAILED = exit $$?
+LINK_STATUS = printf "Link: $@\n"
+LINK_OK = true
+LINK_FAILED = exit $$?
+INSTALL_STATUS = printf "Install: $$i\n"
+INSTALL_OK = true
+INSTALL_FAILED = exit $$?
+DELETE_OK = printf "Delete: $$i\n"
+DELETE_FAILED = exit $$?
+
+else
+
+DIR_ENTER = cd $$i || exit $$?
+DIR_LEAVE = cd .. || exit $$?
+DEPEND_STATUS = true
+DEPEND_OK = true
+DEPEND_FAILED = exit $$?
+COMPILE_STATUS = printf "CompileExe: $$COMPILER $${COMPILER_FLAGS}\n"
+COMPILE_OK = true
+COMPILE_FAILED = exit $$?
+COMPILE_LIB_STATUS = printf "CompileLib: $$COMPILER $${COMPILER_FLAGS}\n"
+COMPILE_LIB_OK = true
+COMPILE_LIB_FAILED = exit $$?
+COMPILE_PLUGIN_STATUS = printf "CompilePlugin: $$COMPILER $${COMPILER_FLAGS}\n"
+COMPILE_PLUGIN_OK = true
+COMPILE_PLUGIN_FAILED = exit $$?
+COMPILE_RESOURCE_STATUS = printf "CompileResource: $$COMPILER $${COMPILER_FLAGS}\n"
+COMPILE_RESOURCE_OK = true
+COMPILE_RESOURCE_FAILED = exit $$?
+LINK_STATUS = printf "Link: ${LD} $@ $$LDOBJS ${LDFLAGS} ${LIBS}\n"
+LINK_OK = true
+LINK_FAILED = exit $$?
+INSTALL_STATUS = printf "Install: $$i\n"
+INSTALL_OK = true
+INSTALL_FAILED = exit $$?
+DELETE_OK = printf "Delete: $$i\n"
+DELETE_FAILED = exit $$?
+
+endif
include .deps
diff --git a/configure.ac b/configure.ac
index be4b19a..9b3bc63 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,7 +43,7 @@ fi
AC_PATH_PROG(AR, ar)
AC_PATH_PROG(RANLIB, ranlib)
-LIBMOWGLI_MODULES="core base container dns eventloop ext linebuf module object thread vio"
+LIBMOWGLI_MODULES="core base container dns eventloop ext linebuf module object platform thread vio"
AC_SUBST(LIBMOWGLI_MODULES)
LIBMOWGLI_MODULE_BUILD="$(echo && echo x)"
@@ -107,6 +107,7 @@ case "$target" in
CPPFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_CHECK_LIB(dl, dlopen, [LIBS="$LIBS -ldl"])
+ AC_CHECK_LIB(rt, clock_gettime, [LIBS="$LIBS -lrt"])
;;
esac
AC_SUBST([LIBMOWGLI_OS])
diff --git a/debian/changelog b/debian/changelog
index ef52417..7f51d4c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+libmowgli-2 (2.0.0+git20140224.89982cf4-1) UNRELEASED; urgency=medium
+
+ * New upstream release
+
+ -- Andrew Shadura <andrewsh@debian.org> Tue, 17 Jun 2014 11:55:29 +0200
+
libmowgli-2 (2.0.0-2) unstable; urgency=medium
* Add missing licenses to debian/copyright (Closes: #741436).
diff --git a/doc/BOOST b/doc/BOOST
index e9569fd..160d4f1 100644
--- a/doc/BOOST
+++ b/doc/BOOST
@@ -1,5 +1,5 @@
This is a list of alphabetical libraries provided by Boost and their
-equivilant in Mowgli:
+equivalent in libmowgli:
dynamic_bitset -> mowgli_bitvector
pool -> mowgli_memorypool
@@ -9,3 +9,4 @@ equivilant in Mowgli:
Many boost libraries that are applicable to C have not yet been
implemented. You can visit http://www.boost.org/libs/libraries.htm
for a full list of libs.
+
diff --git a/doc/design-concepts.txt b/doc/design-concepts.txt
index 5d596bd..1c8ba46 100644
--- a/doc/design-concepts.txt
+++ b/doc/design-concepts.txt
@@ -114,3 +114,8 @@ use a coroutine library, such as the work-in-progress mowgli.coroutine.
Pretty much anything you can do with threads, you can do better with something,
*anything* else.
+
+Please note the Mowgli team will generally not accept intrusive patches to
+add any additional threading support aside from fixes and locking bugs. No
+atomics, no making anything in the library use threads. Don't waste your time.
+
diff --git a/scripts/makerelease.sh b/scripts/makerelease.sh
index 58f6039..eeeb19b 100755
--- a/scripts/makerelease.sh
+++ b/scripts/makerelease.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# mkrelease.sh: Creates a release suitable for distfiles.atheme.org.
#
-# Copyright (c) 2007 atheme.org
+# Copyright (c) 2007-2012 atheme.org
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the above
diff --git a/src/examples/Makefile b/src/examples/Makefile
index 8512305..4fb1edd 100644
--- a/src/examples/Makefile
+++ b/src/examples/Makefile
@@ -1,3 +1,2 @@
-SUBDIRS = echoserver vio-udplistener async_resolver formattertest helpertest libevent-bench linetest listsort memslice-bench patriciatest patriciatest2 randomtest timertest futuretest
-
+SUBDIRS = echoserver vio-udplistener async_resolver formattertest helpertest jsontest libevent-bench linetest listsort memslice-bench patriciatest patriciatest2 randomtest timertest
include ../../buildsys.mk
diff --git a/src/examples/async_resolver/async_resolver.c b/src/examples/async_resolver/async_resolver.c
index 1a05236..8bd0b12 100644
--- a/src/examples/async_resolver/async_resolver.c
+++ b/src/examples/async_resolver/async_resolver.c
@@ -8,7 +8,8 @@ typedef struct
mowgli_dns_query_t query;
} dns_query;
-static void resolve_cb(mowgli_dns_reply_t *reply, int reason, void *vptr)
+static void
+resolve_cb(mowgli_dns_reply_t *reply, int reason, void *vptr)
{
char buf[2048];
dns_query *dnsquery = vptr;
@@ -17,6 +18,7 @@ static void resolve_cb(mowgli_dns_reply_t *reply, int reason, void *vptr)
if (reply == NULL)
{
printf("Got null reply for %s\n", dnsquery->domain);
+
switch (reason)
{
case MOWGLI_DNS_RES_NXDOMAIN:
@@ -29,6 +31,7 @@ static void resolve_cb(mowgli_dns_reply_t *reply, int reason, void *vptr)
printf("Timed out\n");
break;
}
+
goto end;
}
@@ -37,12 +40,12 @@ static void resolve_cb(mowgli_dns_reply_t *reply, int reason, void *vptr)
if (reply->addr.addr.ss_family == AF_INET)
{
- const struct sockaddr_in *saddr = (const struct sockaddr_in *)&reply->addr.addr;
+ const struct sockaddr_in *saddr = (const struct sockaddr_in *) &reply->addr.addr;
sockptr = &saddr->sin_addr;
}
else if (reply->addr.addr.ss_family == AF_INET6)
{
- const struct sockaddr_in6 *saddr = (const struct sockaddr_in6 *)&reply->addr.addr;
+ const struct sockaddr_in6 *saddr = (const struct sockaddr_in6 *) &reply->addr.addr;
sockptr = &saddr->sin6_addr;
}
else
@@ -59,7 +62,8 @@ end:
mowgli_free(vptr);
}
-static void read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
+static void
+read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
{
mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io);
mowgli_dns_t *dns = userdata;
@@ -76,11 +80,14 @@ static void read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io,
return;
}
else if (ret == 0)
+ {
return;
+ }
buf[--ret] = '\0';
ch = strtok(buf, " ");
+
while (ch != NULL)
{
dns_query *dnsquery = mowgli_alloc(sizeof(dns_query));
@@ -99,15 +106,15 @@ static void read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io,
void *addrptr;
struct sockaddr_storage addr;
- if(strchr(++ch, ':') != NULL)
+ if (strchr(++ch, ':') != NULL)
{
- struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr;
+ struct sockaddr_in6 *saddr = (struct sockaddr_in6 *) &addr;
type = AF_INET6;
addrptr = &saddr->sin6_addr;
}
else
{
- struct sockaddr_in *saddr = (struct sockaddr_in *)&addr;
+ struct sockaddr_in *saddr = (struct sockaddr_in *) &addr;
type = AF_INET;
addrptr = &saddr->sin_addr;
}
@@ -127,18 +134,22 @@ static void read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io,
mowgli_dns_gethost_byaddr(dns, &addr, query);
}
else
+ {
mowgli_dns_gethost_byname(dns, ch, query, MOWGLI_DNS_T_A);
+ }
dnsquery->domain = mowgli_strdup(ch);
ch = strtok(NULL, " ");
}
}
-int main (void)
+int
+main(void)
{
mowgli_eventloop_t *evloop = mowgli_eventloop_create();
mowgli_dns_t *dns = mowgli_dns_create(evloop, MOWGLI_DNS_TYPE_ASYNC);
mowgli_eventloop_pollable_t *stdin_pollable = mowgli_pollable_create(evloop, STDIN_FILENO, dns);
+
mowgli_pollable_set_nonblocking(stdin_pollable, true);
mowgli_pollable_setselect(evloop, stdin_pollable, MOWGLI_EVENTLOOP_IO_READ, read_data);
diff --git a/src/examples/echoserver/echoserver.c b/src/examples/echoserver/echoserver.c
index dd1fc05..053b33b 100644
--- a/src/examples/echoserver/echoserver.c
+++ b/src/examples/echoserver/echoserver.c
@@ -26,23 +26,27 @@
mowgli_eventloop_t *base_eventloop;
mowgli_eventloop_pollable_t *listener;
-typedef struct {
+typedef struct
+{
mowgli_eventloop_io_t *io;
char buf[1024];
} client_t;
#ifdef DEBUG
-static void timer_tick(void *unused)
+static void
+timer_tick(void *unused)
{
static int ticks = 0;
printf("tick: %d\n", ++ticks);
}
+
#endif
-static int setup_listener(void)
+static int
+setup_listener(void)
{
- struct sockaddr_in in = {};
+ struct sockaddr_in in = { };
int fd = socket(AF_INET, SOCK_STREAM, 0);
in.sin_family = AF_INET;
@@ -59,7 +63,8 @@ static int setup_listener(void)
return fd;
}
-static void write_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
+static void
+write_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
{
mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io);
client_t *client = userdata;
@@ -72,7 +77,8 @@ static void write_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io,
mowgli_pollable_setselect(base_eventloop, client->io, MOWGLI_EVENTLOOP_IO_WRITE, NULL);
}
-static void read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
+static void
+read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
{
mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io);
int ret;
@@ -90,13 +96,15 @@ static void read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io,
mowgli_pollable_setselect(base_eventloop, client->io, MOWGLI_EVENTLOOP_IO_WRITE, write_data);
}
-static void client_error(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
+static void
+client_error(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
{
mowgli_free(userdata);
mowgli_pollable_destroy(eventloop, io);
}
-static void accept_client(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
+static void
+accept_client(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
{
mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io);
client_t *client;
@@ -115,7 +123,8 @@ static void accept_client(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *
mowgli_pollable_setselect(base_eventloop, client->io, MOWGLI_EVENTLOOP_IO_ERROR, client_error);
}
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
int fd;
diff --git a/src/examples/formattertest/formattertest.c b/src/examples/formattertest/formattertest.c
index 9ec014c..f56b671 100644
--- a/src/examples/formattertest/formattertest.c
+++ b/src/examples/formattertest/formattertest.c
@@ -33,7 +33,8 @@
#include <mowgli.h>
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
char buf[65535];
diff --git a/src/examples/futuretest/futuretest.c b/src/examples/futuretest/futuretest.c
deleted file mode 100644
index e426733..0000000
--- a/src/examples/futuretest/futuretest.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * libmowgli: A collection of useful routines for programming.
- * futuretest: Combustable lemons
- *
- * Copyright (c) 2012 Patrick McFarland <pmcfarland@adterrasperaspera.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-
-#include <mowgli.h>
-
-int main(int argc, char *argv[]) {
- char *text = "hello world";
-
- printf("create future: ");
- mowgli_future_t *future = mowgli_future_create();
- if(future != NULL)
- printf("correctly created future\n");
- else
- printf("error: abandon all hope\n");
-
- printf("get state manually of waiting future: ");
- if(mowgli_future_state(future) == MOWGLI_FUTURE_STATE_WAITING)
- printf("correctly waiting\n");
- else
- printf("error: %i\n", mowgli_future_state(future));
-
- printf("finish future: ");
- if(mowgli_future_finish(future, text) == MOWGLI_FUTURE_STATE_FINISHED)
- printf("correctly finished\n");
- else
- printf("error: %i\n", mowgli_future_state(future));
-
- printf("get result of finished future: ");
- if(mowgli_future_result(future) == text)
- printf("correct: %s\n", text);
- else
- printf("error: %s\n", (char *)mowgli_future_result(future));
-
- printf("get state of finished future: ");
- if(mowgli_future_state(future) == MOWGLI_FUTURE_STATE_FINISHED)
- printf("correctly finished\n");
- else
- printf("error: %i\n", mowgli_future_state(future));
-
- printf("reinit then cancel: ");
- if(mowgli_future_init(future) == 0) {
- if(mowgli_future_cancel(future) == MOWGLI_FUTURE_STATE_CANCELED)
- printf("correctly canceled\n");
- else
- printf("error: failed to cancel: %i\n", mowgli_future_state(future));
-
- printf("try to finish on canceled future: ");
- if(mowgli_future_finish(future, text) == MOWGLI_FUTURE_STATE_CANCELED)
- printf("correctly caught cancel\n");
- else
- printf("error: failed to cancel: %s\n", text);
- } else {
- printf("error: failed to reinit\n");
- }
-
- printf("reinit then finish twice: ");
- if(mowgli_future_init(future) == 0) {
- mowgli_future_finish(future, text);
-
- if(mowgli_future_finish(future, text) == MOWGLI_FUTURE_STATE_CONSISTENCY_FAILURE)
- printf("correctly raised consistency failure\n");
- else
- printf("error: finished twice: %s\n", text);
- } else {
- printf("error: failed to reinit\n");
- }
-}
diff --git a/src/examples/helpertest/helpertest.c b/src/examples/helpertest/helpertest.c
index 9106000..fde9b15 100644
--- a/src/examples/helpertest/helpertest.c
+++ b/src/examples/helpertest/helpertest.c
@@ -25,40 +25,44 @@
int helper_count = 0;
-void timer_oneshot(mowgli_eventloop_helper_proc_t *helper)
+void
+timer_oneshot(mowgli_eventloop_helper_proc_t *helper)
{
- mowgli_writef(helper->out_fd, "oneshot timer hit\n");
+ mowgli_writef(helper->fd, "oneshot timer hit\n");
}
-void timer_tick(mowgli_eventloop_helper_proc_t *helper)
+void
+timer_tick(mowgli_eventloop_helper_proc_t *helper)
{
static int ticks = 0;
- mowgli_writef(helper->out_fd, "tick: %d\n", ++ticks);
+ mowgli_writef(helper->fd, "tick: %d\n", ++ticks);
if (ticks > 10)
mowgli_eventloop_break(helper->eventloop);
}
-void helper_start(mowgli_eventloop_helper_proc_t *helper, void *userdata)
+void
+helper_start(mowgli_eventloop_helper_proc_t *helper, void *userdata)
{
mowgli_eventloop_t *eventloop = helper->eventloop;
- mowgli_writef(helper->out_fd, "hi from pid %d\n", getpid());
+ mowgli_writef(helper->fd, "hi from pid %d\n", getpid());
mowgli_timer_add(eventloop, "timer_tick", (mowgli_event_dispatch_func_t *) timer_tick, helper, 1);
mowgli_timer_add_once(eventloop, "timer_oneshot", (mowgli_event_dispatch_func_t *) timer_oneshot, helper, 5);
mowgli_eventloop_run(eventloop);
- mowgli_writef(helper->out_fd, "eventloop halted\n");
+ mowgli_writef(helper->fd, "eventloop halted\n");
mowgli_eventloop_destroy(eventloop);
}
void helper_read(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata);
-void helper_spawn(mowgli_eventloop_t *eventloop)
+void
+helper_spawn(mowgli_eventloop_t *eventloop)
{
mowgli_eventloop_helper_proc_t *helper;
@@ -71,17 +75,20 @@ void helper_spawn(mowgli_eventloop_t *eventloop)
helper_count++;
}
-void helper_read(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
+void
+helper_read(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
{
size_t r;
char buf[16384];
mowgli_eventloop_helper_proc_t *helper = mowgli_eventloop_io_helper(io);
bzero(buf, sizeof buf);
- r = read(helper->in_fd, buf, sizeof buf);
+ r = read(helper->fd, buf, sizeof buf);
if (r > 0)
- printf("helper %p [%d/%d]: %s", helper, helper->child->pid, helper->in_fd, buf);
+ {
+ printf("helper %p [%d/%d]: %s", helper, helper->child->pid, helper->fd, buf);
+ }
else if (r <= 0)
{
helper_count--;
@@ -92,7 +99,8 @@ void helper_read(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgl
helper_spawn(eventloop);
}
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
mowgli_eventloop_t *base_eventloop;
diff --git a/src/examples/futuretest/Makefile b/src/examples/jsontest/Makefile
index 3be7e23..eb5d82d 100644
--- a/src/examples/futuretest/Makefile
+++ b/src/examples/jsontest/Makefile
@@ -1,5 +1,5 @@
-PROG_NOINST = futuretest${PROG_SUFFIX}
-SRCS = futuretest.c
+PROG_NOINST = jsontest${PROG_SUFFIX}
+SRCS = jsontest.c
include ../../../buildsys.mk
diff --git a/src/examples/jsontest/jsontest.c b/src/examples/jsontest/jsontest.c
new file mode 100644
index 0000000..a63dbc5
--- /dev/null
+++ b/src/examples/jsontest/jsontest.c
@@ -0,0 +1,47 @@
+#include <mowgli.h>
+
+void
+out_string(mowgli_json_output_t *out, const char *str, size_t len)
+{
+ fwrite(str, 1, len, stdout);
+}
+
+void
+out_char(mowgli_json_output_t *out, const char c)
+{
+ fputc(c, stdout);
+}
+
+mowgli_json_output_t out =
+{
+ .append = out_string,
+ .append_char = out_char,
+};
+
+int
+main(int argc, char *argv[])
+{
+ int i;
+ mowgli_json_t *n;
+
+ if (argc < 2)
+ {
+ printf("Usage: %s file [file ...]\n", argv[0]);
+ return 1;
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ n = mowgli_json_parse_file(argv[i]);
+
+ if (n != NULL)
+ {
+ mowgli_json_serialize(n, &out, 1);
+ putchar('\n');
+ }
+
+ mowgli_json_decref(n);
+ }
+
+ return 0;
+}
diff --git a/src/examples/libevent-bench/bench.c b/src/examples/libevent-bench/bench.c
index 0e2cb08..9940b45 100644
--- a/src/examples/libevent-bench/bench.c
+++ b/src/examples/libevent-bench/bench.c
@@ -28,6 +28,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
+
/*
* Copyright 2003 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -63,19 +64,20 @@
*
*/
-#define timersub(tvp, uvp, vvp) \
- do { \
- (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
- (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
- if ((vvp)->tv_usec < 0) { \
- (vvp)->tv_sec--; \
- (vvp)->tv_usec += 1000000; \
- } \
+#define timersub(tvp, uvp, vvp) \
+ do \
+ { \
+ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
+ if ((vvp)->tv_usec < 0) \
+ { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_usec += 1000000; \
+ } \
} while (0)
#include <mowgli.h>
-
static int count, writes, fired;
static mowgli_eventloop_t *base_eventloop;
static mowgli_descriptor_t *pipes;
@@ -93,13 +95,17 @@ void
read_cb(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *arg)
{
mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io);
+
int idx = (int) (long) arg, widx = idx + 1;
u_char ch;
count += read(pollable->fd, &ch, sizeof(ch));
- if (writes) {
+
+ if (writes)
+ {
if (widx >= num_pipes)
widx -= num_pipes;
+
write(pipes[2 * widx + 1], "e", 1);
writes--;
fired++;
@@ -110,24 +116,28 @@ read_cb(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventlo
void
read_thunk(struct ev_io *w, int revents)
{
- read_cb (w->fd, revents, w->data);
+ read_cb(w->fd, revents, w->data);
}
void
-timer_cb (struct ev_timer *w, int revents)
+timer_cb(struct ev_timer *w, int revents)
{
- /* nop */
+ /* nop */
}
+
#endif
struct timeval *
run_once(void)
{
int *cp, i, space;
+
static struct timeval ta, ts, te;
gettimeofday(&ta, NULL);
- for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
+
+ for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2)
+ {
if (events[i] != NULL)
mowgli_pollable_destroy(base_eventloop, events[i]);
@@ -138,6 +148,7 @@ run_once(void)
fired = 0;
space = num_pipes / num_active;
space = space * 2;
+
for (i = 0; i < num_active; i++, fired++)
write(pipes[i * space + 1], "e", 1);
@@ -146,7 +157,9 @@ run_once(void)
int xcount = 0;
gettimeofday(&ts, NULL);
- do {
+
+ do
+ {
mowgli_eventloop_run_once(base_eventloop);
xcount++;
} while (count != fired);
@@ -158,15 +171,16 @@ run_once(void)
fprintf(stdout, "%ld\t%ld\n",
ta.tv_sec * 1000000L + ta.tv_usec,
ts.tv_sec * 1000000L + ts.tv_usec
- );
+ );
- return (&te);
+ return &te;
}
int
-main (int argc, char **argv)
+main(int argc, char **argv)
{
struct rlimit rl;
+
int i, c;
int *cp;
extern char *optarg;
@@ -174,8 +188,11 @@ main (int argc, char **argv)
num_pipes = 100;
num_active = 1;
num_writes = num_pipes;
- while ((c = getopt(argc, argv, "n:a:w:te")) != -1) {
- switch (c) {
+
+ while ((c = getopt(argc, argv, "n:a:w:te")) != -1)
+ {
+ switch (c)
+ {
case 'n':
num_pipes = atoi(optarg);
break;
@@ -186,7 +203,7 @@ main (int argc, char **argv)
num_writes = atoi(optarg);
break;
case 't':
- timers = 1;
+ timers = 1;
break;
default:
fprintf(stderr, "Illegal argument \"%c\"\n", c);
@@ -196,14 +213,17 @@ main (int argc, char **argv)
#if 1
rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50;
- if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
+
+ if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
perror("setrlimit");
- }
+
#endif
events = calloc(num_pipes * 2, sizeof(mowgli_eventloop_pollable_t *));
pipes = calloc(num_pipes * 2, sizeof(mowgli_descriptor_t));
- if (events == NULL || pipes == NULL) {
+
+ if ((events == NULL) || (pipes == NULL))
+ {
perror("malloc");
exit(1);
}
@@ -211,20 +231,24 @@ main (int argc, char **argv)
mowgli_thread_set_policy(MOWGLI_THREAD_POLICY_DISABLED);
base_eventloop = mowgli_eventloop_create();
- for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
+ for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2)
+ {
#ifdef USE_PIPES
- if (pipe(cp) == -1) {
+
+ if (pipe(cp) == -1)
+ {
#else
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) {
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1)
+ {
#endif
perror("pipe");
exit(1);
}
}
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < 2; i++)
run_once();
- }
exit(0);
}
diff --git a/src/examples/linetest/linetest.c b/src/examples/linetest/linetest.c
index 98b8064..3175b84 100644
--- a/src/examples/linetest/linetest.c
+++ b/src/examples/linetest/linetest.c
@@ -27,22 +27,26 @@
mowgli_eventloop_t *base_eventloop;
char buf[512];
-typedef struct {
+typedef struct
+{
mowgli_linebuf_t *linebuf;
} client_t;
void eat_line(mowgli_linebuf_t *linebuf, char *line, size_t len, void *userdata);
-void write_line(mowgli_linebuf_t *linebuf, char *buf, size_t len)
+void
+write_line(mowgli_linebuf_t *linebuf, char *buf, size_t len)
{
- printf("> %s\n", buf);
+ printf("-> %s\n", buf);
mowgli_linebuf_write(linebuf, buf, len);
}
-client_t * create_client(const char *server, const char *port, const char *nick, const char *user, const char *realname)
+client_t *
+create_client(const char *server, const char *port, const char *nick, const char *user, const char *realname)
{
client_t *client;
struct addrinfo hints, *res;
+
bool use_ssl = false;
mowgli_vio_sockaddr_t addr;
int ret;
@@ -77,12 +81,11 @@ client_t * create_client(const char *server, const char *port, const char *nick,
/* Wrap the VIO object */
if (use_ssl)
- {
- if (mowgli_vio_openssl_setssl(linebuf->vio, NULL) != 0)
+ if (mowgli_vio_openssl_setssl(linebuf->vio, NULL, NULL) != 0)
return NULL;
- }
/* We have to have a socket before starting the linebuf */
+
if (mowgli_vio_socket(linebuf->vio, res->ai_family, res->ai_socktype, res->ai_protocol) != 0)
return NULL;
@@ -103,7 +106,8 @@ client_t * create_client(const char *server, const char *port, const char *nick,
return client;
}
-void eat_line(mowgli_linebuf_t *linebuf, char *line, size_t len, void *userdata)
+void
+eat_line(mowgli_linebuf_t *linebuf, char *line, size_t len, void *userdata)
{
char str[512];
@@ -114,12 +118,13 @@ void eat_line(mowgli_linebuf_t *linebuf, char *line, size_t len, void *userdata)
strncpy(str, line, sizeof(str));
str[len + 1] = '\0';
- printf("-> %s\n", str);
+ printf("<- %s\n", str);
/* Since this is just a basic example, we don't have a real dispatcher :p */
if (strstr(str, "PING"))
{
char *pos = strpbrk(str, ":");
+
if (pos)
{
char buf[512];
@@ -131,7 +136,8 @@ void eat_line(mowgli_linebuf_t *linebuf, char *line, size_t len, void *userdata)
return;
}
-int main(int argc, const char *argv[])
+int
+main(int argc, const char *argv[])
{
client_t *client;
const char *serv, *port;
@@ -150,6 +156,7 @@ int main(int argc, const char *argv[])
port = argv[2];
client = create_client(serv, port, "Mowglibot", "Mowglibot", "The libmowgli example bot that does nothing useful");
+
if (client == NULL)
return EXIT_FAILURE;
diff --git a/src/examples/listsort/listsort.c b/src/examples/listsort/listsort.c
index 7aa44c2..17768b5 100644
--- a/src/examples/listsort/listsort.c
+++ b/src/examples/listsort/listsort.c
@@ -34,18 +34,21 @@
#include <mowgli.h>
#ifdef _WIN32
-#define strcasecmp _stricmp
+# define strcasecmp _stricmp
#endif
-int str_comparator(mowgli_node_t *n, mowgli_node_t *n2, void *opaque)
+int
+str_comparator(mowgli_node_t *n, mowgli_node_t *n2, void *opaque)
{
- int ret;
+ int ret;
+
ret = strcasecmp(n->data, n2->data);
return ret;
}
-void test_strings(void)
+void
+test_strings(void)
{
mowgli_list_t l = { NULL, NULL, 0 };
mowgli_node_t *n, *tn;
@@ -73,12 +76,13 @@ void test_strings(void)
MOWGLI_LIST_FOREACH_SAFE(n, tn, l.head)
{
- printf(" %s\n", (char*) n->data);
+ printf(" %s\n", (char *) n->data);
mowgli_node_delete(n, &l);
}
}
-int int_comparator(mowgli_node_t *n, mowgli_node_t *n2, void *opaque)
+int
+int_comparator(mowgli_node_t *n, mowgli_node_t *n2, void *opaque)
{
long a = (long) n->data;
long b = (long) n2->data;
@@ -86,11 +90,12 @@ int int_comparator(mowgli_node_t *n, mowgli_node_t *n2, void *opaque)
return a - b;
}
-void test_integers(void)
+void
+test_integers(void)
{
mowgli_list_t l = { NULL, NULL, 0 };
mowgli_node_t *n, *tn;
-
+
mowgli_node_add((void *) 3, mowgli_node_create(), &l);
mowgli_node_add((void *) 2, mowgli_node_create(), &l);
mowgli_node_add((void *) 4, mowgli_node_create(), &l);
@@ -107,7 +112,8 @@ void test_integers(void)
}
}
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
test_strings();
test_integers();
diff --git a/src/examples/memslice-bench/memslice-bench.c b/src/examples/memslice-bench/memslice-bench.c
index 3fb05d5..3ed95fc 100644
--- a/src/examples/memslice-bench/memslice-bench.c
+++ b/src/examples/memslice-bench/memslice-bench.c
@@ -18,15 +18,17 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#define timersub(tvp, uvp, vvp) \
- do { \
- (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
- (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
- if ((vvp)->tv_usec < 0) { \
- (vvp)->tv_sec--; \
- (vvp)->tv_usec += 1000000; \
- } \
- } while (0)
+#define timersub(tvp, uvp, vvp) \
+ do \
+ { \
+ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
+ if ((vvp)->tv_usec < 0) \
+ { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_usec += 1000000; \
+ } \
+ } while (0)
#include <mowgli.h>
@@ -37,10 +39,11 @@ int
main(int argc, char *argv[])
{
size_t i;
+
size_t objects;
size_t *obj_sizes;
void **ptrs;
- struct timeval ts, te;
+ struct timeval ts, te;
mowgli_thread_set_policy(MOWGLI_THREAD_POLICY_DISABLED);
@@ -66,52 +69,57 @@ main(int argc, char *argv[])
printf("Going to allocate %zu objects of random sizes < 256\n", objects);
printf("Assigning sizes...\n");
- for (i = 0; i < objects; i++) {
+
+ for (i = 0; i < objects; i++)
obj_sizes[i] = rand() % 256;
- }
+
printf("Done! Lets benchmark.\n");
/* allocate using sysmalloc */
gettimeofday(&ts, NULL);
- for (i = 0; i < objects; i++) {
+
+ for (i = 0; i < objects; i++)
ptrs[i] = mowgli_alloc_using_policy(sysmalloc, obj_sizes[i]);
- }
+
gettimeofday(&te, NULL);
timersub(&te, &ts, &ts);
printf("sysmalloc alloc time: %ld usec\n",
- ts.tv_sec * 1000000L + ts.tv_usec);
+ ts.tv_sec * 1000000L + ts.tv_usec);
gettimeofday(&ts, NULL);
- for (i = 0; i < objects; i++) {
+
+ for (i = 0; i < objects; i++)
mowgli_free(ptrs[i]);
- }
+
gettimeofday(&te, NULL);
timersub(&te, &ts, &ts);
printf("sysmalloc free time: %ld usec\n",
- ts.tv_sec * 1000000L + ts.tv_usec);
+ ts.tv_sec * 1000000L + ts.tv_usec);
/* allocate using memslice */
gettimeofday(&ts, NULL);
- for (i = 0; i < objects; i++) {
+
+ for (i = 0; i < objects; i++)
ptrs[i] = mowgli_alloc_using_policy(memslice, obj_sizes[i]);
- }
+
gettimeofday(&te, NULL);
timersub(&te, &ts, &ts);
printf("memslice alloc time: %ld usec\n",
- ts.tv_sec * 1000000L + ts.tv_usec);
+ ts.tv_sec * 1000000L + ts.tv_usec);
gettimeofday(&ts, NULL);
- for (i = 0; i < objects; i++) {
+
+ for (i = 0; i < objects; i++)
mowgli_free(ptrs[i]);
- }
+
gettimeofday(&te, NULL);
timersub(&te, &ts, &ts);
printf("memslice free time: %ld usec\n",
- ts.tv_sec * 1000000L + ts.tv_usec);
+ ts.tv_sec * 1000000L + ts.tv_usec);
return EXIT_SUCCESS;
}
diff --git a/src/examples/patriciatest/patriciatest.c b/src/examples/patriciatest/patriciatest.c
index 98c5f65..4dbb212 100644
--- a/src/examples/patriciatest/patriciatest.c
+++ b/src/examples/patriciatest/patriciatest.c
@@ -35,18 +35,21 @@
int errors = 0;
-void str_canon(char *key)
+void
+str_canon(char *key)
{
return;
}
-void statscb(const char *line, void *data)
+void
+statscb(const char *line, void *data)
{
printf("%s\n", line);
}
/* assumes data is key */
-static void check_all_retrievable(mowgli_patricia_t *dtree)
+static void
+check_all_retrievable(mowgli_patricia_t *dtree)
{
mowgli_patricia_iteration_state_t state;
void *elem, *elem2;
@@ -58,37 +61,45 @@ static void check_all_retrievable(mowgli_patricia_t *dtree)
n2 = mowgli_patricia_size(dtree);
MOWGLI_PATRICIA_FOREACH(elem, &state, dtree)
{
- elem2 = mowgli_patricia_retrieve(dtree, (const char *)elem);
+ elem2 = mowgli_patricia_retrieve(dtree, (const char *) elem);
+
if (elem2 == NULL)
{
errors++;
printf("failed to find element %s\n",
- (const char *)elem);
+ (const char *) elem);
}
else if (strcmp(elem2, elem))
{
printf("element %s != %s\n",
- (const char *)elem,
- (const char *)elem2);
+ (const char *) elem,
+ (const char *) elem2);
errors++;
}
else
+ {
printf(".");
+ }
+
fflush(stdout);
n1++;
+
if (n1 > n2 * 2)
break;
}
+
if (n1 != n2)
{
errors++;
printf("number of iterated elements %u != size %u\n", n1, n2);
}
+
printf("\n");
fflush(stdout);
}
-void test_patricia(void)
+void
+test_patricia(void)
{
mowgli_patricia_t *dtree;
mowgli_patricia_iteration_state_t state;
@@ -119,7 +130,7 @@ void test_patricia(void)
MOWGLI_PATRICIA_FOREACH(elem, &state, dtree)
{
- printf("element -> %s\n", (const char *)elem);
+ printf("element -> %s\n", (const char *) elem);
}
printf("End of elements\n");
mowgli_patricia_stats(dtree, statscb, NULL);
@@ -147,7 +158,8 @@ void test_patricia(void)
mowgli_patricia_destroy(dtree, NULL, NULL);
}
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
test_patricia();
diff --git a/src/examples/patriciatest2/patriciatest2.c b/src/examples/patriciatest2/patriciatest2.c
index d73b1ee..800c59e 100644
--- a/src/examples/patriciatest2/patriciatest2.c
+++ b/src/examples/patriciatest2/patriciatest2.c
@@ -37,17 +37,19 @@
int errors = 0;
-void str_canon(char *key)
+void
+str_canon(char *key)
{
return;
}
-void statscb(const char *line, void *data)
-{
-}
+void
+statscb(const char *line, void *data)
+{ }
/* assumes data is key */
-static void check_all_retrievable(mowgli_patricia_t *dtree)
+static void
+check_all_retrievable(mowgli_patricia_t *dtree)
{
mowgli_patricia_iteration_state_t state;
void *elem, *elem2;
@@ -57,24 +59,28 @@ static void check_all_retrievable(mowgli_patricia_t *dtree)
n2 = mowgli_patricia_size(dtree);
MOWGLI_PATRICIA_FOREACH(elem, &state, dtree)
{
- elem2 = mowgli_patricia_retrieve(dtree, (const char *)elem);
+ elem2 = mowgli_patricia_retrieve(dtree, (const char *) elem);
+
if (elem2 == NULL)
{
errors++;
printf("failed to find element %s\n",
- (const char *)elem);
+ (const char *) elem);
}
else if (strcmp(elem2, elem))
{
printf("element %s != %s\n",
- (const char *)elem,
- (const char *)elem2);
+ (const char *) elem,
+ (const char *) elem2);
errors++;
}
+
n1++;
+
if (n1 > n2 * 2)
break;
}
+
if (n1 != n2)
{
errors++;
@@ -82,17 +88,20 @@ static void check_all_retrievable(mowgli_patricia_t *dtree)
}
}
-void test_patricia(void)
+void
+test_patricia(void)
{
mowgli_patricia_t *dtree;
int i, j;
char buf[100], *strings[TESTSIZE];
srandom(12346);
+
for (i = 0; i < TESTSIZE; i++)
{
for (j = 0; j < 40; j++)
buf[j] = 'a' + random() % 26;
+
buf[20 + random() % 20] = '\0';
strings[i] = strdup(buf);
}
@@ -110,12 +119,14 @@ void test_patricia(void)
for (i = 0; i < TESTSIZE / 2; i++)
{
mowgli_patricia_delete(dtree, strings[i]);
+
if (mowgli_patricia_retrieve(dtree, strings[i]))
{
printf("still retrievable after delete: %s\n",
- strings[i]);
+ strings[i]);
errors++;
}
+
check_all_retrievable(dtree);
}
@@ -128,12 +139,14 @@ void test_patricia(void)
for (i = 0; i < TESTSIZE; i++)
{
mowgli_patricia_delete(dtree, strings[i]);
+
if (mowgli_patricia_retrieve(dtree, strings[i]))
{
printf("still retrievable after delete: %s\n",
- strings[i]);
+ strings[i]);
errors++;
}
+
check_all_retrievable(dtree);
}
@@ -143,7 +156,8 @@ void test_patricia(void)
free(strings[i]);
}
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
test_patricia();
diff --git a/src/examples/randomtest/randomtest.c b/src/examples/randomtest/randomtest.c
index 2c4b2d7..eb7ef05 100644
--- a/src/examples/randomtest/randomtest.c
+++ b/src/examples/randomtest/randomtest.c
@@ -33,16 +33,20 @@
*/
#include <mowgli.h>
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
mowgli_random_t *r = mowgli_random_create();
int i;
printf("1000 iterations:\n");
+
for (i = 0; i < 1000; i++)
{
printf("%10u ", mowgli_random_int(r));
- if (i % 5 == 4) printf("\n");
+
+ if (i % 5 == 4)
+ printf("\n");
}
mowgli_object_unref(r);
diff --git a/src/examples/timertest/timertest.c b/src/examples/timertest/timertest.c
index 242b8a9..f99410b 100644
--- a/src/examples/timertest/timertest.c
+++ b/src/examples/timertest/timertest.c
@@ -25,12 +25,14 @@
mowgli_eventloop_t *eventloop;
-void timer_oneshot(void *unused)
+void
+timer_oneshot(void *unused)
{
printf("oneshot timer hit\n");
}
-void timer_tick(void *unused)
+void
+timer_tick(void *unused)
{
static int ticks = 0;
@@ -40,7 +42,8 @@ void timer_tick(void *unused)
mowgli_eventloop_break(eventloop);
}
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
eventloop = mowgli_eventloop_create();
diff --git a/src/examples/vio-udplistener/vio-udplistener.c b/src/examples/vio-udplistener/vio-udplistener.c
index 9de4e69..1e1dda1 100644
--- a/src/examples/vio-udplistener/vio-udplistener.c
+++ b/src/examples/vio-udplistener/vio-udplistener.c
@@ -7,18 +7,19 @@
#define BUFSIZE 2048
-#define PROTO AF_INET6
-#define LISTEN "::ffff:127.0.0.1" /* 6to4 mapping */
-#define PORT 31337
+#define PROTO AF_INET6
+#define LISTEN "::ffff:127.0.0.1" /* 6to4 mapping */
+#define PORT 31337
#define ECHOBACK "Echo: "
-int main (void)
+int
+main(void)
{
mowgli_vio_t *vio = mowgli_vio_create(NULL);
mowgli_vio_sockaddr_t addr;
-
- mowgli_vio_sockaddr_create(&addr, PROTO, LISTEN, 31337);
+
+ mowgli_vio_sockaddr_create(&addr, PROTO, LISTEN, PORT);
if (mowgli_vio_socket(vio, PROTO, SOCK_DGRAM, 0))
return EXIT_FAILURE;
@@ -41,5 +42,5 @@ int main (void)
mowgli_vio_sendto(vio, buf, strlen(buf), &addr);
}
- return EXIT_SUCCESS; /* Not reached */
+ return EXIT_SUCCESS; /* Not reached */
}
diff --git a/src/libmowgli/Makefile b/src/libmowgli/Makefile
index 4cf3942..b81552a 100644
--- a/src/libmowgli/Makefile
+++ b/src/libmowgli/Makefile
@@ -6,7 +6,7 @@ LIB_MINOR = 0
SHARED_LIB = ${LIBMOWGLI_SHARED_LIB}
STATIC_LIB = ${LIBMOWGLI_STATIC_LIB}
-SUBDIRS = ${LIBMOWGLI_MODULES} platform
+SUBDIRS = ${LIBMOWGLI_MODULES}
INCLUDES = mowgli.h
@@ -15,5 +15,7 @@ OBJS_EXTRA = ${LIBMOWGLI_STATIC_MODULES}
include ../../buildsys.mk
+$(OBJS_EXTRA) $(LIB_OBJS_EXTRA): subdirs
+
LIBS += ${PTHREAD_LIBS}
CPPFLAGS += -I. -I../.. -DMOWGLI_CORE
diff --git a/src/libmowgli/base/argstack.c b/src/libmowgli/base/argstack.c
index ea67da2..560c83e 100644
--- a/src/libmowgli/base/argstack.c
+++ b/src/libmowgli/base/argstack.c
@@ -30,7 +30,8 @@ static mowgli_object_class_t klass;
*
* \param vptr pointer to mowgli_argstack_t to destroy.
*/
-static void mowgli_argstack_destroy(void *vptr)
+static void
+mowgli_argstack_destroy(void *vptr)
{
mowgli_argstack_t *self = (mowgli_argstack_t *) vptr;
mowgli_node_t *n, *tn;
@@ -48,17 +49,18 @@ static void mowgli_argstack_destroy(void *vptr)
/*
* \brief Initialization code for the mowgli.argstack library.
- *
+ *
* Side Effects:
* - the mowgli_argstack_t object class is registered.
*/
-void mowgli_argstack_bootstrap(void)
+void
+mowgli_argstack_bootstrap(void)
{
mowgli_object_class_init(&klass, "mowgli_argstack_t", mowgli_argstack_destroy, FALSE);
}
/*
- * \brief Creates an argument stack from a va_list and an appropriate
+ * \brief Creates an argument stack from a va_list and an appropriate
* description schema.
*
* \param descstr a description string which describes the argument stack, where:
@@ -70,20 +72,20 @@ void mowgli_argstack_bootstrap(void)
*
* \return a mowgli_argstack_t (mowgli.argstack) object.
*/
-mowgli_argstack_t *mowgli_argstack_create_from_va_list(const char *descstr, va_list va)
+mowgli_argstack_t *
+mowgli_argstack_create_from_va_list(const char *descstr, va_list va)
{
+ return_null_if_fail(descstr != NULL);
+
const char *cp = descstr;
mowgli_argstack_t *out = mowgli_alloc(sizeof(mowgli_argstack_t));
mowgli_object_init(mowgli_object(out), descstr, &klass, NULL);
- if (descstr == NULL)
- mowgli_throw_exception_val(mowgli.argstack.invalid_description, NULL);
-
while (*cp)
{
mowgli_argstack_element_t *e = mowgli_alloc(sizeof(mowgli_argstack_element_t));
- switch(*cp)
+ switch (*cp)
{
case 's':
e->data.string = va_arg(va, char *);
@@ -104,7 +106,8 @@ mowgli_argstack_t *mowgli_argstack_create_from_va_list(const char *descstr, va_l
default:
va_end(va);
mowgli_object_unref(out);
- mowgli_throw_exception_val(mowgli.argstack.invalid_description, NULL);
+ mowgli_log_warning("invalid description");
+ return NULL;
break;
}
@@ -127,14 +130,14 @@ mowgli_argstack_t *mowgli_argstack_create_from_va_list(const char *descstr, va_l
*
* \return a mowgli_argstack_t (mowgli.argstack) object.
*/
-mowgli_argstack_t *mowgli_argstack_create(const char *descstr, ...)
+mowgli_argstack_t *
+mowgli_argstack_create(const char *descstr, ...)
{
+ return_null_if_fail(descstr != NULL);
+
va_list va;
mowgli_argstack_t *out;
- if (descstr == NULL)
- mowgli_throw_exception_val(mowgli.argstack.invalid_description, NULL);
-
va_start(va, descstr);
out = mowgli_argstack_create_from_va_list(descstr, va);
va_end(va);
@@ -152,14 +155,14 @@ mowgli_argstack_t *mowgli_argstack_create(const char *descstr, ...)
* Side Effects:
* - the argument is removed from the argstack.
*/
-const char *mowgli_argstack_pop_string(mowgli_argstack_t *self)
+const char *
+mowgli_argstack_pop_string(mowgli_argstack_t *self)
{
+ return_null_if_fail(self != NULL);
+
mowgli_node_t *n;
mowgli_argstack_element_t *e;
- if (self == NULL)
- mowgli_throw_exception_val(mowgli.null_pointer_exception, NULL);
-
n = self->stack.head;
mowgli_node_delete(n, &self->stack);
e = n->data;
@@ -178,14 +181,14 @@ const char *mowgli_argstack_pop_string(mowgli_argstack_t *self)
* Side Effects:
* - the argument is removed from the argstack.
*/
-int mowgli_argstack_pop_numeric(mowgli_argstack_t *self)
+int
+mowgli_argstack_pop_numeric(mowgli_argstack_t *self)
{
+ return_val_if_fail(self != NULL, 0);
+
mowgli_node_t *n;
mowgli_argstack_element_t *e;
- if (self == NULL)
- mowgli_throw_exception_val(mowgli.null_pointer_exception, 0);
-
n = self->stack.head;
mowgli_node_delete(n, &self->stack);
e = n->data;
@@ -204,14 +207,14 @@ int mowgli_argstack_pop_numeric(mowgli_argstack_t *self)
* Side Effects:
* - the argument is removed from the argstack.
*/
-mowgli_boolean_t mowgli_argstack_pop_boolean(mowgli_argstack_t *self)
+mowgli_boolean_t
+mowgli_argstack_pop_boolean(mowgli_argstack_t *self)
{
+ return_val_if_fail(self != NULL, false);
+
mowgli_node_t *n;
mowgli_argstack_element_t *e;
- if (self == NULL)
- mowgli_throw_exception_val(mowgli.null_pointer_exception, FALSE);
-
n = self->stack.head;
mowgli_node_delete(n, &self->stack);
e = n->data;
@@ -230,14 +233,14 @@ mowgli_boolean_t mowgli_argstack_pop_boolean(mowgli_argstack_t *self)
* Side Effects:
* - the argument is removed from the argstack.
*/
-void *mowgli_argstack_pop_pointer(mowgli_argstack_t *self)
+void *
+mowgli_argstack_pop_pointer(mowgli_argstack_t *self)
{
+ return_null_if_fail(self != NULL);
+
mowgli_node_t *n;
mowgli_argstack_element_t *e;
- if (self == NULL)
- mowgli_throw_exception_val(mowgli.null_pointer_exception, NULL);
-
n = self->stack.head;
mowgli_node_delete(n, &self->stack);
e = n->data;
diff --git a/src/libmowgli/base/argstack.h b/src/libmowgli/base/argstack.h
index adf68c2..b3b86f9 100644
--- a/src/libmowgli/base/argstack.h
+++ b/src/libmowgli/base/argstack.h
@@ -24,29 +24,33 @@
#ifndef __MOWGLI_ARGSTACK_H__
#define __MOWGLI_ARGSTACK_H__
-typedef enum {
+typedef enum
+{
MOWGLI_ARG_NUMERIC,
MOWGLI_ARG_POINTER,
MOWGLI_ARG_STRING,
MOWGLI_ARG_BOOLEAN
} mowgli_argstack_element_type_t;
-typedef struct {
- union {
+typedef struct
+{
+ union
+ {
int numeric;
void *pointer;
char *string;
mowgli_boolean_t boolean;
} data;
+
mowgli_argstack_element_type_t type;
} mowgli_argstack_element_t;
-typedef struct {
+typedef struct
+{
mowgli_object_t parent;
mowgli_list_t stack;
} mowgli_argstack_t;
-extern void mowgli_argstack_bootstrap(void);
extern mowgli_argstack_t *mowgli_argstack_create(const char *descstr, ...);
extern mowgli_argstack_t *mowgli_argstack_create_from_va_list(const char *descstr, va_list va);
extern const char *mowgli_argstack_pop_string(mowgli_argstack_t *);
diff --git a/src/libmowgli/base/bitvector.c b/src/libmowgli/base/bitvector.c
index b70df55..45fca31 100644
--- a/src/libmowgli/base/bitvector.c
+++ b/src/libmowgli/base/bitvector.c
@@ -39,7 +39,8 @@ static mowgli_object_class_t klass;
* Side Effects:
* - the mowgli_bitvector_t object class is registered.
*/
-void mowgli_bitvector_bootstrap(void)
+void
+mowgli_bitvector_bootstrap(void)
{
mowgli_object_class_init(&klass, "mowgli_bitvector_t", mowgli_free, FALSE);
}
@@ -58,14 +59,16 @@ void mowgli_bitvector_bootstrap(void)
* Side Effects:
* - none
*/
-mowgli_bitvector_t *mowgli_bitvector_create(int bits)
+mowgli_bitvector_t *
+mowgli_bitvector_create(int bits)
{
mowgli_bitvector_t *bv = (mowgli_bitvector_t *) mowgli_alloc(sizeof(mowgli_bitvector_t));
+
mowgli_object_init(mowgli_object(bv), "mowgli_bitvector_t", &klass, NULL);
- bv->bits = bits;
+ bv->bits = bits;
bv->divisor = sizeof(int);
- bv->vector = (unsigned int *) mowgli_alloc_array(bv->divisor, bv->bits / bv->divisor);
+ bv->vector = (unsigned int *) mowgli_alloc_array(bv->divisor, bv->bits / bv->divisor);
return bv;
}
@@ -86,19 +89,20 @@ mowgli_bitvector_t *mowgli_bitvector_create(int bits)
* Side Effects:
* - a bit is either set ON or OFF in the bitvector.
*/
-void mowgli_bitvector_set(mowgli_bitvector_t *bv, int slot, mowgli_boolean_t val)
+void
+mowgli_bitvector_set(mowgli_bitvector_t *bv, int slot, mowgli_boolean_t val)
{
int value = 1 << slot;
- switch(val)
+ switch (val)
{
- case FALSE:
- bv->vector[bv->bits / bv->divisor] &= ~value;
- break;
- default:
- case TRUE:
- bv->vector[bv->bits / bv->divisor] |= value;
- break;
+ case FALSE:
+ bv->vector[bv->bits / bv->divisor] &= ~value;
+ break;
+ default:
+ case TRUE:
+ bv->vector[bv->bits / bv->divisor] |= value;
+ break;
}
}
@@ -118,7 +122,8 @@ void mowgli_bitvector_set(mowgli_bitvector_t *bv, int slot, mowgli_boolean_t val
* Side Effects:
* - none
*/
-mowgli_boolean_t mowgli_bitvector_get(mowgli_bitvector_t *bv, int slot)
+mowgli_boolean_t
+mowgli_bitvector_get(mowgli_bitvector_t *bv, int slot)
{
int mask = 1 << slot;
@@ -139,7 +144,8 @@ mowgli_boolean_t mowgli_bitvector_get(mowgli_bitvector_t *bv, int slot)
* Side Effects:
* - none
*/
-mowgli_bitvector_t *mowgli_bitvector_combine(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
+mowgli_bitvector_t *
+mowgli_bitvector_combine(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
{
int bits, iter, bs;
mowgli_bitvector_t *out;
@@ -179,7 +185,8 @@ mowgli_bitvector_t *mowgli_bitvector_combine(mowgli_bitvector_t *bv1, mowgli_bit
* Side Effects:
* - none
*/
-mowgli_bitvector_t *mowgli_bitvector_xor(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
+mowgli_bitvector_t *
+mowgli_bitvector_xor(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
{
int bits, iter, bs;
mowgli_bitvector_t *out;
@@ -220,19 +227,18 @@ mowgli_bitvector_t *mowgli_bitvector_xor(mowgli_bitvector_t *bv1, mowgli_bitvect
* Side Effects:
* - none
*/
-mowgli_boolean_t mowgli_bitvector_compare(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
+mowgli_boolean_t
+mowgli_bitvector_compare(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
{
- int iter, bs;
+ int iter, bs;
mowgli_boolean_t ret = TRUE;
/* cache the size of the bitvector in memory. */
bs = bv1->bits / bv1->divisor;
for (iter = 0; iter < bs; iter++)
- {
if (!(bv1->vector[iter] & bv2->vector[iter]))
ret = FALSE;
- }
return ret;
}
diff --git a/src/libmowgli/base/bitvector.h b/src/libmowgli/base/bitvector.h
index 592ba59..f96709d 100644
--- a/src/libmowgli/base/bitvector.h
+++ b/src/libmowgli/base/bitvector.h
@@ -24,13 +24,13 @@
#ifndef __MOWGLI_BITVECTOR_H__
#define __MOWGLI_BITVECTOR_H__
-typedef struct {
+typedef struct
+{
unsigned int bits;
unsigned int divisor;
unsigned int *vector;
} mowgli_bitvector_t;
-extern void mowgli_bitvector_bootstrap(void);
extern mowgli_bitvector_t *mowgli_bitvector_create(int bits);
extern void mowgli_bitvector_set(mowgli_bitvector_t *bv, int slot, mowgli_boolean_t val);
extern mowgli_boolean_t mowgli_bitvector_get(mowgli_bitvector_t *bv, int slot);
diff --git a/src/libmowgli/base/formatter.c b/src/libmowgli/base/formatter.c
index 21d9e46..db908e7 100644
--- a/src/libmowgli/base/formatter.c
+++ b/src/libmowgli/base/formatter.c
@@ -23,7 +23,8 @@
#include "mowgli.h"
-void mowgli_formatter_format_from_argstack(char *buf, size_t bufstr, const char *fmtstr, const char *descstr, mowgli_argstack_t *stack)
+void
+mowgli_formatter_format_from_argstack(char *buf, size_t bufstr, const char *fmtstr, const char *descstr, mowgli_argstack_t *stack)
{
size_t pos = 0;
char *i = buf;
@@ -42,14 +43,17 @@ void mowgli_formatter_format_from_argstack(char *buf, size_t bufstr, const char
pos = strlen(buf);
- switch(*fiter)
+ switch (*fiter)
{
case '%':
fiter++;
arg = atoi(fiter);
e = mowgli_node_nth_data(&stack->stack, arg - 1);
- while (isdigit(*fiter)) fiter++;
+ while (isdigit(*fiter))
+ {
+ fiter++;
+ }
if (e == NULL)
{
@@ -58,7 +62,7 @@ void mowgli_formatter_format_from_argstack(char *buf, size_t bufstr, const char
continue;
}
- switch(e->type)
+ switch (e->type)
{
case MOWGLI_ARG_STRING:
arg = snprintf(i, bufstr - (i - buf), "%s", e->data.string);
@@ -77,7 +81,7 @@ void mowgli_formatter_format_from_argstack(char *buf, size_t bufstr, const char
i += arg;
break;
default:
- mowgli_throw_exception(mowgli.formatter.unhandled_type_exception);
+ mowgli_log("unhandled type");
break;
}
@@ -92,7 +96,8 @@ void mowgli_formatter_format_from_argstack(char *buf, size_t bufstr, const char
}
}
-void mowgli_formatter_format(char *buf, size_t bufstr, const char *fmtstr, const char *descstr, ...)
+void
+mowgli_formatter_format(char *buf, size_t bufstr, const char *fmtstr, const char *descstr, ...)
{
va_list va;
mowgli_argstack_t *stack;
@@ -104,7 +109,8 @@ void mowgli_formatter_format(char *buf, size_t bufstr, const char *fmtstr, const
mowgli_formatter_format_from_argstack(buf, bufstr, fmtstr, descstr, stack);
}
-void mowgli_formatter_print(const char *fmtstr, const char *descstr, ...)
+void
+mowgli_formatter_print(const char *fmtstr, const char *descstr, ...)
{
va_list va;
char buf[65535];
diff --git a/src/libmowgli/base/hash.c b/src/libmowgli/base/hash.c
index 7d70d8c..a2734d0 100644
--- a/src/libmowgli/base/hash.c
+++ b/src/libmowgli/base/hash.c
@@ -25,12 +25,13 @@
#define HASHINIT 0x811c9dc5
#define HASHBITS 16
-#define HASHSIZE (1 << HASHBITS) /* 2^16 = 65536 */
+#define HASHSIZE (1 << HASHBITS)/* 2^16 = 65536 */
-int mowgli_fnv_hash_string(const char *p)
+int
+mowgli_fnv_hash_string(const char *p)
{
static int htoast = 0;
- unsigned int hval = HASHINIT;
+ unsigned int hval = HASHINIT;
if (htoast == 0)
{
@@ -39,21 +40,23 @@ int mowgli_fnv_hash_string(const char *p)
mowgli_object_unref(r);
}
- if (!p)
- return (0);
- for (; *p != '\0'; ++p)
- {
- hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
- hval ^= (tolower(*p) ^ htoast);
- }
+ if (!p)
+ return 0;
- return ((hval >> HASHBITS) ^ (hval & ((1 << HASHBITS) - 1)) % HASHSIZE);
+ for (; *p != '\0'; ++p)
+ {
+ hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
+ hval ^= (tolower(*p) ^ htoast);
+ }
+
+ return (hval >> HASHBITS) ^ (hval & ((1 << HASHBITS) - 1)) % HASHSIZE;
}
-int mowgli_fnv_hash(unsigned int *p)
+int
+mowgli_fnv_hash(unsigned int *p)
{
static int htoast = 0;
- unsigned int hval = HASHINIT;
+ unsigned int hval = HASHINIT;
if (htoast == 0)
{
@@ -62,13 +65,14 @@ int mowgli_fnv_hash(unsigned int *p)
mowgli_object_unref(r);
}
- if (!p)
- return (0);
- for (; *p != '\0'; ++p)
- {
- hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
- hval ^= (tolower(*p) ^ htoast);
- }
+ if (!p)
+ return 0;
+
+ for (; *p != '\0'; ++p)
+ {
+ hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
+ hval ^= (tolower(*p) ^ htoast);
+ }
- return ((hval >> HASHBITS) ^ (hval & ((1 << HASHBITS) - 1)) % HASHSIZE);
+ return (hval >> HASHBITS) ^ (hval & ((1 << HASHBITS) - 1)) % HASHSIZE;
}
diff --git a/src/libmowgli/base/hook.c b/src/libmowgli/base/hook.c
index 0af9660..315266a 100644
--- a/src/libmowgli/base/hook.c
+++ b/src/libmowgli/base/hook.c
@@ -27,7 +27,8 @@
static mowgli_patricia_t *mowgli_hooks = NULL;
static mowgli_heap_t *mowgli_hook_item_heap;
-static void _hook_key_canon(char *str)
+static void
+_hook_key_canon(char *str)
{
while (*str)
{
@@ -116,7 +117,7 @@ mowgli_hook_dissociate(const char *name, mowgli_hook_function_t func)
mowgli_heap_free(mowgli_hook_item_heap, hookitem);
return 0;
- }
+ }
}
return -1;
diff --git a/src/libmowgli/base/hook.h b/src/libmowgli/base/hook.h
index 366e123..5d8d317 100644
--- a/src/libmowgli/base/hook.h
+++ b/src/libmowgli/base/hook.h
@@ -27,21 +27,22 @@
typedef void (*mowgli_hook_function_t)(void *hook_data, void *user_data);
-typedef struct {
- mowgli_hook_function_t func;
- void *user_data;
- mowgli_node_t node;
+typedef struct
+{
+ mowgli_hook_function_t func;
+ void *user_data;
+ mowgli_node_t node;
} mowgli_hook_item_t;
-typedef struct {
- const char *name;
- mowgli_list_t items;
+typedef struct
+{
+ const char *name;
+ mowgli_list_t items;
} mowgli_hook_t;
-extern void mowgli_hook_bootstrap(void);
extern void mowgli_hook_register(const char *name);
-extern int mowgli_hook_associate(const char *name, mowgli_hook_function_t func, void * user_data);
-extern int mowgli_hook_dissociate(const char *name, mowgli_hook_function_t func);
-extern void mowgli_hook_call(const char *name, void * hook_data);
+extern int mowgli_hook_associate(const char *name, mowgli_hook_function_t func, void *user_data);
+extern int mowgli_hook_dissociate(const char *name, mowgli_hook_function_t func);
+extern void mowgli_hook_call(const char *name, void *hook_data);
#endif
diff --git a/src/libmowgli/base/memslice.c b/src/libmowgli/base/memslice.c
index a271821..8d8f3a2 100644
--- a/src/libmowgli/base/memslice.c
+++ b/src/libmowgli/base/memslice.c
@@ -26,7 +26,8 @@ static mowgli_heap_t *allocator_heap;
/*
* Our slice allocation engine.
*/
-typedef struct {
+typedef struct
+{
size_t size;
mowgli_heap_t *heap;
@@ -36,7 +37,8 @@ typedef struct {
/*
* Allocation tag.
*/
-typedef struct {
+typedef struct
+{
slice_alloc_t *owner;
} slice_tag_t;
@@ -49,6 +51,7 @@ nexthigher(size_t k)
size_t i;
k--;
+
for (i = 1; i < sizeof(k) * 8; i <<= 1)
k |= k >> i;
@@ -109,7 +112,7 @@ memslice_alloc(size_t i)
ptr = mowgli_heap_alloc(alloc->heap);
((slice_tag_t *) ptr)->owner = alloc;
- return ptr + sizeof(slice_tag_t);
+ return (char *) ptr + sizeof(slice_tag_t);
}
/*
@@ -122,7 +125,7 @@ memslice_free(void *ptr)
return_if_fail(ptr != NULL);
- tag = ptr - sizeof(slice_tag_t);
+ tag = (void *) ((char *) ptr - sizeof(slice_tag_t));
mowgli_heap_free(tag->owner->heap, tag);
}
diff --git a/src/libmowgli/base/memslice.h b/src/libmowgli/base/memslice.h
index 9d6e842..12ce8f7 100644
--- a/src/libmowgli/base/memslice.h
+++ b/src/libmowgli/base/memslice.h
@@ -21,7 +21,6 @@
#ifndef __MOWGLI_MEMSLICE_H__
#define __MOWGLI_MEMSLICE_H__
-void mowgli_memslice_bootstrap(void);
mowgli_allocation_policy_t *mowgli_memslice_get_policy(void);
#endif
diff --git a/src/libmowgli/base/mowgli_signal.c b/src/libmowgli/base/mowgli_signal.c
index 208ce37..60602b4 100644
--- a/src/libmowgli/base/mowgli_signal.c
+++ b/src/libmowgli/base/mowgli_signal.c
@@ -26,11 +26,15 @@
#include <signal.h>
#include "mowgli.h"
+#if defined(__linux__) && defined(__GNUC__) && defined(__STRICT_ANSI__)
+# error GCC/Linux in -std=c99 mode will not compile mowgli_signal; use -std=gnu99 instead
+#endif
+
static mowgli_signal_handler_t
-mowgli_signal_install_handler_full(int signum, mowgli_signal_handler_t handler,
- int *sigtoblock, size_t sigtoblocksize)
+mowgli_signal_install_handler_full(int signum, mowgli_signal_handler_t handler, int *sigtoblock, size_t sigtoblocksize)
{
struct sigaction action, old_action;
+
size_t i;
action.sa_handler = handler;
diff --git a/src/libmowgli/base/mowgli_signal.h b/src/libmowgli/base/mowgli_signal.h
index b194d8d..1c7f33e 100644
--- a/src/libmowgli/base/mowgli_signal.h
+++ b/src/libmowgli/base/mowgli_signal.h
@@ -24,7 +24,7 @@
#ifndef __MOWGLI_SIGNAL_H__
#define __MOWGLI_SIGNAL_H__
-typedef void (*mowgli_signal_handler_t) (int);
+typedef void (*mowgli_signal_handler_t)(int);
extern mowgli_signal_handler_t mowgli_signal_install_handler(int signum, mowgli_signal_handler_t handler);
diff --git a/src/libmowgli/base/random.c b/src/libmowgli/base/random.c
index b316033..a183057 100644
--- a/src/libmowgli/base/random.c
+++ b/src/libmowgli/base/random.c
@@ -27,9 +27,9 @@
/* period parameters */
#define N 624
#define M 397
-#define MATRIX_A 0x9908b0dfUL /* constant vector a */
-#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
-#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
+#define MATRIX_A 0x9908b0dfUL /* constant vector a */
+#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
+#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
/* mowgli_random_t contains state data which is private */
struct mowgli_random_
@@ -42,20 +42,24 @@ struct mowgli_random_
static mowgli_object_class_t klass;
/* initialization */
-void mowgli_random_bootstrap(void)
+void
+mowgli_random_bootstrap(void)
{
mowgli_object_class_init(&klass, "mowgli_random_t", NULL, FALSE);
}
/* construction and destruction. */
-mowgli_random_t *mowgli_random_create(void)
+mowgli_random_t *
+mowgli_random_create(void)
{
return mowgli_random_create_with_seed(time(NULL));
}
-mowgli_random_t *mowgli_random_create_with_seed(unsigned int seed)
+mowgli_random_t *
+mowgli_random_create_with_seed(unsigned int seed)
{
mowgli_random_t *out = mowgli_alloc(sizeof(mowgli_random_t));
+
mowgli_object_init(mowgli_object(out), NULL, &klass, NULL);
mowgli_random_reseed(out, seed);
@@ -64,11 +68,13 @@ mowgli_random_t *mowgli_random_create_with_seed(unsigned int seed)
}
/* reset seed */
-void mowgli_random_reseed(mowgli_random_t *self, unsigned int seed)
+void
+mowgli_random_reseed(mowgli_random_t *self, unsigned int seed)
{
return_if_fail(self != NULL);
self->mt[0] = seed & 0xffffffffUL;
+
for (self->mti = 1; self->mti < N; self->mti++)
{
self->mt[self->mti] = (1812433253UL * (self->mt[self->mti - 1] ^ (self->mt[self->mti - 1] >> 30)) + self->mti);
@@ -77,7 +83,8 @@ void mowgli_random_reseed(mowgli_random_t *self, unsigned int seed)
}
/* number retrieval */
-unsigned int mowgli_random_int(mowgli_random_t *self)
+unsigned int
+mowgli_random_int(mowgli_random_t *self)
{
unsigned int y;
static unsigned int mag01[2] = { 0x0UL, MATRIX_A };
@@ -97,7 +104,7 @@ unsigned int mowgli_random_int(mowgli_random_t *self)
for (; t < N - 1; t++)
{
y = (self->mt[t] & UPPER_MASK) | (self->mt[t + 1] & LOWER_MASK);
- self->mt[t] = self->mt[t + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1U];
+ self->mt[t] = self->mt[t + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1U];
}
y = (self->mt[N - 1] & UPPER_MASK) | (self->mt[0] & LOWER_MASK);
@@ -116,7 +123,8 @@ unsigned int mowgli_random_int(mowgli_random_t *self)
return y;
}
-int mowgli_random_int_ranged(mowgli_random_t *self, int begin, int end)
+int
+mowgli_random_int_ranged(mowgli_random_t *self, int begin, int end)
{
unsigned int dist = end - begin;
unsigned int max, ret;
@@ -129,13 +137,16 @@ int mowgli_random_int_ranged(mowgli_random_t *self, int begin, int end)
remain -= dist;
max = 0xFFFFFFFFU - remain;
- } else
+ }
+ else
+ {
max = dist - 1;
+ }
do
- {
ret = mowgli_random_int(self);
- } while (ret > max);
+
+ while (ret > max);
ret %= dist;
diff --git a/src/libmowgli/base/random.h b/src/libmowgli/base/random.h
index ea53dd7..9153478 100644
--- a/src/libmowgli/base/random.h
+++ b/src/libmowgli/base/random.h
@@ -26,10 +26,8 @@
/* mowgli_random_t contains state data which is private */
struct mowgli_random_;
-typedef struct mowgli_random_ mowgli_random_t;
-/* object class initialization. */
-extern void mowgli_random_bootstrap(void);
+typedef struct mowgli_random_ mowgli_random_t;
/* construction and destruction. */
extern mowgli_random_t *mowgli_random_create(void);
diff --git a/src/libmowgli/container/dictionary.c b/src/libmowgli/container/dictionary.c
index 22445d7..3ffe08e 100644
--- a/src/libmowgli/container/dictionary.c
+++ b/src/libmowgli/container/dictionary.c
@@ -50,7 +50,8 @@ struct mowgli_dictionary_
* - if services runs out of memory and cannot allocate the object,
* the program will abort.
*/
-mowgli_dictionary_t *mowgli_dictionary_create(mowgli_dictionary_comparator_func_t compare_cb)
+mowgli_dictionary_t *
+mowgli_dictionary_create(mowgli_dictionary_comparator_func_t compare_cb)
{
mowgli_dictionary_t *dtree = (mowgli_dictionary_t *) mowgli_alloc(sizeof(mowgli_dictionary_t));
@@ -63,7 +64,7 @@ mowgli_dictionary_t *mowgli_dictionary_create(mowgli_dictionary_comparator_func_
}
/*
- * mowgli_dictionary_create_named(const char *name,
+ * mowgli_dictionary_create_named(const char *name,
* mowgli_dictionary_comparator_func_t compare_cb)
*
* Dictionary object factory.
@@ -79,8 +80,8 @@ mowgli_dictionary_t *mowgli_dictionary_create(mowgli_dictionary_comparator_func_
* - if services runs out of memory and cannot allocate the object,
* the program will abort.
*/
-mowgli_dictionary_t *mowgli_dictionary_create_named(const char *name,
- mowgli_dictionary_comparator_func_t compare_cb)
+mowgli_dictionary_t *
+mowgli_dictionary_create_named(const char *name, mowgli_dictionary_comparator_func_t compare_cb)
{
mowgli_dictionary_t *dtree = (mowgli_dictionary_t *) mowgli_alloc(sizeof(mowgli_dictionary_t));
@@ -110,8 +111,8 @@ mowgli_dictionary_t *mowgli_dictionary_create_named(const char *name,
* Side Effects:
* - the dictionary comparator function is reset.
*/
-void mowgli_dictionary_set_comparator_func(mowgli_dictionary_t *dict,
- mowgli_dictionary_comparator_func_t compare_cb)
+void
+mowgli_dictionary_set_comparator_func(mowgli_dictionary_t *dict, mowgli_dictionary_comparator_func_t compare_cb)
{
return_if_fail(dict != NULL);
return_if_fail(compare_cb != NULL);
@@ -166,11 +167,14 @@ mowgli_dictionary_get_linear_index(mowgli_dictionary_t *dict, const void *key)
return_val_if_fail(key != NULL, 0);
elem = mowgli_dictionary_find(dict, key);
+
if (elem == NULL)
return -1;
if (!dict->dirty)
+ {
return elem->position;
+ }
else
{
mowgli_dictionary_elem_t *delem;
@@ -248,14 +252,14 @@ mowgli_dictionary_retune(mowgli_dictionary_t *dict, const void *key)
* we initialize n with known values, since it's on stack
* memory. otherwise the dict would become corrupted.
*
- * n is used for temporary storage while the tree is retuned.
+ * n is used for temporary storage while the tree is retuned.
* -nenolod
*/
n.left = n.right = NULL;
left = right = &n;
/* this for(;;) loop is the main workhorse of the rebalancing */
- for (node = dict->root; ; )
+ for (node = dict->root;;)
{
if ((ret = dict->compare_cb(key, node->key)) == 0)
break;
@@ -333,8 +337,7 @@ mowgli_dictionary_retune(mowgli_dictionary_t *dict, const void *key)
* - a node is linked to the dictionary tree
*/
void
-mowgli_dictionary_link(mowgli_dictionary_t *dict,
- mowgli_dictionary_elem_t *delem)
+mowgli_dictionary_link(mowgli_dictionary_t *dict, mowgli_dictionary_elem_t *delem)
{
return_if_fail(dict != NULL);
return_if_fail(delem != NULL);
@@ -420,19 +423,25 @@ mowgli_dictionary_unlink_root(mowgli_dictionary_t *dict)
dict->dirty = true;
delem = dict->root;
+
if (delem == NULL)
return;
if (dict->root->left == NULL)
+ {
dict->root = dict->root->right;
+ }
else if (dict->root->right == NULL)
+ {
dict->root = dict->root->left;
+ }
else
{
/* Make the node with the next highest key the new root.
* This node has a NULL left pointer. */
nextnode = delem->next;
soft_assert(nextnode->left == NULL);
+
if (nextnode == delem->right)
{
dict->root = nextnode;
@@ -441,8 +450,12 @@ mowgli_dictionary_unlink_root(mowgli_dictionary_t *dict)
else
{
parentofnext = delem->right;
+
while (parentofnext->left != NULL && parentofnext->left != nextnode)
+ {
parentofnext = parentofnext->left;
+ }
+
soft_assert(parentofnext->left == nextnode);
parentofnext->left = nextnode->right;
dict->root = nextnode;
@@ -489,9 +502,8 @@ mowgli_dictionary_unlink_root(mowgli_dictionary_t *dict)
* - if this is called without a callback, the objects bound to the
* DTree will not be destroyed.
*/
-void mowgli_dictionary_destroy(mowgli_dictionary_t *dtree,
- void (*destroy_cb)(mowgli_dictionary_elem_t *delem, void *privdata),
- void *privdata)
+void
+mowgli_dictionary_destroy(mowgli_dictionary_t *dtree, void (*destroy_cb)(mowgli_dictionary_elem_t *delem, void *privdata), void *privdata)
{
mowgli_dictionary_elem_t *n, *tn;
@@ -526,9 +538,8 @@ void mowgli_dictionary_destroy(mowgli_dictionary_t *dtree,
* Side Effects:
* - on success, a dtree is iterated
*/
-void mowgli_dictionary_foreach(mowgli_dictionary_t *dtree,
- int (*foreach_cb)(mowgli_dictionary_elem_t *delem, void *privdata),
- void *privdata)
+void
+mowgli_dictionary_foreach(mowgli_dictionary_t *dtree, int (*foreach_cb)(mowgli_dictionary_elem_t *delem, void *privdata), void *privdata)
{
mowgli_dictionary_elem_t *n, *tn;
@@ -563,9 +574,8 @@ void mowgli_dictionary_foreach(mowgli_dictionary_t *dtree,
* Side Effects:
* - a dtree is iterated until the requested conditions are met
*/
-void *mowgli_dictionary_search(mowgli_dictionary_t *dtree,
- void *(*foreach_cb)(mowgli_dictionary_elem_t *delem, void *privdata),
- void *privdata)
+void *
+mowgli_dictionary_search(mowgli_dictionary_t *dtree, void *(*foreach_cb)(mowgli_dictionary_elem_t * delem, void *privdata), void *privdata)
{
mowgli_dictionary_elem_t *n, *tn;
void *ret = NULL;
@@ -603,8 +613,8 @@ void *mowgli_dictionary_search(mowgli_dictionary_t *dtree,
* Side Effects:
* - the static iterator, &state, is initialized.
*/
-void mowgli_dictionary_foreach_start(mowgli_dictionary_t *dtree,
- mowgli_dictionary_iteration_state_t *state)
+void
+mowgli_dictionary_foreach_start(mowgli_dictionary_t *dtree, mowgli_dictionary_iteration_state_t *state)
{
return_if_fail(dtree != NULL);
return_if_fail(state != NULL);
@@ -641,8 +651,8 @@ void mowgli_dictionary_foreach_start(mowgli_dictionary_t *dtree,
* Side Effects:
* - none
*/
-void *mowgli_dictionary_foreach_cur(mowgli_dictionary_t *dtree,
- mowgli_dictionary_iteration_state_t *state)
+void *
+mowgli_dictionary_foreach_cur(mowgli_dictionary_t *dtree, mowgli_dictionary_iteration_state_t *state)
{
return_val_if_fail(dtree != NULL, NULL);
return_val_if_fail(state != NULL, NULL);
@@ -666,15 +676,15 @@ void *mowgli_dictionary_foreach_cur(mowgli_dictionary_t *dtree,
* Side Effects:
* - the static iterator, &state, is advanced to a new DTree node.
*/
-void mowgli_dictionary_foreach_next(mowgli_dictionary_t *dtree,
- mowgli_dictionary_iteration_state_t *state)
+void
+mowgli_dictionary_foreach_next(mowgli_dictionary_t *dtree, mowgli_dictionary_iteration_state_t *state)
{
return_if_fail(dtree != NULL);
return_if_fail(state != NULL);
if (state->cur == NULL)
{
- mowgli_log("mowgli_dictionary_foreach_next(): called again after iteration finished on dtree<%p>", dtree);
+ mowgli_log("mowgli_dictionary_foreach_next(): called again after iteration finished on dtree<%p>", (void *) dtree);
return;
}
@@ -702,7 +712,8 @@ void mowgli_dictionary_foreach_next(mowgli_dictionary_t *dtree,
* Side Effects:
* - none
*/
-mowgli_dictionary_elem_t *mowgli_dictionary_find(mowgli_dictionary_t *dict, const void *key)
+mowgli_dictionary_elem_t *
+mowgli_dictionary_find(mowgli_dictionary_t *dict, const void *key)
{
return_val_if_fail(dict != NULL, NULL);
return_val_if_fail(key != NULL, NULL);
@@ -733,7 +744,8 @@ mowgli_dictionary_elem_t *mowgli_dictionary_find(mowgli_dictionary_t *dict, cons
* Side Effects:
* - data is inserted into the DTree.
*/
-mowgli_dictionary_elem_t *mowgli_dictionary_add(mowgli_dictionary_t *dict, const void *key, void *data)
+mowgli_dictionary_elem_t *
+mowgli_dictionary_add(mowgli_dictionary_t *dict, const void *key, void *data)
{
mowgli_dictionary_elem_t *delem;
@@ -748,7 +760,7 @@ mowgli_dictionary_elem_t *mowgli_dictionary_add(mowgli_dictionary_t *dict, const
if (delem->key == NULL)
{
- mowgli_log("major WTF: delem->key is NULL, not adding node.", key);
+ mowgli_log("major WTF: delem->key<%p> is NULL, not adding node.", (void *) key);
mowgli_heap_free(elem_heap, delem);
return NULL;
}
@@ -777,7 +789,8 @@ mowgli_dictionary_elem_t *mowgli_dictionary_add(mowgli_dictionary_t *dict, const
* Notes:
* - the returned data needs to be mowgli_freed/released manually!
*/
-void *mowgli_dictionary_delete(mowgli_dictionary_t *dtree, const void *key)
+void *
+mowgli_dictionary_delete(mowgli_dictionary_t *dtree, const void *key)
{
mowgli_dictionary_elem_t *delem = mowgli_dictionary_find(dtree, key);
void *data;
@@ -788,7 +801,7 @@ void *mowgli_dictionary_delete(mowgli_dictionary_t *dtree, const void *key)
data = delem->data;
mowgli_dictionary_unlink_root(dtree);
- mowgli_heap_free(elem_heap, delem);
+ mowgli_heap_free(elem_heap, delem);
return data;
}
@@ -809,7 +822,8 @@ void *mowgli_dictionary_delete(mowgli_dictionary_t *dtree, const void *key)
* Side Effects:
* - none
*/
-void *mowgli_dictionary_retrieve(mowgli_dictionary_t *dtree, const void *key)
+void *
+mowgli_dictionary_retrieve(mowgli_dictionary_t *dtree, const void *key)
{
mowgli_dictionary_elem_t *delem = mowgli_dictionary_find(dtree, key);
@@ -833,7 +847,8 @@ void *mowgli_dictionary_retrieve(mowgli_dictionary_t *dtree, const void *key)
* Side Effects:
* - none
*/
-unsigned int mowgli_dictionary_size(mowgli_dictionary_t *dict)
+unsigned int
+mowgli_dictionary_size(mowgli_dictionary_t *dict)
{
return_val_if_fail(dict != NULL, 0);
@@ -848,11 +863,15 @@ stats_recurse(mowgli_dictionary_elem_t *delem, int depth, int *pmaxdepth)
if (depth > *pmaxdepth)
*pmaxdepth = depth;
+
result = depth;
+
if (delem->left)
result += stats_recurse(delem->left, depth + 1, pmaxdepth);
+
if (delem->right)
result += stats_recurse(delem->right, depth + 1, pmaxdepth);
+
return result;
}
@@ -872,7 +891,8 @@ stats_recurse(mowgli_dictionary_elem_t *delem, int depth, int *pmaxdepth)
* Side Effects:
* - callback called with stats text
*/
-void mowgli_dictionary_stats(mowgli_dictionary_t *dict, void (*cb)(const char *line, void *privdata), void *privdata)
+void
+mowgli_dictionary_stats(mowgli_dictionary_t *dict, void (*cb)(const char *line, void *privdata), void *privdata)
{
char str[256];
int sum, maxdepth;
@@ -881,19 +901,24 @@ void mowgli_dictionary_stats(mowgli_dictionary_t *dict, void (*cb)(const char *l
if (dict->id != NULL)
snprintf(str, sizeof str, "Dictionary stats for %s (%d)",
- dict->id, dict->count);
+ dict->id, dict->count);
else
snprintf(str, sizeof str, "Dictionary stats for <%p> (%d)",
- dict, dict->count);
+ (void *) dict, dict->count);
+
cb(str, privdata);
maxdepth = 0;
+
if (dict->root != NULL)
{
sum = stats_recurse(dict->root, 0, &maxdepth);
snprintf(str, sizeof str, "Depth sum %d Avg depth %d Max depth %d", sum, sum / dict->count, maxdepth);
}
else
+ {
snprintf(str, sizeof str, "Depth sum 0 Avg depth 0 Max depth 0");
+ }
+
cb(str, privdata);
return;
}
diff --git a/src/libmowgli/container/dictionary.h b/src/libmowgli/container/dictionary.h
index 3c2f4e5..3745a1a 100644
--- a/src/libmowgli/container/dictionary.h
+++ b/src/libmowgli/container/dictionary.h
@@ -25,7 +25,7 @@
#ifndef __MOWGLI_DICTIONARY_H__
#define __MOWGLI_DICTIONARY_H__
-struct mowgli_dictionary_; /* defined in src/dictionary.c */
+struct mowgli_dictionary_; /* defined in src/dictionary.c */
typedef struct mowgli_dictionary_ mowgli_dictionary_t;
@@ -56,7 +56,8 @@ typedef struct mowgli_dictionary_iteration_state_ mowgli_dictionary_iteration_st
/*
* this is a convenience macro for inlining iteration of dictionaries.
*/
-#define MOWGLI_DICTIONARY_FOREACH(element, state, dict) for (mowgli_dictionary_foreach_start((dict), (state)); (element = mowgli_dictionary_foreach_cur((dict), (state))); mowgli_dictionary_foreach_next((dict), (state)))
+#define MOWGLI_DICTIONARY_FOREACH(element, state, dict) \
+ for (mowgli_dictionary_foreach_start((dict), (state)); (element = mowgli_dictionary_foreach_cur((dict), (state))); mowgli_dictionary_foreach_next((dict), (state)))
/*
* mowgli_dictionary_create() creates a new dictionary tree.
@@ -75,8 +76,7 @@ extern mowgli_dictionary_t *mowgli_dictionary_create_named(const char *name, mow
* mowgli_dictionary_set_comparator_func() resets the comparator used for lookups and
* insertions in the DTree structure.
*/
-extern void mowgli_dictionary_set_comparator_func(mowgli_dictionary_t *dict,
- mowgli_dictionary_comparator_func_t compare_cb);
+extern void mowgli_dictionary_set_comparator_func(mowgli_dictionary_t *dict, mowgli_dictionary_comparator_func_t compare_cb);
/*
* mowgli_dictionary_get_comparator_func() returns the comparator used for lookups and
@@ -94,9 +94,7 @@ extern int mowgli_dictionary_get_linear_index(mowgli_dictionary_t *dict, const v
* mowgli_dictionary_destroy() destroys all entries in a dtree, and also optionally calls
* a defined callback function to destroy any data attached to it.
*/
-extern void mowgli_dictionary_destroy(mowgli_dictionary_t *dtree,
- void (*destroy_cb)(mowgli_dictionary_elem_t *delem, void *privdata),
- void *privdata);
+extern void mowgli_dictionary_destroy(mowgli_dictionary_t *dtree, void (*destroy_cb)(mowgli_dictionary_elem_t *delem, void *privdata), void *privdata);
/*
* mowgli_dictionary_foreach() iterates all entries in a dtree, and also optionally calls
@@ -104,9 +102,7 @@ extern void mowgli_dictionary_destroy(mowgli_dictionary_t *dtree,
*
* To shortcircuit iteration, return non-zero from the callback function.
*/
-extern void mowgli_dictionary_foreach(mowgli_dictionary_t *dtree,
- int (*foreach_cb)(mowgli_dictionary_elem_t *delem, void *privdata),
- void *privdata);
+extern void mowgli_dictionary_foreach(mowgli_dictionary_t *dtree, int (*foreach_cb)(mowgli_dictionary_elem_t *delem, void *privdata), void *privdata);
/*
* mowgli_dictionary_search() iterates all entries in a dtree, and also optionally calls
@@ -115,9 +111,7 @@ extern void mowgli_dictionary_foreach(mowgli_dictionary_t *dtree,
* When the object is found, a non-NULL is returned from the callback, which results
* in that object being returned to the user.
*/
-extern void *mowgli_dictionary_search(mowgli_dictionary_t *dtree,
- void *(*foreach_cb)(mowgli_dictionary_elem_t *delem, void *privdata),
- void *privdata);
+extern void *mowgli_dictionary_search(mowgli_dictionary_t *dtree, void *(*foreach_cb)(mowgli_dictionary_elem_t * delem, void *privdata), void *privdata);
/*
* mowgli_dictionary_foreach_start() begins an iteration over all items
@@ -125,21 +119,18 @@ extern void *mowgli_dictionary_search(mowgli_dictionary_t *dtree,
* in progress at a time, it is permitted to remove the current element
* of the iteration (but not any other element).
*/
-extern void mowgli_dictionary_foreach_start(mowgli_dictionary_t *dtree,
- mowgli_dictionary_iteration_state_t *state);
+extern void mowgli_dictionary_foreach_start(mowgli_dictionary_t *dtree, mowgli_dictionary_iteration_state_t *state);
/*
* mowgli_dictionary_foreach_cur() returns the current element of the iteration,
* or NULL if there are no more elements.
*/
-extern void *mowgli_dictionary_foreach_cur(mowgli_dictionary_t *dtree,
- mowgli_dictionary_iteration_state_t *state);
+extern void *mowgli_dictionary_foreach_cur(mowgli_dictionary_t *dtree, mowgli_dictionary_iteration_state_t *state);
/*
* mowgli_dictionary_foreach_next() moves to the next element.
*/
-extern void mowgli_dictionary_foreach_next(mowgli_dictionary_t *dtree,
- mowgli_dictionary_iteration_state_t *state);
+extern void mowgli_dictionary_foreach_next(mowgli_dictionary_t *dtree, mowgli_dictionary_iteration_state_t *state);
/*
* mowgli_dictionary_add() adds a key->value entry to the dictionary tree.
diff --git a/src/libmowgli/container/index.c b/src/libmowgli/container/index.c
index 81776f5..aeeaf26 100644
--- a/src/libmowgli/container/index.c
+++ b/src/libmowgli/container/index.c
@@ -24,164 +24,185 @@
struct mowgli_index_
{
- void * * data;
- int count, size;
- int (* compare) (const void * a, const void * b, void * data);
- void * compare_data;
+ void **data;
+ int count, size;
+ int (*compare)(const void *a, const void *b, void *data);
+ void *compare_data;
};
static mowgli_heap_t *index_heap = NULL;
-void mowgli_index_init (void)
+void
+mowgli_index_init(void)
{
- index_heap = mowgli_heap_create(sizeof(mowgli_index_t), 32, BH_NOW);
+ index_heap = mowgli_heap_create(sizeof(mowgli_index_t), 32, BH_NOW);
}
-mowgli_index_t * mowgli_index_create (void)
+mowgli_index_t *
+mowgli_index_create(void)
{
- mowgli_index_t * index = mowgli_heap_alloc(index_heap);
+ mowgli_index_t *index = mowgli_heap_alloc(index_heap);
- index->data = NULL;
- index->count = 0;
- index->size = 0;
- index->compare = NULL;
- index->compare_data = NULL;
+ index->data = NULL;
+ index->count = 0;
+ index->size = 0;
+ index->compare = NULL;
+ index->compare_data = NULL;
- return index;
+ return index;
}
-void mowgli_index_destroy (mowgli_index_t * index)
+void
+mowgli_index_destroy(mowgli_index_t *index)
{
- mowgli_free (index->data);
- mowgli_heap_free (index_heap, index);
+ mowgli_free(index->data);
+ mowgli_heap_free(index_heap, index);
}
-int mowgli_index_count (mowgli_index_t * index)
+int
+mowgli_index_count(mowgli_index_t *index)
{
- return index->count;
+ return index->count;
}
-void mowgli_index_allocate (mowgli_index_t * index, int size)
+void
+mowgli_index_allocate(mowgli_index_t *index, int size)
{
- size_t oldsize;
- void *new_ptr;
+ size_t oldsize;
+ void *new_ptr;
- if (size <= index->size)
- return;
+ if (size <= index->size)
+ return;
- if (! index->size)
- index->size = 64;
+ if (!index->size)
+ index->size = 64;
- oldsize = index->size;
- while (size > index->size)
- index->size <<= 1;
+ oldsize = index->size;
- new_ptr = mowgli_alloc_array(sizeof (void *), index->size);
+ while (size > index->size)
+ {
+ index->size <<= 1;
+ }
- if (index->data != NULL)
- {
- memcpy(new_ptr, index->data, oldsize);
- mowgli_free(index->data);
- }
+ new_ptr = mowgli_alloc_array(sizeof(void *), index->size);
- index->data = new_ptr;
+ if (index->data != NULL)
+ {
+ memcpy(new_ptr, index->data, oldsize);
+ mowgli_free(index->data);
+ }
+
+ index->data = new_ptr;
}
-void mowgli_index_set (mowgli_index_t * index, int at, void * value)
+void
+mowgli_index_set(mowgli_index_t *index, int at, void *value)
{
- index->data[at] = value;
+ index->data[at] = value;
}
-void * mowgli_index_get (mowgli_index_t * index, int at)
+void *
+mowgli_index_get(mowgli_index_t *index, int at)
{
- return index->data[at];
+ return index->data[at];
}
-static void make_room (mowgli_index_t * index, int at, int count)
+static void
+make_room(mowgli_index_t *index, int at, int count)
{
- mowgli_index_allocate (index, index->count + count);
+ mowgli_index_allocate(index, index->count + count);
- if (at < index->count)
- memmove (index->data + at + count, index->data + at, sizeof (void *) *
- (index->count - at));
+ if (at < index->count)
+ memmove(index->data + at + count, index->data + at, sizeof(void *) *
+ (index->count - at));
- index->count += count;
+ index->count += count;
}
-void mowgli_index_insert (mowgli_index_t * index, int at, void * value)
+void
+mowgli_index_insert(mowgli_index_t *index, int at, void *value)
{
- make_room (index, at, 1);
- index->data[at] = value;
+ make_room(index, at, 1);
+ index->data[at] = value;
}
-void mowgli_index_append (mowgli_index_t * index, void * value)
+void
+mowgli_index_append(mowgli_index_t *index, void *value)
{
- mowgli_index_insert (index, index->count, value);
+ mowgli_index_insert(index, index->count, value);
}
-void mowgli_index_copy_set (mowgli_index_t * source, int from, mowgli_index_t * target,
- int to, int count)
+void
+mowgli_index_copy_set(mowgli_index_t *source, int from, mowgli_index_t *target, int to, int count)
{
- memcpy (target->data + to, source->data + from, sizeof (void *) * count);
+ memcpy(target->data + to, source->data + from, sizeof(void *) * count);
}
-void mowgli_index_copy_insert (mowgli_index_t * source, int from, mowgli_index_t * target,
- int to, int count)
+void
+mowgli_index_copy_insert(mowgli_index_t *source, int from, mowgli_index_t *target, int to, int count)
{
- make_room (target, to, count);
- memcpy (target->data + to, source->data + from, sizeof (void *) * count);
+ make_room(target, to, count);
+ memcpy(target->data + to, source->data + from, sizeof(void *) * count);
}
-void mowgli_index_copy_append (mowgli_index_t * source, int from, mowgli_index_t * target,
- int count)
+void
+mowgli_index_copy_append(mowgli_index_t *source, int from, mowgli_index_t *target, int count)
{
- mowgli_index_copy_insert (source, from, target, target->count, count);
+ mowgli_index_copy_insert(source, from, target, target->count, count);
}
-void mowgli_index_merge_insert (mowgli_index_t * first, int at, mowgli_index_t * second)
+void
+mowgli_index_merge_insert(mowgli_index_t *first, int at, mowgli_index_t *second)
{
- mowgli_index_copy_insert (second, 0, first, at, second->count);
+ mowgli_index_copy_insert(second, 0, first, at, second->count);
}
-void mowgli_index_merge_append (mowgli_index_t * first, mowgli_index_t * second)
+void
+mowgli_index_merge_append(mowgli_index_t *first, mowgli_index_t *second)
{
- mowgli_index_copy_insert (second, 0, first, first->count, second->count);
+ mowgli_index_copy_insert(second, 0, first, first->count, second->count);
}
-void mowgli_index_move (mowgli_index_t * index, int from, int to, int count)
+void
+mowgli_index_move(mowgli_index_t *index, int from, int to, int count)
{
- memmove (index->data + to, index->data + from, sizeof (void *) * count);
+ memmove(index->data + to, index->data + from, sizeof(void *) * count);
}
-void mowgli_index_delete (mowgli_index_t * index, int at, int count)
+void
+mowgli_index_delete(mowgli_index_t *index, int at, int count)
{
- index->count -= count;
- memmove (index->data + at, index->data + at + count, sizeof (void *) *
- (index->count - at));
+ index->count -= count;
+ memmove(index->data + at, index->data + at + count, sizeof(void *) *
+ (index->count - at));
}
-void mowgli_index_sort (mowgli_index_t * index, int (* compare) (const void *, const void *))
+void
+mowgli_index_sort(mowgli_index_t *index, int (*compare)(const void *, const void *))
{
- qsort(index->data, index->count, sizeof (void *), compare);
+ qsort(index->data, index->count, sizeof(void *), compare);
}
#ifdef NOTYET
-static int mowgli_index_compare_with_data (const void * a, const void * b, void * _index)
+static int
+mowgli_index_compare_with_data(const void *a, const void *b, void *_index)
{
- mowgli_index_t * index = _index;
+ mowgli_index_t *index = _index;
- return index->compare (* (const void * *) a, * (const void * *) b,
- index->compare_data);
+ return index->compare(*(const void **) a, *(const void **) b,
+ index->compare_data);
}
-void mowgli_index_sort_with_data (mowgli_index_t * index, int (* compare)
- (const void * a, const void * b, void * data), void * data)
+void
+mowgli_index_sort_with_data(mowgli_index_t *index, int(*compare)
+ (const void *a, const void *b, void *data), void *data)
{
- index->compare = compare;
- index->compare_data = data;
- g_qsort_with_data (index->data, index->count, sizeof (void *),
- mowgli_index_compare_with_data, index);
- index->compare = NULL;
- index->compare_data = NULL;
+ index->compare = compare;
+ index->compare_data = data;
+ g_qsort_with_data(index->data, index->count, sizeof(void *),
+ mowgli_index_compare_with_data, index);
+ index->compare = NULL;
+ index->compare_data = NULL;
}
+
#endif
diff --git a/src/libmowgli/container/index.h b/src/libmowgli/container/index.h
index 85e9e72..50341db 100644
--- a/src/libmowgli/container/index.h
+++ b/src/libmowgli/container/index.h
@@ -25,27 +25,23 @@ struct mowgli_index_;
typedef struct mowgli_index_ mowgli_index_t;
-mowgli_index_t * mowgli_index_create (void);
-void mowgli_index_destroy (mowgli_index_t * index);
-int mowgli_index_count (mowgli_index_t * index);
-void mowgli_index_allocate (mowgli_index_t * index, int size);
-void mowgli_index_set (mowgli_index_t * index, int at, void * value);
-void * mowgli_index_get (mowgli_index_t * index, int at);
-void mowgli_index_insert (mowgli_index_t * index, int at, void * value);
-void mowgli_index_append (mowgli_index_t * index, void * value);
-void mowgli_index_copy_set (mowgli_index_t * source, int from, mowgli_index_t * target,
- int to, int count);
-void mowgli_index_copy_insert (mowgli_index_t * source, int from, mowgli_index_t * target,
- int to, int count);
-void mowgli_index_copy_append (mowgli_index_t * source, int from, mowgli_index_t * target,
- int count);
-void mowgli_index_merge_insert (mowgli_index_t * first, int at, mowgli_index_t * second);
-void mowgli_index_merge_append (mowgli_index_t * first, mowgli_index_t * second);
-void mowgli_index_move (mowgli_index_t * index, int from, int to, int count);
-void mowgli_index_delete (mowgli_index_t * index, int at, int count);
-void mowgli_index_sort (mowgli_index_t * index, int (* compare) (const void * a,
- const void * b));
-void mowgli_index_sort_with_data (mowgli_index_t * index, int (* compare)
- (const void * a, const void * b, void * data), void * data);
+mowgli_index_t *mowgli_index_create(void);
+void mowgli_index_destroy(mowgli_index_t *index);
+int mowgli_index_count(mowgli_index_t *index);
+void mowgli_index_allocate(mowgli_index_t *index, int size);
+void mowgli_index_set(mowgli_index_t *index, int at, void *value);
+void *mowgli_index_get(mowgli_index_t *index, int at);
+void mowgli_index_insert(mowgli_index_t *index, int at, void *value);
+void mowgli_index_append(mowgli_index_t *index, void *value);
+void mowgli_index_copy_set(mowgli_index_t *source, int from, mowgli_index_t *target, int to, int count);
+void mowgli_index_copy_insert(mowgli_index_t *source, int from, mowgli_index_t *target, int to, int count);
+void mowgli_index_copy_append(mowgli_index_t *source, int from, mowgli_index_t *target, int count);
+void mowgli_index_merge_insert(mowgli_index_t *first, int at, mowgli_index_t *second);
+void mowgli_index_merge_append(mowgli_index_t *first, mowgli_index_t *second);
+void mowgli_index_move(mowgli_index_t *index, int from, int to, int count);
+void mowgli_index_delete(mowgli_index_t *index, int at, int count);
+void mowgli_index_sort(mowgli_index_t *index, int (*compare)(const void *a, const void *b));
+void mowgli_index_sort_with_data(mowgli_index_t *index, int(*compare)
+ (const void *a, const void *b, void *data), void *data);
#endif
diff --git a/src/libmowgli/container/list.c b/src/libmowgli/container/list.c
index 6283910..695417b 100644
--- a/src/libmowgli/container/list.c
+++ b/src/libmowgli/container/list.c
@@ -26,12 +26,13 @@
static mowgli_heap_t *mowgli_node_heap;
static mowgli_heap_t *mowgli_list_heap;
-void mowgli_node_bootstrap(void)
+void
+mowgli_node_bootstrap(void)
{
- mowgli_node_heap = mowgli_heap_create(sizeof(mowgli_node_t), 1024, BH_NOW);
- mowgli_list_heap = mowgli_heap_create(sizeof(mowgli_list_t), 64, BH_NOW);
+ mowgli_node_heap = mowgli_heap_create(sizeof(mowgli_node_t), 1024, BH_NOW);
+ mowgli_list_heap = mowgli_heap_create(sizeof(mowgli_list_t), 64, BH_NOW);
- if (mowgli_node_heap == NULL || mowgli_list_heap == NULL)
+ if ((mowgli_node_heap == NULL) || (mowgli_list_heap == NULL))
{
mowgli_log("heap allocator failure.");
abort();
@@ -39,31 +40,34 @@ void mowgli_node_bootstrap(void)
}
/* creates a new node */
-mowgli_node_t *mowgli_node_create(void)
+mowgli_node_t *
+mowgli_node_create(void)
{
- mowgli_node_t *n;
+ mowgli_node_t *n;
- /* allocate it */
- n = mowgli_heap_alloc(mowgli_node_heap);
+ /* allocate it */
+ n = mowgli_heap_alloc(mowgli_node_heap);
- /* initialize */
- n->next = n->prev = n->data = NULL;
+ /* initialize */
+ n->next = n->prev = n->data = NULL;
- /* return a pointer to the new node */
- return n;
+ /* return a pointer to the new node */
+ return n;
}
/* frees a node */
-void mowgli_node_free(mowgli_node_t *n)
+void
+mowgli_node_free(mowgli_node_t *n)
{
return_if_fail(n != NULL);
- /* free it */
- mowgli_heap_free(mowgli_node_heap, n);
+ /* free it */
+ mowgli_heap_free(mowgli_node_heap, n);
}
/* adds a node to the end of a list */
-void mowgli_node_add(void *data, mowgli_node_t *n, mowgli_list_t *l)
+void
+mowgli_node_add(void *data, mowgli_node_t *n, mowgli_list_t *l)
{
mowgli_node_t *tn;
@@ -78,7 +82,7 @@ void mowgli_node_add(void *data, mowgli_node_t *n, mowgli_list_t *l)
{
l->head = n;
l->tail = n;
- l->count++;
+ l->count = 1;
return;
}
@@ -99,7 +103,8 @@ void mowgli_node_add(void *data, mowgli_node_t *n, mowgli_list_t *l)
}
/* adds a node to the head of a list */
-void mowgli_node_add_head(void *data, mowgli_node_t *n, mowgli_list_t *l)
+void
+mowgli_node_add_head(void *data, mowgli_node_t *n, mowgli_list_t *l)
{
mowgli_node_t *tn;
@@ -110,11 +115,11 @@ void mowgli_node_add_head(void *data, mowgli_node_t *n, mowgli_list_t *l)
n->data = data;
/* first node? */
- if (!l->head)
+ if (l->head == NULL)
{
l->head = n;
l->tail = n;
- l->count++;
+ l->count = 1;
return;
}
@@ -126,15 +131,20 @@ void mowgli_node_add_head(void *data, mowgli_node_t *n, mowgli_list_t *l)
}
/* adds a node to a list before another node, or to the end */
-void mowgli_node_add_before(void *data, mowgli_node_t *n, mowgli_list_t *l, mowgli_node_t *before)
+void
+mowgli_node_add_before(void *data, mowgli_node_t *n, mowgli_list_t *l, mowgli_node_t *before)
{
return_if_fail(n != NULL);
return_if_fail(l != NULL);
if (before == NULL)
+ {
mowgli_node_add(data, n, l);
+ }
else if (before == l->head)
+ {
mowgli_node_add_head(data, n, l);
+ }
else
{
n->data = data;
@@ -150,13 +160,16 @@ void mowgli_node_add_before(void *data, mowgli_node_t *n, mowgli_list_t *l, mowg
}
/* adds a node to a list after another node, or to the end */
-void mowgli_node_add_after(void *data, mowgli_node_t *n, mowgli_list_t *l, mowgli_node_t *before)
+void
+mowgli_node_add_after(void *data, mowgli_node_t *n, mowgli_list_t *l, mowgli_node_t *before)
{
return_if_fail(n != NULL);
return_if_fail(l != NULL);
- if (before == NULL || before->next == NULL)
+ if ((before == NULL) || (before->next == NULL))
+ {
mowgli_node_add(data, n, l);
+ }
else
{
n->data = data;
@@ -169,7 +182,8 @@ void mowgli_node_add_after(void *data, mowgli_node_t *n, mowgli_list_t *l, mowgl
}
/* retrieves a node at `position` position. */
-mowgli_node_t *mowgli_node_nth(mowgli_list_t *l, size_t pos)
+mowgli_node_t *
+mowgli_node_nth(mowgli_list_t *l, size_t pos)
{
size_t iter;
mowgli_node_t *n;
@@ -178,16 +192,20 @@ mowgli_node_t *mowgli_node_nth(mowgli_list_t *l, size_t pos)
/* locate the proper position. */
if (pos < MOWGLI_LIST_LENGTH(l) / 2)
- for (iter = 0, n = l->head; iter != pos && n != NULL; iter++, n = n->next);
+ for (iter = 0, n = l->head; iter != pos && n != NULL; iter++, n = n->next)
+ ;
+
else
for (iter = MOWGLI_LIST_LENGTH(l) - 1, n = l->tail;
- iter != pos && n != NULL; iter--, n = n->prev);
+ iter != pos && n != NULL; iter--, n = n->prev)
+ ;
return n;
}
/* returns the data from node at `position` position, or NULL. */
-void *mowgli_node_nth_data(mowgli_list_t *l, size_t pos)
+void *
+mowgli_node_nth_data(mowgli_list_t *l, size_t pos)
{
mowgli_node_t *n;
@@ -202,7 +220,8 @@ void *mowgli_node_nth_data(mowgli_list_t *l, size_t pos)
}
/* inserts a node at `position` position. */
-void mowgli_node_insert(void *data, mowgli_node_t *n, mowgli_list_t *l, size_t pos)
+void
+mowgli_node_insert(void *data, mowgli_node_t *n, mowgli_list_t *l, size_t pos)
{
mowgli_node_t *tn;
@@ -216,7 +235,8 @@ void mowgli_node_insert(void *data, mowgli_node_t *n, mowgli_list_t *l, size_t p
}
/* retrieves the index position of a node in a list. */
-ssize_t mowgli_node_index(mowgli_node_t *n, mowgli_list_t *l)
+ssize_t
+mowgli_node_index(mowgli_node_t *n, mowgli_list_t *l)
{
ssize_t iter;
mowgli_node_t *tn;
@@ -225,82 +245,89 @@ ssize_t mowgli_node_index(mowgli_node_t *n, mowgli_list_t *l)
return_val_if_fail(l != NULL, -1);
/* locate the proper position. */
- for (iter = 0, tn = l->head; tn != n && tn != NULL; iter++, tn = tn->next);
+ for (iter = 0, tn = l->head; tn != n && tn != NULL; iter++, tn = tn->next)
+ ;
return iter < (ssize_t) MOWGLI_LIST_LENGTH(l) ? iter : -1;
}
/* deletes a link between a node and a list. */
-void mowgli_node_delete(mowgli_node_t *n, mowgli_list_t *l)
+void
+mowgli_node_delete(mowgli_node_t *n, mowgli_list_t *l)
{
return_if_fail(n != NULL);
return_if_fail(l != NULL);
- /* are we the head? */
- if (!n->prev)
- l->head = n->next;
- else
- n->prev->next = n->next;
+ /* are we the head? */
+ if (!n->prev)
+ l->head = n->next;
+ else
+ n->prev->next = n->next;
- /* are we the tail? */
- if (!n->next)
- l->tail = n->prev;
- else
- n->next->prev = n->prev;
+ /* are we the tail? */
+ if (!n->next)
+ l->tail = n->prev;
+ else
+ n->next->prev = n->prev;
- /* down the count */
- l->count--;
+ /* down the count */
+ l->count--;
}
/* finds a node by `data' */
-mowgli_node_t *mowgli_node_find(void *data, mowgli_list_t *l)
+mowgli_node_t *
+mowgli_node_find(void *data, mowgli_list_t *l)
{
mowgli_node_t *n;
return_val_if_fail(l != NULL, NULL);
- MOWGLI_LIST_FOREACH(n, l->head) if (n->data == data)
+ MOWGLI_LIST_FOREACH(n, l->head)
+
+ if (n->data == data)
return n;
return NULL;
}
/* moves a node from one list to another. */
-void mowgli_node_move(mowgli_node_t *m, mowgli_list_t *oldlist, mowgli_list_t *newlist)
+void
+mowgli_node_move(mowgli_node_t *m, mowgli_list_t *oldlist, mowgli_list_t *newlist)
{
return_if_fail(m != NULL);
return_if_fail(oldlist != NULL);
return_if_fail(newlist != NULL);
- /* Assumption: If m->next == NULL, then list->tail == m
- * and: If m->prev == NULL, then list->head == m
- */
- if (m->next != NULL)
- m->next->prev = m->prev;
- else
- oldlist->tail = m->prev;
+ /* Assumption: If m->next == NULL, then list->tail == m
+ * and: If m->prev == NULL, then list->head == m
+ */
+ if (m->next != NULL)
+ m->next->prev = m->prev;
+ else
+ oldlist->tail = m->prev;
- if (m->prev != NULL)
- m->prev->next = m->next;
- else
- oldlist->head = m->next;
+ if (m->prev != NULL)
+ m->prev->next = m->next;
+ else
+ oldlist->head = m->next;
- m->prev = NULL;
- m->next = newlist->head;
+ m->prev = NULL;
+ m->next = newlist->head;
- if (newlist->head != NULL)
- newlist->head->prev = m;
- else if (newlist->tail == NULL)
- newlist->tail = m;
+ if (newlist->head != NULL)
+ newlist->head->prev = m;
+ else if (newlist->tail == NULL)
+ newlist->tail = m;
- newlist->head = m;
+ newlist->head = m;
- oldlist->count--;
- newlist->count++;
+ oldlist->count--;
+ newlist->count++;
}
/* creates a new list. */
-mowgli_list_t *mowgli_list_create(void)
+mowgli_list_t *
+mowgli_list_create(void)
{
mowgli_list_t *out = mowgli_heap_alloc(mowgli_list_heap);
@@ -308,13 +335,15 @@ mowgli_list_t *mowgli_list_create(void)
}
/* frees a created list. */
-void mowgli_list_free(mowgli_list_t *l)
+void
+mowgli_list_free(mowgli_list_t *l)
{
mowgli_heap_free(mowgli_list_heap, l);
}
/* concatenates two lists together. */
-void mowgli_list_concat(mowgli_list_t *l, mowgli_list_t *l2)
+void
+mowgli_list_concat(mowgli_list_t *l, mowgli_list_t *l2)
{
return_if_fail(l != NULL);
return_if_fail(l2 != NULL);
@@ -334,7 +363,8 @@ void mowgli_list_concat(mowgli_list_t *l, mowgli_list_t *l2)
}
/* reverse a list -- O(n)! */
-void mowgli_list_reverse(mowgli_list_t *l)
+void
+mowgli_list_reverse(mowgli_list_t *l)
{
mowgli_node_t *n, *tn;
@@ -343,6 +373,7 @@ void mowgli_list_reverse(mowgli_list_t *l)
MOWGLI_LIST_FOREACH_SAFE(n, tn, l->head)
{
mowgli_node_t *tn2 = n->next;
+
n->next = n->prev;
n->prev = tn2;
}
@@ -353,7 +384,8 @@ void mowgli_list_reverse(mowgli_list_t *l)
}
/* sorts a list -- O(n ^ 2) most likely, i don't want to think about it. --nenolod */
-void mowgli_list_sort(mowgli_list_t *l, mowgli_list_comparator_t comp, void *opaque)
+void
+mowgli_list_sort(mowgli_list_t *l, mowgli_list_comparator_t comp, void *opaque)
{
mowgli_node_t *n, *tn, *n2, *tn2;
@@ -374,13 +406,15 @@ void mowgli_list_sort(mowgli_list_t *l, mowgli_list_comparator_t comp, void *opa
i2 = mowgli_node_index(n2, l);
if ((result = comp(n, n2, opaque)) == 0)
+ {
continue;
- else if (result < 0 && i > i2)
+ }
+ else if ((result < 0) && (i > i2))
{
mowgli_node_delete(n, l);
mowgli_node_add_before(n->data, n, l, n2);
}
- else if (result > 0 && i < i2)
+ else if ((result > 0) && (i < i2))
{
mowgli_node_delete(n, l);
mowgli_node_add_after(n->data, n, l, n2);
diff --git a/src/libmowgli/container/list.h b/src/libmowgli/container/list.h
index 19905b4..338e51c 100644
--- a/src/libmowgli/container/list.h
+++ b/src/libmowgli/container/list.h
@@ -25,13 +25,17 @@
#define __MOWGLI_LIST_H__
/* macros for linked lists */
-#define MOWGLI_LIST_FOREACH(n, head) for (n = (head); n; n = n->next)
-#define MOWGLI_LIST_FOREACH_NEXT(n, head) for (n = (head); n->next; n = n->next)
-#define MOWGLI_LIST_FOREACH_PREV(n, tail) for (n = (tail); n; n = n->prev)
+#define MOWGLI_LIST_FOREACH(n, head) \
+ for (n = (head); n; n = n->next)
+#define MOWGLI_LIST_FOREACH_NEXT(n, head) \
+ for (n = (head); n->next; n = n->next)
+#define MOWGLI_LIST_FOREACH_PREV(n, tail) \
+ for (n = (tail); n; n = n->prev)
#define MOWGLI_LIST_LENGTH(list) (list)->count
-#define MOWGLI_LIST_FOREACH_SAFE(n, tn, head) for (n = (head), tn = n ? n->next : NULL; n != NULL; n = tn, tn = n ? n->next : NULL)
+#define MOWGLI_LIST_FOREACH_SAFE(n, tn, head) \
+ for (n = (head), tn = n ? n->next : NULL; n != NULL; n = tn, tn = n ? n->next : NULL)
/* list node struct */
typedef struct mowgli_node_ mowgli_node_t;
@@ -39,18 +43,18 @@ typedef struct mowgli_list_ mowgli_list_t;
struct mowgli_node_
{
- struct mowgli_node_ *next, *prev;
- void *data; /* pointer to real structure */
+ struct mowgli_node_ *next, *prev;
+
+ void *data; /* pointer to real structure */
};
/* node list struct */
struct mowgli_list_
{
mowgli_node_t *head, *tail;
- size_t count; /* how many entries in the list */
+ size_t count; /* how many entries in the list */
};
-extern void mowgli_node_bootstrap(void);
extern mowgli_node_t *mowgli_node_create(void);
extern void mowgli_node_free(mowgli_node_t *n);
extern void mowgli_node_add(void *data, mowgli_node_t *n, mowgli_list_t *l);
diff --git a/src/libmowgli/container/patricia.c b/src/libmowgli/container/patricia.c
index b530d33..5d5ec3d 100644
--- a/src/libmowgli/container/patricia.c
+++ b/src/libmowgli/container/patricia.c
@@ -57,6 +57,7 @@ struct mowgli_patricia_
{
void (*canonize_cb)(char *key);
union patricia_elem *root;
+
unsigned int count;
char *id;
};
@@ -68,9 +69,12 @@ struct patricia_node
{
/* nibble to test (nibble NUM%2 of byte NUM/2) */
int nibnum;
+
/* branches of the tree */
union patricia_elem *down[POINTERS_PER_NODE];
+
union patricia_elem *parent;
+
char parent_val;
};
@@ -82,11 +86,14 @@ struct patricia_leaf
{
/* -1 to indicate this is a leaf, not a node */
int nibnum;
+
/* data associated with the key */
void *data;
+
/* key (canonized copy) */
char *key;
union patricia_elem *parent;
+
char parent_val;
};
@@ -94,6 +101,7 @@ union patricia_elem
{
int nibnum;
struct patricia_node node;
+
struct patricia_leaf leaf;
};
@@ -117,21 +125,21 @@ union patricia_elem
* Side Effects:
* - none
*/
-static union patricia_elem *first_leaf(union patricia_elem *delem)
+static union patricia_elem *
+first_leaf(union patricia_elem *delem)
{
int val;
while (!IS_LEAF(delem))
{
for (val = 0; val < POINTERS_PER_NODE; val++)
- {
if (delem->node.down[val] != NULL)
{
delem = delem->node.down[val];
break;
}
- }
}
+
return delem;
}
@@ -152,7 +160,8 @@ static union patricia_elem *first_leaf(union patricia_elem *delem)
* - if services runs out of memory and cannot allocate the object,
* the program will abort.
*/
-mowgli_patricia_t *mowgli_patricia_create(void (*canonize_cb)(char *key))
+mowgli_patricia_t *
+mowgli_patricia_create(void (*canonize_cb)(char *key))
{
mowgli_patricia_t *dtree = (mowgli_patricia_t *) mowgli_alloc(sizeof(mowgli_patricia_t));
@@ -160,6 +169,7 @@ mowgli_patricia_t *mowgli_patricia_create(void (*canonize_cb)(char *key))
if (!leaf_heap)
leaf_heap = mowgli_heap_create(sizeof(struct patricia_leaf), 1024, BH_NOW);
+
if (!node_heap)
node_heap = mowgli_heap_create(sizeof(struct patricia_node), 128, BH_NOW);
@@ -187,8 +197,8 @@ mowgli_patricia_t *mowgli_patricia_create(void (*canonize_cb)(char *key))
* - if services runs out of memory and cannot allocate the object,
* the program will abort.
*/
-mowgli_patricia_t *mowgli_patricia_create_named(const char *name,
- void (*canonize_cb)(char *key))
+mowgli_patricia_t *
+mowgli_patricia_create_named(const char *name, void (*canonize_cb)(char *key))
{
mowgli_patricia_t *dtree = (mowgli_patricia_t *) mowgli_alloc(sizeof(mowgli_patricia_t));
@@ -197,6 +207,7 @@ mowgli_patricia_t *mowgli_patricia_create_named(const char *name,
if (!leaf_heap)
leaf_heap = mowgli_heap_create(sizeof(struct patricia_leaf), 1024, BH_NOW);
+
if (!node_heap)
node_heap = mowgli_heap_create(sizeof(struct patricia_node), 128, BH_NOW);
@@ -220,11 +231,13 @@ mowgli_patricia_t *mowgli_patricia_create_named(const char *name,
* Side Effects:
* - patricia's internal heaps are destroyed and deallocated
*/
-void mowgli_patricia_shutdown(void)
+void
+mowgli_patricia_shutdown(void)
{
- if(leaf_heap)
+ if (leaf_heap)
mowgli_heap_destroy(leaf_heap);
- if(node_heap)
+
+ if (node_heap)
mowgli_heap_destroy(node_heap);
return;
@@ -252,12 +265,12 @@ void mowgli_patricia_shutdown(void)
* - if this is called without a callback, the objects bound to the
* DTree will not be destroyed.
*/
-void mowgli_patricia_destroy(mowgli_patricia_t *dtree,
- void (*destroy_cb)(const char *key, void *data, void *privdata),
- void *privdata)
+void
+mowgli_patricia_destroy(mowgli_patricia_t *dtree, void (*destroy_cb)(const char *key, void *data, void *privdata), void *privdata)
{
mowgli_patricia_iteration_state_t state;
union patricia_elem *delem;
+
void *entry;
return_if_fail(dtree != NULL);
@@ -265,9 +278,11 @@ void mowgli_patricia_destroy(mowgli_patricia_t *dtree,
MOWGLI_PATRICIA_FOREACH(entry, &state, dtree)
{
delem = STATE_CUR(&state);
+
if (destroy_cb != NULL)
(*destroy_cb)(delem->leaf.key, delem->leaf.data,
- privdata);
+ privdata);
+
mowgli_patricia_delete(dtree, delem->leaf.key);
}
@@ -292,31 +307,37 @@ void mowgli_patricia_destroy(mowgli_patricia_t *dtree,
* Side Effects:
* - on success, a dtree is iterated
*/
-void mowgli_patricia_foreach(mowgli_patricia_t *dtree,
- int (*foreach_cb)(const char *key, void *data, void *privdata),
- void *privdata)
+void
+mowgli_patricia_foreach(mowgli_patricia_t *dtree, int (*foreach_cb)(const char *key, void *data, void *privdata), void *privdata)
{
union patricia_elem *delem, *next;
+
int val;
return_if_fail(dtree != NULL);
delem = dtree->root;
+
if (delem == NULL)
return;
+
/* Only one element in the tree */
if (IS_LEAF(delem))
{
if (foreach_cb != NULL)
(*foreach_cb)(delem->leaf.key, delem->leaf.data, privdata);
+
return;
}
+
val = 0;
+
do
{
do
next = delem->node.down[val++];
while (next == NULL && val < POINTERS_PER_NODE);
+
if (next != NULL)
{
if (IS_LEAF(next))
@@ -330,12 +351,15 @@ void mowgli_patricia_foreach(mowgli_patricia_t *dtree,
val = 0;
}
}
+
while (val >= POINTERS_PER_NODE)
{
val = delem->node.parent_val;
delem = delem->node.parent;
+
if (delem == NULL)
break;
+
val++;
}
} while (delem != NULL);
@@ -360,38 +384,45 @@ void mowgli_patricia_foreach(mowgli_patricia_t *dtree,
* Side Effects:
* - a dtree is iterated until the requested conditions are met
*/
-void *mowgli_patricia_search(mowgli_patricia_t *dtree,
- void *(*foreach_cb)(const char *key, void *data, void *privdata),
- void *privdata)
+void *
+mowgli_patricia_search(mowgli_patricia_t *dtree, void *(*foreach_cb)(const char *key, void *data, void *privdata), void *privdata)
{
union patricia_elem *delem, *next;
+
int val;
void *ret = NULL;
return_val_if_fail(dtree != NULL, NULL);
delem = dtree->root;
+
if (delem == NULL)
return NULL;
+
/* Only one element in the tree */
if (IS_LEAF(delem))
{
if (foreach_cb != NULL)
return (*foreach_cb)(delem->leaf.key, delem->leaf.data, privdata);
+
return NULL;
}
+
val = 0;
+
for (;;)
{
do
next = delem->node.down[val++];
while (next == NULL && val < POINTERS_PER_NODE);
+
if (next != NULL)
{
if (IS_LEAF(next))
{
if (foreach_cb != NULL)
ret = (*foreach_cb)(next->leaf.key, next->leaf.data, privdata);
+
if (ret != NULL)
break;
}
@@ -401,15 +432,19 @@ void *mowgli_patricia_search(mowgli_patricia_t *dtree,
val = 0;
}
}
+
while (val >= POINTERS_PER_NODE)
{
val = delem->node.parent_val;
delem = delem->node.parent;
+
if (delem == NULL)
break;
+
val++;
}
}
+
return ret;
}
@@ -429,8 +464,8 @@ void *mowgli_patricia_search(mowgli_patricia_t *dtree,
* Side Effects:
* - the static iterator, &state, is initialized.
*/
-void mowgli_patricia_foreach_start(mowgli_patricia_t *dtree,
- mowgli_patricia_iteration_state_t *state)
+void
+mowgli_patricia_foreach_start(mowgli_patricia_t *dtree, mowgli_patricia_iteration_state_t *state)
{
if (dtree == NULL)
return;
@@ -441,6 +476,7 @@ void mowgli_patricia_foreach_start(mowgli_patricia_t *dtree,
STATE_NEXT(state) = first_leaf(dtree->root);
else
STATE_NEXT(state) = NULL;
+
STATE_CUR(state) = STATE_NEXT(state);
if (STATE_NEXT(state) == NULL)
@@ -468,8 +504,8 @@ void mowgli_patricia_foreach_start(mowgli_patricia_t *dtree,
* Side Effects:
* - none
*/
-void *mowgli_patricia_foreach_cur(mowgli_patricia_t *dtree,
- mowgli_patricia_iteration_state_t *state)
+void *
+mowgli_patricia_foreach_cur(mowgli_patricia_t *dtree, mowgli_patricia_iteration_state_t *state)
{
if (dtree == NULL)
return NULL;
@@ -477,7 +513,7 @@ void *mowgli_patricia_foreach_cur(mowgli_patricia_t *dtree,
return_val_if_fail(state != NULL, NULL);
return STATE_CUR(state) != NULL ?
- ((struct patricia_leaf *)STATE_CUR(state))->data : NULL;
+ ((struct patricia_leaf *) STATE_CUR(state))->data : NULL;
}
/*
@@ -496,11 +532,13 @@ void *mowgli_patricia_foreach_cur(mowgli_patricia_t *dtree,
* Side Effects:
* - the static iterator, &state, is advanced to a new DTree node.
*/
-void mowgli_patricia_foreach_next(mowgli_patricia_t *dtree,
- mowgli_patricia_iteration_state_t *state)
+void
+mowgli_patricia_foreach_next(mowgli_patricia_t *dtree, mowgli_patricia_iteration_state_t *state)
{
struct patricia_leaf *leaf;
+
union patricia_elem *delem, *next;
+
int val;
if (dtree == NULL)
@@ -510,7 +548,7 @@ void mowgli_patricia_foreach_next(mowgli_patricia_t *dtree,
if (STATE_CUR(state) == NULL)
{
- mowgli_log("mowgli_patricia_foreach_next(): called again after iteration finished on dtree<%p>", dtree);
+ mowgli_log("mowgli_patricia_foreach_next(): called again after iteration finished on dtree<%p>", (void *) dtree);
return;
}
@@ -528,6 +566,7 @@ void mowgli_patricia_foreach_next(mowgli_patricia_t *dtree,
do
next = delem->node.down[val++];
while (next == NULL && val < POINTERS_PER_NODE);
+
if (next != NULL)
{
if (IS_LEAF(next))
@@ -537,10 +576,11 @@ void mowgli_patricia_foreach_next(mowgli_patricia_t *dtree,
{
if (strcmp(next->leaf.key, leaf->key) < 0)
{
- mowgli_log("mowgli_patricia_foreach_next(): iteration went backwards (libmowgli bug) on dtree<%p>", dtree);
+ mowgli_log("mowgli_patricia_foreach_next(): iteration went backwards (libmowgli bug) on dtree<%p>", (void *) dtree);
STATE_NEXT(state) = NULL;
return;
}
+
STATE_NEXT(state) = next;
return;
}
@@ -551,15 +591,19 @@ void mowgli_patricia_foreach_next(mowgli_patricia_t *dtree,
val = 0;
}
}
+
while (val >= POINTERS_PER_NODE)
{
val = delem->node.parent_val;
delem = delem->node.parent;
+
if (delem == NULL)
break;
+
val++;
}
}
+
STATE_NEXT(state) = NULL;
}
@@ -579,12 +623,15 @@ void mowgli_patricia_foreach_next(mowgli_patricia_t *dtree,
* Side Effects:
* - none
*/
-struct patricia_leaf *mowgli_patricia_elem_find(mowgli_patricia_t *dict, const char *key)
+struct patricia_leaf *
+mowgli_patricia_elem_find(mowgli_patricia_t *dict, const char *key)
{
char ckey_store[256];
+
char *ckey_buf = NULL;
const char *ckey;
union patricia_elem *delem;
+
int val, keylen;
return_val_if_fail(dict != NULL, NULL);
@@ -593,7 +640,9 @@ struct patricia_leaf *mowgli_patricia_elem_find(mowgli_patricia_t *dict, const c
keylen = strlen(key);
if (dict->canonize_cb == NULL)
+ {
ckey = key;
+ }
else
{
if (keylen >= (int) sizeof(ckey_store))
@@ -611,16 +660,19 @@ struct patricia_leaf *mowgli_patricia_elem_find(mowgli_patricia_t *dict, const c
}
delem = dict->root;
+
while (delem != NULL && !IS_LEAF(delem))
{
if (delem->nibnum / 2 < keylen)
val = NIBBLE_VAL(ckey, delem->nibnum);
else
val = 0;
+
delem = delem->node.down[val];
}
+
/* Now, if the key is in the tree, delem contains it. */
- if (delem != NULL && strcmp(delem->leaf.key, ckey))
+ if ((delem != NULL) && strcmp(delem->leaf.key, ckey))
delem = NULL;
if (ckey_buf != NULL)
@@ -646,11 +698,15 @@ struct patricia_leaf *mowgli_patricia_elem_find(mowgli_patricia_t *dict, const c
* Side Effects:
* - data is inserted into the DTree.
*/
-struct patricia_leaf *mowgli_patricia_elem_add(mowgli_patricia_t *dict, const char *key, void *data)
+struct patricia_leaf *
+mowgli_patricia_elem_add(mowgli_patricia_t *dict, const char *key, void *data)
{
char *ckey;
+
union patricia_elem *delem, *prev, *newnode;
+
union patricia_elem **place1;
+
int val, keylen;
int i, j;
@@ -660,39 +716,43 @@ struct patricia_leaf *mowgli_patricia_elem_add(mowgli_patricia_t *dict, const ch
keylen = strlen(key);
ckey = mowgli_strdup(key);
+
if (ckey == NULL)
{
mowgli_log("major WTF: ckey is NULL, not adding node.");
return NULL;
}
+
if (dict->canonize_cb != NULL)
dict->canonize_cb(ckey);
prev = NULL;
- val = POINTERS_PER_NODE + 2; /* trap value */
+ val = POINTERS_PER_NODE + 2; /* trap value */
delem = dict->root;
+
while (delem != NULL && !IS_LEAF(delem))
{
prev = delem;
+
if (delem->nibnum / 2 < keylen)
val = NIBBLE_VAL(ckey, delem->nibnum);
else
val = 0;
+
delem = delem->node.down[val];
}
+
/* Now, if the key is in the tree, delem contains it. */
- if (delem != NULL && !strcmp(delem->leaf.key, ckey))
+ if ((delem != NULL) && !strcmp(delem->leaf.key, ckey))
{
mowgli_log("Key is already in dict, ignoring duplicate");
mowgli_free(ckey);
return NULL;
}
- if (delem == NULL && prev != NULL)
- {
+ if ((delem == NULL) && (prev != NULL))
/* Get a leaf to compare with. */
delem = first_leaf(prev);
- }
if (delem == NULL)
{
@@ -713,13 +773,15 @@ struct patricia_leaf *mowgli_patricia_elem_add(mowgli_patricia_t *dict, const ch
/* Find the first nibble where they differ. */
for (i = 0; NIBBLE_VAL(ckey, i) == NIBBLE_VAL(delem->leaf.key, i); i++)
;
+
/* Find where to insert the new node. */
while (prev != NULL && prev->nibnum > i)
{
val = prev->node.parent_val;
prev = prev->node.parent;
}
- if (prev == NULL || prev->nibnum < i)
+
+ if ((prev == NULL) || (prev->nibnum < i))
{
/* Insert new node below prev */
newnode = mowgli_heap_alloc(node_heap);
@@ -727,11 +789,14 @@ struct patricia_leaf *mowgli_patricia_elem_add(mowgli_patricia_t *dict, const ch
newnode->nibnum = i;
newnode->node.parent = prev;
newnode->node.parent_val = val;
+
for (j = 0; j < POINTERS_PER_NODE; j++)
newnode->node.down[j] = NULL;
+
if (prev == NULL)
{
newnode->node.down[NIBBLE_VAL(delem->leaf.key, i)] = dict->root;
+
if (IS_LEAF(dict->root))
{
dict->root->leaf.parent = newnode;
@@ -743,11 +808,13 @@ struct patricia_leaf *mowgli_patricia_elem_add(mowgli_patricia_t *dict, const ch
dict->root->node.parent = newnode;
dict->root->node.parent_val = NIBBLE_VAL(delem->leaf.key, i);
}
+
dict->root = newnode;
}
else
{
newnode->node.down[NIBBLE_VAL(delem->leaf.key, i)] = prev->node.down[val];
+
if (IS_LEAF(prev->node.down[val]))
{
prev->node.down[val]->leaf.parent = newnode;
@@ -758,6 +825,7 @@ struct patricia_leaf *mowgli_patricia_elem_add(mowgli_patricia_t *dict, const ch
prev->node.down[val]->node.parent = newnode;
prev->node.down[val]->node.parent_val = NIBBLE_VAL(delem->leaf.key, i);
}
+
prev->node.down[val] = newnode;
}
}
@@ -767,6 +835,7 @@ struct patricia_leaf *mowgli_patricia_elem_add(mowgli_patricia_t *dict, const ch
soft_assert(prev->nibnum == i);
newnode = prev;
}
+
val = NIBBLE_VAL(ckey, i);
place1 = &newnode->node.down[val];
soft_assert(*place1 == NULL);
@@ -781,7 +850,8 @@ struct patricia_leaf *mowgli_patricia_elem_add(mowgli_patricia_t *dict, const ch
return &(*place1)->leaf;
}
-mowgli_boolean_t mowgli_patricia_add(mowgli_patricia_t *dict, const char *key, void *data)
+mowgli_boolean_t
+mowgli_patricia_add(mowgli_patricia_t *dict, const char *key, void *data)
{
return (mowgli_patricia_elem_add(dict, key, data) != NULL) ? TRUE : FALSE;
}
@@ -805,12 +875,14 @@ mowgli_boolean_t mowgli_patricia_add(mowgli_patricia_t *dict, const char *key, v
* Notes:
* - the returned data needs to be mowgli_freed/released manually!
*/
-void *mowgli_patricia_delete(mowgli_patricia_t *dict, const char *key)
+void *
+mowgli_patricia_delete(mowgli_patricia_t *dict, const char *key)
{
void *data;
struct patricia_leaf *leaf;
leaf = mowgli_patricia_elem_find(dict, key);
+
if (leaf == NULL)
return NULL;
@@ -819,15 +891,17 @@ void *mowgli_patricia_delete(mowgli_patricia_t *dict, const char *key)
return data;
}
-void mowgli_patricia_elem_delete(mowgli_patricia_t *dict, struct patricia_leaf *leaf)
+void
+mowgli_patricia_elem_delete(mowgli_patricia_t *dict, struct patricia_leaf *leaf)
{
union patricia_elem *delem, *prev, *next;
+
int val, i, used;
return_if_fail(dict != NULL);
return_if_fail(leaf != NULL);
- delem = (union patricia_elem *)leaf;
+ delem = (union patricia_elem *) leaf;
val = delem->leaf.parent_val;
prev = delem->leaf.parent;
@@ -843,10 +917,13 @@ void mowgli_patricia_elem_delete(mowgli_patricia_t *dict, struct patricia_leaf *
delem = prev;
used = -1;
+
for (i = 0; i < POINTERS_PER_NODE; i++)
if (delem->node.down[i] != NULL)
used = used == -1 ? i : -2;
+
soft_assert(used == -2 || used >= 0);
+
if (used >= 0)
{
/* Only one pointer in this node, remove it.
@@ -856,14 +933,17 @@ void mowgli_patricia_elem_delete(mowgli_patricia_t *dict, struct patricia_leaf *
next = delem->node.down[used];
val = delem->node.parent_val;
prev = delem->node.parent;
+
if (prev != NULL)
prev->node.down[val] = next;
else
dict->root = next;
+
if (IS_LEAF(next))
next->leaf.parent = prev, next->leaf.parent_val = val;
else
next->node.parent = prev, next->node.parent_val = val;
+
mowgli_heap_free(node_heap, delem);
}
}
@@ -874,6 +954,7 @@ void mowgli_patricia_elem_delete(mowgli_patricia_t *dict, struct patricia_leaf *
}
dict->count--;
+
if (dict->count == 0)
{
soft_assert(dict->root == NULL);
@@ -897,7 +978,8 @@ void mowgli_patricia_elem_delete(mowgli_patricia_t *dict, struct patricia_leaf *
* Side Effects:
* - none
*/
-void *mowgli_patricia_retrieve(mowgli_patricia_t *dtree, const char *key)
+void *
+mowgli_patricia_retrieve(mowgli_patricia_t *dtree, const char *key)
{
struct patricia_leaf *delem = mowgli_patricia_elem_find(dtree, key);
@@ -907,21 +989,24 @@ void *mowgli_patricia_retrieve(mowgli_patricia_t *dtree, const char *key)
return NULL;
}
-const char *mowgli_patricia_elem_get_key(struct patricia_leaf *leaf)
+const char *
+mowgli_patricia_elem_get_key(struct patricia_leaf *leaf)
{
return_val_if_fail(leaf != NULL, NULL);
return leaf->key;
}
-void mowgli_patricia_elem_set_data(struct patricia_leaf *leaf, void *data)
+void
+mowgli_patricia_elem_set_data(struct patricia_leaf *leaf, void *data)
{
return_if_fail(leaf != NULL);
leaf->data = data;
}
-void *mowgli_patricia_elem_get_data(struct patricia_leaf *leaf)
+void *
+mowgli_patricia_elem_get_data(struct patricia_leaf *leaf)
{
return_val_if_fail(leaf != NULL, NULL);
@@ -942,7 +1027,8 @@ void *mowgli_patricia_elem_get_data(struct patricia_leaf *leaf)
* Side Effects:
* - none
*/
-unsigned int mowgli_patricia_size(mowgli_patricia_t *dict)
+unsigned int
+mowgli_patricia_size(mowgli_patricia_t *dict)
{
return_val_if_fail(dict != NULL, 0);
@@ -960,25 +1046,28 @@ stats_recurse(union patricia_elem *delem, int depth, int *pmaxdepth)
if (depth > *pmaxdepth)
*pmaxdepth = depth;
+
if (depth == 0)
{
if (IS_LEAF(delem))
- {
soft_assert(delem->leaf.parent == NULL);
- }
+
else
- {
soft_assert(delem->node.parent == NULL);
- }
}
+
if (IS_LEAF(delem))
return depth;
+
for (val = 0; val < POINTERS_PER_NODE; val++)
{
next = delem->node.down[val];
+
if (next == NULL)
continue;
+
result += stats_recurse(next, depth + 1, pmaxdepth);
+
if (IS_LEAF(next))
{
soft_assert(next->leaf.parent == delem);
@@ -991,6 +1080,7 @@ stats_recurse(union patricia_elem *delem, int depth, int *pmaxdepth)
soft_assert(next->node.nibnum > delem->node.nibnum);
}
}
+
return result;
}
@@ -1010,7 +1100,8 @@ stats_recurse(union patricia_elem *delem, int depth, int *pmaxdepth)
* Side Effects:
* - callback called with stats text
*/
-void mowgli_patricia_stats(mowgli_patricia_t *dict, void (*cb)(const char *line, void *privdata), void *privdata)
+void
+mowgli_patricia_stats(mowgli_patricia_t *dict, void (*cb)(const char *line, void *privdata), void *privdata)
{
char str[256];
int sum, maxdepth;
@@ -1019,19 +1110,24 @@ void mowgli_patricia_stats(mowgli_patricia_t *dict, void (*cb)(const char *line,
if (dict->id != NULL)
snprintf(str, sizeof str, "Dictionary stats for %s (%d)",
- dict->id, dict->count);
+ dict->id, dict->count);
else
snprintf(str, sizeof str, "Dictionary stats for <%p> (%d)",
- dict, dict->count);
+ (void *) dict, dict->count);
+
cb(str, privdata);
maxdepth = 0;
+
if (dict->count > 0)
{
sum = stats_recurse(dict->root, 0, &maxdepth);
snprintf(str, sizeof str, "Depth sum %d Avg depth %d Max depth %d", sum, sum / dict->count, maxdepth);
}
else
+ {
snprintf(str, sizeof str, "Depth sum 0 Avg depth 0 Max depth 0");
+ }
+
cb(str, privdata);
return;
}
diff --git a/src/libmowgli/container/patricia.h b/src/libmowgli/container/patricia.h
index 417ba62..a0ab515 100644
--- a/src/libmowgli/container/patricia.h
+++ b/src/libmowgli/container/patricia.h
@@ -35,8 +35,9 @@
#ifndef __MOWGLI_PATRICIA_H__
#define __MOWGLI_PATRICIA_H__
-struct mowgli_patricia_; /* defined in src/patricia.c */
-struct mowgli_patricia_elem_; /* defined in src/patricia.c */
+struct mowgli_patricia_;/* defined in src/patricia.c */
+
+struct mowgli_patricia_elem_; /* defined in src/patricia.c */
typedef struct mowgli_patricia_ mowgli_patricia_t;
typedef struct mowgli_patricia_elem_ mowgli_patricia_elem_t;
@@ -56,7 +57,8 @@ typedef struct mowgli_patricia_iteration_state_ mowgli_patricia_iteration_state_
/*
* this is a convenience macro for inlining iteration of dictionaries.
*/
-#define MOWGLI_PATRICIA_FOREACH(element, state, dict) for (mowgli_patricia_foreach_start((dict), (state)); (element = mowgli_patricia_foreach_cur((dict), (state))); mowgli_patricia_foreach_next((dict), (state)))
+#define MOWGLI_PATRICIA_FOREACH(element, state, dict) \
+ for (mowgli_patricia_foreach_start((dict), (state)); (element = mowgli_patricia_foreach_cur((dict), (state))); mowgli_patricia_foreach_next((dict), (state)))
/*
* mowgli_patricia_create() creates a new patricia tree of the defined resolution.
@@ -79,9 +81,7 @@ extern void mowgli_patricia_shutdown(void);
* mowgli_patricia_destroy() destroys all entries in a dtree, and also optionally calls
* a defined callback function to destroy any data attached to it.
*/
-extern void mowgli_patricia_destroy(mowgli_patricia_t *dtree,
- void (*destroy_cb)(const char *key, void *data, void *privdata),
- void *privdata);
+extern void mowgli_patricia_destroy(mowgli_patricia_t *dtree, void (*destroy_cb)(const char *key, void *data, void *privdata), void *privdata);
/*
* mowgli_patricia_foreach() iterates all entries in a dtree, and also optionally calls
@@ -89,9 +89,7 @@ extern void mowgli_patricia_destroy(mowgli_patricia_t *dtree,
*
* To shortcircuit iteration, return non-zero from the callback function.
*/
-extern void mowgli_patricia_foreach(mowgli_patricia_t *dtree,
- int (*foreach_cb)(const char *key, void *data, void *privdata),
- void *privdata);
+extern void mowgli_patricia_foreach(mowgli_patricia_t *dtree, int (*foreach_cb)(const char *key, void *data, void *privdata), void *privdata);
/*
* mowgli_patricia_search() iterates all entries in a dtree, and also optionally calls
@@ -100,9 +98,7 @@ extern void mowgli_patricia_foreach(mowgli_patricia_t *dtree,
* When the object is found, a non-NULL is returned from the callback, which results
* in that object being returned to the user.
*/
-extern void *mowgli_patricia_search(mowgli_patricia_t *dtree,
- void *(*foreach_cb)(const char *key, void *data, void *privdata),
- void *privdata);
+extern void *mowgli_patricia_search(mowgli_patricia_t *dtree, void *(*foreach_cb)(const char *key, void *data, void *privdata), void *privdata);
/*
* mowgli_patricia_foreach_start() begins an iteration over all items
@@ -110,21 +106,18 @@ extern void *mowgli_patricia_search(mowgli_patricia_t *dtree,
* in progress at a time, it is permitted to remove the current element
* of the iteration (but not any other element).
*/
-extern void mowgli_patricia_foreach_start(mowgli_patricia_t *dtree,
- mowgli_patricia_iteration_state_t *state);
+extern void mowgli_patricia_foreach_start(mowgli_patricia_t *dtree, mowgli_patricia_iteration_state_t *state);
/*
* mowgli_patricia_foreach_cur() returns the current element of the iteration,
* or NULL if there are no more elements.
*/
-extern void *mowgli_patricia_foreach_cur(mowgli_patricia_t *dtree,
- mowgli_patricia_iteration_state_t *state);
+extern void *mowgli_patricia_foreach_cur(mowgli_patricia_t *dtree, mowgli_patricia_iteration_state_t *state);
/*
* mowgli_patricia_foreach_next() moves to the next element.
*/
-extern void mowgli_patricia_foreach_next(mowgli_patricia_t *dtree,
- mowgli_patricia_iteration_state_t *state);
+extern void mowgli_patricia_foreach_next(mowgli_patricia_t *dtree, mowgli_patricia_iteration_state_t *state);
/*
* mowgli_patricia_add() adds a key->value entry to the patricia tree.
diff --git a/src/libmowgli/container/queue.c b/src/libmowgli/container/queue.c
index 39150d3..a321d6b 100644
--- a/src/libmowgli/container/queue.c
+++ b/src/libmowgli/container/queue.c
@@ -139,7 +139,8 @@ mowgli_queue_skip(mowgli_queue_t *head, int nodes)
return_val_if_fail(head != NULL, NULL);
- for (iter = 0, n = head; n != NULL && iter < nodes; n = n->next, iter++);
+ for (iter = 0, n = head; n != NULL && iter < nodes; n = n->next, iter++)
+ ;
return n;
}
@@ -152,7 +153,8 @@ mowgli_queue_rewind(mowgli_queue_t *head, int nodes)
return_val_if_fail(head != NULL, NULL);
- for (iter = 0, n = head; n != NULL && iter < nodes; n = n->prev, iter++);
+ for (iter = 0, n = head; n != NULL && iter < nodes; n = n->prev, iter++)
+ ;
return n;
}
@@ -164,7 +166,8 @@ mowgli_queue_head(mowgli_queue_t *n)
return_val_if_fail(n != NULL, NULL);
- for (tn = n; tn != NULL && tn->prev != NULL; tn = tn->prev);
+ for (tn = n; tn != NULL && tn->prev != NULL; tn = tn->prev)
+ ;
return tn;
}
@@ -176,7 +179,8 @@ mowgli_queue_tail(mowgli_queue_t *n)
return_val_if_fail(n != NULL, NULL);
- for (tn = n; tn != NULL && tn->next != NULL; tn = tn->next);
+ for (tn = n; tn != NULL && tn->next != NULL; tn = tn->next)
+ ;
return tn;
}
@@ -225,7 +229,8 @@ mowgli_queue_length(mowgli_queue_t *head)
return_val_if_fail(head != NULL, -1);
- for (n = head, iter = 0; n != NULL; n = n->next, iter++);
+ for (n = head, iter = 0; n != NULL; n = n->next, iter++)
+ ;
return iter;
}
diff --git a/src/libmowgli/container/queue.h b/src/libmowgli/container/queue.h
index 7f8d995..f16a789 100644
--- a/src/libmowgli/container/queue.h
+++ b/src/libmowgli/container/queue.h
@@ -26,7 +26,6 @@
typedef mowgli_iterator_t mowgli_queue_t;
-extern void mowgli_queue_bootstrap(void);
extern mowgli_queue_t *mowgli_queue_push(mowgli_queue_t *head, void *data);
extern mowgli_queue_t *mowgli_queue_shift(mowgli_queue_t *head, void *data);
extern mowgli_queue_t *mowgli_queue_remove(mowgli_queue_t *head);
diff --git a/src/libmowgli/dns/Makefile b/src/libmowgli/dns/Makefile
index 06fb36c..5a1c8ba 100644
--- a/src/libmowgli/dns/Makefile
+++ b/src/libmowgli/dns/Makefile
@@ -4,13 +4,13 @@ STATIC_PIC_LIB_NOINST = ${LIBMOWGLI_SHARED_DNS}
STATIC_LIB_NOINST = ${LIBMOWGLI_STATIC_DNS}
SRCS = dns.c \
- dns_evloop_res.c \
- dns_evloop_reslib.c \
- dns_evloop_reslist_win32.c
+ evloop_res.c \
+ evloop_reslib.c \
+ evloop_reslist_win32.c
INCLUDES = dns.h \
- dns_evloop_res.h \
- dns_evloop_reslib.h
+ evloop_res.h \
+ evloop_reslib.h
include ../../../buildsys.mk
diff --git a/src/libmowgli/dns/dns.c b/src/libmowgli/dns/dns.c
index eff5080..f12eea1 100644
--- a/src/libmowgli/dns/dns.c
+++ b/src/libmowgli/dns/dns.c
@@ -18,9 +18,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "dns.h"
+#include "mowgli.h"
-mowgli_dns_t * mowgli_dns_create(mowgli_eventloop_t *eventloop, int implementation)
+mowgli_dns_t *
+mowgli_dns_create(mowgli_eventloop_t *eventloop, int implementation)
{
mowgli_dns_t *dns = mowgli_alloc(sizeof(mowgli_dns_t));
const mowgli_dns_ops_t *ops;
@@ -44,7 +45,8 @@ mowgli_dns_t * mowgli_dns_create(mowgli_eventloop_t *eventloop, int implementati
return dns;
}
-int mowgli_dns_init(mowgli_dns_t *dns, mowgli_eventloop_t *eventloop, const mowgli_dns_ops_t *ops)
+int
+mowgli_dns_init(mowgli_dns_t *dns, mowgli_eventloop_t *eventloop, const mowgli_dns_ops_t *ops)
{
return_val_if_fail(dns != NULL, -1);
@@ -53,30 +55,34 @@ int mowgli_dns_init(mowgli_dns_t *dns, mowgli_eventloop_t *eventloop, const mowg
return dns->dns_ops->mowgli_dns_init_func_t(dns, eventloop);
}
-void mowgli_dns_destroy(mowgli_dns_t *dns)
+void
+mowgli_dns_destroy(mowgli_dns_t *dns)
{
dns->dns_ops->mowgli_dns_fini_func_t(dns);
mowgli_free(dns);
}
-int mowgli_dns_restart(mowgli_dns_t *dns)
+int
+mowgli_dns_restart(mowgli_dns_t *dns)
{
return dns->dns_ops->mowgli_dns_restart_func_t(dns);
}
-void mowgli_dns_delete_query(mowgli_dns_t *dns, const mowgli_dns_query_t *query)
+void
+mowgli_dns_delete_query(mowgli_dns_t *dns, const mowgli_dns_query_t *query)
{
dns->dns_ops->mowgli_dns_delete_query_func_t(dns, query);
}
-void mowgli_dns_gethost_byname(mowgli_dns_t *dns, const char *name, mowgli_dns_query_t *query, int type)
+void
+mowgli_dns_gethost_byname(mowgli_dns_t *dns, const char *name, mowgli_dns_query_t *query, int type)
{
dns->dns_ops->mowgli_dns_gethost_byname_func_t(dns, name, query, type);
}
-void mowgli_dns_gethost_byaddr(mowgli_dns_t *dns, const struct sockaddr_storage *addr, mowgli_dns_query_t *query)
+void
+mowgli_dns_gethost_byaddr(mowgli_dns_t *dns, const struct sockaddr_storage *addr, mowgli_dns_query_t *query)
{
dns->dns_ops->mowgli_dns_gethost_byaddr_func_t(dns, addr, query);
}
-
diff --git a/src/libmowgli/dns/dns.h b/src/libmowgli/dns/dns.h
index 9cbb6ee..9e097dd 100644
--- a/src/libmowgli/dns/dns.h
+++ b/src/libmowgli/dns/dns.h
@@ -21,15 +21,13 @@
#ifndef __MOWGLI_DNS_DNS_H__
#define __MOWGLI_DNS_DNS_H__
-#include "mowgli.h"
-
/* Longest hostname we're willing to work with */
#define MOWGLI_DNS_RES_HOSTLEN 512
/* Resolver types */
-#define MOWGLI_DNS_TYPE_CUSTOM 0
-#define MOWGLI_DNS_TYPE_ASYNC 1
-#define MOWGLI_DNS_TYPE_HELPER 2
+#define MOWGLI_DNS_TYPE_CUSTOM 0
+#define MOWGLI_DNS_TYPE_ASYNC 1
+#define MOWGLI_DNS_TYPE_HELPER 2
/* Lookup types */
#define MOWGLI_DNS_T_A 1
@@ -76,11 +74,11 @@ struct _mowgli_dns_t
struct _mowgli_dns_query_t
{
- void *ptr; /* pointer used by callback to identify request */
- void (*callback) (mowgli_dns_reply_t * reply, int result, void *vptr); /* callback to call */
+ void *ptr; /* pointer used by callback to identify request */
+ void (*callback)(mowgli_dns_reply_t *reply, int result, void *vptr); /* callback to call */
};
-extern mowgli_dns_t * mowgli_dns_create(mowgli_eventloop_t *eventloop, int implementation);
+extern mowgli_dns_t *mowgli_dns_create(mowgli_eventloop_t *eventloop, int implementation);
extern int mowgli_dns_init(mowgli_dns_t *dns, mowgli_eventloop_t *eventloop, const mowgli_dns_ops_t *ops);
extern void mowgli_dns_destroy(mowgli_dns_t *dns);
extern int mowgli_dns_restart(mowgli_dns_t *dns);
@@ -89,8 +87,7 @@ extern void mowgli_dns_gethost_byname(mowgli_dns_t *dns, const char *name, mowgl
extern void mowgli_dns_gethost_byaddr(mowgli_dns_t *dns, const struct sockaddr_storage *addr, mowgli_dns_query_t *query);
/* Pull in headers that depend on these types */
-#include "dns_evloop_res.h"
-#include "dns_evloop_reslib.h"
+#include "evloop_res.h"
+#include "evloop_reslib.h"
#endif
-
diff --git a/src/libmowgli/dns/dns_evloop_reslib.h b/src/libmowgli/dns/dns_evloop_reslib.h
deleted file mode 100644
index b6fcf03..0000000
--- a/src/libmowgli/dns/dns_evloop_reslib.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * dns/reslib.h
- *
- * $Id: reslib.h 446 2006-02-12 02:46:54Z db $
- */
-
-#ifndef __MOWGLI_DNS_RESLIB_H__
-#define __MOWGLI_DNS_RESLIB_H__
-
-/* Here we define some values lifted from nameser.h */
-#define MOWGLI_DNS_NS_NOTIFY_OP 4
-#define MOWGLI_DNS_NS_INT16SIZE 2
-#define MOWGLI_DNS_NS_IN6ADDRSIZE 16
-#define MOWGLI_DNS_NS_INADDRSIZE 4
-#define MOWGLI_DNS_NS_INT32SIZE 4
-#define MOWGLI_DNS_NS_CMPRSFLAGS 0xc0
-#define MOWGLI_DNS_NS_MAXCDNAME 255
-#define MOWGLI_DNS_QUERY 0
-#define MOWGLI_DNS_IQUERY 1
-#define MOWGLI_DNS_NO_ERRORS 0
-#define MOWGLI_DNS_SERVFAIL 2
-#define MOWGLI_DNS_NXDOMAIN 3
-#define MOWGLI_DNS_C_IN 1
-#define MOWGLI_DNS_QFIXEDSIZE 4
-#define MOWGLI_DNS_RRFIXEDSIZE 10
-#define MOWGLI_DNS_HFIXEDSIZE 12
-
-typedef struct
-{
- unsigned id:16; /* query identification number */
-#ifdef WORDS_BIGENDIAN
- /* fields in third byte */
- unsigned qr:1; /* response flag */
- unsigned opcode:4; /* purpose of message */
- unsigned aa:1; /* authoritive answer */
- unsigned tc:1; /* truncated message */
- unsigned rd:1; /* recursion desired */
- /* fields in fourth byte */
- unsigned ra:1; /* recursion available */
- unsigned unused:1; /* unused bits (MBZ as of 4.9.3a3) */
- unsigned ad:1; /* authentic data from named */
- unsigned cd:1; /* checking disabled by resolver */
- unsigned rcode:4; /* response code */
-#else
- /* fields in third byte */
- unsigned rd:1; /* recursion desired */
- unsigned tc:1; /* truncated message */
- unsigned aa:1; /* authoritive answer */
- unsigned opcode:4; /* purpose of message */
- unsigned qr:1; /* response flag */
- /* fields in fourth byte */
- unsigned rcode:4; /* response code */
- unsigned cd:1; /* checking disabled by resolver */
- unsigned ad:1; /* authentic data from named */
- unsigned unused:1; /* unused bits (MBZ as of 4.9.3a3) */
- unsigned ra:1; /* recursion available */
-#endif
- /* remaining bytes */
- unsigned qdcount:16; /* number of question entries */
- unsigned ancount:16; /* number of answer entries */
- unsigned nscount:16; /* number of authority entries */
- unsigned arcount:16; /* number of resource entries */
-} mowgli_dns_resheader_t;
-
-/*
- * Inline versions of get/put short/long. Pointer is advanced.
- */
-#define MOWGLI_DNS_NS_GET16(s, cp) { \
- const unsigned char *t_cp = (const unsigned char *)(cp); \
- (s) = ((uint16_t)t_cp[0] << 8) \
- | ((uint16_t)t_cp[1]) \
- ; \
- (cp) += MOWGLI_DNS_NS_INT16SIZE; \
-}
-
-#define MOWGLI_DNS_NS_GET32(l, cp) { \
- const unsigned char *t_cp = (const unsigned char *)(cp); \
- (l) = ((uint32_t)t_cp[0] << 24) \
- | ((uint32_t)t_cp[1] << 16) \
- | ((uint32_t)t_cp[2] << 8) \
- | ((uint32_t)t_cp[3]) \
- ; \
- (cp) += MOWGLI_DNS_NS_INT32SIZE; \
-}
-
-#define MOWGLI_DNS_NS_PUT16(s, cp) { \
- uint16_t t_s = (uint16_t)(s); \
- unsigned char *t_cp = (unsigned char *)(cp); \
- *t_cp++ = t_s >> 8; \
- *t_cp = t_s; \
- (cp) += MOWGLI_DNS_NS_INT16SIZE; \
-}
-
-#define MOWGLI_DNS_NS_PUT32(l, cp) { \
- uint32_t t_l = (uint32_t)(l); \
- unsigned char *t_cp = (unsigned char *)(cp); \
- *t_cp++ = t_l >> 24; \
- *t_cp++ = t_l >> 16; \
- *t_cp++ = t_l >> 8; \
- *t_cp = t_l; \
- (cp) += MOWGLI_DNS_NS_INT32SIZE; \
-}
-
-extern int mowgli_dns_dn_expand(const unsigned char *msg, const unsigned char *eom, const unsigned char *src, char *dst, int dstsiz);
-extern int mowgli_dns_dn_skipname(const unsigned char *ptr, const unsigned char *eom);
-extern unsigned int mowgli_dns_ns_get16(const unsigned char *src);
-extern unsigned long mowgli_dns_ns_get32(const unsigned char *src);
-extern void mowgli_dns_ns_put16(unsigned int src, unsigned char *dst);
-extern void mowgli_dns_ns_put32(unsigned long src, unsigned char *dst);
-extern int mowgli_dns_res_mkquery(const char *dname, int query_class, int type, unsigned char *buf, int buflen);
-
-#endif
diff --git a/src/libmowgli/dns/dns_evloop_res.c b/src/libmowgli/dns/evloop_res.c
index a97daf5..f3292dc 100644
--- a/src/libmowgli/dns/dns_evloop_res.c
+++ b/src/libmowgli/dns/evloop_res.c
@@ -1,4 +1,4 @@
-/*
+/*
* A rewrite of Darren Reeds original res.c As there is nothing
* left of Darrens original code, this is now licensed by the hybrid group.
* (Well, some of the function names are the same, and bits of the structs..)
@@ -7,15 +7,12 @@
* The authors takes no responsibility for any damage or loss
* of property which results from the use of this software.
*
- * $Id: res.c 3301 2007-03-28 15:04:06Z jilles $
- * from Hybrid Id: res.c 459 2006-02-12 22:21:37Z db $
- *
* July 1999 - Rewrote a bunch of stuff here. Change hostent builder code,
* added callbacks and reference counting of returned hostents.
* --Bleep (Thomas Helvey <tomh@inxpress.net>)
*
* This was all needlessly complicated for irc. Simplified. No more hostent
- * All we really care about is the IP -> hostname mappings. Thats all.
+ * All we really care about is the IP -> hostname mappings. Thats all.
*
* Apr 28, 2003 --cryogen and Dianora
*
@@ -30,23 +27,23 @@
* its own namespace. Also gutted a lot of needless/one-use/few-line functions.
* Jesus, what were they thinking...
*
- * 2012 --Elizacat
+ * 2012 --Elizacat
*/
#include "mowgli.h"
#include "dns.h"
-#define MOWGLI_DNS_MAXPACKET 1024 /* rfc sez 512 but we expand names so ... */
-#define MOWGLI_DNS_RES_MAXALIASES 35 /* maximum aliases allowed */
-#define MOWGLI_DNS_RES_MAXADDRS 35 /* maximum addresses allowed */
-#define MOWGLI_DNS_AR_TTL 600 /* TTL in seconds for dns cache entries */
+#define MOWGLI_DNS_MAXPACKET 1024 /* rfc sez 512 but we expand names so ... */
+#define MOWGLI_DNS_RES_MAXALIASES 35 /* maximum aliases allowed */
+#define MOWGLI_DNS_RES_MAXADDRS 35 /* maximum addresses allowed */
+#define MOWGLI_DNS_AR_TTL 600 /* TTL in seconds for dns cache entries */
/* RFC 1104/1105 wasn't very helpful about what these fields should be named, so for now, we'll
just name them this way. we probably should look at what named calls them or something. */
-#define MOWGLI_DNS_TYPE_SIZE (size_t)2
-#define MOWGLI_DNS_CLASS_SIZE (size_t)2
-#define MOWGLI_DNS_TTL_SIZE (size_t)4
-#define MOWGLI_DNS_RDLENGTH_SIZE (size_t)2
+#define MOWGLI_DNS_TYPE_SIZE ((size_t) 2)
+#define MOWGLI_DNS_CLASS_SIZE ((size_t) 2)
+#define MOWGLI_DNS_TTL_SIZE ((size_t) 4)
+#define MOWGLI_DNS_RDLENGTH_SIZE ((size_t) 2)
#define MOWGLI_DNS_ANSWER_FIXED_SIZE (MOWGLI_DNS_TYPE_SIZE + MOWGLI_DNS_CLASS_SIZE + MOWGLI_DNS_TTL_SIZE + MOWGLI_DNS_RDLENGTH_SIZE)
#define MOWGLI_DNS_MAXLINE 128
@@ -58,52 +55,56 @@ typedef struct
time_t ttl;
char type;
char queryname[MOWGLI_DNS_RES_HOSTLEN + 1]; /* name currently being queried */
- char retries; /* retry counter */
- char sends; /* number of sends (>1 means resent) */
+ char retries; /* retry counter */
+ char sends; /* number of sends (>1 means resent) */
time_t sentat;
time_t timeout;
- unsigned int lastns; /* index of last server sent to */
+ unsigned int lastns; /* index of last server sent to */
struct sockaddr_storage addr;
+
char *name;
- mowgli_dns_query_t *query; /* query callback for this request */
+ mowgli_dns_query_t *query; /* query callback for this request */
} mowgli_dns_reslist_t;
static mowgli_heap_t *reslist_heap = NULL;
#ifndef _WIN32
static int parse_resvconf(mowgli_dns_t *dns);
+
#else
static void parse_windows_resolvers(mowgli_dns_t *dns);
+
#endif
static void timeout_resolver(void *arg);
static void add_nameserver(mowgli_dns_t *dns, const char *arg);
static int res_ourserver(mowgli_dns_t *dns, const struct sockaddr_storage *inp);
static void rem_request(mowgli_dns_t *dns, mowgli_dns_reslist_t *request);
-static mowgli_dns_reslist_t *make_request(mowgli_dns_t *dns, mowgli_dns_query_t * query);
-static void do_query_name(mowgli_dns_t *dns, mowgli_dns_query_t * query, const char *name, mowgli_dns_reslist_t *request, int);
-static void do_query_number(mowgli_dns_t *dns, mowgli_dns_query_t * query, const struct sockaddr_storage *, mowgli_dns_reslist_t *request);
+static mowgli_dns_reslist_t *make_request(mowgli_dns_t *dns, mowgli_dns_query_t *query);
+static void do_query_name(mowgli_dns_t *dns, mowgli_dns_query_t *query, const char *name, mowgli_dns_reslist_t *request, int);
+static void do_query_number(mowgli_dns_t *dns, mowgli_dns_query_t *query, const struct sockaddr_storage *, mowgli_dns_reslist_t *request);
static void query_name(mowgli_dns_t *dns, mowgli_dns_reslist_t *request);
static int send_res_msg(mowgli_dns_t *dns, const char *buf, int len, int count);
static void resend_query(mowgli_dns_t *dns, mowgli_dns_reslist_t *request);
-static int check_question(mowgli_dns_t *dns, mowgli_dns_reslist_t *request, mowgli_dns_resheader_t * header, char *buf, char *eob);
-static int proc_answer(mowgli_dns_t *dns, mowgli_dns_reslist_t *request, mowgli_dns_resheader_t * header, char *, char *);
+static int check_question(mowgli_dns_reslist_t *request, mowgli_dns_resheader_t *header, char *buf, char *eob);
+static int proc_answer(mowgli_dns_reslist_t *request, mowgli_dns_resheader_t *header, char *, char *);
static mowgli_dns_reslist_t *find_id(mowgli_dns_t *dns, int id);
static mowgli_dns_reply_t *make_dnsreply(mowgli_dns_reslist_t *request);
static void res_readreply(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata);
-/*
+/*
* mowgli_dns_evloop_init - do everything we need to read the resolv.conf file
* and initialize the resolver file descriptor if needed
*/
-int mowgli_dns_evloop_init(mowgli_dns_t *dns, mowgli_eventloop_t *eventloop)
+int
+mowgli_dns_evloop_init(mowgli_dns_t *dns, mowgli_eventloop_t *eventloop)
{
int i;
mowgli_dns_evloop_t *state;
if (dns->dns_state == NULL)
dns->dns_state = mowgli_alloc(sizeof(mowgli_dns_evloop_t));
-
+
dns->dns_type = MOWGLI_DNS_TYPE_ASYNC;
if (!reslist_heap)
@@ -133,26 +134,48 @@ int mowgli_dns_evloop_init(mowgli_dns_t *dns, mowgli_eventloop_t *eventloop)
if (state->vio == NULL)
{
state->vio = mowgli_vio_create(dns);
+
if (mowgli_vio_socket(state->vio, state->nsaddr_list[0].addr.ss_family, SOCK_DGRAM, 0) != 0)
{
mowgli_log("start_resolver(): unable to open UDP resolver socket: %s",
- state->vio->error.string);
+ state->vio->error.string);
return -1;
}
state->eventloop = eventloop;
- mowgli_vio_eventloop_attach(state->vio, state->eventloop);
- mowgli_pollable_setselect(state->eventloop, state->vio->io, MOWGLI_EVENTLOOP_IO_READ, res_readreply);
+ mowgli_vio_eventloop_attach(state->vio, state->eventloop, NULL);
+ mowgli_pollable_setselect(state->eventloop, state->vio->io.e, MOWGLI_EVENTLOOP_IO_READ, res_readreply);
+ mowgli_pollable_set_cloexec(state->vio->io.e, true);
state->timeout_resolver_timer = mowgli_timer_add(state->eventloop, "timeout_resolver", timeout_resolver, dns, 1);
}
return 0;
}
-/*
+int
+mowgli_dns_evloop_set_resolvconf(mowgli_dns_t *dns, const char *respath)
+{
+#ifndef _WIN32
+ mowgli_dns_evloop_t *state = dns->dns_state;
+
+ return_val_if_fail(dns, -1);
+
+ state->resolvconf = respath;
+
+ if (!state->dns_init)
+ return mowgli_dns_evloop_restart(dns);
+
+ return 0;
+#else
+ mowgli_log("Unimplemented on Windows. :(");
+#endif
+}
+
+/*
* mowgli_dns_evloop_restart - reread resolv.conf, reopen socket
*/
-int mowgli_dns_evloop_restart(mowgli_dns_t *dns)
+int
+mowgli_dns_evloop_restart(mowgli_dns_t *dns)
{
mowgli_dns_evloop_t *state = dns->dns_state;
@@ -161,7 +184,8 @@ int mowgli_dns_evloop_restart(mowgli_dns_t *dns)
}
/* mowgli_dns_evloop_destroy - finish us off */
-void mowgli_dns_evloop_destroy(mowgli_dns_t *dns)
+void
+mowgli_dns_evloop_destroy(mowgli_dns_t *dns)
{
mowgli_dns_evloop_t *state = dns->dns_state;
@@ -176,21 +200,32 @@ void mowgli_dns_evloop_destroy(mowgli_dns_t *dns)
#ifndef _WIN32
-/* parse_resvconf() inputs - NONE output - -1 if failure 0 if success side effects - fills in
- * state->nsaddr_list */
-static int parse_resvconf(mowgli_dns_t *dns)
+/* parse_resvconf()
+ * inputs - NONE
+ * output - -1 if failure, 0 if success
+ * side effects - fills in state->nsaddr_list
+ */
+static int
+parse_resvconf(mowgli_dns_t *dns)
{
char *p;
char *opt;
char *arg;
+ const char *respath;
char input[MOWGLI_DNS_MAXLINE];
FILE *file;
mowgli_dns_evloop_t *state = dns->dns_state;
- /* XXX "/etc/resolv.conf" should be from a define in setup.h perhaps for cygwin support etc.
- * this hardcodes it to unix for now -db */
- if ((file = fopen("/etc/resolv.conf", "r")) == NULL)
+ if (state->resolvconf)
+ respath = state->resolvconf;
+ else
+ respath = "/etc/resolv.conf";
+
+ if ((file = fopen(respath, "r")) == NULL)
+ {
+ mowgli_log("Failed to open %s: %s", respath, strerror(errno));
return -1;
+ }
while (fgets(input, sizeof(input), file) != NULL)
{
@@ -199,31 +234,44 @@ static int parse_resvconf(mowgli_dns_t *dns)
*p = '\0';
p = input;
+
/* skip until something thats not a space is seen */
while (isspace(*p))
+ {
p++;
+ }
+
/* if at this point, have a '\0' then continue */
if (*p == '\0')
continue;
/* Ignore comment lines immediately */
- if (*p == '#' || *p == ';')
+ if ((*p == '#') || (*p == ';'))
continue;
/* skip until a space is found */
opt = p;
+
while (!isspace(*p) && *p != '\0')
+ {
p++;
+ }
+
if (*p == '\0')
continue; /* no arguments?.. ignore this line */
+
/* blow away the space character */
*p++ = '\0';
/* skip these spaces that are before the argument */
while (isspace(*p))
+ {
p++;
+ }
+
/* Now arg should be right where p is pointing */
arg = p;
+
if ((p = strpbrk(arg, " \t")) != NULL)
*p = '\0'; /* take the first word */
@@ -234,6 +282,9 @@ static int parse_resvconf(mowgli_dns_t *dns)
}
fclose(file);
+
+ state->dns_init = true;
+
return 0;
}
@@ -249,18 +300,21 @@ parse_windows_resolvers(mowgli_dns_t *dns)
mowgli_dns_get_windows_nameservers(ns_buf, sizeof ns_buf);
- for(server = strtok(ns_buf, ","); server != NULL; server = strtok(NULL, ","))
+ for (server = strtok(ns_buf, ","); server != NULL; server = strtok(NULL, ","))
add_nameserver(dns, server);
}
#endif
-
-/* add_nameserver() input - either an IPV4 address in dotted quad or an IPV6 address in : format
- * output - NONE side effects - entry in state->nsaddr_list is filled in as needed */
-static void add_nameserver(mowgli_dns_t *dns, const char *arg)
+/* add_nameserver()
+ * input - either an IPV4 address in dotted quad or an IPV6 address in : format
+ * output - NONE
+ * side effects - entry in state->nsaddr_list is filled in as needed */
+static void
+add_nameserver(mowgli_dns_t *dns, const char *arg)
{
struct addrinfo hints, *res;
+
mowgli_dns_evloop_t *state = dns->dns_state;
#ifdef DEBUG
@@ -291,7 +345,7 @@ static void add_nameserver(mowgli_dns_t *dns, const char *arg)
freeaddrinfo(res);
}
-/*
+/*
* int
* res_ourserver(dns, inp)
* looks up "inp" in state->nsaddr_list[]
@@ -303,7 +357,8 @@ static void add_nameserver(mowgli_dns_t *dns, const char *arg)
* revised for ircd, cryogen(stu) may03
* rewritten by Elizacat 25mar12
*/
-static int res_ourserver(mowgli_dns_t *dns, const struct sockaddr_storage * inp)
+static int
+res_ourserver(mowgli_dns_t *dns, const struct sockaddr_storage *inp)
{
int ns;
mowgli_dns_evloop_t *state = dns->dns_state;
@@ -318,36 +373,34 @@ static int res_ourserver(mowgli_dns_t *dns, const struct sockaddr_storage * inp)
{
case AF_INET6:
{
- const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)srv;
- const struct sockaddr_in6 *v6in = (const struct sockaddr_in6 *)inp;
+ const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *) srv;
+ const struct sockaddr_in6 *v6in = (const struct sockaddr_in6 *) inp;
- if (srv->ss_family == inp->ss_family && v6->sin6_port == v6in->sin6_port)
- {
+ if ((srv->ss_family == inp->ss_family) && (v6->sin6_port == v6in->sin6_port))
if ((memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr,
- sizeof(struct in6_addr)) == 0) ||
- (memcmp(&v6->sin6_addr.s6_addr, &in6addr_any,
- sizeof(struct in6_addr)) == 0))
+ sizeof(struct in6_addr)) == 0) ||
+ (memcmp(&v6->sin6_addr.s6_addr, &in6addr_any,
+ sizeof(struct in6_addr)) == 0))
{
state->timeout_count[ns] = 0;
return 1;
}
- }
+
break;
}
case AF_INET:
{
- const struct sockaddr_in *v4 = (const struct sockaddr_in *)srv;
- const struct sockaddr_in *v4in = (const struct sockaddr_in *)inp;
+ const struct sockaddr_in *v4 = (const struct sockaddr_in *) srv;
+ const struct sockaddr_in *v4in = (const struct sockaddr_in *) inp;
- if (srv->ss_family == inp->ss_family && v4->sin_port == v4in->sin_port)
- {
+ if ((srv->ss_family == inp->ss_family) && (v4->sin_port == v4in->sin_port))
if ((v4->sin_addr.s_addr == INADDR_ANY)
- || (v4->sin_addr.s_addr == v4in->sin_addr.s_addr))
+ || (v4->sin_addr.s_addr == v4in->sin_addr.s_addr))
{
state->timeout_count[ns] = 0;
return 1;
}
- }
+
break;
}
default:
@@ -358,11 +411,12 @@ static int res_ourserver(mowgli_dns_t *dns, const struct sockaddr_storage * inp)
return 0;
}
-/*
- * timeout_query_list - Remove queries from the list which have been
+/*
+ * timeout_query_list - Remove queries from the list which have been
* there too long without being resolved.
*/
-static time_t timeout_query_list(mowgli_dns_t *dns, time_t now)
+static time_t
+timeout_query_list(mowgli_dns_t *dns, time_t now)
{
mowgli_node_t *ptr;
mowgli_node_t *next_ptr;
@@ -380,7 +434,7 @@ static time_t timeout_query_list(mowgli_dns_t *dns, time_t now)
{
if (--request->retries <= 0)
{
- (*request->query->callback) (NULL, MOWGLI_DNS_RES_TIMEOUT, request->query->ptr);
+ (*request->query->callback)(NULL, MOWGLI_DNS_RES_TIMEOUT, request->query->ptr);
rem_request(dns, request);
continue;
}
@@ -393,41 +447,42 @@ static time_t timeout_query_list(mowgli_dns_t *dns, time_t now)
}
}
- if ((next_time == 0) || timeout < next_time)
+ if ((next_time == 0) || (timeout < next_time))
next_time = timeout;
}
return (next_time > now) ? next_time : (now + MOWGLI_DNS_AR_TTL);
}
-/*
+/*
* timeout_resolver - check request list
*/
-static void timeout_resolver(void *arg)
+static void
+timeout_resolver(void *arg)
{
mowgli_dns_t *dns = arg;
mowgli_dns_evloop_t *state = dns->dns_state;
- time_t next;
+ time_t now, next;
- next = timeout_query_list(dns, mowgli_eventloop_get_time(state->eventloop));
+ now = mowgli_eventloop_get_time(state->eventloop);
+ next = timeout_query_list(dns, now);
/* Reschedule */
mowgli_timer_destroy(state->eventloop, state->timeout_resolver_timer);
- mowgli_timer_add(state->eventloop, "timeout_resolver", timeout_resolver, dns, next);
+ mowgli_timer_add(state->eventloop, "timeout_resolver", timeout_resolver, dns, next - now);
}
-
-/*
+/*
* mowgli_dns_evloop_add_local_domain - Add the domain to hostname, if it is missing
* (as suggested by eps@TOASTER.SFSU.EDU)
*/
-void mowgli_dns_evloop_add_local_domain(mowgli_dns_t *dns, char *hname, size_t size)
+void
+mowgli_dns_evloop_add_local_domain(mowgli_dns_t *dns, char *hname, size_t size)
{
mowgli_dns_evloop_t *state = dns->dns_state;
/* try to fix up unqualified names */
if (strchr(hname, '.') == NULL)
- {
if (state->domain[0])
{
size_t len = strlen(hname);
@@ -438,15 +493,15 @@ void mowgli_dns_evloop_add_local_domain(mowgli_dns_t *dns, char *hname, size_t s
strcpy(hname + len, state->domain);
}
}
- }
}
-/*
- * rem_request - remove a request from the list.
- * This must also free any memory that has been allocated for
+/*
+ * rem_request - remove a request from the list.
+ * This must also free any memory that has been allocated for
* temporary storage of DNS results.
*/
-static void rem_request(mowgli_dns_t *dns, mowgli_dns_reslist_t *request)
+static void
+rem_request(mowgli_dns_t *dns, mowgli_dns_reslist_t *request)
{
mowgli_dns_evloop_t *state = dns->dns_state;
@@ -457,17 +512,18 @@ static void rem_request(mowgli_dns_t *dns, mowgli_dns_reslist_t *request)
mowgli_heap_free(reslist_heap, request);
}
-/*
+/*
* make_request - Create a DNS request record for the server.
*/
-static mowgli_dns_reslist_t *make_request(mowgli_dns_t *dns, mowgli_dns_query_t * query)
+static mowgli_dns_reslist_t *
+make_request(mowgli_dns_t *dns, mowgli_dns_query_t *query)
{
mowgli_dns_reslist_t *request = mowgli_heap_alloc(reslist_heap);
mowgli_dns_evloop_t *state = dns->dns_state;
request->sentat = mowgli_eventloop_get_time(state->eventloop);
request->retries = 3;
- request->timeout = 4; /* start at 4 and exponential inc. */
+ request->timeout = 4; /* start at 4 and exponential inc. */
request->query = query;
mowgli_node_add(request, &request->node, &state->request_list);
@@ -475,11 +531,12 @@ static mowgli_dns_reslist_t *make_request(mowgli_dns_t *dns, mowgli_dns_query_t
return request;
}
-/*
- * mowgli_dns_evloop_delete_queries - cleanup outstanding queries
+/*
+ * mowgli_dns_evloop_delete_queries - cleanup outstanding queries
* for which there no longer exist clients or conf lines.
*/
-void mowgli_dns_evloop_delete_queries(mowgli_dns_t *dns, const mowgli_dns_query_t * query)
+void
+mowgli_dns_evloop_delete_queries(mowgli_dns_t *dns, const mowgli_dns_query_t *query)
{
mowgli_node_t *ptr;
mowgli_node_t *next_ptr;
@@ -489,18 +546,17 @@ void mowgli_dns_evloop_delete_queries(mowgli_dns_t *dns, const mowgli_dns_query_
MOWGLI_ITER_FOREACH_SAFE(ptr, next_ptr, state->request_list.head)
{
if ((request = ptr->data) != NULL)
- {
if (query == request->query)
rem_request(dns, request);
- }
}
}
-/*
+/*
* retryfreq - determine how many queries to wait before resending
* if there have been that many consecutive timeouts
*/
-static inline int retryfreq(int timeouts)
+static inline int
+retryfreq(int timeouts)
{
int i;
int counter = 1;
@@ -512,19 +568,21 @@ static inline int retryfreq(int timeouts)
return counter;
}
-/*
+/*
* send_res_msg - sends msg to a nameserver.
* This should reflect /etc/resolv.conf.
- * Returns number of nameserver successfully sent to
+ * Returns number of nameserver successfully sent to
* or -1 if no successful sends.
*/
-static int send_res_msg(mowgli_dns_t *dns, const char *rmsg, int len, int rcount)
+static int
+send_res_msg(mowgli_dns_t *dns, const char *rmsg, int len, int rcount)
{
int i;
int ns;
mowgli_dns_evloop_t *state = dns->dns_state;
state->retrycnt++;
+
/* First try a nameserver that seems to work. Every once in a while, try a possibly broken one
* to check if it is working again. */
for (i = 0; i < state->nscount; i++)
@@ -542,6 +600,7 @@ static int send_res_msg(mowgli_dns_t *dns, const char *rmsg, int len, int rcount
for (i = 0; i < state->nscount; i++)
{
ns = (i + rcount - 1) % state->nscount;
+
if (!state->timeout_count[ns])
continue;
@@ -552,10 +611,11 @@ static int send_res_msg(mowgli_dns_t *dns, const char *rmsg, int len, int rcount
return -1;
}
-/*
+/*
* find_id - find a dns request id (id is determined by dn_mkquery)
*/
-static mowgli_dns_reslist_t *find_id(mowgli_dns_t *dns, int id)
+static mowgli_dns_reslist_t *
+find_id(mowgli_dns_t *dns, int id)
{
mowgli_node_t *ptr;
mowgli_dns_reslist_t *request;
@@ -572,31 +632,34 @@ static mowgli_dns_reslist_t *find_id(mowgli_dns_t *dns, int id)
return NULL;
}
-/*
+/*
* mowgli_dns_evloop_gethost_byname - get host address from name
*
*/
-void mowgli_dns_evloop_gethost_byname(mowgli_dns_t *dns, const char *name, mowgli_dns_query_t * query, int type)
+void
+mowgli_dns_evloop_gethost_byname(mowgli_dns_t *dns, const char *name, mowgli_dns_query_t *query, int type)
{
return_if_fail(name != NULL);
do_query_name(dns, query, name, NULL, type);
}
-/*
+/*
* mowgli_dns_evloop_gethost_byaddr - get host name from address
*/
-void mowgli_dns_evloop_gethost_byaddr(mowgli_dns_t *dns, const struct sockaddr_storage * addr, mowgli_dns_query_t * query)
+void
+mowgli_dns_evloop_gethost_byaddr(mowgli_dns_t *dns, const struct sockaddr_storage *addr, mowgli_dns_query_t *query)
{
return_if_fail(addr != NULL);
do_query_number(dns, query, addr, NULL);
}
-/*
+/*
* do_query_name - nameserver lookup name
*/
-static void do_query_name(mowgli_dns_t *dns, mowgli_dns_query_t * query, const char *name, mowgli_dns_reslist_t *request, int type)
+static void
+do_query_name(mowgli_dns_t *dns, mowgli_dns_query_t *query, const char *name, mowgli_dns_reslist_t *request, int type)
{
char host_name[MOWGLI_DNS_RES_HOSTLEN + 1];
@@ -614,11 +677,11 @@ static void do_query_name(mowgli_dns_t *dns, mowgli_dns_query_t * query, const c
query_name(dns, request);
}
-/*
+/*
* do_query_number - Use this to do reverse IP# lookups.
*/
-static void do_query_number(mowgli_dns_t *dns, mowgli_dns_query_t * query, const struct sockaddr_storage * addr,
- mowgli_dns_reslist_t *request)
+static void
+do_query_number(mowgli_dns_t *dns, mowgli_dns_query_t *query, const struct sockaddr_storage *addr, mowgli_dns_reslist_t *request)
{
const unsigned char *cp;
const size_t size = addr->ss_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
@@ -627,30 +690,28 @@ static void do_query_number(mowgli_dns_t *dns, mowgli_dns_query_t * query, const
{
request = make_request(dns, query);
memcpy(&request->addr, addr, size);
- request->name = (char *)mowgli_alloc(MOWGLI_DNS_RES_HOSTLEN + 1);
+ request->name = (char *) mowgli_alloc(MOWGLI_DNS_RES_HOSTLEN + 1);
}
if (addr->ss_family == AF_INET)
{
- const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
- cp = (const unsigned char *)&v4->sin_addr.s_addr;
+ const struct sockaddr_in *v4 = (const struct sockaddr_in *) addr;
+ cp = (const unsigned char *) &v4->sin_addr.s_addr;
- sprintf(request->queryname, "%u.%u.%u.%u.in-addr.arpa", (unsigned int)(cp[3]),
- (unsigned int)(cp[2]), (unsigned int)(cp[1]), (unsigned int)(cp[0]));
+ sprintf(request->queryname, "%u.%u.%u.%u.in-addr.arpa", (unsigned int) (cp[3]),
+ (unsigned int) (cp[2]), (unsigned int) (cp[1]), (unsigned int) (cp[0]));
}
else if (addr->ss_family == AF_INET6)
{
int i;
char *rqptr = request->queryname;
- const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
- cp = (const unsigned char *)&v6->sin6_addr.s6_addr;
+ const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *) addr;
+ cp = (const unsigned char *) &v6->sin6_addr.s6_addr;
- for(i = 15; i >= 0; i--, rqptr += 4)
- {
+ for (i = 15; i >= 0; i--, rqptr += 4)
sprintf(rqptr, "%1x.%1x.",
- (unsigned int)(cp[i] & 0xf),
- (unsigned int)(cp[i] >> 4));
- }
+ (unsigned int) (cp[i] & 0xf),
+ (unsigned int) (cp[i] >> 4));
strcpy(rqptr, ".ip6.arpa");
}
@@ -660,15 +721,15 @@ static void do_query_number(mowgli_dns_t *dns, mowgli_dns_query_t * query, const
return;
}
-
request->type = MOWGLI_DNS_T_PTR;
query_name(dns, request);
}
-/*
+/*
* query_name - generate a query based on class, type and name.
*/
-static void query_name(mowgli_dns_t *dns, mowgli_dns_reslist_t *request)
+static void
+query_name(mowgli_dns_t *dns, mowgli_dns_reslist_t *request)
{
char buf[MOWGLI_DNS_MAXPACKET];
int request_len = 0;
@@ -678,32 +739,34 @@ static void query_name(mowgli_dns_t *dns, mowgli_dns_reslist_t *request)
memset(buf, 0, sizeof(buf));
if ((request_len =
- mowgli_dns_res_mkquery(request->queryname, MOWGLI_DNS_C_IN, request->type, (unsigned char *)buf,
- sizeof(buf))) > 0)
+ mowgli_dns_res_mkquery(request->queryname, MOWGLI_DNS_C_IN, request->type, (unsigned char *) buf,
+ sizeof(buf))) > 0)
{
mowgli_dns_resheader_t *header = (mowgli_dns_resheader_t *) buf;
- /*
+
+ /*
* generate an unique id
* NOTE: we don't have to worry about converting this to and from
* network byte order, the nameserver does not interpret this value
* and returns it unchanged
*/
do
- {
header->id = (header->id + mowgli_random_int(state->rand)) & 0xffff;
- }
+
while (find_id(dns, header->id));
request->id = header->id;
++request->sends;
ns = send_res_msg(dns, buf, request_len, request->sends);
+
if (ns != -1)
request->lastns = ns;
}
}
-static void resend_query(mowgli_dns_t *dns, mowgli_dns_reslist_t *request)
+static void
+resend_query(mowgli_dns_t *dns, mowgli_dns_reslist_t *request)
{
switch (request->type)
{
@@ -719,23 +782,24 @@ static void resend_query(mowgli_dns_t *dns, mowgli_dns_reslist_t *request)
}
}
-/*
+/*
* check_question - check if the reply really belongs to the
* name we queried (to guard against late replies from previous
* queries with the same id).
*/
-static int check_question(mowgli_dns_t *dns, mowgli_dns_reslist_t *request, mowgli_dns_resheader_t * header, char *buf, char *eob)
+static int
+check_question(mowgli_dns_reslist_t *request, mowgli_dns_resheader_t *header, char *buf, char *eob)
{
char hostbuf[MOWGLI_DNS_RES_HOSTLEN + 1]; /* working buffer */
- unsigned char *current; /* current position in buf */
- int n; /* temp count */
+ unsigned char *current; /* current position in buf */
+ int n; /* temp count */
- current = (unsigned char *)buf + sizeof(mowgli_dns_resheader_t);
+ current = (unsigned char *) buf + sizeof(mowgli_dns_resheader_t);
if (header->qdcount != 1)
return 0;
- n = mowgli_dns_dn_expand((unsigned char *)buf, (unsigned char *)eob, current, hostbuf, sizeof(hostbuf));
+ n = mowgli_dns_dn_expand((unsigned char *) buf, (unsigned char *) eob, current, hostbuf, sizeof(hostbuf));
if (n <= 0)
return 0;
@@ -746,35 +810,36 @@ static int check_question(mowgli_dns_t *dns, mowgli_dns_reslist_t *request, mowg
return 1;
}
-/*
+/*
* proc_answer - process name server reply
*/
-static int proc_answer(mowgli_dns_t *dns, mowgli_dns_reslist_t *request, mowgli_dns_resheader_t * header, char *buf, char *eob)
+static int
+proc_answer(mowgli_dns_reslist_t *request, mowgli_dns_resheader_t *header, char *buf, char *eob)
{
char hostbuf[MOWGLI_DNS_RES_HOSTLEN + 100]; /* working buffer */
- unsigned char *current; /* current position in buf */
- int query_class; /* answer class */
- int type; /* answer type */
- int n; /* temp count */
+ unsigned char *current; /* current position in buf */
+ int query_class;/* answer class */
+ int type; /* answer type */
+ int n; /* temp count */
int rd_length;
- current = (unsigned char *)buf + sizeof(mowgli_dns_resheader_t);
+ current = (unsigned char *) buf + sizeof(mowgli_dns_resheader_t);
for (; header->qdcount > 0; --header->qdcount)
{
- if ((n = mowgli_dns_dn_skipname(current, (unsigned char *)eob)) < 0)
+ if ((n = mowgli_dns_dn_skipname(current, (unsigned char *) eob)) < 0)
return 0;
current += (size_t) n + MOWGLI_DNS_QFIXEDSIZE;
}
/* process each answer sent to us. */
- while (header->ancount > 0 && (char *)current < eob)
+ while (header->ancount > 0 && (char *) current < eob)
{
header->ancount--;
- n = mowgli_dns_dn_expand((unsigned char *)buf, (unsigned char *)eob, current, hostbuf,
- sizeof(hostbuf));
+ n = mowgli_dns_dn_expand((unsigned char *) buf, (unsigned char *) eob, current, hostbuf,
+ sizeof(hostbuf));
/* Broken message (< 0) or no more answers left (== 0) */
if (n <= 0)
@@ -786,7 +851,7 @@ static int proc_answer(mowgli_dns_t *dns, mowgli_dns_reslist_t *request, mowgli_
* to that (spotted by rodder/jailbird/dianora) */
current += (size_t) n;
- if (!(((char *)current + MOWGLI_DNS_ANSWER_FIXED_SIZE) < eob))
+ if (!(((char *) current + MOWGLI_DNS_ANSWER_FIXED_SIZE) < eob))
break;
type = mowgli_dns_ns_get16(current);
@@ -796,7 +861,7 @@ static int proc_answer(mowgli_dns_t *dns, mowgli_dns_reslist_t *request, mowgli_
current += MOWGLI_DNS_CLASS_SIZE;
/* We may use this later at some point so... eliminate bogus GCC warning */
- (void)query_class;
+ (void) query_class;
request->ttl = mowgli_dns_ns_get32(current);
current += MOWGLI_DNS_TTL_SIZE;
@@ -818,7 +883,7 @@ static int proc_answer(mowgli_dns_t *dns, mowgli_dns_reslist_t *request, mowgli_
if (rd_length != sizeof(struct in_addr))
return 0;
- v4 = (struct sockaddr_in *)&request->addr;
+ v4 = (struct sockaddr_in *) &request->addr;
v4->sin_family = AF_INET;
memcpy(&v4->sin_addr, current, sizeof(struct in_addr));
@@ -830,37 +895,40 @@ static int proc_answer(mowgli_dns_t *dns, mowgli_dns_reslist_t *request, mowgli_
if (request->type != MOWGLI_DNS_T_AAAA)
return 0;
-
+
if (rd_length != sizeof(struct in6_addr))
return 0;
-
- v6 = (struct sockaddr_in6 *)&request->addr;
+
+ v6 = (struct sockaddr_in6 *) &request->addr;
v6->sin6_family = AF_INET6;
memcpy(&v6->sin6_addr, current, sizeof(struct in6_addr));
-
+
return 1;
}
case MOWGLI_DNS_T_PTR:
+
if (request->type != MOWGLI_DNS_T_PTR)
return 0;
-
- n = mowgli_dns_dn_expand((unsigned char *)buf, (unsigned char *)eob, current,
- hostbuf, sizeof(hostbuf));
-
+
+ n = mowgli_dns_dn_expand((unsigned char *) buf, (unsigned char *) eob, current,
+ hostbuf, sizeof(hostbuf));
+
/* Broken message or no more answers left */
if (n <= 0)
return 0;
-
+
mowgli_strlcpy(request->name, hostbuf, MOWGLI_DNS_RES_HOSTLEN + 1);
return 1;
case MOWGLI_DNS_T_CNAME:
+
/* real answer will follow */
current += rd_length;
break;
default:
+
/* XXX I'd rather just throw away the entire bogus thing but its possible its just a
- * broken nameserver with still valid answers. But lets do some rudimentary logging for
+ * broken nameserver with still valid answers. But lets do some rudimentary logging for
* now... */
mowgli_log("proc_answer(): bogus type %d", type);
break;
@@ -870,38 +938,40 @@ static int proc_answer(mowgli_dns_t *dns, mowgli_dns_reslist_t *request, mowgli_
return 1;
}
-/*
+/*
* res_read_single_reply - read a dns reply from the nameserver and process it.
* Return value: 1 if a packet was read, 0 otherwise
*/
-static int res_read_single_reply(mowgli_dns_t *dns)
+static int
+res_read_single_reply(mowgli_dns_t *dns)
{
char buf[sizeof(mowgli_dns_resheader_t) + MOWGLI_DNS_MAXPACKET]
- /* Sparc and alpha need 16bit-alignment for accessing header->id (which is uint16_t).
- Because of the header = (mowgli_dns_resheader_t*) buf; later on, this is neeeded. --FaUl */
+
+ /* Sparc and alpha need 16bit-alignment for accessing header->id (which is uint16_t).
+ Because of the header = (mowgli_dns_resheader_t*) buf; later on, this is neeeded. --FaUl */
#if defined(__sparc__) || defined(__alpha__)
- __attribute__ ((aligned(16)))
+ __attribute__((aligned(16)))
#endif
- ;
+ ;
mowgli_dns_resheader_t *header;
mowgli_dns_reslist_t *request = NULL;
mowgli_dns_reply_t *reply = NULL;
int rc;
int answer_count;
- mowgli_vio_sockaddr_t lsin;
+ mowgli_vio_sockaddr_t lsin = { .addrlen = sizeof(lsin.addr) };
mowgli_dns_evloop_t *state = dns->dns_state;
rc = mowgli_vio_recvfrom(state->vio, buf, sizeof(buf), &lsin);
/* No packet */
- if (rc == 0 || rc == -1)
+ if ((rc == 0) || (rc == -1))
return 0;
/* Too small */
- if (rc <= (int)(sizeof(mowgli_dns_resheader_t)))
+ if (rc <= (int) (sizeof(mowgli_dns_resheader_t)))
return 1;
- /*
+ /*
* convert DNS reply reader from Network byte order to CPU byte order.
*/
header = (mowgli_dns_resheader_t *) buf;
@@ -919,32 +989,33 @@ static int res_read_single_reply(mowgli_dns_t *dns)
if (!res_ourserver(dns, &lsin.addr))
return 1;
- if (!check_question(dns, request, header, buf, buf + rc))
+ if (!check_question(request, header, buf, buf + rc))
return 1;
if ((header->rcode != MOWGLI_DNS_NO_ERRORS) || (header->ancount == 0))
{
if (header->rcode == MOWGLI_DNS_NXDOMAIN)
{
- (*request->query->callback) (NULL, MOWGLI_DNS_RES_NXDOMAIN, request->query->ptr);
+ (*request->query->callback)(NULL, MOWGLI_DNS_RES_NXDOMAIN, request->query->ptr);
rem_request(dns, request);
}
else
{
- /*
+ /*
* If a bad error was returned, we stop here and dont send
* send any more (no retries granted).
*/
- (*request->query->callback) (NULL, MOWGLI_DNS_RES_INVALID, request->query->ptr);
+ (*request->query->callback)(NULL, MOWGLI_DNS_RES_INVALID, request->query->ptr);
rem_request(dns, request);
}
+
return 1;
}
- /* If this fails there was an error decoding the received packet,
+ /* If this fails there was an error decoding the received packet,
* give up. -- jilles
*/
- answer_count = proc_answer(dns, request, header, buf, buf + rc);
+ answer_count = proc_answer(request, header, buf, buf + rc);
if (answer_count)
{
@@ -955,7 +1026,7 @@ static int res_read_single_reply(mowgli_dns_t *dns)
/* got a PTR response with no name, something bogus is happening
* don't bother trying again, the client address doesn't resolve
*/
- (*request->query->callback) (reply, MOWGLI_DNS_RES_INVALID, request->query->ptr);
+ (*request->query->callback)(reply, MOWGLI_DNS_RES_INVALID, request->query->ptr);
rem_request(dns, request);
return 1;
}
@@ -966,13 +1037,14 @@ static int res_read_single_reply(mowgli_dns_t *dns)
mowgli_dns_evloop_gethost_byname(dns, request->name, request->query, MOWGLI_DNS_T_AAAA);
else
mowgli_dns_evloop_gethost_byname(dns, request->name, request->query, MOWGLI_DNS_T_A);
+
rem_request(dns, request);
}
else
{
/* got a name and address response, client resolved */
reply = make_dnsreply(request);
- (*request->query->callback) (reply, MOWGLI_DNS_RES_SUCCESS, request->query->ptr);
+ (*request->query->callback)(reply, MOWGLI_DNS_RES_SUCCESS, request->query->ptr);
mowgli_free(reply);
rem_request(dns, request);
}
@@ -980,16 +1052,18 @@ static int res_read_single_reply(mowgli_dns_t *dns)
else
{
/* couldn't decode, give up -- jilles */
- (*request->query->callback) (NULL, MOWGLI_DNS_RES_INVALID, request->query->ptr);
+ (*request->query->callback)(NULL, MOWGLI_DNS_RES_INVALID, request->query->ptr);
rem_request(dns, request);
}
return 1;
}
-static mowgli_dns_reply_t *make_dnsreply(mowgli_dns_reslist_t *request)
+static mowgli_dns_reply_t *
+make_dnsreply(mowgli_dns_reslist_t *request)
{
mowgli_dns_reply_t *cp;
+
return_val_if_fail(request != 0, NULL);
cp = (mowgli_dns_reply_t *) mowgli_alloc(sizeof(mowgli_dns_reply_t));
@@ -999,14 +1073,18 @@ static mowgli_dns_reply_t *make_dnsreply(mowgli_dns_reslist_t *request)
return cp;
}
-static void res_readreply(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
+static void
+res_readreply(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
{
mowgli_dns_t *dns = userdata;
- while (res_read_single_reply(dns));
+
+ while (res_read_single_reply(dns))
+ { }
}
/* DNS ops for this resolver */
-const mowgli_dns_ops_t mowgli_dns_evloop_resolver = {
+const mowgli_dns_ops_t mowgli_dns_evloop_resolver =
+{
.mowgli_dns_init_func_t = mowgli_dns_evloop_init,
.mowgli_dns_fini_func_t = mowgli_dns_evloop_destroy,
.mowgli_dns_restart_func_t = mowgli_dns_evloop_restart,
@@ -1014,4 +1092,3 @@ const mowgli_dns_ops_t mowgli_dns_evloop_resolver = {
.mowgli_dns_gethost_byname_func_t = mowgli_dns_evloop_gethost_byname,
.mowgli_dns_gethost_byaddr_func_t = mowgli_dns_evloop_gethost_byaddr,
};
-
diff --git a/src/libmowgli/dns/dns_evloop_res.h b/src/libmowgli/dns/evloop_res.h
index 3973533..bb5befc 100644
--- a/src/libmowgli/dns/dns_evloop_res.h
+++ b/src/libmowgli/dns/evloop_res.h
@@ -28,7 +28,10 @@ typedef struct
mowgli_random_t *rand;
- char domain[MOWGLI_DNS_RES_HOSTLEN];
+ const char *resolvconf;
+ bool dns_init;
+
+ char domain[MOWGLI_DNS_RES_HOSTLEN];
} mowgli_dns_evloop_t;
extern int mowgli_dns_evloop_init(mowgli_dns_t *dns, mowgli_eventloop_t *eventloop);
@@ -37,7 +40,9 @@ extern void mowgli_dns_evloop_destroy(mowgli_dns_t *dns);
extern void mowgli_dns_evloop_delete_queries(mowgli_dns_t *dns, const mowgli_dns_query_t *);
extern void mowgli_dns_evloop_gethost_byname(mowgli_dns_t *dns, const char *, mowgli_dns_query_t *, int);
extern void mowgli_dns_evloop_gethost_byaddr(mowgli_dns_t *dns, const struct sockaddr_storage *, mowgli_dns_query_t *);
-extern void mowgli_dns_evloop_add_local_domain(mowgli_dns_t *dns, char *, size_t);
+
+extern void mowgli_dns_evloop_add_local_domain(mowgli_dns_t * dns, char *, size_t);
+extern int mowgli_dns_evloop_set_resolvconf(mowgli_dns_t *dns, const char *respath);
extern const mowgli_dns_ops_t mowgli_dns_evloop_resolver;
diff --git a/src/libmowgli/dns/dns_evloop_reslib.c b/src/libmowgli/dns/evloop_reslib.c
index edefbe7..9dbbfe8 100644
--- a/src/libmowgli/dns/dns_evloop_reslib.c
+++ b/src/libmowgli/dns/evloop_reslib.c
@@ -1,7 +1,7 @@
-/*
+/*
* Copyright (c) 1985, 1993
* The Regents of the University of California. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -13,7 +13,7 @@
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -27,16 +27,16 @@
* SUCH DAMAGE.
*/
-/*
+/*
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
+ *
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies, and that
* the name of Digital Equipment Corporation not be used in advertising or
* publicity pertaining to distribution of the document or software without
* specific, written prior permission.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -47,7 +47,7 @@
* SOFTWARE.
*/
-/*
+/*
* Portions Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -67,18 +67,19 @@
/* Original copyright ISC as above. Code modified specifically for ircd use from the following
* orginal files in bind ... res_comp.c ns_name.c ns_netint.c res_init.c - Dianora */
-#include "dns.h"
+#include "mowgli.h"
#ifdef _WIN32
-#define EMSGSIZE WSAEMSGSIZE
+# define EMSGSIZE WSAEMSGSIZE
#endif
-#define MOWGLI_DNS_NS_TYPE_ELT 0x40 /* EDNS0 extended label type */
-#define MOWGLI_DNS_LABELTYPE_BITSTRING 0x41
+#define MOWGLI_DNS_NS_TYPE_ELT 0x40 /* EDNS0 extended label type */
+#define MOWGLI_DNS_LABELTYPE_BITSTRING 0x41
/* from Hybrid Id: reslib.c 177 2005-10-22 09:05:05Z michael $ */
-static const char digitvalue[256] = {
+static const char digitvalue[256] =
+{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 16 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 32 */
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 48 */
@@ -120,17 +121,17 @@ static int mowgli_dns_mklower(int ch);
* Return size of compressed name or -1 if there was an error.
*/
int
-mowgli_dns_dn_expand(const unsigned char *rmsg, const unsigned char *eom,
- const unsigned char *src, char *dst, int dstsiz)
+mowgli_dns_dn_expand(const unsigned char *rmsg, const unsigned char *eom, const unsigned char *src, char *dst, int dstsiz)
{
int n = mowgli_dns_ns_name_uncompress(rmsg, eom, src, dst, (size_t) dstsiz);
- if (n > 0 && dst[0] == '.')
+ if ((n > 0) && (dst[0] == '.'))
dst[0] = '\0';
+
return n;
}
-/*
+/*
* mowgli_dns_ns_name_uncompress(rmsg, eom, src, dst, dstsiz)
* Expand compressed domain name to presentation format.
* return:
@@ -139,20 +140,21 @@ mowgli_dns_dn_expand(const unsigned char *rmsg, const unsigned char *eom,
* Root domain returns as "." not "".
*/
static int
-mowgli_dns_ns_name_uncompress(const unsigned char *rmsg, const unsigned char *eom,
- const unsigned char *src, char *dst, size_t dstsiz)
+mowgli_dns_ns_name_uncompress(const unsigned char *rmsg, const unsigned char *eom, const unsigned char *src, char *dst, size_t dstsiz)
{
unsigned char tmp[MOWGLI_DNS_NS_MAXCDNAME];
int n;
if ((n = mowgli_dns_ns_name_unpack(rmsg, eom, src, tmp, sizeof tmp)) == -1)
return -1;
- if (mowgli_dns_ns_name_ntop((char *)tmp, dst, dstsiz) == -1)
+
+ if (mowgli_dns_ns_name_ntop((char *) tmp, dst, dstsiz) == -1)
return -1;
+
return n;
}
-/*
+/*
* mowgli_dns_ns_name_unpack(rmsg, eom, src, dst, dstsiz)
* Unpack a domain name from a message, source may be compressed.
* return:
@@ -170,11 +172,13 @@ mowgli_dns_ns_name_unpack(const unsigned char *rmsg, const unsigned char *eom, c
dstp = dst;
srcp = src;
dstlim = dst + dstsiz;
- if (srcp < rmsg || srcp >= eom)
+
+ if ((srcp < rmsg) || (srcp >= eom))
{
errno = EMSGSIZE;
return -1;
}
+
/* Fetch next label in domain name. */
while ((n = *srcp++) != 0)
{
@@ -183,17 +187,20 @@ mowgli_dns_ns_name_unpack(const unsigned char *rmsg, const unsigned char *eom, c
{
case 0:
case MOWGLI_DNS_NS_TYPE_ELT:
+
/* Limit checks. */
if ((l = labellen(srcp - 1)) < 0)
{
errno = EMSGSIZE;
return -1;
}
- if (dstp + l + 1 >= dstlim || srcp + l >= eom)
+
+ if ((dstp + l + 1 >= dstlim) || (srcp + l >= eom))
{
errno = EMSGSIZE;
return -1;
}
+
checked += l + 1;
*dstp++ = n;
memcpy(dstp, srcp, l);
@@ -202,21 +209,27 @@ mowgli_dns_ns_name_unpack(const unsigned char *rmsg, const unsigned char *eom, c
break;
case MOWGLI_DNS_NS_CMPRSFLAGS:
+
if (srcp >= eom)
{
errno = EMSGSIZE;
return -1;
}
+
if (len < 0)
len = srcp - src + 1;
+
srcp = rmsg + (((n & 0x3f) << 8) | (*srcp & 0xff));
- if (srcp < rmsg || srcp >= eom)
- { /* Out of range. */
+
+ if ((srcp < rmsg) || (srcp >= eom)) /* Out of range. */
+ {
errno = EMSGSIZE;
return -1;
}
+
checked += 2;
- /*
+
+ /*
* Check for loops in the compressed name;
* if we've looked at the whole message,
* there must be a loop.
@@ -226,20 +239,24 @@ mowgli_dns_ns_name_unpack(const unsigned char *rmsg, const unsigned char *eom, c
errno = EMSGSIZE;
return -1;
}
+
break;
default:
errno = EMSGSIZE;
- return -1; /* flag error */
+ return -1; /* flag error */
}
}
+
*dstp = '\0';
+
if (len < 0)
len = srcp - src;
+
return len;
}
-/*
+/*
* mowgli_dns_ns_name_ntop(src, dst, dstsiz)
* Convert an encoded domain name to mowgli_dns_is_printable ascii as per RFC1035.
* return:
@@ -248,7 +265,8 @@ mowgli_dns_ns_name_unpack(const unsigned char *rmsg, const unsigned char *eom, c
* The root is returned as "."
* All other domains are returned in non absolute form
*/
-static int mowgli_dns_ns_name_ntop(const char *src, char *dst, size_t dstsiz)
+static int
+mowgli_dns_ns_name_ntop(const char *src, char *dst, size_t dstsiz)
{
const char *cp;
char *dn, *eom;
@@ -268,6 +286,7 @@ static int mowgli_dns_ns_name_ntop(const char *src, char *dst, size_t dstsiz)
errno = EMSGSIZE;
return -1;
}
+
if (dn != dst)
{
if (dn >= eom)
@@ -275,18 +294,22 @@ static int mowgli_dns_ns_name_ntop(const char *src, char *dst, size_t dstsiz)
errno = EMSGSIZE;
return -1;
}
+
*dn++ = '.';
}
- if ((l = labellen((const unsigned char *)(cp - 1))) < 0)
+
+ if ((l = labellen((const unsigned char *) (cp - 1))) < 0)
{
errno = EMSGSIZE; /* XXX */
return -1;
}
+
if (dn + l >= eom)
{
errno = EMSGSIZE;
return -1;
}
+
if ((n & MOWGLI_DNS_NS_CMPRSFLAGS) == MOWGLI_DNS_NS_TYPE_ELT)
{
int m;
@@ -297,17 +320,21 @@ static int mowgli_dns_ns_name_ntop(const char *src, char *dst, size_t dstsiz)
errno = EINVAL;
return -1;
}
+
if ((m = mowgli_dns_decode_bitstring(&cp, dn, eom)) < 0)
{
errno = EMSGSIZE;
return -1;
}
+
dn += m;
continue;
}
- for ((void)NULL; l > 0; l--)
+
+ for ((void) NULL; l > 0; l--)
{
c = *cp++;
+
if (mowgli_dns_is_special(c))
{
if (dn + 1 >= eom)
@@ -315,8 +342,9 @@ static int mowgli_dns_ns_name_ntop(const char *src, char *dst, size_t dstsiz)
errno = EMSGSIZE;
return -1;
}
+
*dn++ = '\\';
- *dn++ = (char)c;
+ *dn++ = (char) c;
}
else if (!mowgli_dns_is_printable(c))
{
@@ -325,6 +353,7 @@ static int mowgli_dns_ns_name_ntop(const char *src, char *dst, size_t dstsiz)
errno = EMSGSIZE;
return -1;
}
+
*dn++ = '\\';
*dn++ = digits[c / 100];
*dn++ = digits[(c % 100) / 10];
@@ -337,10 +366,12 @@ static int mowgli_dns_ns_name_ntop(const char *src, char *dst, size_t dstsiz)
errno = EMSGSIZE;
return -1;
}
- *dn++ = (char)c;
+
+ *dn++ = (char) c;
}
}
}
+
if (dn == dst)
{
if (dn >= eom)
@@ -348,48 +379,53 @@ static int mowgli_dns_ns_name_ntop(const char *src, char *dst, size_t dstsiz)
errno = EMSGSIZE;
return -1;
}
+
*dn++ = '.';
}
+
if (dn >= eom)
{
errno = EMSGSIZE;
return -1;
}
+
*dn++ = '\0';
return dn - dst;
}
-/*
+/*
* Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
* Return the size of the compressed name or -1.
* 'length' is the size of the array pointed to by 'comp_dn'.
*/
static int
-mowgli_dns_dn_comp(const char *src, unsigned char *dst, int dstsiz,
- unsigned char **dnptrs, unsigned char **lastdnptr)
+mowgli_dns_dn_comp(const char *src, unsigned char *dst, int dstsiz, unsigned char **dnptrs, unsigned char **lastdnptr)
{
return mowgli_dns_ns_name_compress(src, dst, (size_t) dstsiz, dnptrs, lastdnptr);
}
-/*
+/*
* Skip over a compressed domain name. Return the size or -1.
*/
-int mowgli_dns_dn_skipname(const unsigned char *ptr, const unsigned char *eom)
+int
+mowgli_dns_dn_skipname(const unsigned char *ptr, const unsigned char *eom)
{
const unsigned char *saveptr = ptr;
if (mowgli_dns_ns_name_skip(&ptr, eom) == -1)
return -1;
+
return ptr - saveptr;
}
-/*
+/*
* ns_name_skip(ptrptr, eom)
* Advance *ptrptr to skip over the compressed name it points at.
* return:
* 0 on success, -1 (with errno set) on failure.
*/
-static int mowgli_dns_ns_name_skip(const unsigned char **ptrptr, const unsigned char *eom)
+static int
+mowgli_dns_ns_name_skip(const unsigned char **ptrptr, const unsigned char *eom)
{
const unsigned char *cp;
unsigned int n;
@@ -402,10 +438,11 @@ static int mowgli_dns_ns_name_skip(const unsigned char **ptrptr, const unsigned
/* Check for indirection. */
switch (n & MOWGLI_DNS_NS_CMPRSFLAGS)
{
- case 0: /* normal case, n == len */
+ case 0: /* normal case, n == len */
cp += n;
continue;
- case MOWGLI_DNS_NS_TYPE_ELT: /* EDNS0 extended label */
+ case MOWGLI_DNS_NS_TYPE_ELT: /* EDNS0 extended label */
+
if ((l = labellen(cp - 1)) < 0)
{
errno = EMSGSIZE; /* XXX */
@@ -414,10 +451,10 @@ static int mowgli_dns_ns_name_skip(const unsigned char **ptrptr, const unsigned
cp += l;
continue;
- case MOWGLI_DNS_NS_CMPRSFLAGS: /* indirection */
+ case MOWGLI_DNS_NS_CMPRSFLAGS: /* indirection */
cp++;
break;
- default: /* illegal type */
+ default:/* illegal type */
errno = EMSGSIZE;
return -1;
}
@@ -435,7 +472,8 @@ static int mowgli_dns_ns_name_skip(const unsigned char **ptrptr, const unsigned
return 0;
}
-unsigned int mowgli_dns_ns_get16(const unsigned char *src)
+unsigned int
+mowgli_dns_ns_get16(const unsigned char *src)
{
unsigned int dst;
@@ -443,7 +481,8 @@ unsigned int mowgli_dns_ns_get16(const unsigned char *src)
return dst;
}
-unsigned long mowgli_dns_ns_get32(const unsigned char *src)
+unsigned long
+mowgli_dns_ns_get32(const unsigned char *src)
{
unsigned long dst;
@@ -451,45 +490,49 @@ unsigned long mowgli_dns_ns_get32(const unsigned char *src)
return dst;
}
-void mowgli_dns_ns_put16(unsigned int src, unsigned char *dst)
+void
+mowgli_dns_ns_put16(unsigned int src, unsigned char *dst)
{
MOWGLI_DNS_NS_PUT16(src, dst);
}
-void mowgli_dns_ns_put32(unsigned long src, unsigned char *dst)
+void
+mowgli_dns_ns_put32(unsigned long src, unsigned char *dst)
{
MOWGLI_DNS_NS_PUT32(src, dst);
}
/* From ns_name.c */
-/*
+/*
* mowgli_dns_is_special(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this characted mowgli_dns_is_special ("in need of quoting") ?
* return:
* boolean.
*/
-static bool mowgli_dns_is_special(int ch)
+static bool
+mowgli_dns_is_special(int ch)
{
switch (ch)
{
- case 0x22: /* '"' */
- case 0x2E: /* '.' */
- case 0x3B: /* ';' */
- case 0x5C: /* '\\' */
- case 0x28: /* '(' */
- case 0x29: /* ')' */
- /* Special modifiers in zone files. */
- case 0x40: /* '@' */
- case 0x24: /* '$' */
+ case 0x22: /* '"' */
+ case 0x2E: /* '.' */
+ case 0x3B: /* ';' */
+ case 0x5C: /* '\\' */
+ case 0x28: /* '(' */
+ case 0x29: /* ')' */
+ /* Special modifiers in zone files. */
+ case 0x40: /* '@' */
+ case 0x24: /* '$' */
return true;
default:
return false;
}
}
-static int labellen(const unsigned char *lp)
+static int
+labellen(const unsigned char *lp)
{
int bitlen;
unsigned char l = *lp;
@@ -508,26 +551,27 @@ static int labellen(const unsigned char *lp)
return (bitlen + 7) / 8 + 1;
}
- return -1; /* unknwon ELT */
+ return -1; /* unknwon ELT */
}
return l;
}
-
-/*
+/*
* mowgli_dns_is_printable(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this character visible and not a space when printed ?
* return:
* boolean.
*/
-static bool mowgli_dns_is_printable(int ch)
+static bool
+mowgli_dns_is_printable(int ch)
{
return (ch > 0x20 && ch < 0x7f) ? true : false;
}
-static int mowgli_dns_decode_bitstring(const char **cpp, char *dn, const char *eom)
+static int
+mowgli_dns_decode_bitstring(const char **cpp, char *dn, const char *eom)
{
const char *cp = *cpp;
char *beg = dn, tc;
@@ -535,15 +579,19 @@ static int mowgli_dns_decode_bitstring(const char **cpp, char *dn, const char *e
if ((blen = (*cp & 0xff)) == 0)
blen = 256;
+
plen = (blen + 3) / 4;
plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
+
if (dn + plen >= eom)
return -1;
cp++;
dn += sprintf(dn, "\\[x");
+
for (b = blen; b > 7; b -= 8, cp++)
dn += sprintf(dn, "%02x", *cp & 0xff);
+
if (b > 4)
{
tc = *cp++;
@@ -554,13 +602,14 @@ static int mowgli_dns_decode_bitstring(const char **cpp, char *dn, const char *e
tc = *cp++;
dn += sprintf(dn, "%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b)));
}
+
dn += sprintf(dn, "/%d]", blen);
*cpp = cp;
- return (dn - beg);
+ return dn - beg;
}
-/*
+/*
* mowgli_dns_ns_name_pton(src, dst, dstsiz)
* Convert a ascii string into an encoded domain name as per RFC1035.
* return:
@@ -570,7 +619,8 @@ static int mowgli_dns_decode_bitstring(const char **cpp, char *dn, const char *e
* notes:
* Enforces label and domain length limits.
*/
-static int mowgli_dns_ns_name_pton(const char *src, unsigned char *dst, size_t dstsiz)
+static int
+mowgli_dns_ns_name_pton(const char *src, unsigned char *dst, size_t dstsiz)
{
unsigned char *label, *bp, *eom;
char *cp;
@@ -581,56 +631,68 @@ static int mowgli_dns_ns_name_pton(const char *src, unsigned char *dst, size_t d
eom = dst + dstsiz;
label = bp++;
-
while ((c = *src++) != 0)
{
if (escaped)
{
- if (c == '[')
- { /* start a bit string label */
+ if (c == '[') /* start a bit string label */
+ {
if ((cp = strchr(src, ']')) == NULL)
{
errno = EINVAL; /* ??? */
return -1;
}
- if ((e = mowgli_dns_encode_bitsring(&src, cp + 2, &label, &bp, (const char *)eom)) != 0)
+
+ if ((e = mowgli_dns_encode_bitsring(&src, cp + 2, &label, &bp, (const char *) eom)) != 0)
{
errno = e;
return -1;
}
+
escaped = 0;
label = bp++;
+
if ((c = *src++) == 0)
+ {
goto done;
+ }
else if (c != '.')
{
errno = EINVAL;
return -1;
}
+
continue;
}
else if ((cp = strchr(digits, c)) != NULL)
{
n = (cp - digits) * 100;
- if ((c = *src++) == 0 || (cp = strchr(digits, c)) == NULL)
+
+ if (((c = *src++) == 0) || ((cp = strchr(digits, c)) == NULL))
{
errno = EMSGSIZE;
return -1;
}
+
n += (cp - digits) * 10;
- if ((c = *src++) == 0 || (cp = strchr(digits, c)) == NULL)
+
+ if (((c = *src++) == 0) || ((cp = strchr(digits, c)) == NULL))
{
errno = EMSGSIZE;
return -1;
}
+
n += (cp - digits);
+
if (n > 255)
{
errno = EMSGSIZE;
return -1;
}
+
c = n;
}
+
escaped = 0;
}
else if (c == '\\')
@@ -641,17 +703,21 @@ static int mowgli_dns_ns_name_pton(const char *src, unsigned char *dst, size_t d
else if (c == '.')
{
c = (bp - label - 1);
- if ((c & MOWGLI_DNS_NS_CMPRSFLAGS) != 0)
- { /* Label too big. */
+
+ if ((c & MOWGLI_DNS_NS_CMPRSFLAGS) != 0)/* Label too big. */
+ {
errno = EMSGSIZE;
return -1;
}
+
if (label >= eom)
{
errno = EMSGSIZE;
return -1;
}
+
*label = c;
+
/* Fully qualified ? */
if (*src == '\0')
{
@@ -662,43 +728,56 @@ static int mowgli_dns_ns_name_pton(const char *src, unsigned char *dst, size_t d
errno = EMSGSIZE;
return -1;
}
+
*bp++ = '\0';
}
+
if ((bp - dst) > MOWGLI_DNS_NS_MAXCDNAME)
{
errno = EMSGSIZE;
return -1;
}
- return (1);
+
+ return 1;
}
- if (c == 0 || *src == '.')
+
+ if ((c == 0) || (*src == '.'))
{
errno = EMSGSIZE;
return -1;
}
+
label = bp++;
continue;
}
+
if (bp >= eom)
{
errno = EMSGSIZE;
return -1;
}
- *bp++ = (unsigned char)c;
+
+ *bp++ = (unsigned char) c;
}
+
c = (bp - label - 1);
- if ((c & MOWGLI_DNS_NS_CMPRSFLAGS) != 0)
- { /* Label too big. */
+
+ if ((c & MOWGLI_DNS_NS_CMPRSFLAGS) != 0)/* Label too big. */
+ {
errno = EMSGSIZE;
return -1;
}
- done:
+
+done:
+
if (label >= eom)
{
errno = EMSGSIZE;
return -1;
}
+
*label = c;
+
if (c != 0)
{
if (bp >= eom)
@@ -706,11 +785,12 @@ static int mowgli_dns_ns_name_pton(const char *src, unsigned char *dst, size_t d
errno = EMSGSIZE;
return -1;
}
+
*bp++ = 0;
}
- if ((bp - dst) > MOWGLI_DNS_NS_MAXCDNAME)
- { /* src too big */
+ if ((bp - dst) > MOWGLI_DNS_NS_MAXCDNAME) /* src too big */
+ {
errno = EMSGSIZE;
return -1;
}
@@ -718,7 +798,7 @@ static int mowgli_dns_ns_name_pton(const char *src, unsigned char *dst, size_t d
return 0;
}
-/*
+/*
* mowgli_dns_ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
* Pack domain name 'domain' into 'comp_dn'.
* return:
@@ -736,8 +816,7 @@ static int mowgli_dns_ns_name_pton(const char *src, unsigned char *dst, size_t d
* list.
*/
static int
-mowgli_dns_ns_name_pack(const unsigned char *src, unsigned char *dst, int dstsiz,
- unsigned char **dnptrs, unsigned char **lastdnptr)
+mowgli_dns_ns_name_pack(const unsigned char *src, unsigned char *dst, int dstsiz, unsigned char **dnptrs, unsigned char **lastdnptr)
{
unsigned char *dstp;
unsigned char **cpp, **lpp;
@@ -749,115 +828,128 @@ mowgli_dns_ns_name_pack(const unsigned char *src, unsigned char *dst, int dstsiz
dstp = dst;
eob = dstp + dstsiz;
lpp = cpp = NULL;
+
if (dnptrs != NULL)
{
if ((rmsg = *dnptrs++) != NULL)
{
for (cpp = dnptrs; *cpp != NULL; cpp++)
- (void)NULL;
- lpp = cpp; /* end of list to search */
+ (void) NULL;
+
+ lpp = cpp; /* end of list to search */
}
}
else
+ {
rmsg = NULL;
+ }
/* make sure the domain we are about to add is legal */
l = 0;
+
do
{
int l0;
n = *srcp;
+
if ((n & MOWGLI_DNS_NS_CMPRSFLAGS) == MOWGLI_DNS_NS_CMPRSFLAGS)
{
errno = EMSGSIZE;
return -1;
}
+
if ((l0 = labellen(srcp)) < 0)
{
errno = EINVAL;
return -1;
}
+
l += l0 + 1;
+
if (l > MOWGLI_DNS_NS_MAXCDNAME)
{
errno = EMSGSIZE;
return -1;
}
+
srcp += l0 + 1;
- }
- while (n != 0);
+ } while (n != 0);
/* from here on we need to reset compression pointer array on error */
srcp = src;
+
do
{
/* Look to see if we can use pointers. */
n = *srcp;
- if (n != 0 && rmsg != NULL)
+
+ if ((n != 0) && (rmsg != NULL))
{
- l = mowgli_dns_dn_find(srcp, rmsg, (const unsigned char *const *)dnptrs,
- (const unsigned char *const *)lpp);
+ l = mowgli_dns_dn_find(srcp, rmsg, (const unsigned char *const *) dnptrs,
+ (const unsigned char *const *) lpp);
+
if (l >= 0)
{
if (dstp + 1 >= eob)
- {
goto cleanup;
- }
+
*dstp++ = (l >> 8) | MOWGLI_DNS_NS_CMPRSFLAGS;
*dstp++ = l % 256;
- return (dstp - dst);
+ return dstp - dst;
}
+
/* Not found, save it. */
- if (lastdnptr != NULL && cpp < lastdnptr - 1 && (dstp - rmsg) < 0x4000 && first)
+ if ((lastdnptr != NULL) && (cpp < lastdnptr - 1) && ((dstp - rmsg) < 0x4000) && first)
{
*cpp++ = dstp;
*cpp = NULL;
first = 0;
}
}
+
/* copy label to buffer */
if ((n & MOWGLI_DNS_NS_CMPRSFLAGS) == MOWGLI_DNS_NS_CMPRSFLAGS)
- {
/* Should not happen. */
goto cleanup;
- }
+
n = labellen(srcp);
+
if (dstp + 1 + n >= eob)
- {
goto cleanup;
- }
+
memcpy(dstp, srcp, n + 1);
srcp += n + 1;
dstp += n + 1;
- }
- while (n != 0);
+ } while (n != 0);
if (dstp > eob)
{
- cleanup:
+cleanup:
+
if (rmsg != NULL)
*lpp = NULL;
+
errno = EMSGSIZE;
return -1;
}
- return (dstp - dst);
+
+ return dstp - dst;
}
static int
-mowgli_dns_ns_name_compress(const char *src, unsigned char *dst, size_t dstsiz,
- unsigned char **dnptrs, unsigned char **lastdnptr)
+mowgli_dns_ns_name_compress(const char *src, unsigned char *dst, size_t dstsiz, unsigned char **dnptrs, unsigned char **lastdnptr)
{
unsigned char tmp[MOWGLI_DNS_NS_MAXCDNAME];
if (mowgli_dns_ns_name_pton(src, tmp, sizeof tmp) == -1)
return -1;
- return (mowgli_dns_ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
+
+ return mowgli_dns_ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr);
}
static int
-mowgli_dns_encode_bitsring(const char **bp, const char *end, unsigned char **labelp,
- unsigned char **dst, const char *eom)
+mowgli_dns_encode_bitsring(const char **bp, const char *end, unsigned char **labelp, unsigned char **dst, const char *eom)
{
int afterslash = 0;
const char *cp = *bp;
@@ -875,42 +967,48 @@ mowgli_dns_encode_bitsring(const char **bp, const char *end, unsigned char **lab
/* XXX: currently, only hex strings are supported */
if (*cp++ != 'x')
return EINVAL;
+
if (!isxdigit((*cp) & 0xff)) /* reject '\[x/BLEN]' */
return EINVAL;
- for (tp = (char *)(dst + 1); cp < end && tp < eom; cp++)
+ for (tp = (char *) (dst + 1); cp < end && tp < eom; cp++)
{
switch ((c = *cp))
{
- case ']': /* end of the bitstring */
+ case ']': /* end of the bitstring */
+
if (afterslash)
{
if (beg_blen == NULL)
return EINVAL;
- blen = (int)strtol(beg_blen, &end_blen, 10);
+
+ blen = (int) strtol(beg_blen, &end_blen, 10);
+
if (*end_blen != ']')
return EINVAL;
}
+
if (count)
*tp++ = ((value << 4) & 0xff);
- cp++; /* skip ']' */
+
+ cp++; /* skip ']' */
goto done;
case '/':
afterslash = 1;
break;
default:
+
if (afterslash)
{
if (!isdigit(c & 0xff))
return EINVAL;
+
if (beg_blen == NULL)
{
-
if (c == '0')
- {
/* blen never begings with 0 */
return EINVAL;
- }
+
beg_blen = cp;
}
}
@@ -918,26 +1016,32 @@ mowgli_dns_encode_bitsring(const char **bp, const char *end, unsigned char **lab
{
if (!isxdigit(c & 0xff))
return EINVAL;
+
value <<= 4;
- value += digitvalue[(int)c];
+ value += digitvalue[(int) c];
count += 4;
tbcount += 4;
+
if (tbcount > 256)
return EINVAL;
+
if (count == 8)
{
*tp++ = value;
count = 0;
}
}
+
break;
}
}
- done:
- if (cp >= end || tp >= eom)
- return (EMSGSIZE);
- /*
+done:
+
+ if ((cp >= end) || (tp >= eom))
+ return EMSGSIZE;
+
+ /*
* bit length validation:
* If a <length> is present, the number of digits in the <bit-data>
* MUST be just sufficient to contain the number of bits specified
@@ -951,12 +1055,17 @@ mowgli_dns_encode_bitsring(const char **bp, const char *end, unsigned char **lab
if (((blen + 3) & ~3) != tbcount)
return EINVAL;
+
traillen = tbcount - blen; /* between 0 and 3 */
+
if (((value << (8 - traillen)) & 0xff) != 0)
return EINVAL;
}
else
+ {
blen = tbcount;
+ }
+
if (blen == 256)
blen = 0;
@@ -965,12 +1074,12 @@ mowgli_dns_encode_bitsring(const char **bp, const char *end, unsigned char **lab
**dst = blen;
*bp = cp;
- *dst = (unsigned char *)tp;
+ *dst = (unsigned char *) tp;
return 0;
}
-/*
+/*
* dn_find(domain, rmsg, dnptrs, lastdnptr)
* Search for the counted-label name in an array of compressed names.
* return:
@@ -980,8 +1089,7 @@ mowgli_dns_encode_bitsring(const char **bp, const char *end, unsigned char **lab
* not the pointer to the start of the message.
*/
static int
-mowgli_dns_dn_find(const unsigned char *domain, const unsigned char *rmsg,
- const unsigned char *const *dnptrs, const unsigned char *const *lastdnptr)
+mowgli_dns_dn_find(const unsigned char *domain, const unsigned char *rmsg, const unsigned char *const *dnptrs, const unsigned char *const *lastdnptr)
{
const unsigned char *dn, *cp, *sp;
const unsigned char *const *cpp;
@@ -990,7 +1098,8 @@ mowgli_dns_dn_find(const unsigned char *domain, const unsigned char *rmsg,
for (cpp = dnptrs; cpp < lastdnptr; cpp++)
{
sp = *cpp;
- /*
+
+ /*
* terminate search on:
* root label
* compression pointer
@@ -1000,53 +1109,59 @@ mowgli_dns_dn_find(const unsigned char *domain, const unsigned char *rmsg,
{
dn = domain;
cp = sp;
+
while ((n = *cp++) != 0)
{
- /*
+ /*
* check for indirection
*/
switch (n & MOWGLI_DNS_NS_CMPRSFLAGS)
{
- case 0: /* normal case, n == len */
+ case 0: /* normal case, n == len */
n = labellen(cp - 1); /* XXX */
if (n != *dn++)
goto next;
- for ( ; n > 0; n--)
+ for (; n > 0; n--)
if (mowgli_dns_mklower(*dn++) != mowgli_dns_mklower(*cp++))
goto next;
-
+
/* Is next root for both ? */
- if (*dn == '\0' && *cp == '\0')
+ if ((*dn == '\0') && (*cp == '\0'))
return sp - rmsg;
+
if (*dn)
continue;
+
goto next;
case MOWGLI_DNS_NS_CMPRSFLAGS: /* indirection */
cp = rmsg + (((n & 0x3f) << 8) | *cp);
break;
- default: /* illegal type */
+ default:/* illegal type */
errno = EMSGSIZE;
return -1;
}
}
- next:;
+
+next:;
sp += *sp + 1;
}
}
+
errno = ENOENT;
return -1;
}
-/*
+/*
* Thinking in noninternationalized USASCII (per the DNS spec),
* convert this character to lower case if it's upper case.
*/
-static int mowgli_dns_mklower(int ch)
+static int
+mowgli_dns_mklower(int ch)
{
- if (ch >= 0x41 && ch <= 0x5A)
+ if ((ch >= 0x41) && (ch <= 0x5A))
return ch + 0x20;
return ch;
@@ -1054,31 +1169,33 @@ static int mowgli_dns_mklower(int ch)
/* From resolv/mkquery.c */
-/*
+/*
* Form all types of queries.
* Returns the size of the result or -1.
*/
-int mowgli_dns_res_mkquery(const char *dname, /* domain name */
- int query_class, int type, /* class and type of query */
- unsigned char *buf, /* buffer to put query */
- int buflen) /* size of buffer */
+int
+mowgli_dns_res_mkquery(const char *dname, /* domain name */
+ int query_class, int type, /* class and type of query */
+ unsigned char *buf, /* buffer to put query */
+ int buflen) /* size of buffer */
{
mowgli_dns_resheader_t *hp;
unsigned char *cp;
int n;
unsigned char *dnptrs[20], **dpp, **lastdnptr;
- /*
+ /*
* Initialize header fields.
*/
if ((buf == NULL) || (buflen < MOWGLI_DNS_HFIXEDSIZE))
return -1;
+
memset(buf, 0, MOWGLI_DNS_HFIXEDSIZE);
hp = (mowgli_dns_resheader_t *) buf;
hp->id = 0;
hp->opcode = MOWGLI_DNS_QUERY;
- hp->rd = 1; /* recurse */
+ hp->rd = 1; /* recurse */
hp->rcode = MOWGLI_DNS_NO_ERRORS;
cp = buf + MOWGLI_DNS_HFIXEDSIZE;
buflen -= MOWGLI_DNS_HFIXEDSIZE;
@@ -1089,6 +1206,7 @@ int mowgli_dns_res_mkquery(const char *dname, /* domain name */
if ((buflen -= MOWGLI_DNS_QFIXEDSIZE) < 0)
return -1;
+
if ((n = mowgli_dns_dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
return -1;
diff --git a/src/libmowgli/dns/evloop_reslib.h b/src/libmowgli/dns/evloop_reslib.h
new file mode 100644
index 0000000..0555eab
--- /dev/null
+++ b/src/libmowgli/dns/evloop_reslib.h
@@ -0,0 +1,115 @@
+/*
+ * dns/reslib.h
+ *
+ * $Id: reslib.h 446 2006-02-12 02:46:54Z db $
+ */
+
+#ifndef __MOWGLI_DNS_RESLIB_H__
+#define __MOWGLI_DNS_RESLIB_H__
+
+/* Here we define some values lifted from nameser.h */
+#define MOWGLI_DNS_NS_NOTIFY_OP 4
+#define MOWGLI_DNS_NS_INT16SIZE 2
+#define MOWGLI_DNS_NS_IN6ADDRSIZE 16
+#define MOWGLI_DNS_NS_INADDRSIZE 4
+#define MOWGLI_DNS_NS_INT32SIZE 4
+#define MOWGLI_DNS_NS_CMPRSFLAGS 0xc0
+#define MOWGLI_DNS_NS_MAXCDNAME 255
+#define MOWGLI_DNS_QUERY 0
+#define MOWGLI_DNS_IQUERY 1
+#define MOWGLI_DNS_NO_ERRORS 0
+#define MOWGLI_DNS_SERVFAIL 2
+#define MOWGLI_DNS_NXDOMAIN 3
+#define MOWGLI_DNS_C_IN 1
+#define MOWGLI_DNS_QFIXEDSIZE 4
+#define MOWGLI_DNS_RRFIXEDSIZE 10
+#define MOWGLI_DNS_HFIXEDSIZE 12
+
+typedef struct
+{
+ unsigned id : 16; /* query identification number */
+#ifdef WORDS_BIGENDIAN
+
+ /* fields in third byte */
+ unsigned qr : 1;/* response flag */
+ unsigned opcode : 4; /* purpose of message */
+ unsigned aa : 1;/* authoritive answer */
+ unsigned tc : 1;/* truncated message */
+ unsigned rd : 1;/* recursion desired */
+ /* fields in fourth byte */
+ unsigned ra : 1;/* recursion available */
+ unsigned unused : 1; /* unused bits (MBZ as of 4.9.3a3) */
+ unsigned ad : 1;/* authentic data from named */
+ unsigned cd : 1;/* checking disabled by resolver */
+ unsigned rcode : 4; /* response code */
+#else
+
+ /* fields in third byte */
+ unsigned rd : 1;/* recursion desired */
+ unsigned tc : 1;/* truncated message */
+ unsigned aa : 1;/* authoritive answer */
+ unsigned opcode : 4; /* purpose of message */
+ unsigned qr : 1;/* response flag */
+ /* fields in fourth byte */
+ unsigned rcode : 4; /* response code */
+ unsigned cd : 1;/* checking disabled by resolver */
+ unsigned ad : 1;/* authentic data from named */
+ unsigned unused : 1; /* unused bits (MBZ as of 4.9.3a3) */
+ unsigned ra : 1;/* recursion available */
+#endif
+
+ /* remaining bytes */
+ unsigned qdcount : 16; /* number of question entries */
+ unsigned ancount : 16; /* number of answer entries */
+ unsigned nscount : 16; /* number of authority entries */
+ unsigned arcount : 16; /* number of resource entries */
+} mowgli_dns_resheader_t;
+
+/*
+ * Inline versions of get/put short/long. Pointer is advanced.
+ */
+#define MOWGLI_DNS_NS_GET16(s, cp) { \
+ const unsigned char *t_cp = (const unsigned char *) (cp); \
+ (s) = ((uint16_t) t_cp[0] << 8) \
+ | ((uint16_t) t_cp[1]) \
+ ; \
+ (cp) += MOWGLI_DNS_NS_INT16SIZE; \
+}
+
+#define MOWGLI_DNS_NS_GET32(l, cp) { \
+ const unsigned char *t_cp = (const unsigned char *) (cp); \
+ (l) = ((uint32_t) t_cp[0] << 24) \
+ | ((uint32_t) t_cp[1] << 16) \
+ | ((uint32_t) t_cp[2] << 8) \
+ | ((uint32_t) t_cp[3]) \
+ ; \
+ (cp) += MOWGLI_DNS_NS_INT32SIZE; \
+}
+
+#define MOWGLI_DNS_NS_PUT16(s, cp) { \
+ uint16_t t_s = (uint16_t) (s); \
+ unsigned char *t_cp = (unsigned char *) (cp); \
+ *t_cp++ = t_s >> 8; \
+ *t_cp = t_s; \
+ (cp) += MOWGLI_DNS_NS_INT16SIZE; \
+}
+
+#define MOWGLI_DNS_NS_PUT32(l, cp) { \
+ uint32_t t_l = (uint32_t) (l); \
+ unsigned char *t_cp = (unsigned char *) (cp); \
+ *t_cp++ = t_l >> 24; \
+ *t_cp++ = t_l >> 16; \
+ *t_cp++ = t_l >> 8; \
+ *t_cp = t_l; \
+ (cp) += MOWGLI_DNS_NS_INT32SIZE; \
+}
+
+extern int mowgli_dns_dn_expand(const unsigned char *msg, const unsigned char *eom, const unsigned char *src, char *dst, int dstsiz);
+extern int mowgli_dns_dn_skipname(const unsigned char *ptr, const unsigned char *eom);
+extern unsigned int mowgli_dns_ns_get16(const unsigned char *src);
+extern unsigned long mowgli_dns_ns_get32(const unsigned char *src);
+extern void mowgli_dns_ns_put16(unsigned int src, unsigned char *dst);
+extern void mowgli_dns_ns_put32(unsigned long src, unsigned char *dst);
+extern int mowgli_dns_res_mkquery(const char *dname, int query_class, int type, unsigned char *buf, int buflen);
+
+#endif
diff --git a/src/libmowgli/dns/dns_evloop_reslist_win32.c b/src/libmowgli/dns/evloop_reslist_win32.c
index eb45ce8..afce82c 100644
--- a/src/libmowgli/dns/dns_evloop_reslist_win32.c
+++ b/src/libmowgli/dns/evloop_reslist_win32.c
@@ -1,6 +1,6 @@
/*
* reslist.c - get nameservers from windows *
- *
+ *
* Copyright 1998 by the Massachusetts Institute of Technology.
* Copyright (C) 2007-2008 by Daniel Stenberg
*
@@ -17,17 +17,19 @@
* without express or implied warranty.
*/
-#ifdef _WIN32
#include "mowgli.h"
-#include <windows.h>
-#include <iphlpapi.h>
+
+#ifdef MOWGLI_OS_WIN
+# include <windows.h>
+# include <iphlpapi.h>
int
mowgli_dns_get_windows_nameservers(char *ret_buf, size_t ret_size)
{
FIXED_INFO *fixedinfo, tfixedinfo;
DWORD size = sizeof(*fixedinfo);
- typedef DWORD(WINAPI * get_net_param_func) (FIXED_INFO *, DWORD *);
+
+ typedef DWORD (WINAPI * get_net_param_func)(FIXED_INFO *, DWORD *);
get_net_param_func get_network_params;
HMODULE handle;
IP_ADDR_STRING *ip_addr;
@@ -40,58 +42,61 @@ mowgli_dns_get_windows_nameservers(char *ret_buf, size_t ret_size)
if (!(handle = LoadLibrary("iphlpapi.dll")))
return 0;
- if (!(get_network_params = (get_net_param_func)GetProcAddress(handle, "GetNetworkParams")))
+ if (!(get_network_params = (get_net_param_func) GetProcAddress(handle, "GetNetworkParams")))
goto quit;
res = (*get_network_params)(&tfixedinfo, &size);
- if((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
+
+ if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
goto quit;
fixedinfo = mowgli_alloc(size);
- if(!fixedinfo || (*get_network_params)(fixedinfo, &size) != ERROR_SUCCESS)
+
+ if (!fixedinfo || ((*get_network_params)(fixedinfo, &size) != ERROR_SUCCESS))
goto quit;
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("Host Name: %s\n", fixedinfo->HostName);
mowgli_log("Domain Name: %s\n", fixedinfo->DomainName);
mowgli_log("DNS Servers:\n\t%s (primary)\n", fixedinfo->DnsServerList.IpAddress.String);
-#endif
+# endif
- if(strlen(fixedinfo->DnsServerList.IpAddress.String) > 0 &&
- inet_addr(fixedinfo->DnsServerList.IpAddress.String) != INADDR_NONE && left > ip_size)
+ if ((strlen(fixedinfo->DnsServerList.IpAddress.String) > 0) &&
+ (inet_addr(fixedinfo->DnsServerList.IpAddress.String) != INADDR_NONE) && (left > ip_size))
{
ret += sprintf(ret, "%s,", fixedinfo->DnsServerList.IpAddress.String);
left -= ret - ret_buf;
count++;
}
- for(i = 0, ip_addr = fixedinfo->DnsServerList.Next; ip_addr && left > ip_size; ip_addr = ip_addr->Next, i++)
+ for (i = 0, ip_addr = fixedinfo->DnsServerList.Next; ip_addr && left > ip_size; ip_addr = ip_addr->Next, i++)
{
- if(inet_addr(ip_addr->IpAddress.String) != INADDR_NONE)
+ if (inet_addr(ip_addr->IpAddress.String) != INADDR_NONE)
{
ret += sprintf(ret, "%s,", ip_addr->IpAddress.String);
left -= ret - ret_buf;
count++;
}
-#ifdef DEBUG
+
+# ifdef DEBUG
mowgli_log("\t%s (secondary %d)\n", ip_addr->IpAddress.String, i + 1);
-#endif
+# endif
}
mowgli_free(fixedinfo);
quit:
- if(handle)
+
+ if (handle)
FreeLibrary(handle);
- if(left <= ip_size)
+ if (left <= ip_size)
mowgli_log("Too many nameservers. Truncating to %d addressess", count);
- if(ret > ret_buf)
+ if (ret > ret_buf)
ret[-1] = '\0';
return count;
}
#endif
-
diff --git a/src/libmowgli/eventloop/epoll_pollops.c b/src/libmowgli/eventloop/epoll_pollops.c
index 596b992..a77c882 100644
--- a/src/libmowgli/eventloop/epoll_pollops.c
+++ b/src/libmowgli/eventloop/epoll_pollops.c
@@ -22,15 +22,17 @@
#ifdef HAVE_SYS_EPOLL_H
-#include <sys/epoll.h>
+# include <sys/epoll.h>
-typedef struct {
+typedef struct
+{
int epoll_fd;
int pfd_size;
struct epoll_event *pfd;
} mowgli_epoll_eventloop_private_t;
-static void mowgli_epoll_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
+static void
+mowgli_epoll_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
{
mowgli_epoll_eventloop_private_t *priv;
@@ -38,13 +40,14 @@ static void mowgli_epoll_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
eventloop->poller = priv;
priv->pfd_size = getdtablesize();
- priv->epoll_fd = epoll_create(priv->pfd_size);
+ priv->epoll_fd = epoll_create1(EPOLL_CLOEXEC); /* Linux 2.6.27+ */
priv->pfd = mowgli_alloc(sizeof(struct epoll_event) * priv->pfd_size);
return;
}
-static void mowgli_epoll_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
+static void
+mowgli_epoll_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
{
mowgli_epoll_eventloop_private_t *priv;
@@ -59,7 +62,8 @@ static void mowgli_epoll_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
return;
}
-static void mowgli_epoll_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
+static void
+mowgli_epoll_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
{
mowgli_epoll_eventloop_private_t *priv;
struct epoll_event ep_event;
@@ -82,10 +86,12 @@ static void mowgli_epoll_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli
}
}
-static void mowgli_epoll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
+static void
+mowgli_epoll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
{
mowgli_epoll_eventloop_private_t *priv;
struct epoll_event ep_event;
+
int op = -1;
unsigned int old_flags;
@@ -95,9 +101,9 @@ static void mowgli_epoll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowg
priv = eventloop->poller;
old_flags = pollable->slot;
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("setselect %p fd %d func %p", pollable, pollable->fd, event_function);
-#endif
+# endif
switch (dir)
{
@@ -114,9 +120,9 @@ static void mowgli_epoll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowg
break;
}
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("%p -> read %p : write %p", pollable, pollable->read_function, pollable->write_function);
-#endif
+# endif
if (pollable->read_function == NULL)
pollable->slot &= ~EPOLLIN;
@@ -124,11 +130,11 @@ static void mowgli_epoll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowg
if (pollable->write_function == NULL)
pollable->slot &= ~EPOLLOUT;
- if (old_flags == 0 && pollable->slot == 0)
+ if ((old_flags == 0) && (pollable->slot == 0))
return;
else if (pollable->slot <= 0)
op = EPOLL_CTL_DEL;
- else if (old_flags == 0 && pollable->slot != 0)
+ else if ((old_flags == 0) && (pollable->slot != 0))
op = EPOLL_CTL_ADD;
else if (pollable->slot != old_flags)
op = EPOLL_CTL_MOD;
@@ -150,7 +156,8 @@ static void mowgli_epoll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowg
return;
}
-static void mowgli_epoll_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
+static void
+mowgli_epoll_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
{
mowgli_epoll_eventloop_private_t *priv;
int i, num, o_errno;
@@ -177,15 +184,16 @@ static void mowgli_epoll_eventloop_select(mowgli_eventloop_t *eventloop, int del
{
mowgli_eventloop_pollable_t *pollable = priv->pfd[i].data.ptr;
- if (priv->pfd[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR) && pollable->read_function != NULL)
- pollable->read_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ, pollable->userdata);
+ if (priv->pfd[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR))
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ);
- if (priv->pfd[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR) && pollable->write_function != NULL)
- pollable->write_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE, pollable->userdata);
+ if (priv->pfd[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR))
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE);
}
}
-mowgli_eventloop_ops_t _mowgli_epoll_pollops = {
+mowgli_eventloop_ops_t _mowgli_epoll_pollops =
+{
.timeout_once = mowgli_simple_eventloop_timeout_once,
.run_once = mowgli_simple_eventloop_run_once,
.pollsetup = mowgli_epoll_eventloop_pollsetup,
diff --git a/src/libmowgli/eventloop/eventloop.c b/src/libmowgli/eventloop/eventloop.c
index d2045cd..d8eb422 100644
--- a/src/libmowgli/eventloop/eventloop.c
+++ b/src/libmowgli/eventloop/eventloop.c
@@ -46,7 +46,8 @@ extern mowgli_eventloop_ops_t _mowgli_kqueue_pollops;
extern mowgli_eventloop_ops_t _mowgli_winsock_pollops;
#endif
-mowgli_eventloop_t *mowgli_eventloop_create(void)
+mowgli_eventloop_t *
+mowgli_eventloop_create(void)
{
mowgli_eventloop_t *eventloop;
@@ -81,18 +82,21 @@ mowgli_eventloop_t *mowgli_eventloop_create(void)
if (mowgli_mutex_init(&eventloop->mutex) != 0)
{
- mowgli_log("couldn't create mutex for eventloop %p, aborting...", eventloop);
+ mowgli_log("couldn't create mutex for eventloop %p, aborting...", (void *) eventloop);
abort();
}
eventloop->eventloop_ops->pollsetup(eventloop);
- mowgli_eventloop_synchronize(eventloop);
+ eventloop->deadline = -1;
+
+ mowgli_eventloop_calibrate(eventloop);
return eventloop;
}
-void mowgli_eventloop_destroy(mowgli_eventloop_t *eventloop)
+void
+mowgli_eventloop_destroy(mowgli_eventloop_t *eventloop)
{
eventloop->eventloop_ops->pollshutdown(eventloop);
@@ -100,7 +104,8 @@ void mowgli_eventloop_destroy(mowgli_eventloop_t *eventloop)
mowgli_heap_free(eventloop_heap, eventloop);
}
-void mowgli_eventloop_run(mowgli_eventloop_t *eventloop)
+void
+mowgli_eventloop_run(mowgli_eventloop_t *eventloop)
{
return_if_fail(eventloop != NULL);
@@ -109,12 +114,15 @@ void mowgli_eventloop_run(mowgli_eventloop_t *eventloop)
eventloop->death_requested = false;
while (!eventloop->death_requested)
+ {
eventloop->eventloop_ops->run_once(eventloop);
+ }
mowgli_mutex_unlock(&eventloop->mutex);
}
-void mowgli_eventloop_run_once(mowgli_eventloop_t *eventloop)
+void
+mowgli_eventloop_run_once(mowgli_eventloop_t *eventloop)
{
return_if_fail(eventloop != NULL);
@@ -125,7 +133,8 @@ void mowgli_eventloop_run_once(mowgli_eventloop_t *eventloop)
mowgli_mutex_unlock(&eventloop->mutex);
}
-void mowgli_eventloop_timeout_once(mowgli_eventloop_t *eventloop, int timeout)
+void
+mowgli_eventloop_timeout_once(mowgli_eventloop_t *eventloop, int timeout)
{
return_if_fail(eventloop != NULL);
@@ -139,7 +148,8 @@ void mowgli_eventloop_timeout_once(mowgli_eventloop_t *eventloop, int timeout)
mowgli_mutex_unlock(&eventloop->mutex);
}
-void mowgli_eventloop_break(mowgli_eventloop_t *eventloop)
+void
+mowgli_eventloop_break(mowgli_eventloop_t *eventloop)
{
return_if_fail(eventloop != NULL);
@@ -147,7 +157,8 @@ void mowgli_eventloop_break(mowgli_eventloop_t *eventloop)
}
/* convenience function to request null pollops */
-void mowgli_eventloop_timers_only(mowgli_eventloop_t *eventloop)
+void
+mowgli_eventloop_timers_only(mowgli_eventloop_t *eventloop)
{
return_if_fail(eventloop != NULL);
@@ -155,14 +166,16 @@ void mowgli_eventloop_timers_only(mowgli_eventloop_t *eventloop)
}
/* userdata setting/getting functions (for bindings) */
-void *mowgli_eventloop_get_data(mowgli_eventloop_t *eventloop)
+void *
+mowgli_eventloop_get_data(mowgli_eventloop_t *eventloop)
{
return_val_if_fail(eventloop != NULL, NULL);
return eventloop->data;
}
-void mowgli_eventloop_set_data(mowgli_eventloop_t *eventloop, void *data)
+void
+mowgli_eventloop_set_data(mowgli_eventloop_t *eventloop, void *data)
{
return_if_fail(eventloop != NULL);
diff --git a/src/libmowgli/eventloop/eventloop.h b/src/libmowgli/eventloop/eventloop.h
index 4c07b27..42a257c 100644
--- a/src/libmowgli/eventloop/eventloop.h
+++ b/src/libmowgli/eventloop/eventloop.h
@@ -21,6 +21,13 @@
#ifndef __MOWGLI_EVENTLOOP_EVENTLOOP_H__
#define __MOWGLI_EVENTLOOP_EVENTLOOP_H__
+#ifdef MOWGLI_OS_OSX
+
+# include <mach/mach.h>
+# include <mach/mach_time.h>
+
+#endif
+
#ifndef _WIN32
typedef int mowgli_descriptor_t;
@@ -31,13 +38,15 @@ typedef SOCKET mowgli_descriptor_t;
#endif
-typedef enum {
+typedef enum
+{
MOWGLI_EVENTLOOP_TYPE_POLLABLE,
MOWGLI_EVENTLOOP_TYPE_HELPER,
MOWGLI_EVENTLOOP_TYPE_ERROR = -1
} mowgli_eventloop_io_type_t;
-typedef struct {
+typedef struct
+{
mowgli_eventloop_io_type_t type;
} mowgli_eventloop_io_obj_t;
@@ -48,7 +57,8 @@ typedef struct _mowgli_helper mowgli_eventloop_helper_proc_t;
typedef struct _mowgli_linebuf mowgli_linebuf_t;
-typedef enum {
+typedef enum
+{
MOWGLI_EVENTLOOP_IO_READ,
MOWGLI_EVENTLOOP_IO_WRITE,
MOWGLI_EVENTLOOP_IO_ERROR = -1
@@ -57,7 +67,8 @@ typedef enum {
typedef void mowgli_eventloop_io_t;
/* checked casts */
-static inline mowgli_eventloop_pollable_t *mowgli_eventloop_io_pollable(mowgli_eventloop_io_t *io)
+static inline mowgli_eventloop_pollable_t *
+mowgli_eventloop_io_pollable(mowgli_eventloop_io_t *io)
{
mowgli_eventloop_io_obj_t *obj = (mowgli_eventloop_io_obj_t *) io;
@@ -67,7 +78,8 @@ static inline mowgli_eventloop_pollable_t *mowgli_eventloop_io_pollable(mowgli_e
return (mowgli_eventloop_pollable_t *) io;
}
-static inline mowgli_eventloop_helper_proc_t *mowgli_eventloop_io_helper(mowgli_eventloop_io_t *io)
+static inline mowgli_eventloop_helper_proc_t *
+mowgli_eventloop_io_helper(mowgli_eventloop_io_t *io)
{
mowgli_eventloop_io_obj_t *obj = (mowgli_eventloop_io_obj_t *) io;
@@ -77,7 +89,8 @@ static inline mowgli_eventloop_helper_proc_t *mowgli_eventloop_io_helper(mowgli_
return (mowgli_eventloop_helper_proc_t *) io;
}
-static inline mowgli_eventloop_io_type_t mowgli_eventloop_io_type(mowgli_eventloop_io_t *io)
+static inline mowgli_eventloop_io_type_t
+mowgli_eventloop_io_type(mowgli_eventloop_io_t *io)
{
mowgli_eventloop_io_obj_t *obj = (mowgli_eventloop_io_obj_t *) io;
@@ -86,9 +99,10 @@ static inline mowgli_eventloop_io_type_t mowgli_eventloop_io_type(mowgli_eventlo
return obj->type;
}
-typedef void mowgli_eventloop_io_cb_t(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata);
+typedef void mowgli_eventloop_io_cb_t (mowgli_eventloop_t * eventloop, mowgli_eventloop_io_t * io, mowgli_eventloop_io_dir_t dir, void *userdata);
-struct _mowgli_pollable {
+struct _mowgli_pollable
+{
mowgli_eventloop_io_obj_t type;
mowgli_descriptor_t fd;
@@ -106,7 +120,8 @@ struct _mowgli_pollable {
mowgli_eventloop_t *eventloop;
};
-typedef struct {
+typedef struct
+{
void (*timeout_once)(mowgli_eventloop_t *eventloop, int timeout);
void (*run_once)(mowgli_eventloop_t *eventloop);
void (*pollsetup)(mowgli_eventloop_t *eventloop);
@@ -116,7 +131,8 @@ typedef struct {
void (*destroy)(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable);
} mowgli_eventloop_ops_t;
-struct _mowgli_eventloop {
+struct _mowgli_eventloop
+{
time_t currtime;
time_t deadline;
@@ -131,41 +147,124 @@ struct _mowgli_eventloop {
bool death_requested;
void *data;
+
+ time_t epochbias;
};
-typedef void mowgli_event_dispatch_func_t(void *userdata);
+typedef void mowgli_event_dispatch_func_t (void *userdata);
-typedef struct {
+typedef struct
+{
mowgli_node_t node;
mowgli_event_dispatch_func_t *func;
void *arg;
const char *name;
time_t frequency;
- time_t when;
+ time_t deadline;
bool active;
} mowgli_eventloop_timer_t;
-static inline void mowgli_eventloop_set_time(mowgli_eventloop_t *eventloop, time_t newtime)
+static inline void
+mowgli_eventloop_set_time(mowgli_eventloop_t *eventloop, time_t newtime)
{
return_if_fail(eventloop != NULL);
eventloop->currtime = newtime;
}
-static inline time_t mowgli_eventloop_get_time(mowgli_eventloop_t *eventloop)
+static inline time_t
+mowgli_eventloop_get_time(mowgli_eventloop_t *eventloop)
{
return_val_if_fail(eventloop != NULL, 0);
- return eventloop->currtime;
+ return eventloop->epochbias + eventloop->currtime;
}
-static inline void mowgli_eventloop_synchronize(mowgli_eventloop_t *eventloop)
+static inline void
+mowgli_eventloop_synchronize(mowgli_eventloop_t *eventloop)
{
- mowgli_eventloop_set_time(eventloop, time(NULL));
+ long long time_;
+
+#if defined(CLOCK_MONOTONIC)
+ struct timespec tp;
+
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ time_ = tp.tv_sec;
+#elif defined(CLOCK_HIGHRES)
+ struct timespec tp;
+
+ clock_gettime(CLOCK_HIGHRES, &tp);
+ time_ = tp.tv_sec;
+#elif defined(MOWGLI_OS_WIN)
+ static ULONGLONG (CALLBACK *GetTickCount64)(void) = NULL;
+ static OSVERSIONINFOEX *winver = NULL;
+ static bool load_err = false;
+
+ if (winver == NULL)
+ {
+ winver = mowgli_alloc(sizeof(OSVERSIONINFOEX));
+ winver->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+ if (!GetVersionEx((OSVERSIONINFO *) winver))
+ {
+ mowgli_free(winver);
+ winver = NULL; /* FIXME */
+ }
+ }
+
+ if (winver && (winver->dwMajorVersion >= 6))
+ {
+ if ((GetTickCount64 == NULL) && !load_err)
+ {
+ HINSTANCE hKernel32;
+
+ hKernel32 = GetModuleHandle("KERNEL32");
+ GetTickCount64 = GetProcAddress(hKernel32, "GetTickCount64");
+
+ if (GetTickCount64 == NULL)
+ load_err = true;
+ }
+
+ if (load_err)
+ {
+ time_ = time(NULL);
+ }
+ else
+ {
+ soft_assert(GetTickCount64 != NULL);
+
+ time_ = (int) (GetTickCount64() * 1e-3);
+ }
+ }
+ else
+ {
+ time_ = time(NULL);
+ }
+
+#elif defined(MOWGLI_OS_OSX)
+ static mach_timebase_info_data_t timebase;
+
+ if (timebase.denom == 0)
+ mach_timebase_info(&timebase);
+
+ time_ = (int) (mach_absolute_time() * timebase.numer / timebase.denom * 1e-9);
+#else
+ time_ = time(NULL);
+#endif
+ mowgli_eventloop_set_time(eventloop, (time_t) time_);
+}
+
+/* Sets the bias of eventloop->currtime relative to Jan 1 00:00:00 1970 */
+static inline void
+mowgli_eventloop_calibrate(mowgli_eventloop_t *eventloop)
+{
+ mowgli_eventloop_synchronize(eventloop);
+ eventloop->epochbias = time(NULL) - eventloop->currtime;
}
-static inline bool mowgli_eventloop_ignore_errno(int error)
+static inline bool
+mowgli_eventloop_ignore_errno(int error)
{
switch (error)
{
@@ -178,6 +277,9 @@ static inline bool mowgli_eventloop_ignore_errno(int error)
#if defined(EAGAIN) && (EWOULDBLOCK != EAGAIN)
case EAGAIN:
#endif
+#ifdef ETIME
+ case ETIME:
+#endif
#ifdef EINTR
case EINTR:
#endif
@@ -198,9 +300,10 @@ static inline bool mowgli_eventloop_ignore_errno(int error)
return false;
}
-typedef void mowgli_eventloop_helper_start_fn_t(mowgli_eventloop_helper_proc_t *helper, void *userdata);
+typedef void mowgli_eventloop_helper_start_fn_t (mowgli_eventloop_helper_proc_t * helper, void *userdata);
-struct _mowgli_helper {
+struct _mowgli_helper
+{
mowgli_eventloop_io_obj_t type;
mowgli_process_t *child;
@@ -254,6 +357,7 @@ extern mowgli_eventloop_pollable_t *mowgli_pollable_create(mowgli_eventloop_t *e
extern void mowgli_pollable_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable);
extern void mowgli_pollable_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function);
extern void mowgli_pollable_set_nonblocking(mowgli_eventloop_pollable_t *pollable, bool nonblocking);
+extern void mowgli_pollable_set_cloexec(mowgli_eventloop_pollable_t *pollable, bool cloexec);
+extern void mowgli_pollable_trigger(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir);
#endif
-
diff --git a/src/libmowgli/eventloop/helper.c b/src/libmowgli/eventloop/helper.c
index b89e447..5acc5f0 100644
--- a/src/libmowgli/eventloop/helper.c
+++ b/src/libmowgli/eventloop/helper.c
@@ -20,7 +20,8 @@
#include "mowgli.h"
-typedef struct {
+typedef struct
+{
mowgli_eventloop_helper_start_fn_t *start_fn;
void *userdata;
mowgli_descriptor_t fd;
@@ -30,6 +31,7 @@ static void
mowgli_helper_trampoline(mowgli_helper_create_req_t *req)
{
mowgli_eventloop_helper_proc_t *helper;
+
#ifndef _WIN32
int i, x;
#endif
@@ -42,22 +44,20 @@ mowgli_helper_trampoline(mowgli_helper_create_req_t *req)
helper->fd = req->fd;
#ifndef _WIN32
+
for (i = 0; i < 1024; i++)
- {
if (i != req->fd)
close(i);
- }
x = open("/dev/null", O_RDWR);
for (i = 0; i < 2; i++)
- {
if (req->fd != i)
dup2(x, i);
- }
if (x > 2)
close(x);
+
#endif
helper->eventloop = mowgli_eventloop_create();
@@ -194,10 +194,16 @@ mowgli_helper_io_trampoline(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t
{
mowgli_eventloop_helper_proc_t *helper = userdata;
- switch (dir) {
+ switch (dir)
+ {
case MOWGLI_EVENTLOOP_IO_READ:
+
if (helper->read_function != NULL)
- return helper->read_function(eventloop, helper, MOWGLI_EVENTLOOP_IO_READ, helper->userdata);
+ {
+ helper->read_function(eventloop, helper, MOWGLI_EVENTLOOP_IO_READ, helper->userdata);
+ return;
+ }
+
default:
break;
}
diff --git a/src/libmowgli/eventloop/kqueue_pollops.c b/src/libmowgli/eventloop/kqueue_pollops.c
index 7bfa2bb..113d7b3 100644
--- a/src/libmowgli/eventloop/kqueue_pollops.c
+++ b/src/libmowgli/eventloop/kqueue_pollops.c
@@ -23,15 +23,17 @@
#ifdef HAVE_KQUEUE
-#include <sys/event.h>
+# include <sys/event.h>
-typedef struct {
+typedef struct
+{
int kqueue_fd;
int nevents;
struct kevent *events;
} mowgli_kqueue_eventloop_private_t;
-static void mowgli_kqueue_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
+static void
+mowgli_kqueue_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
{
mowgli_kqueue_eventloop_private_t *priv;
@@ -42,10 +44,14 @@ static void mowgli_kqueue_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
priv->kqueue_fd = kqueue();
priv->events = mowgli_alloc(sizeof(struct kevent) * priv->nevents);
+ /* attempt to set the fd as close-on-exec, but ignore errors */
+ fcntl(priv->kqueue_fd, F_SETFD, FD_CLOEXEC);
+
return;
}
-static void mowgli_kqueue_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
+static void
+mowgli_kqueue_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
{
mowgli_kqueue_eventloop_private_t *priv;
@@ -60,7 +66,8 @@ static void mowgli_kqueue_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
return;
}
-static void mowgli_kqueue_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
+static void
+mowgli_kqueue_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
{
mowgli_kqueue_eventloop_private_t *priv;
struct kevent event;
@@ -71,19 +78,20 @@ static void mowgli_kqueue_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgl
priv = eventloop->poller;
EV_SET(&event, pollable->fd, EVFILT_READ | EVFILT_WRITE, EV_DELETE, 0, 0, pollable);
+
if (kevent(priv->kqueue_fd, &event, 1, NULL, 0,
- &(const struct timespec){ .tv_sec = 0, .tv_nsec = 0}
- ) != 0)
- {
+ &(const struct timespec) { .tv_sec = 0, .tv_nsec = 0 }
+ ) != 0)
mowgli_log("mowgli_kqueue_eventloop_setselect(): kevent failed: %d (%s)", errno, strerror(errno));
- }
}
-static void mowgli_kqueue_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
+static void
+mowgli_kqueue_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
{
mowgli_kqueue_eventloop_private_t *priv;
mowgli_eventloop_io_cb_t **fptr;
struct kevent event;
+
int filter;
bool change;
@@ -93,9 +101,9 @@ static void mowgli_kqueue_eventloop_setselect(mowgli_eventloop_t *eventloop, mow
priv = eventloop->poller;
change = false;
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("setselect %p fd %d func %p", pollable, pollable->fd, event_function);
-#endif
+# endif
switch (dir)
{
@@ -119,21 +127,21 @@ static void mowgli_kqueue_eventloop_setselect(mowgli_eventloop_t *eventloop, mow
if (!change)
return;
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("%p -> read %p : write %p", pollable, pollable->read_function, pollable->write_function);
-#endif
+# endif
EV_SET(&event, pollable->fd, filter,
- event_function ? EV_ADD : EV_DELETE, 0, 0, pollable);
+ event_function ? EV_ADD : EV_DELETE, 0, 0, pollable);
+
if (kevent(priv->kqueue_fd, &event, 1, NULL, 0,
- &(const struct timespec){ .tv_sec = 0, .tv_nsec = 0}
- ) != 0)
- {
+ &(const struct timespec) { .tv_sec = 0, .tv_nsec = 0 }
+ ) != 0)
mowgli_log("mowgli_kqueue_eventloop_setselect(): kevent failed: %d (%s)", errno, strerror(errno));
- }
}
-static void mowgli_kqueue_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
+static void
+mowgli_kqueue_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
{
mowgli_kqueue_eventloop_private_t *priv;
int i, num, o_errno;
@@ -143,8 +151,8 @@ static void mowgli_kqueue_eventloop_select(mowgli_eventloop_t *eventloop, int de
priv = eventloop->poller;
num = kevent(priv->kqueue_fd, NULL, 0, priv->events, priv->nevents,
- delay >= 0 ? &(const struct timespec){ .tv_sec = delay / 1000,
- .tv_nsec = delay % 1000 * 1000000 } : NULL);
+ delay >= 0 ? &(const struct timespec) { .tv_sec = delay / 1000,
+ .tv_nsec = delay % 1000 * 1000000 } : NULL);
o_errno = errno;
mowgli_eventloop_synchronize(eventloop);
@@ -162,13 +170,11 @@ static void mowgli_kqueue_eventloop_select(mowgli_eventloop_t *eventloop, int de
{
mowgli_eventloop_pollable_t *pollable = priv->events[i].udata;
- if (priv->events[i].filter == EVFILT_READ &&
- pollable->read_function != NULL)
- pollable->read_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ, pollable->userdata);
+ if (priv->events[i].filter == EVFILT_READ)
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ);
- if (priv->events[i].filter == EVFILT_WRITE &&
- pollable->write_function != NULL)
- pollable->write_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE, pollable->userdata);
+ if (priv->events[i].filter == EVFILT_WRITE)
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE);
/* XXX Perhaps we need to recheck read_function and
* write_function now.
@@ -176,7 +182,8 @@ static void mowgli_kqueue_eventloop_select(mowgli_eventloop_t *eventloop, int de
}
}
-mowgli_eventloop_ops_t _mowgli_kqueue_pollops = {
+mowgli_eventloop_ops_t _mowgli_kqueue_pollops =
+{
.timeout_once = mowgli_simple_eventloop_timeout_once,
.run_once = mowgli_simple_eventloop_run_once,
.pollsetup = mowgli_kqueue_eventloop_pollsetup,
diff --git a/src/libmowgli/eventloop/null_pollops.c b/src/libmowgli/eventloop/null_pollops.c
index 8fcabe4..7788aec 100644
--- a/src/libmowgli/eventloop/null_pollops.c
+++ b/src/libmowgli/eventloop/null_pollops.c
@@ -20,7 +20,8 @@
#include "mowgli.h"
-void mowgli_simple_eventloop_timeout_once(mowgli_eventloop_t *eventloop, int timeout)
+void
+mowgli_simple_eventloop_timeout_once(mowgli_eventloop_t *eventloop, int timeout)
{
time_t delay, currtime;
int t;
@@ -33,7 +34,7 @@ void mowgli_simple_eventloop_timeout_once(mowgli_eventloop_t *eventloop, int tim
currtime = mowgli_eventloop_get_time(eventloop);
delay = mowgli_eventloop_next_timer(eventloop);
- if (delay <= currtime)
+ while (delay != -1 && delay <= currtime)
{
mowgli_eventloop_run_timers(eventloop);
mowgli_eventloop_synchronize(eventloop);
@@ -44,28 +45,26 @@ void mowgli_simple_eventloop_timeout_once(mowgli_eventloop_t *eventloop, int tim
if (timeout)
t = timeout;
+ else if (delay == -1)
+ t = 5000; /* arbitrary 5 second default timeout */
else
- {
- if (delay <= currtime)
- t = -1;
- else
- t = (delay - currtime) * 1000;
- }
+ t = (delay - currtime) * 1000;
#ifdef DEBUG
mowgli_log("delay: %ld, currtime: %ld, select period: %d", delay, currtime, t);
#endif
eventloop->eventloop_ops->select(eventloop, t);
-
}
-void mowgli_simple_eventloop_run_once(mowgli_eventloop_t *eventloop)
+void
+mowgli_simple_eventloop_run_once(mowgli_eventloop_t *eventloop)
{
eventloop->eventloop_ops->timeout_once(eventloop, 0);
}
-void mowgli_simple_eventloop_error_handler(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
+void
+mowgli_simple_eventloop_error_handler(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
{
mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io);
@@ -73,24 +72,28 @@ void mowgli_simple_eventloop_error_handler(mowgli_eventloop_t *eventloop, mowgli
mowgli_pollable_destroy(eventloop, pollable);
}
-static void mowgli_null_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
+static void
+mowgli_null_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
{
return;
}
-static void mowgli_null_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
+static void
+mowgli_null_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
{
return;
}
-static void mowgli_null_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
+static void
+mowgli_null_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
{
return;
}
-static void mowgli_null_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
+static void
+mowgli_null_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
{
- mowgli_log("null eventloop does not really do polling, events for pollable<%p> will be ignored", pollable);
+ mowgli_log("null eventloop does not really do polling, events for pollable<%p> will be ignored", (void *) pollable);
switch (dir)
{
@@ -108,12 +111,16 @@ static void mowgli_null_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgl
return;
}
-static void mowgli_null_eventloop_select(mowgli_eventloop_t *eventloop, int time)
+static void
+mowgli_null_eventloop_select(mowgli_eventloop_t *eventloop, int time)
{
+ for (; time > 999999; time -= 999999)
+ usleep(999999);
usleep(time);
}
-mowgli_eventloop_ops_t _mowgli_null_pollops = {
+mowgli_eventloop_ops_t _mowgli_null_pollops =
+{
.timeout_once = mowgli_simple_eventloop_timeout_once,
.run_once = mowgli_simple_eventloop_run_once,
.pollsetup = mowgli_null_eventloop_pollsetup,
diff --git a/src/libmowgli/eventloop/poll_pollops.c b/src/libmowgli/eventloop/poll_pollops.c
index 0bea454..6c5d7e5 100644
--- a/src/libmowgli/eventloop/poll_pollops.c
+++ b/src/libmowgli/eventloop/poll_pollops.c
@@ -22,22 +22,25 @@
#ifdef HAVE_POLL_H
-#include <poll.h>
+# include <poll.h>
-#ifndef POLLRDNORM
-#define POLLRDNORM POLLIN
-#endif
-#ifndef POLLWRNORM
-#define POLLWRNORM POLLOUT
-#endif
+# ifndef POLLRDNORM
+# define POLLRDNORM POLLIN
+# endif
+# ifndef POLLWRNORM
+# define POLLWRNORM POLLOUT
+# endif
-typedef struct {
+typedef struct
+{
struct pollfd pollfds[FD_SETSIZE];
+
nfds_t nfds;
mowgli_list_t pollable_list;
} mowgli_poll_eventloop_private_t;
-static nfds_t update_poll_fds(mowgli_eventloop_t *eventloop)
+static nfds_t
+update_poll_fds(mowgli_eventloop_t *eventloop)
{
mowgli_node_t *n, *tn;
mowgli_poll_eventloop_private_t *priv;
@@ -49,13 +52,13 @@ static nfds_t update_poll_fds(mowgli_eventloop_t *eventloop)
memset(priv->pollfds, '\0', sizeof(priv->pollfds));
- MOWGLI_ITER_FOREACH_SAFE(n, tn, priv->pollable_list.head)
- {
+ MOWGLI_ITER_FOREACH_SAFE(n, tn, priv->pollable_list.head)
+ {
mowgli_eventloop_pollable_t *pollable = n->data;
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("considering fd %d pollable %p count %d", pollable->fd, pollable, priv->pollable_list.count);
-#endif
+# endif
if (pollable->read_function || pollable->write_function)
{
@@ -72,13 +75,16 @@ static nfds_t update_poll_fds(mowgli_eventloop_t *eventloop)
slot++;
}
else
+ {
pollable->slot = -1;
+ }
}
- return slot;
+ return slot;
}
-static void mowgli_poll_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
+static void
+mowgli_poll_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
{
mowgli_poll_eventloop_private_t *priv;
@@ -88,7 +94,8 @@ static void mowgli_poll_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
return;
}
-static void mowgli_poll_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
+static void
+mowgli_poll_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
{
mowgli_node_t *n, *tn;
mowgli_poll_eventloop_private_t *priv;
@@ -106,7 +113,8 @@ static void mowgli_poll_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
return;
}
-static void mowgli_poll_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
+static void
+mowgli_poll_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
{
mowgli_poll_eventloop_private_t *priv;
@@ -118,7 +126,8 @@ static void mowgli_poll_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_
mowgli_node_delete(&pollable->node, &priv->pollable_list);
}
-static void mowgli_poll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
+static void
+mowgli_poll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
{
mowgli_poll_eventloop_private_t *priv;
@@ -127,9 +136,9 @@ static void mowgli_poll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgl
priv = eventloop->poller;
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("setselect %p fd %d func %p", pollable, pollable->fd, event_function);
-#endif
+# endif
if (pollable->read_function || pollable->write_function)
mowgli_node_delete(&pollable->node, &priv->pollable_list);
@@ -147,9 +156,9 @@ static void mowgli_poll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgl
break;
}
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("%p -> read %p : write %p", pollable, pollable->read_function, pollable->write_function);
-#endif
+# endif
if (pollable->read_function || pollable->write_function)
mowgli_node_add(pollable, &pollable->node, &priv->pollable_list);
@@ -157,7 +166,8 @@ static void mowgli_poll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgl
return;
}
-static void mowgli_poll_eventloop_select(mowgli_eventloop_t *eventloop, int time)
+static void
+mowgli_poll_eventloop_select(mowgli_eventloop_t *eventloop, int time)
{
mowgli_node_t *n, *tn;
nfds_t nfds;
@@ -181,17 +191,17 @@ static void mowgli_poll_eventloop_select(mowgli_eventloop_t *eventloop, int time
pollable = n->data;
slot = pollable->slot;
- if (slot == -1 || priv->pollfds[slot].revents == 0)
+ if ((slot == -1) || (priv->pollfds[slot].revents == 0))
continue;
if (priv->pollfds[slot].revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR) && pollable->read_function)
{
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("run %p(%p, %p, MOWGLI_EVENTLOOP_IO_READ, %p)\n", pollable->read_function, eventloop, pollable, pollable->userdata);
-#endif
+# endif
priv->pollfds[slot].events &= ~(POLLRDNORM | POLLIN);
- pollable->read_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ, pollable->userdata);
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ);
}
}
@@ -200,23 +210,24 @@ static void mowgli_poll_eventloop_select(mowgli_eventloop_t *eventloop, int time
pollable = n->data;
slot = pollable->slot;
- if (slot == -1 || priv->pollfds[slot].revents == 0)
+ if ((slot == -1) || (priv->pollfds[slot].revents == 0))
continue;
if (priv->pollfds[slot].revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR) && pollable->write_function)
{
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("run %p(%p, %p, MOWGLI_EVENTLOOP_IO_WRITE, %p)\n", pollable->write_function, eventloop, pollable, pollable->userdata);
-#endif
+# endif
priv->pollfds[slot].events &= ~(POLLWRNORM | POLLOUT);
- pollable->write_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE, pollable->userdata);
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE);
}
}
}
}
-mowgli_eventloop_ops_t _mowgli_poll_pollops = {
+mowgli_eventloop_ops_t _mowgli_poll_pollops =
+{
.timeout_once = mowgli_simple_eventloop_timeout_once,
.run_once = mowgli_simple_eventloop_run_once,
.pollsetup = mowgli_poll_eventloop_pollsetup,
diff --git a/src/libmowgli/eventloop/pollable.c b/src/libmowgli/eventloop/pollable.c
index e2c2e2a..5f9526e 100644
--- a/src/libmowgli/eventloop/pollable.c
+++ b/src/libmowgli/eventloop/pollable.c
@@ -22,7 +22,8 @@
static mowgli_heap_t *pollable_heap = NULL;
-mowgli_eventloop_pollable_t *mowgli_pollable_create(mowgli_eventloop_t *eventloop, mowgli_descriptor_t fd, void *userdata)
+mowgli_eventloop_pollable_t *
+mowgli_pollable_create(mowgli_eventloop_t *eventloop, mowgli_descriptor_t fd, void *userdata)
{
mowgli_eventloop_pollable_t *pollable;
@@ -41,7 +42,8 @@ mowgli_eventloop_pollable_t *mowgli_pollable_create(mowgli_eventloop_t *eventloo
return pollable;
}
-void mowgli_pollable_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
+void
+mowgli_pollable_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
{
return_if_fail(eventloop != NULL);
return_if_fail(pollable != NULL);
@@ -52,7 +54,8 @@ void mowgli_pollable_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pol
mowgli_heap_free(pollable_heap, pollable);
}
-void mowgli_pollable_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
+void
+mowgli_pollable_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
{
return_if_fail(eventloop != NULL);
return_if_fail(pollable != NULL);
@@ -61,7 +64,8 @@ void mowgli_pollable_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_p
eventloop->eventloop_ops->setselect(eventloop, pollable, dir, event_function);
}
-void mowgli_pollable_set_nonblocking(mowgli_eventloop_pollable_t *pollable, bool nonblocking)
+void
+mowgli_pollable_set_nonblocking(mowgli_eventloop_pollable_t *pollable, bool nonblocking)
{
#if defined(HAVE_FCNTL)
unsigned long flags;
@@ -86,3 +90,53 @@ void mowgli_pollable_set_nonblocking(mowgli_eventloop_pollable_t *pollable, bool
ioctlsocket(pollable->fd, FIONBIO, &mode);
#endif
}
+
+void
+mowgli_pollable_set_cloexec(mowgli_eventloop_pollable_t *pollable, bool cloexec)
+{
+#if defined(FD_CLOEXEC)
+ unsigned long flags;
+
+ return_if_fail(pollable != NULL);
+
+ flags = fcntl(pollable->fd, F_GETFD);
+
+ if (cloexec)
+ flags |= FD_CLOEXEC;
+ else
+ flags &= ~FD_CLOEXEC;
+
+ fcntl(pollable->fd, F_SETFD, flags);
+#elif defined(HAVE_WINSOCK2_H)
+ return_if_fail(pollable != NULL);
+
+ SetHandleInformation((HANDLE)pollable->fd, HANDLE_FLAG_INHERIT, !cloexec);
+#endif
+}
+
+void
+mowgli_pollable_trigger(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir)
+{
+ mowgli_eventloop_io_cb_t *event_function;
+
+ return_if_fail(eventloop != NULL);
+ return_if_fail(pollable != NULL);
+
+ switch (dir)
+ {
+ case MOWGLI_EVENTLOOP_IO_READ:
+ event_function = pollable->read_function;
+ break;
+ case MOWGLI_EVENTLOOP_IO_WRITE:
+ event_function = pollable->write_function;
+ break;
+ default:
+ event_function = NULL;
+ return;
+ }
+
+ if (event_function == NULL)
+ return;
+
+ event_function(eventloop, pollable, dir, pollable->userdata);
+}
diff --git a/src/libmowgli/eventloop/ports_pollops.c b/src/libmowgli/eventloop/ports_pollops.c
index bc838da..0c68fd5 100644
--- a/src/libmowgli/eventloop/ports_pollops.c
+++ b/src/libmowgli/eventloop/ports_pollops.c
@@ -22,15 +22,17 @@
#ifdef HAVE_PORT_CREATE
-#include <port.h>
+# include <port.h>
-typedef struct {
+typedef struct
+{
int port_fd;
int pfd_size;
port_event_t *pfd;
} mowgli_ports_eventloop_private_t;
-static void mowgli_ports_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
+static void
+mowgli_ports_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
{
mowgli_ports_eventloop_private_t *priv;
@@ -44,7 +46,8 @@ static void mowgli_ports_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
return;
}
-static void mowgli_ports_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
+static void
+mowgli_ports_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
{
mowgli_ports_eventloop_private_t *priv;
@@ -59,7 +62,8 @@ static void mowgli_ports_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
return;
}
-static void mowgli_ports_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
+static void
+mowgli_ports_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
{
mowgli_ports_eventloop_private_t *priv;
@@ -78,7 +82,8 @@ static void mowgli_ports_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli
}
}
-static void mowgli_ports_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
+static void
+mowgli_ports_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
{
mowgli_ports_eventloop_private_t *priv;
unsigned int old_flags;
@@ -89,9 +94,9 @@ static void mowgli_ports_eventloop_setselect(mowgli_eventloop_t *eventloop, mowg
priv = eventloop->poller;
old_flags = pollable->slot;
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("setselect %p fd %d func %p", pollable, pollable->fd, event_function);
-#endif
+# endif
switch (dir)
{
@@ -108,9 +113,9 @@ static void mowgli_ports_eventloop_setselect(mowgli_eventloop_t *eventloop, mowg
break;
}
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("%p -> read %p : write %p", pollable, pollable->read_function, pollable->write_function);
-#endif
+# endif
if (pollable->read_function == NULL)
pollable->slot &= ~POLLIN;
@@ -118,8 +123,10 @@ static void mowgli_ports_eventloop_setselect(mowgli_eventloop_t *eventloop, mowg
if (pollable->write_function == NULL)
pollable->slot &= ~POLLOUT;
- if (old_flags == 0 && pollable->slot == 0)
+ if ((old_flags == 0) && (pollable->slot == 0))
+ {
return;
+ }
else if (pollable->slot == 0)
{
port_dissociate(priv->port_fd, PORT_SOURCE_FD, (uintptr_t) pollable->fd);
@@ -137,24 +144,25 @@ static void mowgli_ports_eventloop_setselect(mowgli_eventloop_t *eventloop, mowg
return;
}
-static void mowgli_ports_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
+static void
+mowgli_ports_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
{
mowgli_ports_eventloop_private_t *priv;
- int i, num, o_errno, nget = 1;
+ int i, ret, o_errno, nget = 1;
return_if_fail(eventloop != NULL);
priv = eventloop->poller;
- num = port_getn(priv->port_fd, priv->pfd, priv->pfd_size, &nget,
- delay >= 0 ? &(struct timespec){ .tv_sec = delay / 1000, .tv_nsec = delay % 1000 * 1000000 } : NULL);
+ ret = port_getn(priv->port_fd, priv->pfd, priv->pfd_size, &nget,
+ delay >= 0 ? &(struct timespec) { .tv_sec = delay / 1000, .tv_nsec = delay % 1000 * 1000000 } : NULL);
o_errno = errno;
mowgli_eventloop_synchronize(eventloop);
- if (num < 0)
+ if (ret == -1)
{
- if (mowgli_eventloop_ignore_errno(errno))
+ if (mowgli_eventloop_ignore_errno(o_errno))
return;
mowgli_log("mowgli_ports_eventloop_select(): port_getn failed: %d (%s)", o_errno, strerror(o_errno));
@@ -165,15 +173,19 @@ static void mowgli_ports_eventloop_select(mowgli_eventloop_t *eventloop, int del
{
mowgli_eventloop_pollable_t *pollable = priv->pfd[i].portev_user;
- if (priv->pfd[i].portev_events & (POLLIN | POLLHUP | POLLERR) && pollable->read_function != NULL)
- pollable->read_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ, pollable->userdata);
+ if (priv->pfd[i].portev_source != PORT_SOURCE_FD)
+ continue;
- if (priv->pfd[i].portev_events & (POLLOUT | POLLHUP | POLLERR) && pollable->write_function != NULL)
- pollable->write_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE, pollable->userdata);
+ if (priv->pfd[i].portev_events & (POLLIN | POLLHUP | POLLERR))
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ);
+
+ if (priv->pfd[i].portev_events & (POLLOUT | POLLHUP | POLLERR))
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE);
}
}
-mowgli_eventloop_ops_t _mowgli_ports_pollops = {
+mowgli_eventloop_ops_t _mowgli_ports_pollops =
+{
.timeout_once = mowgli_simple_eventloop_timeout_once,
.run_once = mowgli_simple_eventloop_run_once,
.pollsetup = mowgli_ports_eventloop_pollsetup,
diff --git a/src/libmowgli/eventloop/qnx_pollops.c b/src/libmowgli/eventloop/qnx_pollops.c
index 7417ef4..6c114d5 100644
--- a/src/libmowgli/eventloop/qnx_pollops.c
+++ b/src/libmowgli/eventloop/qnx_pollops.c
@@ -22,15 +22,17 @@
#ifdef HAVE_DISPATCH_BLOCK
-#include <sys/iofunc.h>
-#include <sys/dispatch.h>
+# include <sys/iofunc.h>
+# include <sys/dispatch.h>
-typedef struct {
+typedef struct
+{
dispatch_t *dpp;
dispatch_context_t *ctp;
} mowgli_qnx_eventloop_private_t;
-static void mowgli_qnx_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
+static void
+mowgli_qnx_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
{
mowgli_qnx_eventloop_private_t *priv;
@@ -42,7 +44,8 @@ static void mowgli_qnx_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
return;
}
-static void mowgli_qnx_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
+static void
+mowgli_qnx_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
{
mowgli_qnx_eventloop_private_t *priv;
@@ -59,7 +62,8 @@ static void mowgli_qnx_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
return;
}
-static void mowgli_qnx_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
+static void
+mowgli_qnx_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
{
mowgli_qnx_eventloop_private_t *priv;
@@ -77,7 +81,8 @@ static void mowgli_qnx_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_e
}
}
-static void mowgli_qnx_eventloop_event_cb(select_context_t *ctp, mowgli_descriptor_t fd, unsigned int flags, void *userdata)
+static void
+mowgli_qnx_eventloop_event_cb(select_context_t *ctp, mowgli_descriptor_t fd, unsigned int flags, void *userdata)
{
mowgli_eventloop_t *eventloop;
mowgli_eventloop_pollable_t *pollable;
@@ -91,16 +96,17 @@ static void mowgli_qnx_eventloop_event_cb(select_context_t *ctp, mowgli_descript
return_if_fail(eventloop != NULL);
if (flags & (SELECT_FLAG_READ | SELECT_FLAG_EXCEPT))
- pollable->read_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ, pollable->userdata);
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ);
if (flags & (SELECT_FLAG_WRITE | SELECT_FLAG_EXCEPT))
- pollable->write_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE, pollable->userdata);
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE);
}
-static void mowgli_qnx_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
+static void
+mowgli_qnx_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
{
mowgli_qnx_eventloop_private_t *priv;
- select_attr_t attr = {};
+ select_attr_t attr = { };
unsigned int old_flags;
return_if_fail(eventloop != NULL);
@@ -109,9 +115,9 @@ static void mowgli_qnx_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli
priv = eventloop->poller;
old_flags = pollable->slot;
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("setselect %p fd %d func %p", pollable, pollable->fd, event_function);
-#endif
+# endif
switch (dir)
{
@@ -128,9 +134,9 @@ static void mowgli_qnx_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli
break;
}
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("%p -> read %p : write %p", pollable, pollable->read_function, pollable->write_function);
-#endif
+# endif
if (pollable->read_function == NULL)
pollable->slot &= ~SELECT_FLAG_READ;
@@ -138,14 +144,13 @@ static void mowgli_qnx_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli
if (pollable->write_function == NULL)
pollable->slot &= ~SELECT_FLAG_WRITE;
- if (old_flags == 0 && pollable->slot == 0)
+ if ((old_flags == 0) && (pollable->slot == 0))
return;
if (old_flags)
select_detach(priv->dpp, pollable->fd);
if (pollable->slot)
- {
if (select_attach(priv->dpp, &attr, pollable->fd, pollable->slot, mowgli_qnx_eventloop_event_cb, pollable) != 0)
{
if (mowgli_eventloop_ignore_errno(errno))
@@ -153,12 +158,12 @@ static void mowgli_qnx_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli
mowgli_log("mowgli_qnx_eventloop_setselect(): select_attach failed: %d (%s)", errno, strerror(errno));
}
- }
return;
}
-static void mowgli_qnx_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
+static void
+mowgli_qnx_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
{
dispatch_context_t *new_ctp;
mowgli_qnx_eventloop_private_t *priv;
@@ -168,14 +173,16 @@ static void mowgli_qnx_eventloop_select(mowgli_eventloop_t *eventloop, int delay
priv = eventloop->poller;
/* set timeout if needed */
- dispatch_timeout(priv->dpp, delay >= 0 ? &(struct timespec){ .tv_sec = delay / 1000, .tv_nsec = delay % 1000 * 1000000 } : NULL);
+ dispatch_timeout(priv->dpp, delay >= 0 ? &(struct timespec) { .tv_sec = delay / 1000, .tv_nsec = delay % 1000 * 1000000 } : NULL);
if (priv->ctp != NULL)
priv->ctp = dispatch_context_alloc(priv->dpp);
/* if dispatch_block returns non-NULL, priv->ctp may have been realloc()'d, NULL is error condition */
if ((new_ctp = dispatch_block(priv->ctp)) != NULL)
+ {
priv->ctp = new_ctp;
+ }
else
{
if (mowgli_eventloop_ignore_errno(errno))
@@ -187,7 +194,8 @@ static void mowgli_qnx_eventloop_select(mowgli_eventloop_t *eventloop, int delay
mowgli_eventloop_synchronize(eventloop);
}
-mowgli_eventloop_ops_t _mowgli_qnx_pollops = {
+mowgli_eventloop_ops_t _mowgli_qnx_pollops =
+{
.timeout_once = mowgli_simple_eventloop_timeout_once,
.run_once = mowgli_simple_eventloop_run_once,
.pollsetup = mowgli_qnx_eventloop_pollsetup,
diff --git a/src/libmowgli/eventloop/select_pollops.c b/src/libmowgli/eventloop/select_pollops.c
index 467b4f5..ee5a966 100644
--- a/src/libmowgli/eventloop/select_pollops.c
+++ b/src/libmowgli/eventloop/select_pollops.c
@@ -22,15 +22,17 @@
#ifdef HAVE_SELECT
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
+# ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+# endif
-typedef struct {
+typedef struct
+{
mowgli_list_t pollable_list;
} mowgli_select_eventloop_private_t;
-static void mowgli_select_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
+static void
+mowgli_select_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
{
mowgli_select_eventloop_private_t *priv;
@@ -40,7 +42,8 @@ static void mowgli_select_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
return;
}
-static void mowgli_select_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
+static void
+mowgli_select_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
{
mowgli_node_t *n, *tn;
mowgli_select_eventloop_private_t *priv;
@@ -58,7 +61,8 @@ static void mowgli_select_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
return;
}
-static void mowgli_select_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
+static void
+mowgli_select_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
{
mowgli_select_eventloop_private_t *priv;
@@ -70,7 +74,8 @@ static void mowgli_select_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgl
mowgli_node_delete(&pollable->node, &priv->pollable_list);
}
-static void mowgli_select_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
+static void
+mowgli_select_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
{
mowgli_select_eventloop_private_t *priv;
@@ -79,9 +84,9 @@ static void mowgli_select_eventloop_setselect(mowgli_eventloop_t *eventloop, mow
priv = eventloop->poller;
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("setselect %p fd %d func %p", pollable, pollable->fd, event_function);
-#endif
+# endif
if (pollable->read_function || pollable->write_function)
mowgli_node_delete(&pollable->node, &priv->pollable_list);
@@ -99,9 +104,9 @@ static void mowgli_select_eventloop_setselect(mowgli_eventloop_t *eventloop, mow
break;
}
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("%p -> read %p : write %p", pollable, pollable->read_function, pollable->write_function);
-#endif
+# endif
if (pollable->read_function || pollable->write_function)
mowgli_node_add(pollable, &pollable->node, &priv->pollable_list);
@@ -109,7 +114,8 @@ static void mowgli_select_eventloop_setselect(mowgli_eventloop_t *eventloop, mow
return;
}
-static void mowgli_select_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
+static void
+mowgli_select_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
{
mowgli_node_t *n, *tn;
mowgli_eventloop_pollable_t *pollable;
@@ -126,13 +132,13 @@ static void mowgli_select_eventloop_select(mowgli_eventloop_t *eventloop, int de
FD_ZERO(&wfds);
FD_ZERO(&efds);
- MOWGLI_ITER_FOREACH_SAFE(n, tn, priv->pollable_list.head)
- {
+ MOWGLI_ITER_FOREACH_SAFE(n, tn, priv->pollable_list.head)
+ {
mowgli_eventloop_pollable_t *pollable = n->data;
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("considering fd %d pollable %p count %d", pollable->fd, pollable, priv->pollable_list.count);
-#endif
+# endif
if (pollable->read_function || pollable->write_function)
{
@@ -164,13 +170,13 @@ static void mowgli_select_eventloop_select(mowgli_eventloop_t *eventloop, int de
{
pollable = n->data;
- if ((FD_ISSET(pollable->fd, &rfds) || FD_ISSET(pollable->fd, &efds)) && pollable->read_function)
+ if ((FD_ISSET(pollable->fd, &rfds) || FD_ISSET(pollable->fd, &efds)))
{
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("run %p(%p, %p, MOWGLI_EVENTLOOP_IO_READ, %p)\n", pollable->read_function, eventloop, pollable, pollable->userdata);
-#endif
+# endif
- pollable->read_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ, pollable->userdata);
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ);
}
}
@@ -178,19 +184,20 @@ static void mowgli_select_eventloop_select(mowgli_eventloop_t *eventloop, int de
{
pollable = n->data;
- if ((FD_ISSET(pollable->fd, &wfds) || FD_ISSET(pollable->fd, &efds)) && pollable->write_function)
+ if ((FD_ISSET(pollable->fd, &wfds) || FD_ISSET(pollable->fd, &efds)))
{
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("run %p(%p, %p, MOWGLI_EVENTLOOP_IO_WRITE, %p)\n", pollable->write_function, eventloop, pollable, pollable->userdata);
-#endif
+# endif
- pollable->write_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE, pollable->userdata);
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE);
}
}
}
}
-mowgli_eventloop_ops_t _mowgli_select_pollops = {
+mowgli_eventloop_ops_t _mowgli_select_pollops =
+{
.timeout_once = mowgli_simple_eventloop_timeout_once,
.run_once = mowgli_simple_eventloop_run_once,
.pollsetup = mowgli_select_eventloop_pollsetup,
diff --git a/src/libmowgli/eventloop/timer.c b/src/libmowgli/eventloop/timer.c
index d8c5061..efdbdea 100644
--- a/src/libmowgli/eventloop/timer.c
+++ b/src/libmowgli/eventloop/timer.c
@@ -23,8 +23,8 @@
static mowgli_heap_t *timer_heap = NULL;
-static mowgli_eventloop_timer_t *mowgli_timer_add_real(mowgli_eventloop_t *eventloop,
- const char *name, mowgli_event_dispatch_func_t *func, void *arg, time_t when, time_t frequency)
+static mowgli_eventloop_timer_t *
+mowgli_timer_add_real(mowgli_eventloop_t *eventloop, const char *name, mowgli_event_dispatch_func_t *func, void *arg, time_t when, time_t frequency)
{
mowgli_eventloop_timer_t *timer;
@@ -39,36 +39,39 @@ static mowgli_eventloop_timer_t *mowgli_timer_add_real(mowgli_eventloop_t *event
timer->func = func;
timer->name = name;
timer->arg = arg;
- timer->when = mowgli_eventloop_get_time(eventloop) + when;
+ timer->deadline = mowgli_eventloop_get_time(eventloop) + when;
timer->frequency = frequency;
timer->active = true;
- if (eventloop->deadline <= mowgli_eventloop_get_time(eventloop) || timer->when <= eventloop->deadline)
- eventloop->deadline = timer->when;
+ if (eventloop->deadline != -1 && timer->deadline <= eventloop->deadline)
+ eventloop->deadline = timer->deadline;
mowgli_node_add(timer, &timer->node, &eventloop->timer_list);
#ifdef DEBUG
- mowgli_log("[timer(%p) add when:%d active:%d] [eventloop deadline:%d]", timer, timer->when, timer->active, eventloop->deadline);
+ mowgli_log("[timer(%p) add when:%d active:%d] [eventloop deadline:%d]", timer, timer->deadline, timer->active, eventloop->deadline);
#endif
return timer;
}
/* add an event to the table to be continually ran */
-mowgli_eventloop_timer_t *mowgli_timer_add(mowgli_eventloop_t *eventloop, const char *name, mowgli_event_dispatch_func_t *func, void *arg, time_t when)
+mowgli_eventloop_timer_t *
+mowgli_timer_add(mowgli_eventloop_t *eventloop, const char *name, mowgli_event_dispatch_func_t *func, void *arg, time_t when)
{
return mowgli_timer_add_real(eventloop, name, func, arg, when, when);
}
/* adds an event to the table to be ran only once */
-mowgli_eventloop_timer_t *mowgli_timer_add_once(mowgli_eventloop_t *eventloop, const char *name, mowgli_event_dispatch_func_t *func, void *arg, time_t when)
+mowgli_eventloop_timer_t *
+mowgli_timer_add_once(mowgli_eventloop_t *eventloop, const char *name, mowgli_event_dispatch_func_t *func, void *arg, time_t when)
{
return mowgli_timer_add_real(eventloop, name, func, arg, when, 0);
}
/* delete an event from the table */
-void mowgli_timer_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_timer_t *timer)
+void
+mowgli_timer_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_timer_t *timer)
{
return_if_fail(eventloop != NULL);
return_if_fail(timer != NULL);
@@ -81,7 +84,8 @@ void mowgli_timer_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_timer_
}
/* checks all pending events */
-void mowgli_eventloop_run_timers(mowgli_eventloop_t *eventloop)
+void
+mowgli_eventloop_run_timers(mowgli_eventloop_t *eventloop)
{
mowgli_node_t *n, *tn;
time_t currtime;
@@ -94,7 +98,7 @@ void mowgli_eventloop_run_timers(mowgli_eventloop_t *eventloop)
{
mowgli_eventloop_timer_t *timer = n->data;
- if (timer->active && timer->when <= currtime)
+ if (timer->active && (timer->deadline <= currtime))
{
/* now we call it */
eventloop->last_ran = timer->name;
@@ -105,7 +109,9 @@ void mowgli_eventloop_run_timers(mowgli_eventloop_t *eventloop)
/* event is scheduled more than once */
if (timer->frequency)
- timer->when = currtime + timer->frequency;
+ {
+ timer->deadline = currtime + timer->frequency;
+ }
else
{
/* XXX: yuck. find a better way to handle this. */
@@ -118,36 +124,37 @@ void mowgli_eventloop_run_timers(mowgli_eventloop_t *eventloop)
}
/* returns the time the next mowgli_timer_run() should happen */
-time_t mowgli_eventloop_next_timer(mowgli_eventloop_t *eventloop)
+time_t
+mowgli_eventloop_next_timer(mowgli_eventloop_t *eventloop)
{
mowgli_node_t *n;
return_val_if_fail(eventloop != NULL, 0);
if (eventloop->deadline == -1)
- {
MOWGLI_ITER_FOREACH(n, eventloop->timer_list.head)
{
mowgli_eventloop_timer_t *timer = n->data;
- if (timer->active && (timer->when < eventloop->deadline || eventloop->deadline == -1))
- eventloop->deadline = timer->when;
+ if (timer->active && ((timer->deadline < eventloop->deadline) || (eventloop->deadline == -1)))
+ eventloop->deadline = timer->deadline;
#ifdef DEBUG
- mowgli_log("timer %p active:%d when:%ld deadline:%ld", timer, timer->active, timer->when, eventloop->deadline);
+ mowgli_log("timer %p active:%d when:%ld deadline:%ld", timer, timer->active, timer->deadline, eventloop->deadline);
#endif
}
- }
#ifdef DEBUG
mowgli_log("eventloop deadline:%ld", eventloop->deadline);
+
#endif
return eventloop->deadline;
}
/* finds an event in the table */
-mowgli_eventloop_timer_t *mowgli_timer_find(mowgli_eventloop_t *eventloop, mowgli_event_dispatch_func_t *func, void *arg)
+mowgli_eventloop_timer_t *
+mowgli_timer_find(mowgli_eventloop_t *eventloop, mowgli_event_dispatch_func_t *func, void *arg)
{
mowgli_node_t *n;
@@ -158,7 +165,7 @@ mowgli_eventloop_timer_t *mowgli_timer_find(mowgli_eventloop_t *eventloop, mowgl
{
mowgli_eventloop_timer_t *timer = n->data;
- if (timer->func == func && timer->arg == arg)
+ if ((timer->func == func) && (timer->arg == arg))
return timer;
}
diff --git a/src/libmowgli/eventloop/windows_pollops.c b/src/libmowgli/eventloop/windows_pollops.c
index f1c9c0f..8133bc1 100644
--- a/src/libmowgli/eventloop/windows_pollops.c
+++ b/src/libmowgli/eventloop/windows_pollops.c
@@ -22,9 +22,10 @@
#ifdef _WIN32
-#define DEFAULT_SOCKETMAX (2048)
+# define DEFAULT_SOCKETMAX (2048)
-typedef struct {
+typedef struct
+{
WSAEVENT *pfd;
unsigned short pfd_size;
unsigned short last_slot;
@@ -33,11 +34,13 @@ typedef struct {
static WSADATA wsock_env;
-void mowgli_winsock_bootstrap(void)
+void
+mowgli_winsock_bootstrap(void)
{
int r;
r = WSAStartup((short) 0x202, &wsock_env);
+
if (r != 0)
{
printf("mowgli bootstrap failure (win32): %d\n", r);
@@ -50,7 +53,8 @@ void mowgli_winsock_bootstrap(void)
wsock_env.iMaxSockets -= (wsock_env.iMaxSockets % MAXIMUM_WAIT_OBJECTS);
}
-static void mowgli_winsock_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
+static void
+mowgli_winsock_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
{
unsigned short i;
mowgli_winsock_eventloop_private_t *priv;
@@ -74,7 +78,8 @@ static void mowgli_winsock_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
return;
}
-static unsigned short mowgli_winsock_eventloop_find_slot(mowgli_winsock_eventloop_private_t *priv)
+static unsigned short
+mowgli_winsock_eventloop_find_slot(mowgli_winsock_eventloop_private_t *priv)
{
unsigned short i = 1;
@@ -84,23 +89,20 @@ static unsigned short mowgli_winsock_eventloop_find_slot(mowgli_winsock_eventloo
i = priv->last_slot;
for (; i < priv->pfd_size; i++)
- {
if (priv->pfd[i] == INVALID_HANDLE_VALUE)
{
priv->last_slot = i;
return i;
}
- }
/* miss, try from beginning. */
+
for (i = 1; i < priv->pfd_size; i++)
- {
if (priv->pfd[i] == INVALID_HANDLE_VALUE)
{
priv->last_slot = i;
return i;
}
- }
/* if this happens, we're boned... */
mowgli_log("out of handles for eventloop %p, aborting\n", priv);
@@ -109,7 +111,8 @@ static unsigned short mowgli_winsock_eventloop_find_slot(mowgli_winsock_eventloo
return 0;
}
-static void mowgli_winsock_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
+static void
+mowgli_winsock_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
{
unsigned short i;
mowgli_winsock_eventloop_private_t *priv;
@@ -130,7 +133,8 @@ static void mowgli_winsock_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
return;
}
-static void mowgli_winsock_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
+static void
+mowgli_winsock_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
{
mowgli_winsock_eventloop_private_t *priv;
@@ -152,7 +156,8 @@ static void mowgli_winsock_eventloop_destroy(mowgli_eventloop_t *eventloop, mowg
pollable->events = 0;
}
-static void mowgli_winsock_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
+static void
+mowgli_winsock_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
{
mowgli_winsock_eventloop_private_t *priv;
unsigned int old_flags;
@@ -163,9 +168,9 @@ static void mowgli_winsock_eventloop_setselect(mowgli_eventloop_t *eventloop, mo
priv = eventloop->poller;
old_flags = pollable->events;
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("setselect %p fd %d func %p", pollable, pollable->fd, event_function);
-#endif
+# endif
switch (dir)
{
@@ -182,9 +187,9 @@ static void mowgli_winsock_eventloop_setselect(mowgli_eventloop_t *eventloop, mo
break;
}
-#ifdef DEBUG
+# ifdef DEBUG
mowgli_log("%p -> read %p : write %p", pollable, pollable->read_function, pollable->write_function);
-#endif
+# endif
if (pollable->read_function == NULL)
pollable->events &= ~(FD_READ | FD_CLOSE | FD_ACCEPT | FD_OOB);
@@ -192,8 +197,10 @@ static void mowgli_winsock_eventloop_setselect(mowgli_eventloop_t *eventloop, mo
if (pollable->write_function == NULL)
pollable->events &= ~(FD_WRITE | FD_CONNECT | FD_CLOSE);
- if (old_flags == 0 && pollable->events == 0)
+ if ((old_flags == 0) && (pollable->events == 0))
+ {
return;
+ }
else if (pollable->events <= 0)
{
mowgli_winsock_eventloop_destroy(eventloop, pollable);
@@ -220,7 +227,8 @@ static void mowgli_winsock_eventloop_setselect(mowgli_eventloop_t *eventloop, mo
return;
}
-static void mowgli_winsock_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
+static void
+mowgli_winsock_eventloop_select(mowgli_eventloop_t *eventloop, int delay)
{
mowgli_winsock_eventloop_private_t *priv;
int i, j;
@@ -252,18 +260,19 @@ static void mowgli_winsock_eventloop_select(mowgli_eventloop_t *eventloop, int d
WSAEnumNetworkEvents(pollable->fd, priv->pfd[pollable->slot], &events);
- if (events.lNetworkEvents & (FD_READ | FD_CLOSE | FD_ACCEPT | FD_OOB) && pollable->read_function != NULL)
- pollable->read_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ, pollable->userdata);
+ if (events.lNetworkEvents & (FD_READ | FD_CLOSE | FD_ACCEPT | FD_OOB))
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ);
- if (events.lNetworkEvents & (FD_WRITE | FD_CONNECT | FD_CLOSE) && pollable->write_function != NULL)
- pollable->write_function(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE, pollable->userdata);
+ if (events.lNetworkEvents & (FD_WRITE | FD_CONNECT | FD_CLOSE))
+ mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE);
}
}
mowgli_eventloop_synchronize(eventloop);
}
-mowgli_eventloop_ops_t _mowgli_winsock_pollops = {
+mowgli_eventloop_ops_t _mowgli_winsock_pollops =
+{
.timeout_once = mowgli_simple_eventloop_timeout_once,
.run_once = mowgli_simple_eventloop_run_once,
.pollsetup = mowgli_winsock_eventloop_pollsetup,
diff --git a/src/libmowgli/ext/Makefile b/src/libmowgli/ext/Makefile
index d7466b6..1cb198f 100644
--- a/src/libmowgli/ext/Makefile
+++ b/src/libmowgli/ext/Makefile
@@ -8,14 +8,17 @@ SRCS = confparse.c \
getopt_long.c \
global_storage.c \
program_opts.c \
- proctitle.c
+ proctitle.c \
+ json.c
INCLUDES = confparse.h \
error_backtrace.h \
getopt_long.h \
global_storage.h \
program_opts.h \
- proctitle.h
+ proctitle.h \
+ json.h \
+ json-inline.h
include ../../../buildsys.mk
diff --git a/src/libmowgli/ext/confparse.c b/src/libmowgli/ext/confparse.c
index 898ba8c..e498055 100644
--- a/src/libmowgli/ext/confparse.c
+++ b/src/libmowgli/ext/confparse.c
@@ -17,6 +17,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
+
/*
* Description of config files parsed by this:
*
@@ -35,6 +36,7 @@
* no matter where the include directive is. Include files must have balanced
* braces.
*/
+
/*
* Original idea from the csircd config parser written by Fred Jacobs
* and Chris Behrens.
@@ -52,7 +54,8 @@ static mowgli_config_file_t *mowgli_config_file_load_internal(mowgli_config_file
#define CF_ERRORED(cf) ((cf)->curline <= 0)
-static void mowgli_config_file_error(mowgli_config_file_t *cf, const char *format, ...)
+static void
+mowgli_config_file_error(mowgli_config_file_t *cf, const char *format, ...)
{
va_list ap;
char buffer[1024];
@@ -70,16 +73,19 @@ static void mowgli_config_file_error(mowgli_config_file_t *cf, const char *forma
if (cf->curline < 0)
cf->curline = -cf->curline;
- mowgli_log("%s:%d: %s", cf->filename, cf->curline, buffer);
+ mowgli_log("%s:%d: %s", cf->filename, cf->curline, buffer);
/* mark config parse as failed */
cf->curline = -cf->curline;
}
else
+ {
mowgli_log("mowgli_config_file_parse(): %s", buffer);
+ }
}
-static void skip_ws(char **pos, mowgli_config_file_t *cf)
+static void
+skip_ws(char **pos, mowgli_config_file_t *cf)
{
int startline;
@@ -87,86 +93,110 @@ static void skip_ws(char **pos, mowgli_config_file_t *cf)
{
switch (**pos)
{
- case ' ':
- case '\t':
- case '\r':
- case '=': /* XXX */
- break;
- case '\n':
- cf->curline++;
- break;
- case '/':
- if ((*pos)[1] == '*')
+ case ' ':
+ case '\t':
+ case '\r':
+ case '=': /* XXX */
+ break;
+ case '\n':
+ cf->curline++;
+ break;
+ case '/':
+
+ if ((*pos)[1] == '*')
+ {
+ startline = cf->curline;
+ (*pos)++;
+ (*pos)++;
+
+ while (**pos != '\0' && (**pos != '*' || (*pos)[1] != '/'))
{
- startline = cf->curline;
- (*pos)++;
+ if (**pos == '\n')
+ cf->curline++;
+
(*pos)++;
- while (**pos != '\0' && (**pos != '*' || (*pos)[1] != '/'))
- {
- if (**pos == '\n')
- cf->curline++;
- (*pos)++;
- }
- if (**pos == '\0')
- mowgli_config_file_error(cf, "File ends inside comment starting at line %d", startline);
- else
- (*pos)++; /* skip '*' */
- }
- else if ((*pos)[1] == '/')
- {
- while (**pos != '\0' && **pos != '\n' && **pos != '\r')
- (*pos)++;
- continue;
}
+
+ if (**pos == '\0')
+ mowgli_config_file_error(cf, "File ends inside comment starting at line %d", startline);
else
- return;
- break;
- case '#':
+ (*pos)++; /* skip '*' */
+ }
+ else if ((*pos)[1] == '/')
+ {
while (**pos != '\0' && **pos != '\n' && **pos != '\r')
+ {
(*pos)++;
+ }
+
continue;
- default:
+ }
+ else
+ {
return;
+ }
+
+ break;
+ case '#':
+
+ while (**pos != '\0' && **pos != '\n' && **pos != '\r')
+ {
+ (*pos)++;
+ }
+
+ continue;
+ default:
+ return;
}
+
if (**pos == '\0')
return;
+
(*pos)++;
}
}
-static char *get_value(char **pos, mowgli_config_file_t *cf, char *skipped)
+static char *
+get_value(char **pos, mowgli_config_file_t *cf, char *skipped)
{
char *p = *pos;
char *q;
char *start;
*skipped = '\0';
+
if (*p == '"')
{
p++;
start = p;
q = p;
+
while (*p != '\0' && *p != '\r' && *p != '\n' && *p != '"')
{
- if (*p == '\\' && (p[1] == '"' || p[1] == '\\'))
+ if ((*p == '\\') && ((p[1] == '"') || (p[1] == '\\')))
p++;
+
*q++ = *p++;
}
+
if (*p == '\0')
{
mowgli_config_file_error(cf, "File ends inside quoted string");
return NULL;
}
- if (*p == '\r' || *p == '\n')
+
+ if ((*p == '\r') || (*p == '\n'))
{
mowgli_config_file_error(cf, "Newline inside quoted string");
return NULL;
}
+
if (*p != '"')
{
mowgli_config_file_error(cf, "Weird character terminating quoted string (BUG)");
return NULL;
}
+
p++;
*q = '\0';
*pos = p;
@@ -176,24 +206,34 @@ static char *get_value(char **pos, mowgli_config_file_t *cf, char *skipped)
else
{
start = p;
+
while (*p != '\0' && *p != '\t' && *p != '\r' && *p != '\n' &&
- *p != ' ' && *p != '/' && *p != '#' &&
- *p != ';' && *p != '{' && *p != '}')
+ *p != ' ' && *p != '/' && *p != '#' &&
+ *p != ';' && *p != '{' && *p != '}')
+ {
p++;
+ }
+
if (p == start)
return NULL;
+
*pos = p;
skip_ws(pos, cf);
+
if (p == *pos)
*skipped = *p;
+
*p = '\0';
+
if (p == *pos)
(*pos)++;
+
return start;
}
}
-static mowgli_config_file_t *mowgli_config_file_parse(const char *filename, char *confdata)
+static mowgli_config_file_t *
+mowgli_config_file_parse(const char *filename, char *confdata)
{
mowgli_config_file_t *cf, *subcf, *lastcf;
mowgli_config_file_entry_t **pprevce, *ce, *upce;
@@ -208,11 +248,14 @@ static mowgli_config_file_t *mowgli_config_file_parse(const char *filename, char
pprevce = &cf->entries;
upce = NULL;
p = confdata;
+
while (*p != '\0')
{
skip_ws(&p, cf);
- if (*p == '\0' || CF_ERRORED(cf))
+
+ if ((*p == '\0') || CF_ERRORED(cf))
break;
+
if (*p == '}')
{
if (upce == NULL)
@@ -220,31 +263,39 @@ static mowgli_config_file_t *mowgli_config_file_parse(const char *filename, char
mowgli_config_file_error(cf, "Extraneous closing brace");
break;
}
+
ce = upce;
ce->sectlinenum = cf->curline;
pprevce = &ce->next;
upce = ce->prevlevel;
p++;
skip_ws(&p, cf);
+
if (CF_ERRORED(cf))
break;
+
if (*p != ';')
{
mowgli_config_file_error(cf, "Missing semicolon after closing brace for section ending at line %d", ce->sectlinenum);
break;
}
+
ce = NULL;
p++;
continue;
}
+
val = get_value(&p, cf, &c);
+
if (CF_ERRORED(cf))
break;
+
if (val == NULL)
{
mowgli_config_file_error(cf, "Unexpected character trying to read variable name");
break;
}
+
ce = mowgli_alloc(sizeof *ce);
ce->fileptr = cf;
ce->varlinenum = cf->curline;
@@ -252,8 +303,10 @@ static mowgli_config_file_t *mowgli_config_file_parse(const char *filename, char
ce->prevlevel = upce;
*pprevce = ce;
pprevce = &ce->next;
- if (c == '\0' && (*p == '{' || *p == ';'))
+
+ if ((c == '\0') && ((*p == '{') || (*p == ';')))
c = *p++;
+
if (c == '{')
{
pprevce = &ce->entries;
@@ -272,16 +325,21 @@ static mowgli_config_file_t *mowgli_config_file_parse(const char *filename, char
else
{
val = get_value(&p, cf, &c);
+
if (CF_ERRORED(cf))
break;
+
if (val == NULL)
{
mowgli_config_file_error(cf, "Unexpected character trying to read value for %s", ce->varname);
break;
}
+
ce->vardata = val;
- if (c == '\0' && (*p == '{' || *p == ';'))
+
+ if ((c == '\0') && ((*p == '{') || (*p == ';')))
c = *p++;
+
if (c == '{')
{
pprevce = &ce->entries;
@@ -290,18 +348,24 @@ static mowgli_config_file_t *mowgli_config_file_parse(const char *filename, char
}
else if (c == ';')
{
- if (upce == NULL && !strcasecmp(ce->varname, "include"))
+ if ((upce == NULL) && !strcasecmp(ce->varname, "include"))
{
subcf = mowgli_config_file_load_internal(cf, ce->vardata);
+
if (subcf == NULL)
{
mowgli_config_file_error(cf, "Error in file included from here");
break;
}
+
lastcf->next = subcf;
+
while (lastcf->next != NULL)
+ {
lastcf = lastcf->next;
+ }
}
+
ce = NULL;
}
else
@@ -311,59 +375,74 @@ static mowgli_config_file_t *mowgli_config_file_parse(const char *filename, char
}
}
}
- if (!CF_ERRORED(cf) && upce != NULL)
+
+ if (!CF_ERRORED(cf) && (upce != NULL))
{
mowgli_config_file_error(cf, "One or more sections not closed");
ce = upce;
+
while (ce->prevlevel != NULL)
+ {
ce = ce->prevlevel;
+ }
+
if (ce->vardata != NULL)
mowgli_config_file_error(cf, "First unclosed section is %s %s at line %d",
- ce->varname, ce->vardata, ce->varlinenum);
+ ce->varname, ce->vardata, ce->varlinenum);
else
mowgli_config_file_error(cf, "First unclosed section is %s at line %d",
- ce->varname, ce->varlinenum);
+ ce->varname, ce->varlinenum);
}
+
if (CF_ERRORED(cf))
{
mowgli_config_file_free(cf);
cf = NULL;
}
+
return cf;
}
-static void mowgli_config_file_entry_free(mowgli_config_file_entry_t *ceptr)
+static void
+mowgli_config_file_entry_free(mowgli_config_file_entry_t *ceptr)
{
mowgli_config_file_entry_t *nptr;
for (; ceptr; ceptr = nptr)
{
nptr = ceptr->next;
+
if (ceptr->entries)
mowgli_config_file_entry_free(ceptr->entries);
+
/* ce_varname and ce_vardata are inside cf_mem */
mowgli_free(ceptr);
}
}
-void mowgli_config_file_free(mowgli_config_file_t *cfptr)
+void
+mowgli_config_file_free(mowgli_config_file_t *cfptr)
{
mowgli_config_file_t *nptr;
for (; cfptr; cfptr = nptr)
{
nptr = cfptr->next;
+
if (cfptr->entries)
mowgli_config_file_entry_free(cfptr->entries);
+
mowgli_free(cfptr->filename);
mowgli_free(cfptr->mem);
mowgli_free(cfptr);
}
}
-static mowgli_config_file_t *mowgli_config_file_load_internal(mowgli_config_file_t *parent, const char *filename)
+static mowgli_config_file_t *
+mowgli_config_file_load_internal(mowgli_config_file_t *parent, const char *filename)
{
struct stat sb;
+
FILE *fp;
size_t ret;
char *buf = NULL;
@@ -377,35 +456,42 @@ static mowgli_config_file_t *mowgli_config_file_load_internal(mowgli_config_file
}
fp = fopen(filename, "rb");
+
if (!fp)
{
mowgli_config_file_error(parent, "Couldn't open \"%s\": %s\n", filename, strerror(errno));
return NULL;
}
+
if (stat(filename, &sb) == -1)
{
mowgli_config_file_error(parent, "Couldn't fstat \"%s\": %s\n", filename, strerror(errno));
fclose(fp);
return NULL;
}
+
if (!S_ISREG(sb.st_mode))
{
mowgli_config_file_error(parent, "Not a regular file: \"%s\"\n", filename);
fclose(fp);
return NULL;
}
+
if (sb.st_size > SSIZE_MAX - 1)
{
mowgli_config_file_error(parent, "File too large: \"%s\"\n", filename);
fclose(fp);
return NULL;
}
+
buf = (char *) mowgli_alloc(sb.st_size + 1);
+
if (sb.st_size)
{
errno = 0;
ret = fread(buf, 1, sb.st_size, fp);
- if (ret != (size_t)sb.st_size)
+
+ if (ret != (size_t) sb.st_size)
{
mowgli_config_file_error(parent, "Error reading \"%s\": %s\n", filename, strerror(errno ? errno : EFAULT));
mowgli_free(buf);
@@ -414,17 +500,22 @@ static mowgli_config_file_t *mowgli_config_file_load_internal(mowgli_config_file
}
}
else
+ {
ret = 0;
+ }
+
buf[ret] = '\0';
fclose(fp);
nestcnt++;
cfptr = mowgli_config_file_parse(filename, buf);
nestcnt--;
+
/* buf is owned by cfptr or freed now */
return cfptr;
}
-mowgli_config_file_t *mowgli_config_file_load(const char *filename)
+mowgli_config_file_t *
+mowgli_config_file_load(const char *filename)
{
return mowgli_config_file_load_internal(NULL, filename);
}
diff --git a/src/libmowgli/ext/confparse.h b/src/libmowgli/ext/confparse.h
index d498b87..cedf708 100644
--- a/src/libmowgli/ext/confparse.h
+++ b/src/libmowgli/ext/confparse.h
@@ -28,7 +28,7 @@ struct _mowgli_configentry
int varlinenum;
char *varname;
char *vardata;
- int sectlinenum; /* line containing closing brace */
+ int sectlinenum;/* line containing closing brace */
mowgli_config_file_entry_t *entries;
mowgli_config_file_entry_t *prevlevel;
diff --git a/src/libmowgli/ext/error_backtrace.c b/src/libmowgli/ext/error_backtrace.c
index 6c28c22..2adb906 100644
--- a/src/libmowgli/ext/error_backtrace.c
+++ b/src/libmowgli/ext/error_backtrace.c
@@ -26,14 +26,12 @@
void
mowgli_error_context_display(mowgli_error_context_t *e, const char *delim)
{
- mowgli_node_t *n;
- char *bt_msg;
-
return_if_fail(e != NULL);
return_if_fail(delim != NULL);
+ return_if_fail(MOWGLI_LIST_LENGTH(&e->bt) != 0);
- if (MOWGLI_LIST_LENGTH(&e->bt) == 0)
- mowgli_throw_exception(mowgli.error_backtrace.no_backtrace);
+ mowgli_node_t *n;
+ char *bt_msg;
MOWGLI_LIST_FOREACH(n, e->bt.head)
{
diff --git a/src/libmowgli/ext/error_backtrace.h b/src/libmowgli/ext/error_backtrace.h
index d7da7cf..3ec54de 100644
--- a/src/libmowgli/ext/error_backtrace.h
+++ b/src/libmowgli/ext/error_backtrace.h
@@ -24,7 +24,8 @@
#ifndef __MOWGLI_ERROR_BACKTRACE_H__
#define __MOWGLI_ERROR_BACKTRACE_H__
-typedef struct mowgli_error_context_ {
+typedef struct mowgli_error_context_
+{
mowgli_list_t bt;
} mowgli_error_context_t;
diff --git a/src/libmowgli/ext/getopt_long.c b/src/libmowgli/ext/getopt_long.c
index adf64e5..dd70325 100644
--- a/src/libmowgli/ext/getopt_long.c
+++ b/src/libmowgli/ext/getopt_long.c
@@ -33,37 +33,40 @@
#include "getopt_long.h"
-int mowgli_opterr = 1; /* if error message should be printed */
-int mowgli_optind = 1; /* index into parent argv vector */
-int mowgli_optopt = '?'; /* character checked for validity */
-int mowgli_optreset = 0; /* reset getopt */
-char *mowgli_optarg = NULL; /* argument associated with option */
+int mowgli_opterr = 1; /* if error message should be printed */
+int mowgli_optind = 1; /* index into parent argv vector */
+int mowgli_optopt = '?';/* character checked for validity */
+int mowgli_optreset = 0;/* reset getopt */
+char *mowgli_optarg = NULL; /* argument associated with option */
/* XXX: suppress const warnings */
-#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
+#define __UNCONST(a) ((void *) (unsigned long) (const void *) (a))
-#define IGNORE_FIRST (*options == '-' || *options == '+')
-#define PRINT_ERROR ((mowgli_opterr) && ((*options != ':') \
- || (IGNORE_FIRST && options[1] != ':')))
+#define IGNORE_FIRST (*options == '-' || *options == '+')
+#define PRINT_ERROR ((mowgli_opterr) && ((*options != ':') \
+ || (IGNORE_FIRST && options[1] != ':')))
#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL)
-#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST)
+#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST)
+
/* XXX: GNU ignores PC if *options == '-' */
-#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-')
+#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-')
/* return values */
-#define BADCH (int)'?'
-#define BADARG ((IGNORE_FIRST && options[1] == ':') \
- || (*options == ':') ? (int)':' : (int)'?')
-#define INORDER (int)1
+#define BADCH (int) '?'
+#define BADARG ((IGNORE_FIRST && options[1] == ':') \
+ || (*options == ':') ? (int) ':' : (int) '?')
+#define INORDER (int) 1
-#define EMSG ""
+#define EMSG ""
static inline void
warnx(const char *fmt, ...)
{
va_list ap;
+
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
+ fputc('\n', stderr);
va_end(ap);
}
@@ -71,11 +74,11 @@ static int getopt_internal(int, char **, const char *);
static int gcd(int, int);
static void permute_args(int, int, int, char **);
-static const char *place = EMSG; /* option letter processing */
+static const char *place = EMSG;/* option letter processing */
/* XXX: set mowgli_optreset to 1 rather than these two */
-static int nonopt_start = -1; /* first non option argument (for permute) */
-static int nonopt_end = -1; /* first option after non options (for permute) */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1; /* first option after non options (for permute) */
/* Error messages */
static const char recargchar[] = "option requires an argument -- %c";
@@ -85,7 +88,6 @@ static const char noarg[] = "option doesn't take an argument -- %.*s";
static const char illoptchar[] = "unknown option -- %c";
static const char illoptstring[] = "unknown option -- %s";
-
/*
* Compute the greatest common divisor of a and b.
*/
@@ -95,12 +97,14 @@ gcd(int a, int b)
int c;
c = a % b;
- while (c != 0) {
+
+ while (c != 0)
+ {
a = b;
b = c;
c = a % b;
}
-
+
return b;
}
@@ -125,14 +129,18 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, char **nargv)
ncycle = gcd(nnonopts, nopts);
cyclelen = (opt_end - panonopt_start) / ncycle;
- for (i = 0; i < ncycle; i++) {
- cstart = panonopt_end+i;
+ for (i = 0; i < ncycle; i++)
+ {
+ cstart = panonopt_end + i;
pos = cstart;
- for (j = 0; j < cyclelen; j++) {
+
+ for (j = 0; j < cyclelen; j++)
+ {
if (pos >= panonopt_end)
pos -= nnonopts;
else
pos += nopts;
+
swap = nargv[pos];
nargv[pos] = nargv[cstart];
nargv[cstart] = swap;
@@ -148,7 +156,7 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, char **nargv)
static int
getopt_internal(int nargc, char **nargv, const char *options)
{
- char *oli; /* option letter list index */
+ char *oli; /* option letter list index */
int optchar;
return_val_if_fail(nargv != NULL, -1);
@@ -166,116 +174,167 @@ getopt_internal(int nargc, char **nargv, const char *options)
if (mowgli_optreset)
nonopt_start = nonopt_end = -1;
+
start:
- if (mowgli_optreset || !*place) { /* update scanning pointer */
+
+ if (mowgli_optreset || !*place) /* update scanning pointer */
+ {
mowgli_optreset = 0;
- if (mowgli_optind >= nargc) { /* end of argument vector */
+
+ if (mowgli_optind >= nargc) /* end of argument vector */
+ {
place = EMSG;
- if (nonopt_end != -1) {
+
+ if (nonopt_end != -1)
+ {
/* do permutation, if we have to */
permute_args(nonopt_start, nonopt_end,
- mowgli_optind, nargv);
+ mowgli_optind, nargv);
mowgli_optind -= nonopt_end - nonopt_start;
}
- else if (nonopt_start != -1) {
+ else if (nonopt_start != -1)
+ {
/*
* If we skipped non-options, set mowgli_optind
* to the first of them.
*/
mowgli_optind = nonopt_start;
}
+
nonopt_start = nonopt_end = -1;
return -1;
}
+
if ((*(place = nargv[mowgli_optind]) != '-')
- || (place[1] == '\0')) { /* found non-option */
+ || (place[1] == '\0')) /* found non-option */
+ {
place = EMSG;
- if (IN_ORDER) {
+
+ if (IN_ORDER)
+ {
/*
- * GNU extension:
+ * GNU extension:
* return non-option as argument to option 1
*/
mowgli_optarg = nargv[mowgli_optind++];
return INORDER;
}
- if (!PERMUTE) {
+
+ if (!PERMUTE)
/*
* if no permutation wanted, stop parsing
* at first non-option
*/
return -1;
- }
+
/* do permutation */
if (nonopt_start == -1)
+ {
nonopt_start = mowgli_optind;
- else if (nonopt_end != -1) {
+ }
+ else if (nonopt_end != -1)
+ {
permute_args(nonopt_start, nonopt_end,
- mowgli_optind, nargv);
+ mowgli_optind, nargv);
nonopt_start = mowgli_optind -
- (nonopt_end - nonopt_start);
+ (nonopt_end - nonopt_start);
nonopt_end = -1;
}
+
mowgli_optind++;
+
/* process next argument */
goto start;
}
- if (nonopt_start != -1 && nonopt_end == -1)
+
+ if ((nonopt_start != -1) && (nonopt_end == -1))
nonopt_end = mowgli_optind;
- if (place[1] && *++place == '-') { /* found "--" */
+
+ if (place[1] && (*++place == '-')) /* found "--" */
+ {
place++;
return -2;
}
}
- if ((optchar = (int)*place++) == (int)':' ||
- (oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) {
+
+ if (((optchar = (int) *place++) == (int) ':') ||
+ ((oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL))
+ {
/* option letter unknown or ':' */
if (!*place)
++mowgli_optind;
+
if (PRINT_ERROR)
warnx(illoptchar, optchar);
+
mowgli_optopt = optchar;
return BADCH;
}
- if (optchar == 'W' && oli[1] == ';') { /* -W long-option */
- /* XXX: what if no long options provided (called by getopt)? */
- if (*place)
+
+ if ((optchar == 'W') && (oli[1] == ';'))/* -W long-option */
+ { /* XXX: what if no long options provided (called by getopt)? */
+ if (*place)
return -2;
- if (++mowgli_optind >= nargc) { /* no arg */
+ if (++mowgli_optind >= nargc) /* no arg */
+ {
place = EMSG;
+
if (PRINT_ERROR)
warnx(recargchar, optchar);
+
mowgli_optopt = optchar;
return BADARG;
- } else /* white space */
+ }
+ else /* white space */
+ {
place = nargv[mowgli_optind];
+ }
+
/*
* Handle -W arg the same as --arg (which causes getopt to
* stop parsing).
*/
return -2;
}
- if (*++oli != ':') { /* doesn't take argument */
+
+ if (*++oli != ':') /* doesn't take argument */
+ {
if (!*place)
++mowgli_optind;
- } else { /* takes (optional) argument */
+ }
+ else /* takes (optional) argument */
+ {
mowgli_optarg = NULL;
- if (*place) /* no white space */
+
+ if (*place) /* no white space */
+ {
mowgli_optarg = __UNCONST(place);
+ }
+
/* XXX: disable test for :: if PC? (GNU doesn't) */
- else if (oli[1] != ':') { /* arg not optional */
- if (++mowgli_optind >= nargc) { /* no arg */
+ else if (oli[1] != ':') /* arg not optional */
+ {
+ if (++mowgli_optind >= nargc) /* no arg */
+ {
place = EMSG;
+
if (PRINT_ERROR)
warnx(recargchar, optchar);
+
mowgli_optopt = optchar;
return BADARG;
- } else
+ }
+ else
+ {
mowgli_optarg = nargv[mowgli_optind];
+ }
}
+
place = EMSG;
++mowgli_optind;
}
+
/* dump back option letter */
return optchar;
}
@@ -286,11 +345,11 @@ start:
*
* [eventually this will replace the real getopt]
*/
-int
-mowgli_getopt(nargc, nargv, options)
- int nargc;
- char * const *nargv;
- const char *options;
+int mowgli_getopt(nargc, nargv, options)
+int nargc;
+
+char *const *nargv;
+const char *options;
{
int retval;
@@ -298,20 +357,26 @@ mowgli_getopt(nargc, nargv, options)
return_val_if_fail(options != NULL, -1);
retval = getopt_internal(nargc, __UNCONST(nargv), options);
- if (retval == -2) {
+
+ if (retval == -2)
+ {
++mowgli_optind;
+
/*
* We found an option (--), so if we skipped non-options,
* we have to permute.
*/
- if (nonopt_end != -1) {
+ if (nonopt_end != -1)
+ {
permute_args(nonopt_start, nonopt_end, mowgli_optind,
- __UNCONST(nargv));
+ __UNCONST(nargv));
mowgli_optind -= nonopt_end - nonopt_start;
}
+
nonopt_start = nonopt_end = -1;
retval = -1;
}
+
return retval;
}
@@ -320,23 +385,25 @@ mowgli_getopt(nargc, nargv, options)
* Parse argc/argv argument vector.
*/
int
-mowgli_getopt_long(int nargc, char * const *nargv, const char *options,
- const mowgli_getopt_option_t *long_options, int *idx)
+mowgli_getopt_long(int nargc, char *const *nargv, const char *options, const mowgli_getopt_option_t *long_options, int *idx)
{
int retval;
-#define IDENTICAL_INTERPRETATION(_x, _y) \
- (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \
- long_options[(_x)].flag == long_options[(_y)].flag && \
+#define IDENTICAL_INTERPRETATION(_x, _y) \
+ (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \
+ long_options[(_x)].flag == long_options[(_y)].flag && \
long_options[(_x)].val == long_options[(_y)].val)
return_val_if_fail(nargv != NULL, -1);
return_val_if_fail(options != NULL, -1);
return_val_if_fail(long_options != NULL, -1);
+
/* idx may be NULL */
retval = getopt_internal(nargc, __UNCONST(nargv), options);
- if (retval == -2) {
+
+ if (retval == -2)
+ {
char *current_argv, *has_equal;
size_t current_argv_len;
int i, ambiguous, match;
@@ -348,58 +415,75 @@ mowgli_getopt_long(int nargc, char * const *nargv, const char *options,
mowgli_optind++;
place = EMSG;
- if (*current_argv == '\0') { /* found "--" */
- /*
+ if (*current_argv == '\0') /* found "--" */
+ { /*
* We found an option (--), so if we skipped
* non-options, we have to permute.
*/
- if (nonopt_end != -1) {
+ if (nonopt_end != -1)
+ {
permute_args(nonopt_start, nonopt_end,
- mowgli_optind, __UNCONST(nargv));
+ mowgli_optind, __UNCONST(nargv));
mowgli_optind -= nonopt_end - nonopt_start;
}
+
nonopt_start = nonopt_end = -1;
return -1;
}
- if ((has_equal = strchr(current_argv, '=')) != NULL) {
+
+ if ((has_equal = strchr(current_argv, '=')) != NULL)
+ {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
- } else
+ }
+ else
+ {
current_argv_len = strlen(current_argv);
+ }
- for (i = 0; long_options[i].name; i++) {
+ for (i = 0; long_options[i].name; i++)
+ {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
- current_argv_len))
+ current_argv_len))
continue;
if (strlen(long_options[i].name) ==
- (unsigned)current_argv_len) {
+ (unsigned) current_argv_len)
+ {
/* exact match */
match = i;
ambiguous = 0;
break;
}
- if (match == -1) /* partial match */
+
+ if (match == -1)/* partial match */
match = i;
else if (!IDENTICAL_INTERPRETATION(i, match))
ambiguous = 1;
}
- if (ambiguous) {
+
+ if (ambiguous)
+ {
/* ambiguous abbreviation */
if (PRINT_ERROR)
- warnx(ambig, (int)current_argv_len,
- current_argv);
+ warnx(ambig, (int) current_argv_len,
+ current_argv);
+
mowgli_optopt = 0;
return BADCH;
}
- if (match != -1) { /* option found */
- if (long_options[match].has_arg == no_argument
- && has_equal) {
+
+ if (match != -1)/* option found */
+ {
+ if ((long_options[match].has_arg == no_argument)
+ && has_equal)
+ {
if (PRINT_ERROR)
- warnx(noarg, (int)current_argv_len,
- current_argv);
+ warnx(noarg, (int) current_argv_len,
+ current_argv);
+
/*
* XXX: GNU sets mowgli_optopt to val regardless of
* flag
@@ -408,29 +492,34 @@ mowgli_getopt_long(int nargc, char * const *nargv, const char *options,
mowgli_optopt = long_options[match].val;
else
mowgli_optopt = 0;
+
return BADARG;
}
- if (long_options[match].has_arg == required_argument ||
- long_options[match].has_arg == optional_argument) {
+
+ if ((long_options[match].has_arg == required_argument) ||
+ (long_options[match].has_arg == optional_argument))
+ {
if (has_equal)
mowgli_optarg = has_equal;
else if (long_options[match].has_arg ==
- required_argument) {
+ required_argument)
/*
* optional argument doesn't use
* next nargv
*/
mowgli_optarg = nargv[mowgli_optind++];
- }
}
+
if ((long_options[match].has_arg == required_argument)
- && (mowgli_optarg == NULL)) {
+ && (mowgli_optarg == NULL))
+ {
/*
* Missing argument; leading ':'
* indicates no error should be generated
*/
if (PRINT_ERROR)
warnx(recargstring, current_argv);
+
/*
* XXX: GNU sets mowgli_optopt to val regardless
* of flag
@@ -439,23 +528,34 @@ mowgli_getopt_long(int nargc, char * const *nargv, const char *options,
mowgli_optopt = long_options[match].val;
else
mowgli_optopt = 0;
+
--mowgli_optind;
return BADARG;
}
- } else { /* unknown option */
+ }
+ else /* unknown option */
+ {
if (PRINT_ERROR)
warnx(illoptstring, current_argv);
+
mowgli_optopt = 0;
return BADCH;
}
- if (long_options[match].flag) {
+
+ if (long_options[match].flag)
+ {
*long_options[match].flag = long_options[match].val;
retval = 0;
- } else
+ }
+ else
+ {
retval = long_options[match].val;
+ }
+
if (idx)
*idx = match;
}
+
return retval;
#undef IDENTICAL_INTERPRETATION
}
diff --git a/src/libmowgli/ext/getopt_long.h b/src/libmowgli/ext/getopt_long.h
index 94c90a9..84653ab 100644
--- a/src/libmowgli/ext/getopt_long.h
+++ b/src/libmowgli/ext/getopt_long.h
@@ -35,30 +35,34 @@
/*
* Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions
*/
-#define no_argument 0
-#define required_argument 1
-#define optional_argument 2
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
-typedef struct {
+typedef struct
+{
/* name of long option */
const char *name;
+
/*
* one of no_argument, required_argument, and optional_argument:
* whether option takes an argument
*/
int has_arg;
+
/* if not NULL, set *flag to val when option found */
int *flag;
+
/* if flag not NULL, value to set *flag to; else return value */
int val;
+
/* internal value */
int iflag;
} mowgli_getopt_option_t;
-extern int mowgli_getopt(int nargc, char * const *nargv, const char *options);
+extern int mowgli_getopt(int nargc, char *const *nargv, const char *options);
-extern int mowgli_getopt_long(int, char * const *, const char *,
- const mowgli_getopt_option_t *, int *);
+extern int mowgli_getopt_long(int, char *const *, const char *, const mowgli_getopt_option_t *, int *);
extern int mowgli_opterr;
extern int mowgli_optind;
diff --git a/src/libmowgli/ext/global_storage.c b/src/libmowgli/ext/global_storage.c
index 4fec74d..f9196ab 100644
--- a/src/libmowgli/ext/global_storage.c
+++ b/src/libmowgli/ext/global_storage.c
@@ -26,10 +26,9 @@
static mowgli_patricia_t *mowgli_global_storage_dict = NULL;
static mowgli_mutex_t mowgli_global_storage_lock;
-static void _storage_key_canon(char *key)
-{
-
-}
+static void
+_storage_key_canon(char *key)
+{ }
void
mowgli_global_storage_bootstrap(void)
@@ -66,4 +65,3 @@ mowgli_global_storage_free(char *name)
mowgli_patricia_delete(mowgli_global_storage_dict, name);
mowgli_mutex_unlock(&mowgli_global_storage_lock);
}
-
diff --git a/src/libmowgli/ext/global_storage.h b/src/libmowgli/ext/global_storage.h
index a26e699..59bc995 100644
--- a/src/libmowgli/ext/global_storage.h
+++ b/src/libmowgli/ext/global_storage.h
@@ -24,7 +24,6 @@
#ifndef MOWGLI_GLOBAL_STORAGE_H
#define MOWGLI_GLOBAL_STORAGE_H
-extern void mowgli_global_storage_bootstrap(void);
extern void *mowgli_global_storage_get(char *name);
extern void mowgli_global_storage_put(char *name, void *value);
extern void mowgli_global_storage_free(char *name);
diff --git a/src/libmowgli/ext/json-inline.h b/src/libmowgli/ext/json-inline.h
new file mode 100644
index 0000000..787b7a7
--- /dev/null
+++ b/src/libmowgli/ext/json-inline.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 Alex Iadicicco
+ * Rights to this code are as documented in COPYING.
+ *
+ * JSON inline functions, to simplify refcounting etc for other users
+ */
+
+#ifndef MOWGLI_JSON_INLINE_H
+#define MOWGLI_JSON_INLINE_H
+
+/* We don't need to include any other headers here. This is in a separate
+ file to keep clutter out of the main json.h */
+
+/* string */
+static inline void
+mowgli_json_string_reset(mowgli_json_t *s)
+{
+ mowgli_string_reset(MOWGLI_JSON_STRING(s));
+}
+
+static inline void
+mowgli_json_string_append(mowgli_json_t *s, const char *src, size_t n)
+{
+ mowgli_string_append(MOWGLI_JSON_STRING(s), src, n);
+}
+
+static inline void
+mowgli_json_string_append_char(mowgli_json_t *s, const char c)
+{
+ mowgli_string_append_char(MOWGLI_JSON_STRING(s), c);
+}
+
+/* array */
+static inline size_t
+mowgli_json_array_size(mowgli_json_t *arr)
+{
+ return MOWGLI_JSON_ARRAY(arr)->count;
+}
+
+static inline void
+mowgli_json_array_add(mowgli_json_t *arr, mowgli_json_t *data)
+{
+ mowgli_node_add(mowgli_json_incref(data), mowgli_node_create(), MOWGLI_JSON_ARRAY(arr));
+}
+
+static inline void
+mowgli_json_array_add_head(mowgli_json_t *arr, mowgli_json_t *data)
+{
+ mowgli_node_add_head(mowgli_json_incref(data), mowgli_node_create(), MOWGLI_JSON_ARRAY(arr));
+}
+
+static inline void
+mowgli_json_array_insert(mowgli_json_t *arr, mowgli_json_t *data, size_t pos)
+{
+ mowgli_node_insert(mowgli_json_incref(data), mowgli_node_create(), MOWGLI_JSON_ARRAY(arr), pos);
+}
+
+static inline void
+mowgli_json_array_delete(mowgli_json_t *arr, mowgli_json_t *data)
+{
+ mowgli_node_t *n = mowgli_node_find(data, MOWGLI_JSON_ARRAY(arr));
+
+ if (n == NULL)
+ return;
+
+ mowgli_node_delete(n, MOWGLI_JSON_ARRAY(arr));
+ mowgli_json_decref(data);
+}
+
+static inline bool
+mowgli_json_array_contains(mowgli_json_t *arr, mowgli_json_t *data)
+{
+ return mowgli_node_find(data, MOWGLI_JSON_ARRAY(arr)) != NULL;
+}
+
+static inline mowgli_json_t *
+mowgli_json_array_nth(mowgli_json_t *arr, size_t pos)
+{
+ return (mowgli_json_t *) mowgli_node_nth_data(MOWGLI_JSON_ARRAY(arr), pos);
+}
+
+/* object */
+static inline size_t
+mowgli_json_object_size(mowgli_json_t *obj)
+{
+ return mowgli_patricia_size(MOWGLI_JSON_OBJECT(obj));
+}
+
+static inline void
+mowgli_json_object_add(mowgli_json_t *obj, const char *key, mowgli_json_t *data)
+{
+ mowgli_patricia_add(MOWGLI_JSON_OBJECT(obj), key, mowgli_json_incref(data));
+}
+
+static inline mowgli_json_t *
+mowgli_json_object_retrieve(mowgli_json_t *obj, const char *key)
+{
+ return (mowgli_json_t *) mowgli_patricia_retrieve(MOWGLI_JSON_OBJECT(obj), key);
+}
+
+static inline mowgli_json_t *
+mowgli_json_object_delete(mowgli_json_t *obj, const char *key)
+{
+ return (mowgli_json_t *) mowgli_patricia_delete(MOWGLI_JSON_OBJECT(obj), key);
+}
+
+#endif
diff --git a/src/libmowgli/ext/json.c b/src/libmowgli/ext/json.c
new file mode 100644
index 0000000..3e273a4
--- /dev/null
+++ b/src/libmowgli/ext/json.c
@@ -0,0 +1,1475 @@
+/*
+ * Copyright (C) 2012 Alex Iadicicco
+ * Rights to this code are as documented in COPYING
+ *
+ * Structs and functions for interacting with JSON documents from C
+ */
+
+#include <mowgli.h>
+
+/* TOC:
+ * 0. JSON subsystem constants
+ * 1. Reference counters
+ * 2. Object creation and deletion
+ * 3. Serializer (a.k.a. formatter, printer, etc.)
+ * 4. Deserializer (a.k.a. parser, etc.)
+ */
+
+/*
+ * 0. JSON SUBSYSTEM CONSTANTS
+ */
+
+#define LL_STACK_SIZE 128
+
+#define JSON_REFCOUNT_CONSTANT -42
+
+static mowgli_json_t json_null =
+{
+ .tag = MOWGLI_JSON_TAG_NULL,
+ .refcount = JSON_REFCOUNT_CONSTANT,
+};
+mowgli_json_t *mowgli_json_null = &json_null;
+
+static mowgli_json_t json_true =
+{
+ .tag = MOWGLI_JSON_TAG_BOOLEAN,
+ .refcount = JSON_REFCOUNT_CONSTANT,
+ { .v_bool = true, }
+};
+mowgli_json_t *mowgli_json_true = &json_true;
+
+static mowgli_json_t json_false =
+{
+ .tag = MOWGLI_JSON_TAG_BOOLEAN,
+ .refcount = JSON_REFCOUNT_CONSTANT,
+ { .v_bool = false, }
+};
+mowgli_json_t *mowgli_json_false = &json_false;
+
+static mowgli_json_t *json_alloc(mowgli_json_tag_t tag);
+static void json_destroy(mowgli_json_t *n);
+static void destroy_extra_string(mowgli_json_t *n);
+static void destroy_extra_array(mowgli_json_t *n);
+static void destroy_extra_object(mowgli_json_t *n);
+
+typedef void (*destroy_extra_cb_t)(mowgli_json_t *);
+static destroy_extra_cb_t destroy_extra[] =
+{
+ [MOWGLI_JSON_TAG_STRING] = destroy_extra_string,
+ [MOWGLI_JSON_TAG_ARRAY] = destroy_extra_array,
+ [MOWGLI_JSON_TAG_OBJECT] = destroy_extra_object,
+};
+
+/*
+ * 1. REFERENCE COUNTERS
+ */
+
+mowgli_json_t *
+mowgli_json_incref(mowgli_json_t *n)
+{
+ if ((n == NULL) || (n->refcount == JSON_REFCOUNT_CONSTANT))
+ return n;
+
+ n->refcount++;
+
+ return n;
+}
+
+mowgli_json_t *
+mowgli_json_decref(mowgli_json_t *n)
+{
+ if ((n == NULL) || (n->refcount == JSON_REFCOUNT_CONSTANT))
+ return n;
+
+ n->refcount--;
+
+ if (n->refcount <= 0)
+ {
+ json_destroy(n);
+ return NULL;
+ }
+
+ return n;
+}
+
+/* Debugging tool to recursively dump reference counts for an object
+ and any children it may have. This function will never be called
+ outside of development, so is commented here.
+ void dump_refs(mowgli_json_t *n)
+ {
+ char *s = "unk";
+ mowgli_patricia_iteration_state_t st;
+
+ switch (n->tag) {
+ case MOWGLI_JSON_TAG_NULL: s = "null"; break;
+ case MOWGLI_JSON_TAG_BOOLEAN: s = "boolean"; break;
+ case MOWGLI_JSON_TAG_INTEGER: s = "integer"; break;
+ case MOWGLI_JSON_TAG_FLOAT: s = "float"; break;
+ case MOWGLI_JSON_TAG_STRING: s = "string"; break;
+ case MOWGLI_JSON_TAG_ARRAY: s = "array"; break;
+ case MOWGLI_JSON_TAG_OBJECT: s = "object"; break;
+ }
+
+ if (n->refcount == JSON_REFCOUNT_CONSTANT)
+ printf("- %s\n", s);
+ else
+ printf("%d %s\n", n->refcount, s);
+
+ if (n->tag == MOWGLI_JSON_TAG_ARRAY) {
+ mowgli_node_t *cur;
+
+ MOWGLI_LIST_FOREACH(cur, n->v_array->head) {
+ dump_refs(cur->data);
+ }
+ } else if (n->tag == MOWGLI_JSON_TAG_OBJECT) {
+ mowgli_json_t *cur;
+
+ mowgli_patricia_foreach_start(n->v_object, &st);
+ while ((cur = mowgli_patricia_foreach_cur(n->v_object, &st)) != NULL) {
+ dump_refs(cur);
+ mowgli_patricia_foreach_next(n->v_object, &st);
+ }
+ }
+ }
+ */
+
+/*
+ * 2. OBJECT CREATION AND DELETION
+ */
+
+static mowgli_json_t *
+json_alloc(mowgli_json_tag_t tag)
+{
+ mowgli_json_t *n;
+
+ n = mowgli_alloc(sizeof(*n));
+
+ n->tag = tag;
+ n->refcount = 0;
+
+ return n;
+}
+
+static void
+json_destroy(mowgli_json_t *n)
+{
+ return_if_fail(n != NULL);
+
+ if (destroy_extra[n->tag] != NULL)
+ destroy_extra[n->tag](n);
+
+ mowgli_free(n);
+}
+
+mowgli_json_t *
+mowgli_json_create_integer(int v_int)
+{
+ mowgli_json_t *n = json_alloc(MOWGLI_JSON_TAG_INTEGER);
+
+ n->v.v_int = v_int;
+ return n;
+}
+
+mowgli_json_t *
+mowgli_json_create_float(double v_float)
+{
+ mowgli_json_t *n = json_alloc(MOWGLI_JSON_TAG_FLOAT);
+
+ n->v.v_float = v_float;
+ return n;
+}
+
+mowgli_json_t *
+mowgli_json_create_string_n(const char *str, size_t len)
+{
+ mowgli_json_t *n = json_alloc(MOWGLI_JSON_TAG_STRING);
+
+ n->v.v_string = mowgli_string_create();
+ mowgli_string_append(n->v.v_string, str, len);
+
+ return n;
+}
+
+mowgli_json_t *
+mowgli_json_create_string(const char *str)
+{
+ return mowgli_json_create_string_n(str, strlen(str));
+}
+
+static void
+destroy_extra_string(mowgli_json_t *n)
+{
+ mowgli_string_destroy(n->v.v_string);
+}
+
+mowgli_json_t *
+mowgli_json_create_array(void)
+{
+ mowgli_json_t *n = json_alloc(MOWGLI_JSON_TAG_ARRAY);
+
+ n->v.v_array = mowgli_list_create();
+ return n;
+}
+
+static void
+destroy_extra_array(mowgli_json_t *n)
+{
+ mowgli_node_t *cur, *next;
+
+ MOWGLI_LIST_FOREACH_SAFE(cur, next, n->v.v_array->head)
+ {
+ mowgli_json_decref((mowgli_json_t *) cur->data);
+ mowgli_node_delete(cur, n->v.v_array);
+ }
+
+ mowgli_list_free(n->v.v_array);
+}
+
+mowgli_json_t *
+mowgli_json_create_object(void)
+{
+ mowgli_json_t *n = json_alloc(MOWGLI_JSON_TAG_OBJECT);
+
+ n->v.v_object = mowgli_patricia_create(NULL);
+ return n;
+}
+
+static void
+destroy_extra_object_cb(const char *key, void *data, void *privdata)
+{
+ mowgli_json_decref((mowgli_json_t *) data);
+}
+
+static void
+destroy_extra_object(mowgli_json_t *n)
+{
+ mowgli_patricia_destroy(n->v.v_object, destroy_extra_object_cb, NULL);
+}
+
+/*
+ * 3. SERIALIZER (A.K.A. FORMATTER, PRINTER, ETC.)
+ */
+
+#define TAB_STRING " "
+#define TAB_LEN 4
+
+static void
+serialize_pretty_indent(mowgli_json_output_t *out, int pretty)
+{
+ int i;
+
+ for (i = 0; i < pretty; i++)
+ out->append(out, TAB_STRING, TAB_LEN);
+}
+
+static void
+serialize_pretty_break(mowgli_json_output_t *out, int pretty)
+{
+ if (pretty < 1)
+ return;
+
+ out->append_char(out, '\n');
+}
+
+static int
+serialize_pretty_increment(int pretty)
+{
+ return pretty > 0 ? pretty + 1 : 0;
+}
+
+static void
+serialize_boolean(mowgli_json_t *n, mowgli_json_output_t *out, int pretty)
+{
+ if (n->v.v_bool)
+ out->append(out, "true", 4);
+ else
+ out->append(out, "false", 5);
+}
+
+static void
+serialize_int(mowgli_json_t *n, mowgli_json_output_t *out, int pretty)
+{
+ char buf[32];
+ size_t len;
+
+ len = snprintf(buf, 32, "%d", n->v.v_int);
+ out->append(out, buf, len);
+}
+
+static void
+serialize_float(mowgli_json_t *n, mowgli_json_output_t *out, int pretty)
+{
+ char buf[32];
+ size_t len;
+
+ len = snprintf(buf, 32, "%g", n->v.v_float);
+ out->append(out, buf, len);
+}
+
+static const char *serialize_hex_digits = "0123456789abcdef";
+static const char *serialize_escape = "\"\\\b\f\n\r\t";
+static void
+serialize_string_data(const char *p, size_t len, mowgli_json_output_t *out)
+{
+ unsigned i;
+ unsigned char c;
+
+ out->append_char(out, '"');
+
+ for (i = 0; i < len; i++)
+ {
+ c = p[i];
+
+ if (strchr(serialize_escape, c))
+ {
+ out->append_char(out, '\\');
+
+ switch (c)
+ {
+ case '"': out->append_char(out, '"'); break;
+ case '\\': out->append_char(out, '\\'); break;
+
+ // case '/': out->append_char(out, '/'); break;
+ case '\b': out->append_char(out, 'b'); break;
+ case '\f': out->append_char(out, 'f'); break;
+ case '\n': out->append_char(out, 'n'); break;
+ case '\r': out->append_char(out, 'r'); break;
+ case '\t': out->append_char(out, 't'); break;
+ default:// hurrr
+ out->append_char(out, c);
+ }
+ }
+ else if ((c < 0x20) || (c > 0x7f))
+ {
+ out->append_char(out, '\\');
+
+ /* XXX: \u output does not do UTF-8 */
+ out->append_char(out, 'u');
+ out->append_char(out, '0');
+ out->append_char(out, '0');
+ out->append_char(out, serialize_hex_digits[(c >> 4) & 0xf]);
+ out->append_char(out, serialize_hex_digits[(c >> 0) & 0xf]);
+ }
+ else
+ {
+ out->append_char(out, c);
+ }
+ }
+
+ out->append_char(out, '"');
+}
+
+static void
+serialize_string(mowgli_json_t *n, mowgli_json_output_t *out, int pretty)
+{
+ serialize_string_data(n->v.v_string->str, n->v.v_string->pos, out);
+}
+
+static void
+serialize_array(mowgli_json_t *n, mowgli_json_output_t *out, int pretty)
+{
+ mowgli_node_t *cur;
+
+ out->append_char(out, '[');
+ serialize_pretty_break(out, pretty);
+
+ MOWGLI_LIST_FOREACH(cur, n->v.v_array->head)
+ {
+ serialize_pretty_indent(out, pretty);
+ mowgli_json_serialize(cur->data, out, serialize_pretty_increment(pretty));
+
+ if (cur->next != NULL)
+ out->append_char(out, ',');
+
+ serialize_pretty_break(out, pretty);
+ }
+
+ serialize_pretty_indent(out, pretty - 1);
+ out->append_char(out, ']');
+}
+
+struct serialize_object_priv /* lol, this is bullshit */
+{
+ int pretty;
+ int remaining;
+ mowgli_json_output_t *out;
+};
+
+static int
+serialize_object_cb(const char *key, void *data, void *privdata)
+{
+ struct serialize_object_priv *priv = privdata;
+
+ priv->remaining--;
+
+ serialize_pretty_indent(priv->out, priv->pretty);
+
+ serialize_string_data(key, strlen(key), priv->out);
+ priv->out->append_char(priv->out, ':');
+
+ if (priv->pretty)
+ priv->out->append_char(priv->out, ' ');
+
+ mowgli_json_serialize(data, priv->out,
+ serialize_pretty_increment(priv->pretty));
+
+ if (priv->remaining)
+ priv->out->append_char(priv->out, ',');
+
+ serialize_pretty_break(priv->out, priv->pretty);
+
+ return 0;
+}
+
+static void
+serialize_object(mowgli_json_t *n, mowgli_json_output_t *out, int pretty)
+{
+ struct serialize_object_priv priv;
+
+ out->append_char(out, '{');
+ serialize_pretty_break(out, pretty);
+
+ priv.pretty = pretty;
+ priv.remaining = mowgli_patricia_size(n->v.v_object);
+ priv.out = out;
+ mowgli_patricia_foreach(n->v.v_object, serialize_object_cb, &priv);
+
+ serialize_pretty_indent(out, pretty - 1);
+ out->append_char(out, '}');
+}
+
+typedef void (*serializer_t)(mowgli_json_t *, mowgli_json_output_t *, int);
+static serializer_t serializers[] =
+{
+ [MOWGLI_JSON_TAG_BOOLEAN] = serialize_boolean,
+ [MOWGLI_JSON_TAG_INTEGER] = serialize_int,
+ [MOWGLI_JSON_TAG_FLOAT] = serialize_float,
+ [MOWGLI_JSON_TAG_STRING] = serialize_string,
+ [MOWGLI_JSON_TAG_ARRAY] = serialize_array,
+ [MOWGLI_JSON_TAG_OBJECT] = serialize_object,
+};
+
+void
+mowgli_json_serialize(mowgli_json_t *n, mowgli_json_output_t *out, int pretty)
+{
+ if (n && serializers[n->tag])
+ serializers[n->tag](n, out, pretty);
+ else
+ out->append(out, "null", 4);
+}
+
+static void
+to_string_append(mowgli_json_output_t *out, const char *str, size_t len)
+{
+ mowgli_string_append(out->priv, str, len);
+}
+
+static void
+to_string_append_char(mowgli_json_output_t *out, const char c)
+{
+ mowgli_string_append_char(out->priv, c);
+}
+
+void
+mowgli_json_serialize_to_string(mowgli_json_t *n, mowgli_string_t *str, int pretty)
+{
+ mowgli_json_output_t out;
+
+ out.append = to_string_append;
+ out.append_char = to_string_append_char;
+ out.priv = str;
+
+ mowgli_json_serialize(n, &out, pretty);
+}
+
+/*
+ * 4. DESERIALIZER (A.K.A. PARSER, ETC.)
+ */
+
+/* LL(1) parser format:
+
+ Terminal symbols: { } [ ] : , STR NUM ID
+
+ Rule table:
+ 0. [invalid]
+
+ 1. <json-document> := <object>
+ 2. <json-document> := <array>
+
+ 3. <value> := <object>
+ 4. <value> := <array>
+ 5. <value> := STR
+ 6. <value> := NUM
+ 7. <value> := ID
+
+ 8. <object> := { <obj-body>
+ 9. <obj-body> := }
+ 10. <obj-body> := <obj-elems>
+ 11. <obj-elems> := <obj-elem> <obj-tail>
+ 12. <obj-tail> := , <obj-elems>
+ 13. <obj-tail> := }
+ 14. <obj-elem> := STR : <value>
+
+ 15. <array> := [ <arr-body>
+ 16. <arr-body> := ]
+ 17. <arr-body> := <arr-elems>
+ 18. <arr-elems> := <value> <arr-tail>
+ 19. <arr-tail> := , <arr-elems>
+ 20. <arr-tail> := ]
+
+ Transition table:
+ { } [ ] : , STR NUM ID
+ --- --- --- --- --- --- --- --- ---
+ json-document 1 2
+ value 3 4 5 6 7
+ object 8
+ obj-body 9 10
+ obj-elems 11
+ obj-tail 13 12
+ obj-elem 14
+ array 15
+ arr-body 17 17 16 17 17 17
+ arr-elems 18 18 18 18 18
+ arr-tail 20 19
+
+ These two tables are effectively a program for an LL(1) parser. The
+ hard work has been done. The remaining steps are to attach appropriate
+ actions to the rules above, and to implement the LL(1) parsing
+ algorithm.
+ */
+
+enum ll_sym
+{
+ SYM_NONE,
+
+ TS_BEGIN_OBJECT,/* { */
+ TS_END_OBJECT, /* } */
+ TS_BEGIN_ARRAY, /* [ */
+ TS_END_ARRAY, /* ] */
+ TS_NAME_SEP, /* : */
+ TS_VALUE_SEP, /* , */
+ TS_STRING,
+ TS_NUMBER,
+ TS_IDENTIFIER,
+
+ NTS_JSON_DOCUMENT,
+ NTS_VALUE,
+ NTS_OBJECT,
+ NTS_OBJ_BODY,
+ NTS_OBJ_ELEMS,
+ NTS_OBJ_TAIL,
+ NTS_OBJ_ELEM,
+ NTS_ARRAY,
+ NTS_ARR_BODY,
+ NTS_ARR_ELEMS,
+ NTS_ARR_TAIL,
+
+ SYM_COUNT
+};
+
+struct ll_token
+{
+ enum ll_sym sym;
+
+ mowgli_json_t *val;
+};
+
+#define ERRBUFSIZE 128
+
+/* typedef'd to mowgli_json_parse_t in json.h */
+struct _mowgli_json_parse_t
+{
+ /* output queue */
+ mowgli_list_t *out;
+
+ /* error buffer */
+ char error[ERRBUFSIZE];
+
+ /* parser */
+ bool multidoc;
+ mowgli_list_t *build;
+ enum ll_sym stack[LL_STACK_SIZE];
+
+ unsigned top;
+
+ /* lexer */
+ mowgli_string_t *buf;
+ enum
+ {
+ LEX_LIMBO,
+ LEX_STRING,
+ LEX_STRING_ESC,
+ LEX_STRING_ESC_U,
+ LEX_NUMBER,
+ LEX_IDENTIFIER
+ } lex;
+
+ unsigned lex_u;
+};
+
+typedef void ll_action_t (mowgli_json_parse_t *, struct ll_token *tok);
+
+/* Human-readable versions of symbols used in errors, etc. */
+static char *ll_sym_name[] =
+{
+ [SYM_NONE] = "(none)",
+
+ [TS_BEGIN_OBJECT] = "'{'",
+ [TS_END_OBJECT] = "'}'",
+ [TS_BEGIN_ARRAY] = "'['",
+ [TS_END_ARRAY] = "']'",
+ [TS_NAME_SEP] = "':'",
+ [TS_VALUE_SEP] = "','",
+ [TS_STRING] = "string",
+ [TS_NUMBER] = "number",
+ [TS_IDENTIFIER] = "identifier",
+
+ [NTS_JSON_DOCUMENT] = "json-document",
+ [NTS_VALUE] = "value",
+ [NTS_OBJECT] = "object",
+ [NTS_OBJ_BODY] = "object body",
+ [NTS_OBJ_ELEMS] = "object elements",
+ [NTS_OBJ_TAIL] = "object tail",
+ [NTS_OBJ_ELEM] = "object element",
+
+ [NTS_ARRAY] = "array",
+ [NTS_ARR_BODY] = "array body",
+ [NTS_ARR_ELEMS] = "array elements",
+ [NTS_ARR_TAIL] = "array tail",
+
+ [SYM_COUNT] = "(none)",
+};
+
+/* The LL(1) parser table. Uglier than it could have been, unfortunately */
+static unsigned char ll_table[SYM_COUNT][SYM_COUNT] =
+{
+ [NTS_JSON_DOCUMENT] =
+ {
+ [TS_BEGIN_OBJECT] = 1,
+ [TS_BEGIN_ARRAY] = 2,
+ },
+
+ [NTS_VALUE] =
+ {
+ [TS_BEGIN_OBJECT] = 3,
+ [TS_BEGIN_ARRAY] = 4,
+ [TS_STRING] = 5,
+ [TS_NUMBER] = 6,
+ [TS_IDENTIFIER] = 7,
+ },
+
+ [NTS_OBJECT] =
+ {
+ [TS_BEGIN_OBJECT] = 8,
+ },
+ [NTS_OBJ_BODY] =
+ {
+ [TS_END_OBJECT] = 9,
+ [TS_STRING] = 10,
+ },
+ [NTS_OBJ_ELEMS] =
+ {
+ [TS_STRING] = 11,
+ },
+ [NTS_OBJ_TAIL] =
+ {
+ [TS_END_OBJECT] = 13,
+ [TS_VALUE_SEP] = 12,
+ },
+ [NTS_OBJ_ELEM] =
+ {
+ [TS_STRING] = 14,
+ },
+
+ [NTS_ARRAY] =
+ {
+ [TS_BEGIN_ARRAY] = 15,
+ },
+ [NTS_ARR_BODY] =
+ {
+ [TS_BEGIN_OBJECT] = 17,
+ [TS_BEGIN_ARRAY] = 17,
+ [TS_END_ARRAY] = 16,
+ [TS_STRING] = 17,
+ [TS_NUMBER] = 17,
+ [TS_IDENTIFIER] = 17,
+ },
+ [NTS_ARR_ELEMS] =
+ {
+ [TS_BEGIN_OBJECT] = 18,
+ [TS_BEGIN_ARRAY] = 18,
+ [TS_STRING] = 18,
+ [TS_NUMBER] = 18,
+ [TS_IDENTIFIER] = 18,
+ },
+ [NTS_ARR_TAIL] =
+ {
+ [TS_END_ARRAY] = 20,
+ [TS_VALUE_SEP] = 19,
+ },
+};
+
+/* The LL(1) rule table */
+static enum ll_sym ll_rules[][3] =
+{
+ { 0 }, /* 0 */
+
+ { NTS_OBJECT },
+ { NTS_ARRAY },
+
+ { NTS_OBJECT },
+ { NTS_ARRAY },
+ { TS_STRING }, /* 5 */
+ { TS_NUMBER },
+ { TS_IDENTIFIER },
+
+ { TS_BEGIN_OBJECT, NTS_OBJ_BODY },
+ { TS_END_OBJECT },
+ { NTS_OBJ_ELEMS }, /* 10 */
+ { NTS_OBJ_ELEM, NTS_OBJ_TAIL },
+ { TS_VALUE_SEP, NTS_OBJ_ELEMS },
+ { TS_END_OBJECT },
+ { TS_STRING, TS_NAME_SEP, NTS_VALUE },
+
+ { TS_BEGIN_ARRAY, NTS_ARR_BODY }, /* 15 */
+ { TS_END_ARRAY },
+ { NTS_ARR_ELEMS },
+ { NTS_VALUE, NTS_ARR_TAIL },
+ { TS_VALUE_SEP, NTS_ARR_ELEMS },
+ { TS_END_ARRAY }, /* 20 */
+};
+
+static struct ll_token *
+ll_token_alloc(enum ll_sym sym, mowgli_json_t *val)
+{
+ struct ll_token *tok;
+
+ tok = mowgli_alloc(sizeof(*tok));
+ tok->sym = sym;
+ tok->val = val;
+
+ return tok;
+}
+
+static void
+ll_token_free(struct ll_token *tok)
+{
+ mowgli_json_decref(tok->val);
+ mowgli_free(tok);
+}
+
+static bool
+parse_out_empty(mowgli_json_parse_t *parse)
+{
+ return MOWGLI_LIST_LENGTH(parse->out) == 0;
+}
+
+static void
+parse_out_enqueue(mowgli_json_parse_t *parse, mowgli_json_t *val)
+{
+ mowgli_node_add(val, mowgli_node_create(), parse->out);
+}
+
+static mowgli_json_t *
+parse_out_dequeue(mowgli_json_parse_t *parse)
+{
+ mowgli_json_t *n;
+ mowgli_node_t *head;
+
+ if (MOWGLI_LIST_LENGTH(parse->out) == 0)
+ return NULL;
+
+ head = parse->out->head;
+
+ if (head == NULL)
+ return NULL;
+
+ n = head->data;
+ mowgli_node_delete(head, parse->out);
+ mowgli_node_free(head);
+
+ return n;
+}
+
+static void
+parse_error(mowgli_json_parse_t *parse, const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ vsnprintf(parse->error, ERRBUFSIZE, fmt, va);
+ va_end(va);
+
+ /* TODO: shut down everything, yadda yadda */
+}
+
+static void
+ll_build_push(mowgli_json_parse_t *parse, mowgli_json_t *val)
+{
+ mowgli_node_add_head(val, mowgli_node_create(), parse->build);
+}
+
+static mowgli_json_t *
+ll_build_pop(mowgli_json_parse_t *parse)
+{
+ mowgli_json_t *n;
+ mowgli_node_t *head;
+
+ if (MOWGLI_LIST_LENGTH(parse->build) == 0)
+ return NULL;
+
+ head = parse->build->head;
+
+ if (head == NULL) /* shouldn't happen... */
+ return NULL;
+
+ n = head->data;
+ mowgli_node_delete(head, parse->build);
+ mowgli_node_free(head);
+
+ return n;
+}
+
+static mowgli_json_t obj_start_marker =
+{
+ .refcount = JSON_REFCOUNT_CONSTANT,
+};
+static mowgli_json_t arr_start_marker =
+{
+ .refcount = JSON_REFCOUNT_CONSTANT,
+};
+
+static void
+ll_act_echo(mowgli_json_parse_t *parse, struct ll_token *tok)
+{
+ ll_build_push(parse, mowgli_json_incref(tok->val));
+}
+
+static void
+ll_act_obj_start(mowgli_json_parse_t *parse, struct ll_token *tok)
+{
+ ll_build_push(parse, &obj_start_marker);
+}
+
+static void
+ll_act_obj_end(mowgli_json_parse_t *parse, struct ll_token *tok)
+{
+ mowgli_json_t *obj;
+ mowgli_json_t *key, *val;
+
+ obj = mowgli_json_incref(mowgli_json_create_object());
+
+ for (;;)
+ {
+ val = ll_build_pop(parse);
+
+ if (val == &obj_start_marker)
+ break;
+
+ key = ll_build_pop(parse);
+
+ if (key == &obj_start_marker)
+ break; /* should never happen, but in case */
+
+ if (MOWGLI_JSON_TAG(key) != MOWGLI_JSON_TAG_STRING)
+ break; /* should also never happen */
+
+ mowgli_json_object_add(obj, MOWGLI_JSON_STRING_STR(key), val);
+ mowgli_json_decref(key);
+ mowgli_json_decref(val);
+ }
+
+ ll_build_push(parse, obj);
+}
+
+static void
+ll_act_arr_start(mowgli_json_parse_t *parse, struct ll_token *tok)
+{
+ ll_build_push(parse, &arr_start_marker);
+}
+
+static void
+ll_act_arr_end(mowgli_json_parse_t *parse, struct ll_token *tok)
+{
+ mowgli_json_t *arr;
+ mowgli_json_t *val;
+
+ arr = mowgli_json_incref(mowgli_json_create_array());
+
+ for (;;)
+ {
+ val = ll_build_pop(parse);
+
+ if (val == &arr_start_marker)
+ break;
+
+ mowgli_json_array_add_head(arr, val);
+ mowgli_json_decref(val);
+ }
+
+ ll_build_push(parse, arr);
+}
+
+static ll_action_t *ll_action[] =
+{
+ NULL, /* 0 */
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+ ll_act_echo, /* 5 */
+ ll_act_echo,
+ ll_act_echo,
+
+ ll_act_obj_start,
+ ll_act_obj_end,
+ NULL, /* 10 */
+ NULL,
+ NULL,
+ ll_act_obj_end,
+ ll_act_echo,
+
+ ll_act_arr_start, /* 15 */
+ ll_act_arr_end,
+ NULL,
+ NULL,
+ NULL,
+ ll_act_arr_end, /* 20 */
+};
+
+static void
+ll_push(mowgli_json_parse_t *parse, enum ll_sym sym)
+{
+ parse->stack[parse->top++] = sym;
+}
+
+static enum ll_sym
+ll_pop(mowgli_json_parse_t *parse)
+{
+ if (parse->top <= 0)
+ return SYM_NONE;
+
+ return parse->stack[--parse->top];
+}
+
+static bool
+ll_stack_empty(mowgli_json_parse_t *parse)
+{
+ return parse->top == 0;
+}
+
+static void
+ll_cycle(mowgli_json_parse_t *parse)
+{
+ mowgli_json_t *n;
+
+ n = ll_build_pop(parse);
+
+ if (n != NULL)
+ parse_out_enqueue(parse, n);
+
+ if (parse->multidoc)
+ ll_push(parse, NTS_JSON_DOCUMENT);
+}
+
+static void
+ll_parse(mowgli_json_parse_t *parse, struct ll_token *tok)
+{
+ enum ll_sym top, sym;
+
+ int rule, i;
+
+ for (;;)
+ {
+ if (ll_stack_empty(parse))
+ {
+ parse_error(parse, "Unexpected %s after JSON input", ll_sym_name[tok->sym]);
+ break;
+ }
+
+ top = ll_pop(parse);
+
+ if (top == tok->sym)
+ {
+ /* perfect! */
+
+ if (ll_stack_empty(parse))
+ ll_cycle(parse);
+
+ break;
+ }
+
+ rule = ll_table[top][tok->sym];
+
+ if (rule == 0)
+ {
+ parse_error(parse, "Expected %s, got %s", ll_sym_name[top],
+ ll_sym_name[tok->sym]);
+ break;
+ }
+
+ if (ll_action[rule] != NULL)
+ ll_action[rule](parse, tok);
+
+ for (i = 2; i >= 0; i--)
+ {
+ sym = ll_rules[rule][i];
+
+ if (sym != SYM_NONE)
+ ll_push(parse, sym);
+ }
+ }
+
+ ll_token_free(tok);
+}
+
+static void
+lex_easy(mowgli_json_parse_t *parse, enum ll_sym sym)
+{
+ ll_parse(parse, ll_token_alloc(sym, NULL));
+}
+
+static void
+lex_append(mowgli_json_parse_t *parse, char c)
+{
+ mowgli_string_append_char(parse->buf, c);
+}
+
+static mowgli_json_t *
+lex_string_scan(char *s, size_t n)
+{
+ mowgli_json_t *val;
+ mowgli_string_t *str;
+ char ubuf[5];
+ char *end = s + n;
+
+ val = mowgli_json_incref(mowgli_json_create_string(""));
+ str = val->v.v_string;
+
+ ubuf[4] = '\0'; /* always */
+
+ while (s < end)
+ {
+ if (*s == '\\')
+ {
+ /* Should this be moved to a separate function? */
+ s++;
+
+ switch (*s)
+ {
+ case '\"':
+ case '\\':
+ case '/':
+ mowgli_string_append_char(str, *s);
+ break;
+
+ case 'b': mowgli_string_append_char(str, 0x8); break;
+ case 'f': mowgli_string_append_char(str, 0xc); break;
+ case 'n': mowgli_string_append_char(str, 0xa); break;
+ case 'r': mowgli_string_append_char(str, 0xd); break;
+ case 't': mowgli_string_append_char(str, 0x9); break;
+
+ /* XXX: this is not the right way to parse \u */
+ case 'u':
+ s++;
+
+ if (end - s < 4)
+ {
+ /* error */
+ }
+ else
+ {
+ memcpy(ubuf, s, 4);
+ mowgli_string_append_char(str, strtol(ubuf, NULL, 16) & 0xff);
+ }
+
+ s += 3; /* +3 points to last char */
+ break;
+
+ default:/* aww */
+ break;
+ }
+ }
+ else
+ {
+ mowgli_string_append_char(str, *s);
+ }
+
+ s++;
+ }
+
+ return val;
+}
+
+static void
+lex_tokenize(mowgli_json_parse_t *parse)
+{
+ char *s = parse->buf->str;
+ size_t n = parse->buf->pos;
+ enum ll_sym sym = SYM_NONE;
+ mowgli_json_t *val = NULL;
+
+ switch (parse->lex)
+ {
+ case LEX_STRING:
+ sym = TS_STRING;
+ val = lex_string_scan(s, n);
+ break;
+
+ case LEX_NUMBER:
+
+ if (strchr(s, '.') || strchr(s, 'e'))
+ val = mowgli_json_incref(mowgli_json_create_float(strtod(s, NULL)));
+
+ else
+ val = mowgli_json_incref(mowgli_json_create_integer(strtol(s, NULL, 0)));
+
+ sym = TS_NUMBER;
+ break;
+
+ case LEX_IDENTIFIER:
+ sym = TS_IDENTIFIER;
+
+ if (!strcmp(s, "null"))
+ val = mowgli_json_null;
+
+ else if (!strcmp(s, "true"))
+ val = mowgli_json_true;
+
+ else if (!strcmp(s, "false"))
+ val = mowgli_json_false;
+
+ else
+ val = mowgli_json_null;
+
+ /* error condition! */
+
+ break;
+
+ default:
+
+ /* we should not be tokenizing here! */
+ break;
+ }
+
+ mowgli_string_reset(parse->buf);
+ parse->lex = LEX_LIMBO;
+
+ ll_parse(parse, ll_token_alloc(sym, val));
+}
+
+/* lex_char returns true if it wants the char to be sent through again */
+static bool
+lex_char(mowgli_json_parse_t *parse, char c)
+{
+ switch (parse->lex)
+ {
+ case LEX_LIMBO:
+
+ /* the easy ones */
+ switch (c)
+ {
+ case '{': lex_easy(parse, TS_BEGIN_OBJECT); return false;
+ case '}': lex_easy(parse, TS_END_OBJECT); return false;
+ case '[': lex_easy(parse, TS_BEGIN_ARRAY); return false;
+ case ']': lex_easy(parse, TS_END_ARRAY); return false;
+ case ':': lex_easy(parse, TS_NAME_SEP); return false;
+ case ',': lex_easy(parse, TS_VALUE_SEP); return false;
+ }
+
+ if ((c == '-') || (c == '.') || isdigit(c))
+ {
+ parse->lex = LEX_NUMBER;
+ return true;
+ }
+ else if (isalpha(c))
+ {
+ parse->lex = LEX_IDENTIFIER;
+ return true;
+ }
+ else if (c == '"')
+ {
+ parse->lex = LEX_STRING;
+ return false;
+ }
+ else if (isspace(c))
+ {
+ return false;
+ }
+
+ parse_error(parse, "Cannot process character '%c' in input stream", c);
+
+ return false;
+
+ case LEX_STRING:
+
+ if (c == '\\')
+ {
+ lex_append(parse, c);
+ parse->lex = LEX_STRING_ESC;
+ }
+ else if (c == '"')
+ {
+ lex_tokenize(parse);
+ }
+ else
+ {
+ lex_append(parse, c);
+ }
+
+ return false;
+
+ case LEX_STRING_ESC:
+ lex_append(parse, c);
+
+ if (c == 'u')
+ {
+ parse->lex_u = 0;
+ parse->lex = LEX_STRING_ESC_U;
+ }
+ else
+ {
+ parse->lex = LEX_STRING;
+ }
+
+ return false;
+
+ case LEX_STRING_ESC_U:
+ lex_append(parse, c);
+
+ parse->lex_u++;
+
+ if (parse->lex_u >= 4)
+ parse->lex = LEX_STRING;
+
+ return false;
+
+ case LEX_NUMBER:
+
+ if ((c == '-') || (c == '.') || isdigit(c) || (toupper(c) == 'E'))
+ {
+ lex_append(parse, c);
+ return false;
+ }
+ else
+ {
+ lex_tokenize(parse);
+ return true;
+ }
+
+ break;
+
+ case LEX_IDENTIFIER:
+
+ if (isalpha(c))
+ {
+ lex_append(parse, c);
+ return false;
+ }
+ else
+ {
+ lex_tokenize(parse);
+ return true;
+ }
+
+ break;
+ }
+
+ /* This should never happen... */
+ parse->lex = LEX_LIMBO;
+ return false;
+}
+
+mowgli_json_parse_t *
+mowgli_json_parse_create(bool multidoc)
+{
+ mowgli_json_parse_t *parse;
+
+ parse = mowgli_alloc(sizeof(*parse));
+
+ parse->out = mowgli_list_create();
+ parse->error[0] = '\0';
+ parse->multidoc = multidoc;
+ parse->build = mowgli_list_create();
+ parse->top = 0;
+ parse->buf = mowgli_string_create();
+ parse->lex = LEX_LIMBO;
+
+ ll_push(parse, NTS_JSON_DOCUMENT);
+
+ return parse;
+}
+
+void
+mowgli_json_parse_destroy(mowgli_json_parse_t *parse)
+{
+ mowgli_node_t *n;
+
+ return_if_fail(parse != NULL);
+
+ MOWGLI_LIST_FOREACH(n, parse->out->head)
+ mowgli_json_decref(n->data);
+ MOWGLI_LIST_FOREACH(n, parse->build->head)
+ mowgli_json_decref(n->data);
+
+ mowgli_list_free(parse->out);
+ mowgli_list_free(parse->build);
+ mowgli_string_destroy(parse->buf);
+
+ mowgli_free(parse);
+}
+
+void
+mowgli_json_parse_reset(mowgli_json_parse_t *parse, bool multidoc)
+{
+ mowgli_node_t *n, *tn;
+
+ if (parse->out == NULL)
+ parse->out = mowgli_list_create();
+
+ if (parse->build == NULL)
+ parse->build = mowgli_list_create();
+
+ MOWGLI_LIST_FOREACH_SAFE(n, tn, parse->out->head)
+ {
+ mowgli_json_decref(n->data);
+ mowgli_node_delete(n, parse->out);
+ }
+ MOWGLI_LIST_FOREACH_SAFE(n, tn, parse->build->head)
+ {
+ mowgli_json_decref(n->data);
+ mowgli_node_delete(n, parse->build);
+ }
+
+ parse->error[0] = '\0';
+ parse->multidoc = multidoc;
+ parse->top = 0;
+
+ if (parse->buf == NULL)
+ parse->buf = mowgli_string_create();
+ else
+ mowgli_string_reset(parse->buf);
+
+ parse->lex = LEX_LIMBO;
+
+ ll_push(parse, NTS_JSON_DOCUMENT);
+}
+
+void
+mowgli_json_parse_data(mowgli_json_parse_t *parse, const char *data, size_t len)
+{
+ while (len > 0)
+ {
+ /* We cannot continue parsing if there's an error! */
+ if (mowgli_json_parse_error(parse))
+ return;
+
+ while (lex_char(parse, *data))
+ { }
+
+ data++;
+ len--;
+ }
+}
+
+char *
+mowgli_json_parse_error(mowgli_json_parse_t *parse)
+{
+ if (parse->error[0])
+ return parse->error;
+
+ return NULL;
+}
+
+bool
+mowgli_json_parse_more(mowgli_json_parse_t *parse)
+{
+ return !parse_out_empty(parse);
+}
+
+mowgli_json_t *
+mowgli_json_parse_next(mowgli_json_parse_t *parse)
+{
+ return parse_out_dequeue(parse);
+}
+
+/* Note: Static parsers like these should last the life of the program,
+ since mowgli_json_parse_destroy will attempt to mowgli_free the
+ parser. */
+
+static mowgli_json_parse_t static_parser;
+
+mowgli_json_t *
+mowgli_json_parse_file(const char *path)
+{
+ char *s;
+ char buf[512];
+ size_t n;
+ mowgli_json_t *ret;
+ FILE *f;
+
+ mowgli_json_parse_reset(&static_parser, false);
+
+ f = fopen(path, "r");
+
+ if (f == NULL)
+ {
+ mowgli_log("Could not open %s for reading", path);
+ return NULL;
+ }
+
+ s = NULL;
+
+ while (!feof(f) && s == NULL)
+ {
+ n = fread(buf, 1, 512, f);
+ mowgli_json_parse_data(&static_parser, buf, n);
+
+ s = mowgli_json_parse_error(&static_parser);
+ }
+
+ if (s != NULL)
+ {
+ mowgli_log("%s: %s", path, s);
+ ret = NULL;
+ }
+ else
+ {
+ ret = mowgli_json_parse_next(&static_parser);
+
+ if (ret == NULL)
+ mowgli_log("%s: Incomplete JSON document", path);
+ }
+
+ fclose(f);
+
+ return ret;
+}
+
+mowgli_json_t *
+mowgli_json_parse_string(const char *data)
+{
+ mowgli_json_t *ret;
+ char *s;
+
+ mowgli_json_parse_reset(&static_parser, false);
+
+ mowgli_json_parse_data(&static_parser, data, strlen(data));
+
+ if ((s = mowgli_json_parse_error(&static_parser)) != NULL)
+ {
+ mowgli_log("%s", s);
+ ret = NULL;
+ }
+ else
+ {
+ ret = mowgli_json_parse_next(&static_parser);
+
+ if (ret == NULL)
+ mowgli_log("Incomplete JSON document");
+ }
+
+ return ret;
+}
diff --git a/src/libmowgli/ext/json.h b/src/libmowgli/ext/json.h
new file mode 100644
index 0000000..247018a
--- /dev/null
+++ b/src/libmowgli/ext/json.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2012 Alex Iadicicco
+ * Rights to this code are as documented in COPYING.
+ *
+ * Structs and functions for interacting with JSON documents from C
+ */
+
+/* A note about refcounting:
+
+ Since JSON cannot represent recursive structures, it makes sense
+ to use refcounting. If a recursive structure is created then it's
+ guaranteed to be the programmer's fault, and the programmer deserves
+ every memory leak he gets.
+
+ When cared for and fed daily, refcounting is a very nifty tool. Entire
+ structures can be destroyed cleanly by a single mowgli_json_decref. To
+ fully take advantage of this, know the refcounting rules:
+
+ o JSON objects as arguments should NEVER have a reference for
+ the callee. If the callee wants to keep the object somewhere,
+ they will incref themselves.
+
+ o When returning a JSON object, be sure to leave a single reference
+ for the caller. (If you tried to decref before returning, you
+ could potentially drop the refcount to zero.)
+
+ o Newly created structures are the sole exception to the previous
+ rule. This is because it is useful to be able to use constructors
+ as arguments to functions as follows:
+ mowgli_json_object_add(obj, "sum", mowgli_json_create_integer(10));
+ Note that this ONLY applies to the mowgli_json_create_*
+ constructors provided by mowgli.json. The typical case of
+ assigning a new structure to a variable name then looks like this:
+ my_integer = mowgli_json_incref(mowgli_json_create_integer(0));
+
+ Since failure to pay attention to reference counts will cause memory
+ problems, *always double check your reference counting*!
+
+ --aji */
+
+#ifndef MOWGLI_JSON_H
+#define MOWGLI_JSON_H
+
+/* Types with public definitons */
+typedef enum
+{
+ MOWGLI_JSON_TAG_NULL,
+ MOWGLI_JSON_TAG_BOOLEAN,
+
+ /* JSON does not distinguish between integers or floating points
+ (they are both just number types), but in C we are forced to
+ make the distinction */
+ MOWGLI_JSON_TAG_INTEGER,
+ MOWGLI_JSON_TAG_FLOAT,
+ MOWGLI_JSON_TAG_STRING,
+ MOWGLI_JSON_TAG_ARRAY,
+ MOWGLI_JSON_TAG_OBJECT,
+} mowgli_json_tag_t;
+typedef struct _mowgli_json_t mowgli_json_t;
+
+/* Types whose definitons are kept private */
+typedef struct _mowgli_json_parse_t mowgli_json_parse_t;
+
+struct _mowgli_json_t
+{
+ mowgli_json_tag_t tag;
+ int refcount;
+
+ union
+ {
+ bool v_bool;
+ int v_int;
+ double v_float;
+ mowgli_string_t *v_string;
+ mowgli_list_t *v_array;
+ mowgli_patricia_t *v_object;
+ } v;
+};
+
+/* Helper macros useful for cleanly interacting with mowgli_json_t
+ structs. These are just helpers and are not intended to provide a
+ consistent interface. They are as likely to change as the mowgli_json_t
+ struct itself. */
+#define MOWGLI_JSON_TAG(n) ((n)->tag)
+#define MOWGLI_JSON_BOOLEAN(n) ((n)->v.v_bool)
+#define MOWGLI_JSON_INTEGER(n) ((n)->v.v_int)
+#define MOWGLI_JSON_FLOAT(n) ((n)->v.v_float)
+#define MOWGLI_JSON_NUMBER(n) ((n)->tag == MOWGLI_JSON_TAG_FLOAT ? \
+ (n)->v.v_float : (n)->v.v_int)
+#define MOWGLI_JSON_STRING(n) ((n)->v.v_string)
+#define MOWGLI_JSON_STRING_STR(n) ((n)->v.v_string->str)
+#define MOWGLI_JSON_STRING_LEN(n) ((n)->v.v_string->pos)
+#define MOWGLI_JSON_ARRAY(n) ((n)->v.v_array)
+#define MOWGLI_JSON_OBJECT(n) ((n)->v.v_object)
+
+/* Users of the JSON parser/formatter are not required to use these
+ constants, but the parser will ALWAYS parse the symbols "null",
+ "true", and "false" into these constants */
+extern mowgli_json_t *mowgli_json_null;
+extern mowgli_json_t *mowgli_json_true;
+extern mowgli_json_t *mowgli_json_false;
+
+/* These simply return the node argument. If the node was destroyed,
+ the return value will be NULL. Note that in all other cases (invalid
+ refcount, unknown type, etc.) the node will be returned untouched */
+extern mowgli_json_t *mowgli_json_incref(mowgli_json_t *n);
+extern mowgli_json_t *mowgli_json_decref(mowgli_json_t *n);
+
+extern mowgli_json_t *mowgli_json_create_integer(int v_int);
+extern mowgli_json_t *mowgli_json_create_float(double v_float);
+
+/* #define mowgli_json_create_number(V) _Generic((V), \
+ int: mowgli_json_create_integer, \
+ double: mowgli_json_create_float)(V) */
+extern mowgli_json_t *mowgli_json_create_string_n(const char *str, size_t len);
+extern mowgli_json_t *mowgli_json_create_string(const char *str);
+extern mowgli_json_t *mowgli_json_create_array(void);
+extern mowgli_json_t *mowgli_json_create_object(void);
+
+#include "json-inline.h"
+
+typedef struct _mowgli_json_output_t mowgli_json_output_t;
+
+struct _mowgli_json_output_t
+{
+ void (*append)(mowgli_json_output_t *out, const char *str, size_t len);
+ void (*append_char)(mowgli_json_output_t *out, const char c);
+ void *priv;
+};
+
+extern void mowgli_json_serialize(mowgli_json_t *n, mowgli_json_output_t *out, int pretty);
+extern void mowgli_json_serialize_to_string(mowgli_json_t *n, mowgli_string_t *str, int pretty);
+
+/* extended parsing interface. The 'multidoc' parameter here indicates
+ whether we intend to parse multiple documents from a single data source
+ or not. If you are expecting exactly one complete JSON document,
+ indicate 'false'. */
+extern mowgli_json_parse_t *mowgli_json_parse_create(bool multidoc);
+extern void mowgli_json_parse_destroy(mowgli_json_parse_t *parse);
+extern void mowgli_json_parse_reset(mowgli_json_parse_t *parse, bool multidoc);
+extern void mowgli_json_parse_data(mowgli_json_parse_t *parse, const char *data, size_t len);
+extern char *mowgli_json_parse_error(mowgli_json_parse_t *parse);
+extern bool mowgli_json_parse_more(mowgli_json_parse_t *parse);
+extern mowgli_json_t *mowgli_json_parse_next(mowgli_json_parse_t *parse);
+
+/* Simple parsing interface. These expect the given data source to
+ represent exactly one complete JSON document */
+extern mowgli_json_t *mowgli_json_parse_file(const char *path);
+extern mowgli_json_t *mowgli_json_parse_string(const char *data);
+
+#endif
diff --git a/src/libmowgli/ext/proctitle.c b/src/libmowgli/ext/proctitle.c
index 91885d5..ee3a764 100644
--- a/src/libmowgli/ext/proctitle.c
+++ b/src/libmowgli/ext/proctitle.c
@@ -1,9 +1,10 @@
-/*
+/*
* Code has been calqued from PostgreSQL 9.1 by Elizabeth J. Myers.
* Below is their copyright header.
*
* Do note I've made extensive changes to this code, including adding
- * Linux (and Irix?) prctl support.
+ * Linux (and Irix?) prctl support. Also added support for searching for
+ * argc/argv.
*/
/*--------------------------------------------------------------------
@@ -17,26 +18,28 @@
*
* Copyright (c) 2000-2011, PostgreSQL Global Development Group
* various details abducted from various places
- *--------------------------------------------------------------------
+ ***--------------------------------------------------------------------
*/
#include "mowgli.h"
#ifdef HAVE_SYS_PSTAT_H
-#include <sys/pstat.h> /* for HP-UX */
+# include <sys/pstat.h> /* for HP-UX */
#endif
#ifdef HAVE_PS_STRINGS
-#include <machine/vmparam.h> /* for old BSD */
-#include <sys/exec.h>
+# include <machine/vmparam.h> /* for old BSD */
+# include <sys/exec.h>
#endif
-#if defined(__darwin__)
-#include <crt_externs.h>
+#ifdef MOWGLI_OS_OSX
+# include <crt_externs.h>
#endif
#ifdef HAVE_SYS_PRCTL_H
-#include <sys/prctl.h>
+# include <sys/prctl.h>
#endif
+#if !defined(MOWGLI_OS_WIN) && !defined(MOWGLI_OS_OSX)
extern char **environ;
+#endif
/*
* Alternative ways of updating ps display:
@@ -66,63 +69,62 @@ extern char **environ;
* (This is the default, as it is safest.)
*/
#if defined(HAVE_SETPROCTITLE)
-#define MOWGLI_SETPROC_USE_SETPROCTITLE
+# define MOWGLI_SETPROC_USE_SETPROCTITLE
#elif defined(PR_SET_NAME) && defined(HAVE_SYS_PRCTL_H)
-#define MOWGLI_SETPROC_USE_PRCTL
+# define MOWGLI_SETPROC_USE_PRCTL
#elif defined(HAVE_PSTAT) && defined(PSTAT_SETCMD)
-#define MOWGLI_SETPROC_USE_PSTAT
+# define MOWGLI_SETPROC_USE_PSTAT
#elif defined(HAVE_PS_STRINGS)
-#define MOWGLI_SETPROC_USE_PS_STRINGS
+# define MOWGLI_SETPROC_USE_PS_STRINGS
#elif (defined(BSD) || defined(__bsdi__) || defined(__hurd__)) && !defined(__darwin__)
-#define MOWGLI_SETPROC_USE_CHANGE_ARGV
+# define MOWGLI_SETPROC_USE_CHANGE_ARGV
#elif defined(__linux__) || defined(_AIX) || defined(__sgi) || (defined(sun) && !defined(BSD)) || defined(ultrix) || defined(__ksr__) || defined(__osf__) || defined(__svr4__) || defined(__svr5__) || defined(__darwin__)
-#define MOWGLI_SETPROC_USE_CLOBBER_ARGV
+# define MOWGLI_SETPROC_USE_CLOBBER_ARGV
#elif defined(WIN32)
-#define MOWGLI_SETPROC_USE_WIN32
+# define MOWGLI_SETPROC_USE_WIN32
#else
-#define MOWGLI_SETPROC_USE_NONE
+# define MOWGLI_SETPROC_USE_NONE
#endif
-
/* Different systems want the buffer padded differently */
#if defined(_AIX) || defined(__linux__) || defined(__svr4__) || defined(__darwin__)
-#define PS_PADDING '\0'
+# define PS_PADDING '\0'
#else
-#define PS_PADDING ' '
+# define PS_PADDING ' '
#endif
-
#ifndef MOWGLI_SETPROC_USE_CLOBBER_ARGV
+
/* all but one option need a buffer to write their ps line in */
-#define PS_BUFFER_SIZE 256
+# define PS_BUFFER_SIZE 256
static char ps_buffer[PS_BUFFER_SIZE];
static const size_t ps_buffer_size = PS_BUFFER_SIZE;
-#else /* MOWGLI_SETPROC_USE_CLOBBER_ARGV */
-static char *ps_buffer; /* will point to argv area */
+#else /* MOWGLI_SETPROC_USE_CLOBBER_ARGV */
+static char *ps_buffer; /* will point to argv area */
static size_t ps_buffer_size; /* space determined at run time */
-#endif /* MOWGLI_SETPROC_USE_CLOBBER_ARGV */
+#endif /* MOWGLI_SETPROC_USE_CLOBBER_ARGV */
static size_t ps_buffer_fixed_size;
-static size_t ps_buffer_cur_len; /* nominal strlen(ps_buffer) */
+static size_t ps_buffer_cur_len;/* nominal strlen(ps_buffer) */
/* save the original argv[] location here */
static int save_argc;
static char **save_argv;
+int mowgli_argc = 0;
+char **mowgli_argv = NULL;
+
/*
- * Call this early in startup to save the original argc/argv values.
+ * Save the original argc/argv values.
* If needed, we make a copy of the original argv[] array to preserve it
* from being clobbered by subsequent ps_display actions.
- *
- * (The original argv[] will not be overwritten by this routine, but may be
- * overwritten during mowgli_proctitle_set. Also, the physical location of the
- * environment strings may be moved, so this should be called before any code
- * that might try to hang onto a getenv() result.)
*/
char **
mowgli_proctitle_init(int argc, char **argv)
{
- save_argc = argc;
+ if ((argc == 0) || (argv == NULL))
+ save_argc = argc;
+
save_argv = argv;
#if defined(MOWGLI_SETPROC_USE_CLOBBER_ARGV)
@@ -139,12 +141,10 @@ mowgli_proctitle_init(int argc, char **argv)
* check for contiguous argv strings
*/
for (i = 0; i < argc; i++)
- {
- if (i == 0 || end_of_area + 1 == argv[i])
+ if ((i == 0) || (end_of_area + 1 == argv[i]))
end_of_area = argv[i] + strlen(argv[i]);
- }
- if (end_of_area == NULL) /* probably can't happen? */
+ if (end_of_area == NULL)/* probably can't happen? */
{
ps_buffer = NULL;
ps_buffer_size = 0;
@@ -155,10 +155,8 @@ mowgli_proctitle_init(int argc, char **argv)
* check for contiguous environ strings following argv
*/
for (i = 0; environ[i] != NULL; i++)
- {
if (end_of_area + 1 == environ[i])
end_of_area = environ[i] + strlen(environ[i]);
- }
ps_buffer = argv[0];
ps_buffer_size = end_of_area - argv[0];
@@ -167,12 +165,14 @@ mowgli_proctitle_init(int argc, char **argv)
* move the environment out of the way
*/
new_environ = (char **) mowgli_alloc((i + 1) * sizeof(char *));
+
for (i = 0; environ[i] != NULL; i++)
new_environ[i] = mowgli_strdup(environ[i]);
+
new_environ[i] = NULL;
environ = new_environ;
-#endif /* MOWGLI_SETPROC_USE_CLOBBER_ARGV */
+#endif /* MOWGLI_SETPROC_USE_CLOBBER_ARGV */
#if defined(MOWGLI_SETPROC_USE_CHANGE_ARGV) || defined(MOWGLI_SETPROC_USE_CLOBBER_ARGV)
@@ -188,24 +188,30 @@ mowgli_proctitle_init(int argc, char **argv)
*/
char **new_argv;
- int i;
+ int j;
new_argv = (char **) mowgli_alloc((argc + 1) * sizeof(char *));
- for (i = 0; i < argc; i++)
- new_argv[i] = mowgli_strdup(argv[i]);
+
+ for (j = 0; j < argc; j++)
+ new_argv[j] = mowgli_strdup(argv[j]);
+
new_argv[argc] = NULL;
-#if defined(__darwin__)
+# ifdef MOWGLI_OS_OSX
+
/*
* Darwin (and perhaps other NeXT-derived platforms?) has a static
* copy of the argv pointer, which we may fix like so:
*/
*_NSGetArgv() = new_argv;
-#endif
+# endif
argv = new_argv;
-#endif /* MOWGLI_SETPROC_USE_CHANGE_ARGV or MOWGLI_SETPROC_USE_CLOBBER_ARGV */
+#endif /* MOWGLI_SETPROC_USE_CHANGE_ARGV or MOWGLI_SETPROC_USE_CLOBBER_ARGV */
+
+ mowgli_argc = argc;
+ mowgli_argv = argv;
return argv;
}
@@ -216,10 +222,12 @@ mowgli_proctitle_set(const char *fmt, ...)
#ifndef MOWGLI_SETPROC_USE_NONE
va_list va;
-#if defined(MOWGLI_SETPROC_USE_CHANGE_ARGV) || defined(MOWGLI_SETPROC_USE_CLOBBER_ARGV)
+# if defined(MOWGLI_SETPROC_USE_CHANGE_ARGV) || defined(MOWGLI_SETPROC_USE_CLOBBER_ARGV)
+
if (!save_argv)
return;
-#endif
+
+# endif
va_start(va, fmt);
vsnprintf(ps_buffer, ps_buffer_size, fmt, va);
@@ -229,45 +237,46 @@ mowgli_proctitle_set(const char *fmt, ...)
ps_buffer_cur_len = ps_buffer_fixed_size = strlen(ps_buffer);
-#ifdef MOWGLI_SETPROC_USE_CHANGE_ARGV
+# ifdef MOWGLI_SETPROC_USE_CHANGE_ARGV
save_argv[0] = ps_buffer;
save_argv[1] = NULL;
-#endif
+# endif
+
+# ifdef MOWGLI_SETPROC_USE_CLOBBER_ARGV
-#ifdef MOWGLI_SETPROC_USE_CLOBBER_ARGV
for (int i = 1; i < save_argc; i++)
save_argv[i] = ps_buffer + ps_buffer_size;
/* Pad unused bytes */
- printf("%d %d\n", ps_buffer_size, ps_buffer_cur_len);
memset(ps_buffer + ps_buffer_cur_len, PS_PADDING, ps_buffer_size - ps_buffer_cur_len + 1);
-#endif
+# endif
-#ifdef MOWGLI_SETPROC_USE_SETPROCTITLE
+# ifdef MOWGLI_SETPROC_USE_SETPROCTITLE
setproctitle("%s", ps_buffer);
-#endif
+# endif
+
+# ifdef MOWGLI_SETPROC_USE_PRCTL
-#ifdef MOWGLI_SETPROC_USE_PRCTL
/* Limit us to 16 chars to be safe */
char procbuf[16];
mowgli_strlcpy(procbuf, ps_buffer, sizeof(procbuf));
prctl(PR_SET_NAME, procbuf, 0, 0, 0);
- printf("%s\n", procbuf);
-#endif
+# endif
-#ifdef MOWGLI_SETPROC_USE_PSTAT
+# ifdef MOWGLI_SETPROC_USE_PSTAT
union pstun pst;
pst.pst_command = ps_buffer;
pstat(PSTAT_SETCMD, pst, ps_buffer_cur_len, 0, 0);
-#endif /* MOWGLI_SETPROC_USE_PSTAT */
+# endif /* MOWGLI_SETPROC_USE_PSTAT */
-#ifdef MOWGLI_SETPROC_USE_PS_STRINGS
+# ifdef MOWGLI_SETPROC_USE_PS_STRINGS
PS_STRINGS->ps_nargvstr = 1;
PS_STRINGS->ps_argvstr = ps_buffer;
-#endif /* MOWGLI_SETPROC_USE_PS_STRINGS */
+# endif /* MOWGLI_SETPROC_USE_PS_STRINGS */
+
+# ifdef MOWGLI_SETPROC_USE_WIN32
-#ifdef MOWGLI_SETPROC_USE_WIN32
/*
* Win32 does not support showing any changed arguments. To make it at
* all possible to track which backend is doing what, we create a
@@ -282,11 +291,10 @@ mowgli_proctitle_set(const char *fmt, ...)
sprintf(name, "mowgli_ident(%d): %s", getpid(), ps_buffer);
ident_handle = CreateEvent(NULL, TRUE, FALSE, name);
-#endif /* MOWGLI_SETPROC_USE_WIN32 */
-#endif /* not MOWGLI_SETPROC_USE_NONE */
+# endif /* MOWGLI_SETPROC_USE_WIN32 */
+#endif /* not MOWGLI_SETPROC_USE_NONE */
}
-
/*
* Returns what's currently in the ps display, in case someone needs
* it. Note that only the activity part is returned. On some platforms
@@ -297,12 +305,14 @@ const char *
mowgli_proctitle_get(int *displen)
{
#ifdef MOWGLI_SETPROC_USE_CLOBBER_ARGV
+
/* If ps_buffer is a pointer, it might still be null */
if (!ps_buffer)
{
*displen = 0;
return "";
}
+
#endif
*displen = (int) (ps_buffer_cur_len - ps_buffer_fixed_size);
diff --git a/src/libmowgli/ext/proctitle.h b/src/libmowgli/ext/proctitle.h
index 479ee84..cee99f0 100644
--- a/src/libmowgli/ext/proctitle.h
+++ b/src/libmowgli/ext/proctitle.h
@@ -6,7 +6,7 @@
*
* src/include/utils/ps_status.h
*
- *-------------------------------------------------------------------------
+ ***-------------------------------------------------------------------------
*/
#ifndef __PS_STATUS_H__
@@ -14,10 +14,13 @@
extern bool mowgli_proctitle_update;
+extern char **mowgli_argv;
+extern int mowgli_argc;
+
extern char **mowgli_proctitle_init(int argc, char **argv);
extern void mowgli_proctitle_set(const char *fmt, ...);
extern const char *mowgli_proctitle_get(int *displen);
-#endif /* __PS_STATUS_H__ */
+#endif /* __PS_STATUS_H__ */
diff --git a/src/libmowgli/ext/program_opts.c b/src/libmowgli/ext/program_opts.c
index 75acd53..d07c063 100644
--- a/src/libmowgli/ext/program_opts.c
+++ b/src/libmowgli/ext/program_opts.c
@@ -58,21 +58,14 @@ mowgli_program_opts_lookup_name(mowgli_program_opts_t *opts, size_t opts_size, c
size_t i;
if (strlen(name) > 1)
- {
for (i = 0; i < opts_size; i++)
- {
if (!strcasecmp(name, opts[i].longopt))
return &opts[i];
- }
- }
- else
- {
- for (i = 0; i < opts_size; i++)
- {
- if (*name == opts[i].smallopt)
- return &opts[i];
- }
- }
+
+ else
+ for (i = 0; i < opts_size; i++)
+ if (*name == opts[i].smallopt)
+ return &opts[i];
return NULL;
}
@@ -94,6 +87,7 @@ mowgli_program_opts_convert(const mowgli_program_opts_t *opts, size_t opts_size)
g_opts[i].name = opts[i].longopt;
g_opts[i].iflag = i;
+
if (opts[i].has_param)
g_opts[i].has_arg = 1;
}
@@ -118,6 +112,7 @@ mowgli_program_opts_compute_optstr(const mowgli_program_opts_t *opts, size_t opt
continue;
*p++ = opts[i].smallopt;
+
if (opts[i].has_param)
*p++ = ':';
}
@@ -132,7 +127,7 @@ mowgli_program_opts_dispatch(const mowgli_program_opts_t *opt, const char *optar
{
return_if_fail(opt != NULL);
- if (opt->has_param && optarg == NULL)
+ if (opt->has_param && (optarg == NULL))
{
fprintf(stderr, "no optarg for option %s", opt->longopt);
return;
@@ -163,24 +158,26 @@ mowgli_program_opts_parse(const mowgli_program_opts_t *opts, size_t opts_size, i
const mowgli_program_opts_t *opt = NULL;
c = mowgli_getopt_long(*argc, *argv, shortops, g_opts, &opt_index);
+
if (c == -1)
break;
switch (c)
{
case 0:
+
/* long-option was provided, resolve it. */
opt = &opts[g_opts[opt_index].iflag];
break;
default:
+
for (i = 0; i < opts_size; i++)
- {
if (opts[i].smallopt == c)
{
opt = &opts[i];
break;
}
- }
+
break;
}
diff --git a/src/libmowgli/ext/program_opts.h b/src/libmowgli/ext/program_opts.h
index f418b96..e79580d 100644
--- a/src/libmowgli/ext/program_opts.h
+++ b/src/libmowgli/ext/program_opts.h
@@ -26,7 +26,8 @@
typedef void (*mowgli_program_opts_consumer_t)(const char *arg, void *userdata);
-typedef struct {
+typedef struct
+{
const char *longopt;
const char smallopt;
bool has_param;
diff --git a/src/libmowgli/linebuf/linebuf.c b/src/libmowgli/linebuf/linebuf.c
index 8b13040..0395680 100644
--- a/src/libmowgli/linebuf/linebuf.c
+++ b/src/libmowgli/linebuf/linebuf.c
@@ -28,9 +28,18 @@ static mowgli_heap_t *linebuf_heap = NULL;
static void mowgli_linebuf_read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata);
static void mowgli_linebuf_write_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata);
static void mowgli_linebuf_process(mowgli_linebuf_t *linebuf);
+static void mowgli_linebuf_do_shutdown(mowgli_linebuf_t *linebuf);
static int mowgli_linebuf_error(mowgli_vio_t *vio);
+#ifdef NOTYET
+static mowgli_vio_evops_t linebuf_evops =
+{
+ .read_cb = mowgli_linebuf_read_data,
+ .write_cb = mowgli_linebuf_write_data
+};
+#endif
+
mowgli_linebuf_t *
mowgli_linebuf_create(mowgli_linebuf_readline_cb_t *cb, void *userdata)
{
@@ -41,7 +50,8 @@ mowgli_linebuf_create(mowgli_linebuf_readline_cb_t *cb, void *userdata)
linebuf = mowgli_heap_alloc(linebuf_heap);
- linebuf->delim = "\r\n"; /* Sane default */
+ /* Sane default */
+ mowgli_linebuf_delim(linebuf, "\r\n", "\r\n");
linebuf->readline_cb = cb;
linebuf->flags = 0;
@@ -51,7 +61,9 @@ mowgli_linebuf_create(mowgli_linebuf_readline_cb_t *cb, void *userdata)
mowgli_linebuf_setbuflen(&(linebuf->readbuf), 65536);
mowgli_linebuf_setbuflen(&(linebuf->writebuf), 65536);
- linebuf->return_normal_strings = true; /* This is generally what you want, but beware of malicious \0's in input data! */
+ linebuf->eventloop = NULL;
+
+ linebuf->return_normal_strings = true; /* This is generally what you want, but beware of malicious \0's in input data! */
linebuf->userdata = userdata;
@@ -61,22 +73,43 @@ mowgli_linebuf_create(mowgli_linebuf_readline_cb_t *cb, void *userdata)
}
/* Attach the linebuf instance to the eventloop -- socket must be created first with VIO instance! */
-void mowgli_linebuf_attach_to_eventloop(mowgli_linebuf_t *linebuf, mowgli_eventloop_t *eventloop)
+void
+mowgli_linebuf_attach_to_eventloop(mowgli_linebuf_t *linebuf, mowgli_eventloop_t *eventloop)
{
return_if_fail(eventloop != NULL);
return_if_fail(linebuf != NULL);
return_if_fail(linebuf->vio != NULL);
return_if_fail((linebuf->vio->flags & MOWGLI_VIO_FLAGS_ISCLOSED) == 0);
- mowgli_vio_eventloop_attach(linebuf->vio, eventloop);
- mowgli_pollable_setselect(eventloop, linebuf->vio->io, MOWGLI_EVENTLOOP_IO_READ, mowgli_linebuf_read_data);
- mowgli_pollable_setselect(eventloop, linebuf->vio->io, MOWGLI_EVENTLOOP_IO_WRITE, mowgli_linebuf_write_data);
+#ifdef NOTYET
+ mowgli_vio_eventloop_attach(linebuf->vio, eventloop, &linebuf_evops);
+#else
+ mowgli_vio_eventloop_attach(linebuf->vio, eventloop, NULL);
+#endif
+ mowgli_pollable_setselect(eventloop, linebuf->vio->io.e, MOWGLI_EVENTLOOP_IO_READ, mowgli_linebuf_read_data);
+ mowgli_pollable_setselect(eventloop, linebuf->vio->io.e, MOWGLI_EVENTLOOP_IO_WRITE, mowgli_linebuf_write_data);
linebuf->eventloop = eventloop;
}
-void mowgli_linebuf_destroy(mowgli_linebuf_t *linebuf)
+/* Detach the linebuf instance from the eventloop */
+void
+mowgli_linebuf_detach_from_eventloop(mowgli_linebuf_t *linebuf)
+{
+ return_if_fail(linebuf != NULL);
+ return_if_fail(linebuf->eventloop != NULL);
+ mowgli_pollable_setselect(linebuf->eventloop, linebuf->vio->io.e, MOWGLI_EVENTLOOP_IO_READ, NULL);
+ mowgli_pollable_setselect(linebuf->eventloop, linebuf->vio->io.e, MOWGLI_EVENTLOOP_IO_WRITE, NULL);
+ mowgli_vio_eventloop_detach(linebuf->vio);
+ linebuf->eventloop = NULL;
+}
+
+void
+mowgli_linebuf_destroy(mowgli_linebuf_t *linebuf)
{
+ if (linebuf->eventloop != NULL)
+ mowgli_linebuf_detach_from_eventloop(linebuf);
+
mowgli_vio_destroy(linebuf->vio);
mowgli_free(linebuf->readbuf.buffer);
@@ -84,18 +117,21 @@ void mowgli_linebuf_destroy(mowgli_linebuf_t *linebuf)
mowgli_heap_free(linebuf_heap, linebuf);
}
-void mowgli_linebuf_setbuflen(mowgli_linebuf_buf_t *buffer, size_t buflen)
+void
+mowgli_linebuf_setbuflen(mowgli_linebuf_buf_t *buffer, size_t buflen)
{
return_if_fail(buffer != NULL);
if (buffer->buffer == NULL)
+ {
buffer->buffer = mowgli_alloc(buflen);
+ }
else
{
char tmpbuf[buffer->maxbuflen];
if (buffer->buflen > 0)
- memcpy(tmpbuf, buffer->buffer, buffer->maxbuflen); /* Copy into tmp buffer */
+ memcpy(tmpbuf, buffer->buffer, buffer->maxbuflen); /* Copy into tmp buffer */
/* Free old buffer and reallocate */
mowgli_free(buffer->buffer);
@@ -109,9 +145,22 @@ void mowgli_linebuf_setbuflen(mowgli_linebuf_buf_t *buffer, size_t buflen)
buffer->maxbuflen = buflen;
}
-static void mowgli_linebuf_read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
+void
+mowgli_linebuf_delim(mowgli_linebuf_t *linebuf, const char *delim, const char *endl)
{
- mowgli_linebuf_t *linebuf = (mowgli_linebuf_t *)userdata;
+ return_if_fail(linebuf != NULL);
+ return_if_fail(delim != NULL && *delim != '\0');
+ return_if_fail(endl != NULL && *endl != '\0');
+
+ linebuf->delim = delim;
+ linebuf->endl = endl;
+ linebuf->endl_len = strlen(endl);
+}
+
+static void
+mowgli_linebuf_read_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
+{
+ mowgli_linebuf_t *linebuf = (mowgli_linebuf_t *) userdata;
mowgli_linebuf_buf_t *buffer = &(linebuf->readbuf);
void *bufpos;
size_t offset;
@@ -129,9 +178,12 @@ static void mowgli_linebuf_read_data(mowgli_eventloop_t *eventloop, mowgli_event
if ((ret = mowgli_vio_read(linebuf->vio, bufpos, offset)) <= 0)
{
- if (linebuf->vio->error.code != MOWGLI_VIO_ERR_NONE)
- /* Let's never come back here */
- mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_READ, NULL);
+ if (linebuf->vio->error.type == MOWGLI_VIO_ERR_NONE)
+ return;
+
+ /* Let's never come back here */
+ mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_READ, NULL);
+ mowgli_linebuf_do_shutdown(linebuf);
return;
}
@@ -147,29 +199,43 @@ static void mowgli_linebuf_read_data(mowgli_eventloop_t *eventloop, mowgli_event
mowgli_linebuf_process(linebuf);
}
-static void mowgli_linebuf_write_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
+static void
+mowgli_linebuf_write_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
{
- mowgli_linebuf_t *linebuf = (mowgli_linebuf_t *)userdata;
+ mowgli_linebuf_t *linebuf = (mowgli_linebuf_t *) userdata;
mowgli_linebuf_buf_t *buffer = &(linebuf->writebuf);
int ret;
if ((ret = mowgli_vio_write(linebuf->vio, buffer->buffer, buffer->buflen)) <= 0)
- {
if (linebuf->vio->error.code != MOWGLI_VIO_ERR_NONE)
- /* If we have a genuine error, we shouldn't come back to this func
+ /* If we have a genuine error, we shouldn't come back to this func
* Otherwise we'll try again. */
- mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, NULL);
- return;
- }
+ if (ret != 0)
+ {
+ mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, NULL);
+ mowgli_log("mowgli_vio_write returned error [%ld]: %s", linebuf->vio->error.code, linebuf->vio->error.string);
+ return;
+ }
buffer->buflen -= ret;
/* Anything else to write? */
if (buffer->buflen == 0)
- mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, NULL);
+ {
+ if (!mowgli_vio_hasflag(linebuf->vio, MOWGLI_VIO_FLAGS_NEEDWRITE))
+ mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, NULL);
+
+ if ((linebuf->flags & MOWGLI_LINEBUF_SHUTTING_DOWN) != 0)
+ mowgli_linebuf_do_shutdown(linebuf);
+ }
+ else
+ {
+ mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, mowgli_linebuf_write_data);
+ }
}
-void mowgli_linebuf_writef(mowgli_linebuf_t *linebuf, const char *format, ...)
+void
+mowgli_linebuf_writef(mowgli_linebuf_t *linebuf, const char *format, ...)
{
char buf[linebuf->writebuf.maxbuflen];
size_t len;
@@ -182,34 +248,48 @@ void mowgli_linebuf_writef(mowgli_linebuf_t *linebuf, const char *format, ...)
mowgli_linebuf_write(linebuf, buf, len);
}
-void mowgli_linebuf_write(mowgli_linebuf_t *linebuf, const char *data, int len)
+void
+mowgli_linebuf_write(mowgli_linebuf_t *linebuf, const char *data, int len)
{
char *ptr = linebuf->writebuf.buffer + linebuf->writebuf.buflen;
- int delim_len = strlen(linebuf->delim);
return_if_fail(len > 0);
return_if_fail(data != NULL);
- if (linebuf->writebuf.buflen + len + delim_len > linebuf->writebuf.maxbuflen)
+ if (linebuf->flags & MOWGLI_LINEBUF_SHUTTING_DOWN)
+ return;
+
+ if (linebuf->writebuf.buflen + len + linebuf->endl_len > linebuf->writebuf.maxbuflen)
{
linebuf->flags |= MOWGLI_LINEBUF_ERR_WRITEBUF_FULL;
mowgli_linebuf_error(linebuf->vio);
return;
}
- memcpy((void *)ptr, data, len);
- memcpy((void *)(ptr + len), linebuf->delim, delim_len);
+ memcpy((void *) ptr, data, len);
+ memcpy((void *) (ptr + len), linebuf->endl, linebuf->endl_len);
- linebuf->writebuf.buflen += len + delim_len;
+ linebuf->writebuf.buflen += len + linebuf->endl_len;
/* Schedule our write */
- mowgli_pollable_setselect(linebuf->eventloop, linebuf->vio->io, MOWGLI_EVENTLOOP_IO_WRITE, mowgli_linebuf_write_data);
+ mowgli_pollable_setselect(linebuf->eventloop, linebuf->vio->io.e, MOWGLI_EVENTLOOP_IO_WRITE, mowgli_linebuf_write_data);
+}
+
+void
+mowgli_linebuf_shut_down(mowgli_linebuf_t *linebuf)
+{
+ return_if_fail(linebuf != NULL);
+
+ linebuf->flags |= MOWGLI_LINEBUF_SHUTTING_DOWN;
+
+ if (linebuf->writebuf.buflen == 0)
+ mowgli_linebuf_do_shutdown(linebuf);
}
-static void mowgli_linebuf_process(mowgli_linebuf_t *linebuf)
+static void
+mowgli_linebuf_process(mowgli_linebuf_t *linebuf)
{
mowgli_linebuf_buf_t *buffer = &(linebuf->readbuf);
- size_t delim_len = strlen(linebuf->delim);
char *line_start;
char *cptr;
@@ -223,11 +303,12 @@ static void mowgli_linebuf_process(mowgli_linebuf_t *linebuf)
while (len < buffer->buflen)
{
- if (memcmp((void *)cptr, linebuf->delim, delim_len) != 0)
+ if (!strchr(linebuf->delim, *cptr))
{
if (*cptr == '\0')
/* Warn about unexpected null chars in the string */
linebuf->flags |= MOWGLI_LINEBUF_LINE_HASNULLCHAR;
+
cptr++;
len++;
continue;
@@ -239,20 +320,25 @@ static void mowgli_linebuf_process(mowgli_linebuf_t *linebuf)
if (linebuf->return_normal_strings)
*cptr = '\0';
- linebuf->readline_cb(linebuf, line_start, cptr - line_start, linebuf->userdata);
+ if ((linebuf->flags & MOWGLI_LINEBUF_SHUTTING_DOWN) == 0)
+ linebuf->readline_cb(linebuf, line_start, cptr - line_start, linebuf->userdata);
/* Next line starts here; begin scanning and set the start of it */
- len += delim_len;
- cptr += delim_len;
+ while (strchr(linebuf->delim, *cptr))
+ {
+ len++;
+ cptr++;
+ }
+
line_start = cptr;
/* Reset this for next line */
linebuf->flags &= ~MOWGLI_LINEBUF_LINE_HASNULLCHAR;
}
- if (linecount == 0 && (buffer->buflen == buffer->maxbuflen))
+ if ((linecount == 0) && (buffer->buflen == buffer->maxbuflen))
{
- /* No more chars will fit in the buffer and we don't have a line
+ /* No more chars will fit in the buffer and we don't have a line
* We're really screwed, let's trigger an error. */
linebuf->flags |= MOWGLI_LINEBUF_ERR_READBUF_FULL;
mowgli_linebuf_error(linebuf->vio);
@@ -265,10 +351,20 @@ static void mowgli_linebuf_process(mowgli_linebuf_t *linebuf)
memmove(buffer->buffer, line_start, cptr - line_start);
}
else
+ {
buffer->buflen = 0;
+ }
+}
+
+static void
+mowgli_linebuf_do_shutdown(mowgli_linebuf_t *linebuf)
+{
+ if (linebuf && linebuf->shutdown_cb)
+ linebuf->shutdown_cb(linebuf, linebuf->userdata);
}
-static int mowgli_linebuf_error(mowgli_vio_t *vio)
+static int
+mowgli_linebuf_error(mowgli_vio_t *vio)
{
mowgli_linebuf_t *linebuf = vio->userdata;
mowgli_vio_error_t *error = &(linebuf->vio->error);
@@ -289,4 +385,3 @@ static int mowgli_linebuf_error(mowgli_vio_t *vio)
/* Pass this up to higher callback */
return mowgli_vio_error(vio);
}
-
diff --git a/src/libmowgli/linebuf/linebuf.h b/src/libmowgli/linebuf/linebuf.h
index 17c45ea..e05629b 100644
--- a/src/libmowgli/linebuf/linebuf.h
+++ b/src/libmowgli/linebuf/linebuf.h
@@ -21,41 +21,52 @@
#ifndef __MOWGLI_LINEBUF_LINEBUF_H__
#define __MOWGLI_LINEBUF_LINEBUF_H__
-#include "eventloop/eventloop.h"
-#include "vio/vio.h"
-
typedef struct _mowgli_linebuf_buf mowgli_linebuf_buf_t;
-typedef void mowgli_linebuf_readline_cb_t(mowgli_linebuf_t *, char *, size_t, void *);
+typedef void mowgli_linebuf_readline_cb_t (mowgli_linebuf_t *, char *, size_t, void *);
+typedef void mowgli_linebuf_shutdown_cb_t (mowgli_linebuf_t *, void *);
+
+extern mowgli_linebuf_t *mowgli_linebuf_create(mowgli_linebuf_readline_cb_t *cb, void *userdata);
-extern mowgli_linebuf_t * mowgli_linebuf_create(mowgli_linebuf_readline_cb_t *cb, void *userdata);
+/* XXX these are unfortunately named and will change */
extern void mowgli_linebuf_attach_to_eventloop(mowgli_linebuf_t *linebuf, mowgli_eventloop_t *eventloop);
+extern void mowgli_linebuf_detach_from_eventloop(mowgli_linebuf_t *linebuf);
extern void mowgli_linebuf_destroy(mowgli_linebuf_t *linebuf);
extern void mowgli_linebuf_setbuflen(mowgli_linebuf_buf_t *buffer, size_t buflen);
+extern void mowgli_linebuf_delim(mowgli_linebuf_t *linebuf, const char *delim, const char *endl);
extern void mowgli_linebuf_write(mowgli_linebuf_t *linebuf, const char *data, int len);
extern void mowgli_linebuf_writef(mowgli_linebuf_t *linebuf, const char *format, ...);
+extern void mowgli_linebuf_shut_down(mowgli_linebuf_t *linebuf);
-struct _mowgli_linebuf_buf {
+struct _mowgli_linebuf_buf
+{
char *buffer;
size_t buflen;
size_t maxbuflen;
};
/* Errors */
-#define MOWGLI_LINEBUF_ERR_NONE 0x0000
-#define MOWGLI_LINEBUF_ERR_READBUF_FULL 0x0001
-#define MOWGLI_LINEBUF_ERR_WRITEBUF_FULL 0x0002
+#define MOWGLI_LINEBUF_ERR_NONE 0x0000
+#define MOWGLI_LINEBUF_ERR_READBUF_FULL 0x0001
+#define MOWGLI_LINEBUF_ERR_WRITEBUF_FULL 0x0002
/* Informative */
-#define MOWGLI_LINEBUF_LINE_HASNULLCHAR 0x0004
+#define MOWGLI_LINEBUF_LINE_HASNULLCHAR 0x0004
-struct _mowgli_linebuf {
+/* State */
+#define MOWGLI_LINEBUF_SHUTTING_DOWN 0x0100
+
+struct _mowgli_linebuf
+{
mowgli_linebuf_readline_cb_t *readline_cb;
+ mowgli_linebuf_shutdown_cb_t *shutdown_cb;
mowgli_vio_t *vio;
const char *delim;
+ const char *endl;
+ size_t endl_len;
int flags;
@@ -69,11 +80,11 @@ struct _mowgli_linebuf {
void *userdata;
};
-static inline mowgli_vio_t * mowgli_linebuf_get_vio(mowgli_linebuf_t *linebuf)
+static inline mowgli_vio_t *
+mowgli_linebuf_get_vio(mowgli_linebuf_t *linebuf)
{
return_val_if_fail(linebuf != NULL, NULL);
return linebuf->vio;
}
#endif
-
diff --git a/src/libmowgli/module/Makefile b/src/libmowgli/module/Makefile
index 702ed7c..19d885a 100644
--- a/src/libmowgli/module/Makefile
+++ b/src/libmowgli/module/Makefile
@@ -3,7 +3,7 @@ include ../../../extra.mk
STATIC_PIC_LIB_NOINST = ${LIBMOWGLI_SHARED_MODULE}
STATIC_LIB_NOINST = ${LIBMOWGLI_STATIC_MODULE}
-SRCS = loader_${LIBMOWGLI_OS}.c
+SRCS = interface.c loader_${LIBMOWGLI_OS}.c
INCLUDES = module.h
diff --git a/src/libmowgli/module/interface.c b/src/libmowgli/module/interface.c
new file mode 100644
index 0000000..a552605
--- /dev/null
+++ b/src/libmowgli/module/interface.c
@@ -0,0 +1,73 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * module.h: Loadable modules.
+ *
+ * Copyright (c) 2007, 2014 William Pitcock <william@dereferenced.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mowgli.h"
+
+static mowgli_patricia_t *mowgli_interface_dict = NULL;
+static mowgli_mutex_t mowgli_interface_lock;
+
+void
+mowgli_interface_bootstrap(void)
+{
+ mowgli_interface_dict = mowgli_patricia_create(NULL);
+ mowgli_mutex_init(&mowgli_interface_lock);
+}
+
+void
+mowgli_interface_register(mowgli_interface_t *iface)
+{
+ mowgli_interface_base_t *base_iface = iface;
+
+ mowgli_mutex_lock(&mowgli_interface_lock);
+ mowgli_patricia_add(mowgli_interface_dict, base_iface->id, iface);
+ mowgli_mutex_unlock(&mowgli_interface_lock);
+}
+
+void
+mowgli_interface_unregister(mowgli_interface_t *iface)
+{
+ mowgli_interface_base_t *base_iface = iface;
+
+ mowgli_mutex_lock(&mowgli_interface_lock);
+ mowgli_patricia_delete(mowgli_interface_dict, base_iface->id);
+ mowgli_mutex_unlock(&mowgli_interface_lock);
+}
+
+mowgli_interface_t *
+mowgli_interface_get(const char *id, uint32_t abirev)
+{
+ mowgli_interface_base_t *base_iface;
+
+ mowgli_mutex_lock(&mowgli_interface_lock);
+
+ base_iface = mowgli_patricia_retrieve(mowgli_interface_dict, id);
+ if (base_iface->abirev != abirev)
+ {
+ mowgli_log("requested interface %s, abi mismatch %d != %d", id, abirev, base_iface->abirev);
+ base_iface = NULL;
+ }
+
+ mowgli_mutex_unlock(&mowgli_interface_lock);
+
+ return base_iface;
+}
diff --git a/src/libmowgli/module/loader_posix.c b/src/libmowgli/module/loader_posix.c
index f15c38a..d4114e7 100644
--- a/src/libmowgli/module/loader_posix.c
+++ b/src/libmowgli/module/loader_posix.c
@@ -30,22 +30,25 @@
#endif
#ifndef RTLD_LOCAL
-#define RTLD_LOCAL 0
+# define RTLD_LOCAL 0
#endif
-mowgli_module_t mowgli_module_open(const char *path)
+mowgli_module_t
+mowgli_module_open(const char *path)
{
void *handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
- /* make sure we have something. make this an assertion so that
- * there is feedback if something happens. (poor programming practice).
- */
- return_val_if_fail(handle != NULL, NULL);
+ if (handle == NULL)
+ {
+ mowgli_log("Failed to open %s: %s", path, dlerror());
+ return NULL;
+ }
return handle;
}
-void * mowgli_module_symbol(mowgli_module_t module, const char *symbol)
+void *
+mowgli_module_symbol(mowgli_module_t module, const char *symbol)
{
void *handle;
@@ -53,15 +56,17 @@ void * mowgli_module_symbol(mowgli_module_t module, const char *symbol)
handle = dlsym(module, symbol);
- /* make sure we have something. make this an assertion so that
- * there is feedback if something happens. (poor programming practice).
- */
- return_val_if_fail(handle != NULL, NULL);
+ if (handle == NULL)
+ {
+ mowgli_log("Failed to find symbol %s: %s", symbol, dlerror());
+ return NULL;
+ }
return handle;
}
-void mowgli_module_close(mowgli_module_t module)
+void
+mowgli_module_close(mowgli_module_t module)
{
return_if_fail(module != NULL);
diff --git a/src/libmowgli/module/loader_win32.c b/src/libmowgli/module/loader_win32.c
index f42a742..70cd1b6 100644
--- a/src/libmowgli/module/loader_win32.c
+++ b/src/libmowgli/module/loader_win32.c
@@ -23,30 +23,32 @@
#include "mowgli.h"
-#define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-mowgli_module_t mowgli_module_open(const char *path)
+mowgli_module_t
+mowgli_module_open(const char *path)
{
HANDLE handle = LoadLibraryA(path);
- /* make sure we have something. make this an assertion so that
+ /* make sure we have something. make this an assertion so that
* there is feedback if something happens. (poor programming practice).
*/
return_val_if_fail(handle != NULL, NULL);
- return (mowgli_module_t)handle;
+ return (mowgli_module_t) handle;
}
-void * mowgli_module_symbol(mowgli_module_t module, const char *symbol)
+void *
+mowgli_module_symbol(mowgli_module_t module, const char *symbol)
{
void *handle;
return_val_if_fail(module != NULL, NULL);
- handle = GetProcAddress((HANDLE)module, symbol);
+ handle = GetProcAddress((HANDLE) module, symbol);
- /* make sure we have something. make this an assertion so that
+ /* make sure we have something. make this an assertion so that
* there is feedback if something happens. (poor programming practice).
*/
return_val_if_fail(handle != NULL, NULL);
@@ -54,9 +56,10 @@ void * mowgli_module_symbol(mowgli_module_t module, const char *symbol)
return handle;
}
-void mowgli_module_close(mowgli_module_t module)
+void
+mowgli_module_close(mowgli_module_t module)
{
return_if_fail(module != NULL);
- FreeLibrary((HANDLE)module);
+ FreeLibrary((HANDLE) module);
}
diff --git a/src/libmowgli/module/module.h b/src/libmowgli/module/module.h
index 54fc344..214fd51 100644
--- a/src/libmowgli/module/module.h
+++ b/src/libmowgli/module/module.h
@@ -2,7 +2,7 @@
* libmowgli: A collection of useful routines for programming.
* module.h: Loadable modules.
*
- * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ * Copyright (c) 2007, 2014 William Pitcock <william@dereferenced.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -24,10 +24,21 @@
#ifndef __MOWGLI_MODULE_H__
#define __MOWGLI_MODULE_H__
-typedef void * mowgli_module_t;
+typedef void *mowgli_module_t;
extern mowgli_module_t mowgli_module_open(const char *path);
-extern void * mowgli_module_symbol(mowgli_module_t module, const char *symbol);
+extern void *mowgli_module_symbol(mowgli_module_t module, const char *symbol);
extern void mowgli_module_close(mowgli_module_t module);
+typedef void mowgli_interface_t;
+
+typedef struct {
+ const char *id;
+ uint32_t abirev;
+} mowgli_interface_base_t;
+
+extern void mowgli_interface_register(mowgli_interface_t *iface);
+extern void mowgli_interface_unregister(mowgli_interface_t *iface);
+extern mowgli_interface_t *mowgli_interface_get(const char *id, uint32_t abirev);
+
#endif
diff --git a/src/libmowgli/mowgli.h b/src/libmowgli/mowgli.h
index 6a64f0d..fca8f70 100644
--- a/src/libmowgli/mowgli.h
+++ b/src/libmowgli/mowgli.h
@@ -26,7 +26,8 @@
#ifdef __cplusplus
# define MOWGLI_DECLS_START extern "C" {
-# define MOWGLI_DECLS_END }
+# define MOWGLI_DECLS_END \
+ }
#else
# define MOWGLI_DECLS_START
# define MOWGLI_DECLS_END
@@ -40,12 +41,13 @@
MOWGLI_DECLS_START
-#include "platform/constructor.h"
#include "platform/machine.h"
+#include "platform/cacheline.h"
+#include "platform/attributes.h"
+#include "platform/constructor.h"
#include "core/logger.h"
#include "core/assert.h"
-#include "core/exception.h"
#include "core/iterator.h"
#include "container/list.h"
@@ -88,10 +90,11 @@ MOWGLI_DECLS_START
#include "ext/confparse.h"
#include "ext/program_opts.h"
+#include "ext/json.h"
+
#include "linebuf/linebuf.h"
#include "dns/dns.h"
MOWGLI_DECLS_END
#endif
-
diff --git a/src/libmowgli/object/class.c b/src/libmowgli/object/class.c
index 9bddf79..627b59d 100644
--- a/src/libmowgli/object/class.c
+++ b/src/libmowgli/object/class.c
@@ -23,9 +23,10 @@
#include "mowgli.h"
-static mowgli_patricia_t *mowgli_object_class_dict = NULL;
+static mowgli_patricia_t *mowgli_object_class_dict;
-static void _object_key_canon(char *str)
+static void
+_object_key_canon(char *str)
{
while (*str)
{
@@ -34,17 +35,17 @@ static void _object_key_canon(char *str)
}
}
-void mowgli_object_class_init(mowgli_object_class_t *klass, const char *name, mowgli_destructor_t des, mowgli_boolean_t dynamic)
+void
+mowgli_object_class_bootstrap()
{
- /* if the object_class dictionary has not yet been initialized, we will want to do that. */
- if (mowgli_object_class_dict == NULL)
- mowgli_object_class_dict = mowgli_patricia_create(_object_key_canon);
-
- if (klass == NULL)
- mowgli_throw_exception_fatal(mowgli.object_class.invalid_object_class_exception);
+ mowgli_object_class_dict = mowgli_patricia_create(_object_key_canon);
+}
- if (mowgli_object_class_find_by_name(name) != NULL)
- mowgli_throw_exception_fatal(mowgli.object_class.duplicate_object_class_exception);
+void
+mowgli_object_class_init(mowgli_object_class_t *klass, const char *name, mowgli_destructor_t des, mowgli_boolean_t dynamic)
+{
+ return_if_fail(klass != NULL);
+ return_if_fail(mowgli_object_class_find_by_name(name) == NULL);
/* initialize object_class::name */
klass->name = mowgli_strdup(name);
@@ -64,12 +65,13 @@ void mowgli_object_class_init(mowgli_object_class_t *klass, const char *name, mo
mowgli_patricia_add(mowgli_object_class_dict, klass->name, klass);
}
-int mowgli_object_class_check_cast(mowgli_object_class_t *klass1, mowgli_object_class_t *klass2)
+int
+mowgli_object_class_check_cast(mowgli_object_class_t *klass1, mowgli_object_class_t *klass2)
{
- mowgli_node_t *n;
+ return_val_if_fail(klass1 != NULL, 0);
+ return_val_if_fail(klass2 != NULL, 0);
- if (klass1 == NULL || klass2 == NULL)
- mowgli_throw_exception_val(mowgli.object_class.invalid_object_class_exception, 0);
+ mowgli_node_t *n;
MOWGLI_LIST_FOREACH(n, klass1->derivitives.head)
{
@@ -82,15 +84,17 @@ int mowgli_object_class_check_cast(mowgli_object_class_t *klass1, mowgli_object_
return 0;
}
-void mowgli_object_class_set_derivitive(mowgli_object_class_t *klass, mowgli_object_class_t *parent)
+void
+mowgli_object_class_set_derivitive(mowgli_object_class_t *klass, mowgli_object_class_t *parent)
{
- if (klass == NULL || parent == NULL)
- mowgli_throw_exception_fatal(mowgli.object_class.invalid_object_class_exception);
+ return_if_fail(klass != NULL);
+ return_if_fail(parent != NULL);
mowgli_node_add(klass, mowgli_node_create(), &parent->derivitives);
}
-void *mowgli_object_class_reinterpret_impl(/* mowgli_object_t */ void *opdata, mowgli_object_class_t *klass)
+void *
+mowgli_object_class_reinterpret_impl( /* mowgli_object_t */ void *opdata, mowgli_object_class_t *klass)
{
mowgli_object_t *object = mowgli_object(opdata);
@@ -101,24 +105,23 @@ void *mowgli_object_class_reinterpret_impl(/* mowgli_object_t */ void *opdata, m
if (mowgli_object_class_check_cast(object->klass, klass))
return object;
- mowgli_log("Invalid reinterpreted cast from %s<%p> to %s", object->klass->name, klass->name);
+ mowgli_log("Invalid reinterpreted cast from %s<%p> to %s", object->klass->name, (void *) object, klass->name);
return NULL;
}
-mowgli_object_class_t *mowgli_object_class_find_by_name(const char *name)
+mowgli_object_class_t *
+mowgli_object_class_find_by_name(const char *name)
{
return mowgli_patricia_retrieve(mowgli_object_class_dict, name);
}
-void mowgli_object_class_destroy(mowgli_object_class_t *klass)
+void
+mowgli_object_class_destroy(mowgli_object_class_t *klass)
{
- mowgli_node_t *n, *tn;
+ return_if_fail(klass != NULL);
+ return_if_fail(klass->dynamic == TRUE);
- if (klass == NULL)
- mowgli_throw_exception_fatal(mowgli.object_class.invalid_object_class_exception);
-
- if (klass->dynamic != TRUE)
- mowgli_throw_exception_fatal(mowgli.object_class.nondynamic_object_class_exception);
+ mowgli_node_t *n, *tn;
MOWGLI_LIST_FOREACH_SAFE(n, tn, klass->derivitives.head)
{
diff --git a/src/libmowgli/object/class.h b/src/libmowgli/object/class.h
index 9612aa4..121368b 100644
--- a/src/libmowgli/object/class.h
+++ b/src/libmowgli/object/class.h
@@ -26,7 +26,8 @@
typedef void (*mowgli_destructor_t)(void *);
-typedef struct {
+typedef struct
+{
char *name;
mowgli_list_t derivitives;
mowgli_destructor_t destructor;
@@ -37,24 +38,25 @@ typedef struct {
extern void mowgli_object_class_init(mowgli_object_class_t *klass, const char *name, mowgli_destructor_t des, mowgli_boolean_t dynamic);
extern int mowgli_object_class_check_cast(mowgli_object_class_t *klass1, mowgli_object_class_t *klass2);
extern void mowgli_object_class_set_derivitive(mowgli_object_class_t *klass, mowgli_object_class_t *parent);
-extern void *mowgli_object_class_reinterpret_impl(/* mowgli_object_t */ void *object, mowgli_object_class_t *klass);
+extern void *mowgli_object_class_reinterpret_impl( /* mowgli_object_t */ void *object, mowgli_object_class_t *klass);
extern mowgli_object_class_t *mowgli_object_class_find_by_name(const char *name);
extern void mowgli_object_class_destroy(mowgli_object_class_t *klass);
-#define MOWGLI_REINTERPRET_CAST(object, klass) (klass *) mowgli_object_class_reinterpret_impl(object, mowgli_object_class_find_by_name( # klass ));
+#define MOWGLI_REINTERPRET_CAST(object, klass) (klass *) mowgli_object_class_reinterpret_impl(object, mowgli_object_class_find_by_name(#klass))
-#define mowgli_forced_cast(from_type, to_type, from, to)\
-do { \
- union cast_union \
- { \
- to_type out; \
- from_type in; \
- } u; \
- typedef int cant_use_union_cast[ \
- sizeof (from_type) == sizeof (u) \
- && sizeof (from_type) == sizeof (to_type) ? 1 : -1];\
- u.in = from; \
- to = u.out; \
-} while (0)
+#define mowgli_forced_cast(from_type, to_type, from, to) \
+ do \
+ { \
+ union cast_union \
+ { \
+ to_type out; \
+ from_type in; \
+ } u; \
+ typedef int cant_use_union_cast[ \
+ sizeof(from_type) == sizeof(u) \
+ && sizeof(from_type) == sizeof(to_type) ? 1 : -1]; \
+ u.in = from; \
+ to = u.out; \
+ } while (0)
#endif
diff --git a/src/libmowgli/object/message.c b/src/libmowgli/object/message.c
index e4328c8..d99f53b 100644
--- a/src/libmowgli/object/message.c
+++ b/src/libmowgli/object/message.c
@@ -23,71 +23,61 @@
#include "mowgli.h"
-void mowgli_object_class_message_handler_attach(mowgli_object_class_t *klass, mowgli_object_message_handler_t *sig)
+void
+mowgli_object_class_message_handler_attach(mowgli_object_class_t *klass, mowgli_object_message_handler_t *sig)
{
- if (klass == NULL)
- mowgli_throw_exception(mowgli.object_messaging.invalid_object_class_exception);
-
- if (sig == NULL)
- mowgli_throw_exception(mowgli.object_messaging.invalid_signal_exception);
+ return_if_fail(klass != NULL);
+ return_if_fail(sig != NULL);
mowgli_node_add(sig, mowgli_node_create(), &klass->message_handlers);
}
-void mowgli_object_class_message_handler_detach(mowgli_object_class_t *klass, mowgli_object_message_handler_t *sig)
+void
+mowgli_object_class_message_handler_detach(mowgli_object_class_t *klass, mowgli_object_message_handler_t *sig)
{
- mowgli_node_t *n;
+ return_if_fail(klass != NULL);
+ return_if_fail(sig != NULL);
- if (klass == NULL)
- mowgli_throw_exception(mowgli.object_messaging.invalid_object_class_exception);
-
- if (sig == NULL)
- mowgli_throw_exception(mowgli.object_messaging.invalid_signal_exception);
+ mowgli_node_t *n;
n = mowgli_node_find(sig, &klass->message_handlers);
mowgli_node_delete(n, &klass->message_handlers);
mowgli_node_free(n);
}
-void mowgli_object_message_handler_attach(mowgli_object_t *self, mowgli_object_message_handler_t *sig)
+void
+mowgli_object_message_handler_attach(mowgli_object_t *self, mowgli_object_message_handler_t *sig)
{
- if (self == NULL)
- mowgli_throw_exception(mowgli.object_messaging.invalid_object_exception);
-
- if (sig == NULL)
- mowgli_throw_exception(mowgli.object_messaging.invalid_signal_exception);
+ return_if_fail(self != NULL);
+ return_if_fail(sig != NULL);
mowgli_node_add(sig, mowgli_node_create(), &self->message_handlers);
}
-void mowgli_object_message_handler_detach(mowgli_object_t *self, mowgli_object_message_handler_t *sig)
+void
+mowgli_object_message_handler_detach(mowgli_object_t *self, mowgli_object_message_handler_t *sig)
{
- mowgli_node_t *n;
+ return_if_fail(self != NULL);
+ return_if_fail(sig != NULL);
- if (self == NULL)
- mowgli_throw_exception(mowgli.object_messaging.invalid_object_exception);
-
- if (sig == NULL)
- mowgli_throw_exception(mowgli.object_messaging.invalid_signal_exception);
+ mowgli_node_t *n;
n = mowgli_node_find(sig, &self->message_handlers);
mowgli_node_delete(n, &self->message_handlers);
mowgli_node_free(n);
}
-void mowgli_object_message_broadcast(mowgli_object_t *self, const char *name, ...)
+void
+mowgli_object_message_broadcast(mowgli_object_t *self, const char *name, ...)
{
+ return_if_fail(self != NULL);
+ return_if_fail(name != NULL);
+
mowgli_argstack_t *stack;
mowgli_object_message_handler_t *sig = NULL;
mowgli_node_t *n;
va_list va;
- if (self == NULL)
- mowgli_throw_exception(mowgli.object_messaging.invalid_object_exception);
-
- if (name == NULL)
- mowgli_throw_exception(mowgli.null_pointer_exception);
-
/* try to find a signal to compile the argument stack from, we start with self::klass first. */
MOWGLI_LIST_FOREACH(n, self->klass->message_handlers.head)
{
@@ -101,7 +91,6 @@ void mowgli_object_message_broadcast(mowgli_object_t *self, const char *name, ..
}
if (sig == NULL)
- {
MOWGLI_LIST_FOREACH(n, self->klass->message_handlers.head)
{
mowgli_object_message_handler_t *sig2 = (mowgli_object_message_handler_t *) n->data;
@@ -112,11 +101,10 @@ void mowgli_object_message_broadcast(mowgli_object_t *self, const char *name, ..
break;
}
}
- }
- /* return if no signals found, else compile the argstack */
- if (sig == NULL)
- return;
+ /* return if no signals found, else compile the argstack */
+ if (sig == NULL)
+ return;
va_start(va, name);
stack = mowgli_argstack_create_from_va_list(sig->descstr, va);
@@ -126,7 +114,7 @@ void mowgli_object_message_broadcast(mowgli_object_t *self, const char *name, ..
{
sig = (mowgli_object_message_handler_t *) n->data;
- if (!strcasecmp(sig->name, name) && sig->handler != NULL)
+ if (!strcasecmp(sig->name, name) && (sig->handler != NULL))
sig->handler(self, sig, stack);
}
@@ -134,7 +122,7 @@ void mowgli_object_message_broadcast(mowgli_object_t *self, const char *name, ..
{
sig = (mowgli_object_message_handler_t *) n->data;
- if (!strcasecmp(sig->name, name) && sig->handler != NULL)
+ if (!strcasecmp(sig->name, name) && (sig->handler != NULL))
sig->handler(self, sig, stack);
}
diff --git a/src/libmowgli/object/message.h b/src/libmowgli/object/message.h
index 4a49d00..aee82af 100644
--- a/src/libmowgli/object/message.h
+++ b/src/libmowgli/object/message.h
@@ -27,7 +27,8 @@
typedef struct mowgli_object_message_handler_ mowgli_object_message_handler_t;
typedef void (*mowgli_object_messaging_func_t)(mowgli_object_t *self, mowgli_object_message_handler_t *sig, mowgli_argstack_t *argstack);
-struct mowgli_object_message_handler_ {
+struct mowgli_object_message_handler_
+{
char *name;
char *descstr;
mowgli_object_messaging_func_t handler;
diff --git a/src/libmowgli/object/metadata.c b/src/libmowgli/object/metadata.c
index 742e0dc..307947e 100644
--- a/src/libmowgli/object/metadata.c
+++ b/src/libmowgli/object/metadata.c
@@ -23,17 +23,15 @@
#include "mowgli.h"
-void mowgli_object_metadata_associate(mowgli_object_t *self, const char *key, void *value)
+void
+mowgli_object_metadata_associate(mowgli_object_t *self, const char *key, void *value)
{
+ return_if_fail(self != NULL);
+ return_if_fail(key != NULL);
+
mowgli_object_metadata_entry_t *e = NULL;
mowgli_node_t *n;
- if (self == NULL)
- mowgli_throw_exception(mowgli.object_metadata.invalid_object_exception);
-
- if (key == NULL)
- mowgli_throw_exception(mowgli.null_pointer_exception);
-
MOWGLI_LIST_FOREACH(n, self->metadata.head)
{
e = (mowgli_object_metadata_entry_t *) n->data;
@@ -55,17 +53,15 @@ void mowgli_object_metadata_associate(mowgli_object_t *self, const char *key, vo
mowgli_node_add(e, mowgli_node_create(), &self->metadata);
}
-void mowgli_object_metadata_dissociate(mowgli_object_t *self, const char *key)
+void
+mowgli_object_metadata_dissociate(mowgli_object_t *self, const char *key)
{
+ return_if_fail(self != NULL);
+ return_if_fail(key != NULL);
+
mowgli_object_metadata_entry_t *e;
mowgli_node_t *n, *tn;
- if (self == NULL)
- mowgli_throw_exception(mowgli.object_metadata.invalid_object_exception);
-
- if (key == NULL)
- mowgli_throw_exception(mowgli.null_pointer_exception);
-
MOWGLI_LIST_FOREACH_SAFE(n, tn, self->metadata.head)
{
e = (mowgli_object_metadata_entry_t *) n->data;
@@ -81,17 +77,15 @@ void mowgli_object_metadata_dissociate(mowgli_object_t *self, const char *key)
}
}
-void *mowgli_object_metadata_retrieve(mowgli_object_t *self, const char *key)
+void *
+mowgli_object_metadata_retrieve(mowgli_object_t *self, const char *key)
{
+ return_null_if_fail(self != NULL);
+ return_null_if_fail(key != NULL);
+
mowgli_object_metadata_entry_t *e;
mowgli_node_t *n;
- if (self == NULL)
- mowgli_throw_exception_val(mowgli.object_metadata.invalid_object_exception, NULL);
-
- if (key == NULL)
- mowgli_throw_exception_val(mowgli.null_pointer_exception, NULL);
-
MOWGLI_LIST_FOREACH(n, self->metadata.head)
{
e = (mowgli_object_metadata_entry_t *) n->data;
diff --git a/src/libmowgli/object/metadata.h b/src/libmowgli/object/metadata.h
index 0cdda69..fe2170c 100644
--- a/src/libmowgli/object/metadata.h
+++ b/src/libmowgli/object/metadata.h
@@ -24,7 +24,8 @@
#ifndef __MOWGLI_OBJECT_METADATA_H__
#define __MOWGLI_OBJECT_METADATA_H__
-typedef struct {
+typedef struct
+{
char *name;
void *data;
} mowgli_object_metadata_entry_t;
diff --git a/src/libmowgli/object/object.c b/src/libmowgli/object/object.c
index 7b24ea7..04a218f 100644
--- a/src/libmowgli/object/object.c
+++ b/src/libmowgli/object/object.c
@@ -40,7 +40,8 @@
* Side Effects:
* - none
*/
-void mowgli_object_init(mowgli_object_t *obj, const char *name, mowgli_object_class_t *klass, mowgli_destructor_t des)
+void
+mowgli_object_init(mowgli_object_t *obj, const char *name, mowgli_object_class_t *klass, mowgli_destructor_t des)
{
return_if_fail(obj != NULL);
@@ -48,7 +49,9 @@ void mowgli_object_init(mowgli_object_t *obj, const char *name, mowgli_object_cl
obj->name = mowgli_strdup(name);
if (klass != NULL)
+ {
obj->klass = klass;
+ }
else
{
mowgli_object_class_t *tmp = mowgli_alloc(sizeof(mowgli_object_class_t));
@@ -85,8 +88,7 @@ void mowgli_object_init(mowgli_object_t *obj, const char *name, mowgli_object_cl
* - none
*/
void
-mowgli_object_init_from_class(mowgli_object_t *obj, const char *name,
- mowgli_object_class_t *klass)
+mowgli_object_init_from_class(mowgli_object_t *obj, const char *name, mowgli_object_class_t *klass)
{
return_if_fail(obj != NULL);
return_if_fail(klass != NULL);
@@ -108,7 +110,8 @@ mowgli_object_init_from_class(mowgli_object_t *obj, const char *name,
* Side Effects:
* - none
*/
-void * mowgli_object_ref(void *object)
+void *
+mowgli_object_ref(void *object)
{
return_val_if_fail(object != NULL, NULL);
@@ -131,7 +134,8 @@ void * mowgli_object_ref(void *object)
* Side Effects:
* - if the refcount is 0, the object is destroyed.
*/
-void mowgli_object_unref(void *object)
+void
+mowgli_object_unref(void *object)
{
mowgli_object_t *obj = mowgli_object(object);
@@ -159,6 +163,8 @@ void mowgli_object_unref(void *object)
free(obj);
}
else
- mowgli_throw_exception(mowgli.object.invalid_object_class_exception);
+ {
+ mowgli_log_warning("invalid object class");
+ }
}
}
diff --git a/src/libmowgli/object/object.h b/src/libmowgli/object/object.h
index 0f13ce1..255df10 100644
--- a/src/libmowgli/object/object.h
+++ b/src/libmowgli/object/object.h
@@ -24,7 +24,8 @@
#ifndef __MOWGLI_OBJECT_H__
#define __MOWGLI_OBJECT_H__
-typedef struct {
+typedef struct
+{
char *name;
int refcount;
mowgli_object_class_t *klass;
diff --git a/src/libmowgli/platform/Makefile b/src/libmowgli/platform/Makefile
index 6b6d7b9..7d883d4 100644
--- a/src/libmowgli/platform/Makefile
+++ b/src/libmowgli/platform/Makefile
@@ -1,9 +1,17 @@
+include ../../../extra.mk
+
+STATIC_PIC_LIB_NOINST = ${LIBMOWGLI_SHARED_PLATFORM}
+STATIC_LIB_NOINST = ${LIBMOWGLI_STATIC_PLATFORM}
+
SUBDIRS = win32
-INCLUDES = constructor.h machine.h
+SRCS = cacheline.c
+
+INCLUDES = attributes.h cacheline.h constructor.h machine.h
include ../../../buildsys.mk
includesubdir = $(PACKAGE_NAME)/platform
-include ../../../extra.mk
+CPPFLAGS += -I. -I.. -I../../.. -DMOWGLI_CORE
+
diff --git a/src/libmowgli/platform/attributes.h b/src/libmowgli/platform/attributes.h
new file mode 100644
index 0000000..35e5d68
--- /dev/null
+++ b/src/libmowgli/platform/attributes.h
@@ -0,0 +1,69 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * attributes.h: Compiler attributes to help write better code
+ *
+ * Copyright (c) 2013 Patrick McFarland <pmcfarland@adterrasperaspera.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MOWGLI_PLATFORM_ATTRIBUTES_H__
+#define __MOWGLI_PLATFORM_ATTRIBUTES_H__
+
+/* Deprecated */
+#if defined MOWGLI_COMPILER_GCC_COMPAT
+# define MOWGLI_DEPRECATED(proto, msg) proto __attribute__((deprecated(msg)))
+#elif defined MOWGLI_COMPILER_MSVC
+# define MOWGLI_DEPRECATED(proto, msg) __declspec(deprecated(msg)) proto
+#else
+# define MOWGLI_DEPRECATED(proto, msg) proto
+#endif
+
+/* printf, n is number of args to skip to get to fmt */
+#if defined MOWGLI_COMPILER_GCC_COMPAT
+# define MOWGLI_PRINTF(proto, n) proto __attribute__((format(printf, n, n + 1)))
+#else
+# define MOWGLI_PRINTF(proto) proto
+#endif
+
+/* Hot and cold paths */
+#if MOWGLI_COMPILER_GCC_VERSION > 403000
+# define MOWGLI_HOT(proto) proto __attribute__((hot))
+# define MOWGLI_COLD(proto) proto __attribute__((cold))
+#else
+# define MOWGLI_HOT(proto) proto
+# define MOWGLI_COLD(proto) proto
+#endif
+
+#if MOWGLI_COMPILER_GCC_VERSION > 408000
+# define MOWGLI_HOT_LABEL(label) label __attribute__((hot))
+# define MOWGLI_COLD_LABEL(label) label __attribute__((cold))
+#else
+# define MOWGLI_HOT_LABEL(label) label
+# define MOWGLI_COLD_LABEL(label) label
+#endif
+
+/* malloc, n is the arg used for allocation size */
+#ifdef MOWGLI_COMPILER_GCC_COMPAT
+# define MOWGLI_MALLOC(proto, n) \
+ proto __attribute__((malloc, alloc_size(n), warn_unused_result))
+#else
+# define MOWGLI_MALLOC(proto, n) \
+ proto
+#endif
+
+#endif
diff --git a/src/libmowgli/platform/cacheline.c b/src/libmowgli/platform/cacheline.c
new file mode 100644
index 0000000..90c803f
--- /dev/null
+++ b/src/libmowgli/platform/cacheline.c
@@ -0,0 +1,72 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * cacheline.c: Platform specific routines to get L1 cache line size
+ *
+ * Copyright (c) 2013 Patrick McFarland <pmcfarland@adterrasperaspera.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mowgli.h"
+
+#ifdef MOWGLI_OS_OSX
+# include <sys/sysctl.h>
+#endif
+
+size_t cacheline_size;
+
+void
+mowgli_cacheline_bootstrap(void)
+{
+#ifdef MOWGLI_OS_LINUX
+ cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
+#elif defined(MOWGLI_OS_OSX)
+ size_t size = sizeof(size_t);
+ sysctlbyname("hw.cachelinesize", &cacheline_size, &size, 0, 0);
+#elif defined(MOWGLI_OS_WIN)
+ DWORD buf_size = 0;
+ DWORD i = 0;
+ SYSTEM_LOGICAL_PROCESSOR_INFORMATION *buf = 0;
+
+ GetLogicalProcessorInformation(0, &buf_size);
+ buf = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION *) mowgli_alloc(buf_size);
+ GetLogicalProcessorInformation(&buf[0], &buf_size);
+
+ for (i = 0; i != buf_size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i)
+ if ((buf[i].Relationship == RelationCache) && (buf[i].Cache.Level == 1))
+ {
+ cacheline_size = buf[i].Cache.LineSize;
+ break;
+ }
+
+ mowgli_free(buf);
+#else
+
+ // This is often true
+# ifdef MOWGLI_CPU_BITS_32
+ cacheline_size = 32;
+# else
+ cacheline_size = 64;
+# endif
+#endif
+}
+
+size_t
+mowgli_cacheline_size(void)
+{
+ return cacheline_size;
+}
diff --git a/src/libmowgli/platform/win32/gettimeofday.c b/src/libmowgli/platform/cacheline.h
index 1e96797..a1e6c3f 100644
--- a/src/libmowgli/platform/win32/gettimeofday.c
+++ b/src/libmowgli/platform/cacheline.h
@@ -1,8 +1,8 @@
/*
* libmowgli: A collection of useful routines for programming.
- * win32_support.c: Support functions and values for Win32 platform.
+ * cacheline.h: Platform specific routines to get L1 cache line size
*
- * Copyright (c) 2009 SystemInPlace, Inc.
+ * Copyright (c) 2013 Patrick McFarland <pmcfarland@adterrasperaspera.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -21,46 +21,9 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "mowgli.h"
+#ifndef __MOWGLI_PLATFORM_CACHELINE_H__
+#define __MOWGLI_PLATFORM_CACHELINE_H__
-#ifdef _MSC_VER
-# define EPOCH_TIME_IN_MICROSECS 11644473600000000Ui64
-#else
-# define EPOCH_TIME_IN_MICROSECS 11644473600000000ULL
-#endif
-
-#ifdef _WIN32
-int gettimeofday(struct timeval *tv, struct timezone *tz)
-{
- FILETIME ft;
- ULARGE_INTEGER tmpres;
- static mowgli_boolean_t tz_init_done = FALSE;
-
- if (tv != NULL)
- {
- GetSystemTimeAsFileTime(&ft);
-
- tmpres.u.HighPart = ft.dwHighDateTime;
- tmpres.u.LowPart = ft.dwLowDateTime;
-
- tmpres.QuadPart /= 10;
- tmpres.QuadPart -= EPOCH_TIME_IN_MICROSECS;
- tv->tv_sec = (long) (tmpres.QuadPart / 1000000UL);
- tv->tv_usec = (long) (tmpres.QuadPart % 1000000UL);
- }
-
- if (tz != NULL)
- {
- if (!tz_init_done)
- {
- _tzset();
- tz_init_done = TRUE;
- }
-
- tz->tz_minuteswest = _timezone / 60;
- tz->tz_dsttime = _daylight;
- }
+extern size_t mowgli_cacheline_size(void);
- return 0;
-}
#endif
diff --git a/src/libmowgli/platform/constructor.h b/src/libmowgli/platform/constructor.h
index 8446f44..7675703 100644
--- a/src/libmowgli/platform/constructor.h
+++ b/src/libmowgli/platform/constructor.h
@@ -24,7 +24,7 @@
#ifndef __MOWGLI_PLATFORM_CONSTRUCTOR_H__
#define __MOWGLI_PLATFORM_CONSTRUCTOR_H__
-#ifdef _MSC_VER
+#if defined MOWGLI_COMPILER_MSVC
/*
* Automatic constructors are not yet officially supported in MSVC, however,
@@ -34,21 +34,22 @@
* See http://blogs.msdn.com/b/vcblog/archive/2006/10/20/crt-initialization.aspx
* for more information.
*/
-#define MOWGLI_BOOTSTRAP_FUNC(func) \
- static void __cdecl func(void); \
- __declspec(allocate(".CRT$XCU")) void (__cdecl *func##_)(void) = func; \
+# define MOWGLI_BOOTSTRAP_FUNC(func) \
+ static void __cdecl func(void); \
+ __declspec(allocate(".CRT$XCU")) void(__cdecl * func##_) (void) = func; \
static void __cdecl func(void)
-
-#elif defined(__GNUC__) || defined(__SUNPRO_C)
-
-#define MOWGLI_BOOTSTRAP_FUNC(func) \
- static void func(void) __attribute__((constructor)); \
+#elif defined MOWGLI_COMPILER_GCC_COMPAT
+# if MOWGLI_COMPILER_GCC_VERSION >= 403000
+# define MOWGLI_BOOTSTRAP_FUNC(func) \
+ static void func(void) __attribute__((cold, constructor, flatten)); \
static void func(void)
-
+# else
+# define MOWGLI_BOOTSTRAP_FUNC(func) \
+ static void func(void) __attribute__((constructor, flatten)); \
+ static void func(void)
+# endif
#else
-
-#error MOWGLI_BOOTSTRAP_FUNC not implemented for your platform :(
-
+# error MOWGLI_BOOTSTRAP_FUNC not implemented for your platform :(
#endif
#endif
diff --git a/src/libmowgli/platform/machine.h b/src/libmowgli/platform/machine.h
index b2a2e50..6b23514 100644
--- a/src/libmowgli/platform/machine.h
+++ b/src/libmowgli/platform/machine.h
@@ -2,7 +2,7 @@
* libmowgli: A collection of useful routines for programming.
* machine.h: Defines to discover what machine we're on easily
*
- * Copyright (c) 2012 Patrick McFarland <pmcfarland@adterrasperaspera.com>
+ * Copyright (c) 2012, 2013 Patrick McFarland <pmcfarland@adterrasperaspera.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -21,8 +21,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "mowgli.h"
-
/* Machine environment specific macros, mostly sourced from this URL:
* http://sourceforge.net/apps/mediawiki/predef/
*
@@ -37,298 +35,306 @@
#define __MOWGLI_MACHINE_H__
#if defined __clang__
-#define MOWGLI_COMPILER_CLANG
-#define MOWGLI_COMPILER clang
+# define MOWGLI_COMPILER_CLANG
+# define MOWGLI_COMPILER clang
#elif defined __INTEL_COMPILER || defined __ICC || defined __ICL
-#define MOWGLI_COMPILER_ICC
-#define MOWGLI_COMPILER icc
+# define MOWGLI_COMPILER_ICC
+# define MOWGLI_COMPILER icc
#elif defined __CC_ARM
-#define MOWGLI_COMPILER_ARM
-#define MOWGLI_COMPILER arm
+# define MOWGLI_COMPILER_ARM
+# define MOWGLI_COMPILER arm
#elif defined __xlc__ || defined __xlC__
-#define MOWGLI_COMPILER_IBM
-#define MOWGLI_COMPILER ibm
+# define MOWGLI_COMPILER_IBM
+# define MOWGLI_COMPILER ibm
#elif defined __SUNPRO_C || defined __SUNPRO_CC
-#define MOWGLI_COMPILER_SUN
-#define MOWGLI_COMPILER sun
+# define MOWGLI_COMPILER_SUN
+# define MOWGLI_COMPILER sun
#elif defined __GNUC__
-#define MOWGLI_COMPILER_GCC
-#define MOWGLI_COMPILER gcc
+# define MOWGLI_COMPILER_GCC
+# define MOWGLI_COMPILER gcc
#elif defined _MSC_VER
-#define MOWGLI_COMPILER_MSVC
-#define MOWGLI_COMPILER msvc
+# define MOWGLI_COMPILER_MSVC
+# define MOWGLI_COMPILER msvc
#else
-#define MOWGLI_COMPILER_UNKNOWN
-#define MOWGLI_COMPILER unknown
+# define MOWGLI_COMPILER_UNKNOWN
+# define MOWGLI_COMPILER unknown
#endif
#if defined __GNUC__
-#define MOWGLI_COMPILER_GCC_COMPAT
+# define MOWGLI_COMPILER_GCC_COMPAT
+# define MOWGLI_COMPILER_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#else
+# define MOWGLI_COMPILER_GCC_VERSION (0)
#endif
#if defined __amd64__ || defined __amd64 || defined __x86_64__ || defined __x86_64 || defined _M_X64 || defined _M_AMD64
-#define MOWGLI_CPU_X86_64
-#define MOWGLI_CPU x86_64
-#define MOWGLI_CPU_BITS_64
-#define MOWGLI_CPU_BITS 64
-#define MOWGLI_CPU_ENDIAN_LITTLE
-#define MOWGLI_CPU_ENDIAN little
+# define MOWGLI_CPU_X86_64
+# define MOWGLI_CPU x86_64
+# define MOWGLI_CPU_BITS_64
+# define MOWGLI_CPU_BITS 64
+# define MOWGLI_CPU_ENDIAN_LITTLE
+# define MOWGLI_CPU_ENDIAN little
#elif defined __i386__ || defined __i386 || defined __IA32__ || defined _M_IX86 || defined __X86__ || defined _X86__ || defined __I86__
-#define MOWGLI_CPU_X86
-#define MOWGLI_CPU x86
-#define MOWGLI_CPU_BITS_32
-#define MOWGLI_CPU_BITS 32
-#define MOWGLI_CPU_ENDIAN_LITTLE
-#define MOWGLI_CPU_ENDIAN little
+# define MOWGLI_CPU_X86
+# define MOWGLI_CPU x86
+# define MOWGLI_CPU_BITS_32
+# define MOWGLI_CPU_BITS 32
+# define MOWGLI_CPU_ENDIAN_LITTLE
+# define MOWGLI_CPU_ENDIAN little
#elif defined __arm__ || defined __TARGET_ARCH_ARM || defined _ARM
-#if defined __thumb__ || defined __TARGET_ARCH_THUMB
-#define MOWGLI_CPU_ARM_THUMB
-#endif
-#define MOWGLI_CPU_ARM
-#define MOWGLI_CPU arm
-#define MOWGLI_CPU_BITS_32
-#define MOWGLI_CPU_BITS 32
+# if defined __thumb__ || defined __TARGET_ARCH_THUMB
+# define MOWGLI_CPU_ARM_THUMB
+# endif
+# define MOWGLI_CPU_ARM
+# define MOWGLI_CPU arm
+# define MOWGLI_CPU_BITS_32
+# define MOWGLI_CPU_BITS 32
+
// ARM can be either endian
#elif defined __hppa__ || defined __HPPA__ || defined __hppa
-#if defined _PA_RISC2_0 || defined __HPPA20__ || defined __RISC2_0__
-#define MOWGLI_CPU_HPPA20
-#define MOWGLI_CPU hppa20
-#define MOWGLI_CPU_BITS_64
-#define MOWGLI_CPU_BITS 64
-#else
-#define MOWGLI_CPU_HPPA10
-#define MOWGLI_CPU hppa10
-#define MOWGLI_CPU_BITS_32
-#define MOWGLI_CPU_BITS 32
-#endif
-#define MOWGLI_CPU_ENDIAN_BIG
-#define MOWGLI_CPU_ENDIAN big
+# if defined _PA_RISC2_0 || defined __HPPA20__ || defined __RISC2_0__
+# define MOWGLI_CPU_HPPA20
+# define MOWGLI_CPU hppa20
+# define MOWGLI_CPU_BITS_64
+# define MOWGLI_CPU_BITS 64
+# else
+# define MOWGLI_CPU_HPPA10
+# define MOWGLI_CPU hppa10
+# define MOWGLI_CPU_BITS_32
+# define MOWGLI_CPU_BITS 32
+# endif
+# define MOWGLI_CPU_ENDIAN_BIG
+# define MOWGLI_CPU_ENDIAN big
#elif defined __ia64__ || defined __IA64__ || defined _M_IA64 || defined __ia64 || defined __itanium__
-#define MOWGLI_CPU_ITANIUM
-#define MOWGLI_CPU itanium
-#define MOWGLI_CPU_BITS_64
-#define MOWGLI_CPU_BITS 64
+# define MOWGLI_CPU_ITANIUM
+# define MOWGLI_CPU itanium
+# define MOWGLI_CPU_BITS_64
+# define MOWGLI_CPU_BITS 64
+
// Itanium can be either endian
#elif defined __mips__ || defined mips || defined __mips || defined __MIPS__
-#if defined __mips64 || defined __mips64__
-#define MOWGLI_CPU_MIPS64
-#define MOWGLI_CPU mips64
-#define MOWGLI_CPU_BITS_64
-#define MOWGLI_CPU_BITS 64
-#else
-#define MOWGLI_CPU_MIPS
-#define MOWGLI_CPU mips
-#define MOWGLI_CPU_BITS_32
-#define MOWGLI_CPU_BITS 32
-#endif
+# if defined __mips64 || defined __mips64__
+# define MOWGLI_CPU_MIPS64
+# define MOWGLI_CPU mips64
+# define MOWGLI_CPU_BITS_64
+# define MOWGLI_CPU_BITS 64
+# else
+# define MOWGLI_CPU_MIPS
+# define MOWGLI_CPU mips
+# define MOWGLI_CPU_BITS_32
+# define MOWGLI_CPU_BITS 32
+# endif
+
// MIPS can be either endian
#elif defined __powerpc || defined __powerpc__ || defined __POWERPC__ || defined __ppc__ || defined _M_PPC
-#if defined __ppc64__ || defined __PPC64__
-#define MOWGLI_CPU_POWERPC64
-#define MOWGLI_CPU powerpc64
-#define MOWGLI_CPU_BITS_64
-#define MOWGLI_CPU_BITS 64
-#else
-#define MOWGLI_CPU powerpc
-#define MOWGLI_CPU_BITS_32
-#define MOWGLI_CPU_BITS 32
-#endif
-#define MOWGLI_CPU_POWERPC
+# if defined __ppc64__ || defined __PPC64__
+# define MOWGLI_CPU_POWERPC64
+# define MOWGLI_CPU powerpc64
+# define MOWGLI_CPU_BITS_64
+# define MOWGLI_CPU_BITS 64
+# else
+# define MOWGLI_CPU powerpc
+# define MOWGLI_CPU_BITS_32
+# define MOWGLI_CPU_BITS 32
+# endif
+# define MOWGLI_CPU_POWERPC
+
// PowerPC can be either endian
#elif defined __sparc__ || defined __sparc
-#if defined __sparcv9 || defined __sparc64 || defined __sparc64__
-#define MOWGLI_CPU_SPARC64
-#define MOWGLI_CPU sparc64
-#define MOWGLI_CPU_BITS_64
-#define MOWGLI_CPU_BITS 64
-#else
-#define MOWGLI_CPU_SPARC
-#define MOWGLI_CPU sparc
-#define MOWGLI_CPU_BITS_32
-#define MOWGLI_CPU_BITS 32
-#endif
-#define MOWGLI_CPU_ENDIAN_BIG
-#define MOWGLI_CPU_ENDIAN big
+# if defined __sparcv9 || defined __sparc64 || defined __sparc64__
+# define MOWGLI_CPU_SPARC64
+# define MOWGLI_CPU sparc64
+# define MOWGLI_CPU_BITS_64
+# define MOWGLI_CPU_BITS 64
+# else
+# define MOWGLI_CPU_SPARC
+# define MOWGLI_CPU sparc
+# define MOWGLI_CPU_BITS_32
+# define MOWGLI_CPU_BITS 32
+# endif
+# define MOWGLI_CPU_ENDIAN_BIG
+# define MOWGLI_CPU_ENDIAN big
#elif defined __alpha || defined __alpha__ || defined _M_ALPHA
-#define MOWGLI_CPU_ALPHA
-#define MOWGLI_CPU alpha
-#define MOWGLI_CPU_BITS_64
-#define MOWGLI_CPU_BITS 64
-#define MOWGLI_CPU_ENDIAN_LITTLE
-#define MOWGLI_CPU_ENDIAN little
+# define MOWGLI_CPU_ALPHA
+# define MOWGLI_CPU alpha
+# define MOWGLI_CPU_BITS_64
+# define MOWGLI_CPU_BITS 64
+# define MOWGLI_CPU_ENDIAN_LITTLE
+# define MOWGLI_CPU_ENDIAN little
#elif defined __avr32__ || defined __AVR32__
-#define MOWGLI_CPU_AVR32
-#define MOWGLI_CPU avr
-#define MOWGLI_CPU_BITS_32
-#define MOWGLI_CPU_BITS 32
-#define MOWGLI_CPU_ENDIAN_LITTLE
-#define MOWGLI_CPU_ENDIAN little
+# define MOWGLI_CPU_AVR32
+# define MOWGLI_CPU avr
+# define MOWGLI_CPU_BITS_32
+# define MOWGLI_CPU_BITS 32
+# define MOWGLI_CPU_ENDIAN_LITTLE
+# define MOWGLI_CPU_ENDIAN little
#elif defined __sh__ || defined __SH__
-#define MOWGLI_CPU_SuperH
-#define MOWGLI_CPU superh
-#define MOWGLI_CPU_BITS_32
-#define MOWGLI_CPU_BITS 32
+# define MOWGLI_CPU_SuperH
+# define MOWGLI_CPU superh
+# define MOWGLI_CPU_BITS_32
+# define MOWGLI_CPU_BITS 32
+
// SyoerH can be either endian
#endif
#ifndef MOWGLI_CPU
-#define MOWGLI_CPU_UNKNOWN
-#define MOWGLI_CPU unknown
+# define MOWGLI_CPU_UNKNOWN
+# define MOWGLI_CPU unknown
#endif
#ifndef MOWGLI_CPU_BITS
-#if defined _LP64 || defined __LP64
-#define MOWGLI_CPU_BITS 64
-#define MOWGLI_CPU_BITS_64
-#elif
-#define MOWGLI_CPU_BITS 32
-#define MOWGLI_CPU_BITS_32
-#endif
+# if defined _LP64 || defined __LP64
+# define MOWGLI_CPU_BITS 64
+# define MOWGLI_CPU_BITS_64
+# elif
+# define MOWGLI_CPU_BITS 32
+# define MOWGLI_CPU_BITS_32
+# endif
#endif
#if defined __linux || defined __linux__
-#define MOWGLI_OS_LINUX
-#define MOWGLI_OS linux
-#define MOWGLI_OS_THREADS_POSIX
-#define MOWGLI_OS_THREADS posix
-#define MOWGLI_OS_MUTEX_POSIX
-#define MOWGLI_OS_MUTEX posix
+# define MOWGLI_OS_LINUX
+# define MOWGLI_OS linux
+# define MOWGLI_OS_THREADS_POSIX
+# define MOWGLI_OS_THREADS posix
+# define MOWGLI_OS_MUTEX_POSIX
+# define MOWGLI_OS_MUTEX posix
#elif defined __APPLE__
-#define MOWGLI_OS_OSX
-#define MOWGLI_OS osx
-#define MOWGLI_OS_THREADS_POSIX
-#define MOWGLI_OS_THREADS posix
-#define MOWGLI_OS_MUTEX_POSIX
-#define MOWGLI_OS_MUTEX posix
-#define MOWGLI_OS_BSD_TYPE
+# define MOWGLI_OS_OSX
+# define MOWGLI_OS osx
+# define MOWGLI_OS_THREADS_POSIX
+# define MOWGLI_OS_THREADS posix
+# define MOWGLI_OS_MUTEX_POSIX
+# define MOWGLI_OS_MUTEX posix
+# define MOWGLI_OS_BSD_TYPE
-#ifdef MOWGLI_CPU_POWERPC
-#define MOWGLI_CPU_ENDIAN_BIG
-#define MOWGLI_CPU_ENDIAN big
-#endif
+# ifdef MOWGLI_CPU_POWERPC
+# define MOWGLI_CPU_ENDIAN_BIG
+# define MOWGLI_CPU_ENDIAN big
+# endif
#elif defined __WINDOWS__ || defined _WIN32 || defined __WIN32__ || defined __TOS_WIN__
-#if defined _WIN64
-#define MOWGLI_OS_WIN64
-#define MOWGLI_OS win64
-#else
-#define MOWGLI_OS_WIN32
-#define MOWGLI_OS win32
-#endif
-#define MOWGLI_OS_WIN
-#define MOWGLI_OS_THREADS_WIN
-#define MOWGLI_OS_THREADS win
-#define MOWGLI_OS_MUTEX_WIN
-#define MOWGLI_OS_MUTEX win
+# if defined _WIN64
+# define MOWGLI_OS_WIN64
+# define MOWGLI_OS win64
+# else
+# define MOWGLI_OS_WIN32
+# define MOWGLI_OS win32
+# endif
+# define MOWGLI_OS_WIN
+# define MOWGLI_OS_THREADS_WIN
+# define MOWGLI_OS_THREADS win
+# define MOWGLI_OS_MUTEX_WIN
+# define MOWGLI_OS_MUTEX win
-#if defined __CYGWIN__
-#define MOWGLI_OS_WIN_CYGWIN
-#elif defined __MINGW32__
-#define MOWGLI_OS_WIN_MINGW
-#endif
+# if defined __CYGWIN__
+# define MOWGLI_OS_WIN_CYGWIN
+# elif defined __MINGW32__
+# define MOWGLI_OS_WIN_MINGW
+# endif
-#if defined MOWGLI_CPU_POWERPC || defined MOWGLI_CPU_MIPS || defined MOWGLI_CPU_ITANIUM
-#define MOWGLI_ENDIAN_CPU_LITTLE
-#endif
+# if defined MOWGLI_CPU_POWERPC || defined MOWGLI_CPU_MIPS || defined MOWGLI_CPU_ITANIUM
+# define MOWGLI_ENDIAN_CPU_LITTLE
+# endif
#elif defined __NetBSD__ || defined __OpenBSD__ || defined __FreeBSD__ || defined __bsdi__ || defined __DragonFly__ || defined BSD || defined _SYSTYPE_BSD
-#define MOWGLI_OS_BSD
-#define MOWGLI_OS bsd
-#define MOWGLI_OS_THREADS_POSIX
-#define MOWGLI_OS_THREADS posix
-#define MOWGLI_OS_MUTEX_POSIX
-#define MOWGLI_OS_MUTEX posix
-#define MOWGLI_OS_BSD_TYPE
+# define MOWGLI_OS_BSD
+# define MOWGLI_OS bsd
+# define MOWGLI_OS_THREADS_POSIX
+# define MOWGLI_OS_THREADS posix
+# define MOWGLI_OS_MUTEX_POSIX
+# define MOWGLI_OS_MUTEX posix
+# define MOWGLI_OS_BSD_TYPE
#elif defined __GNU__
-#define MOWGLI_OS_HURD
-#define MOWGLI_OS hurd
-#define MOWGLI_OS_THREADS_POSIX
-#define MOWGLI_OS_THREADS posix
-#define MOWGLI_OS_MUTEX_POSIX
-#define MOWGLI_OS_MUTEX posix
+# define MOWGLI_OS_HURD
+# define MOWGLI_OS hurd
+# define MOWGLI_OS_THREADS_POSIX
+# define MOWGLI_OS_THREADS posix
+# define MOWGLI_OS_MUTEX_POSIX
+# define MOWGLI_OS_MUTEX posix
#elif defined sco || defined __sco
-#define MOWGLI_OS_SCO
-#define MOWGLI_OS sco
-#define MOWGLI_OS_THREADS_POSIX
-#define MOWGLI_OS_THREADS posix
-#define MOWGLI_OS_MUTEX_POSIX
-#define MOWGLI_OS_MUTEX posix
-#define MOWGLI_OS_UNIX_TYPE
+# define MOWGLI_OS_SCO
+# define MOWGLI_OS sco
+# define MOWGLI_OS_THREADS_POSIX
+# define MOWGLI_OS_THREADS posix
+# define MOWGLI_OS_MUTEX_POSIX
+# define MOWGLI_OS_MUTEX posix
+# define MOWGLI_OS_UNIX_TYPE
#elif defined sun || defined __sun
-#define MOWGLI_OS_SOLARIS
-#define MOWGLI_OS solaris
-#define MOWGLI_OS_THREADS_POSIX
-#define MOWGLI_OS_THREADS posix
-#define MOWGLI_OS_MUTEX_POSIX
-#define MOWGLI_OS_MUTEX posix
-#define MOWGLI_OS_UNIX_TYPE
-#if defined MOWGLI_CPU_POWERPC
-#define MOWGLI_CPU_ENDIAN_LITTLE
-#define MOWGLI_CPU_ENDIAN little
-#endif
+# define MOWGLI_OS_SOLARIS
+# define MOWGLI_OS solaris
+# define MOWGLI_OS_THREADS_SOLARIS
+# define MOWGLI_OS_THREADS solaris
+# define MOWGLI_OS_MUTEX_POSIX
+# define MOWGLI_OS_MUTEX posix
+# define MOWGLI_OS_UNIX_TYPE
+# if defined MOWGLI_CPU_POWERPC
+# define MOWGLI_CPU_ENDIAN_LITTLE
+# define MOWGLI_CPU_ENDIAN little
+# endif
#elif defined _hpux || defined hpux || defined __hpux
-#define MOWGLI_OS_HPUX
-#define MOWGLI_OS hpux
-#define MOWGLI_OS_THREADS_POSIX
-#define MOWGLI_OS_THREADS posix
-#define MOWGLI_OS_MUTEX_POSIX
-#define MOWGLI_OS_MUTEX posix
-#define MOWGLI_OS_UNIX_TYPE
-#if defined MOWGLI_CPU_ITANIUM
-#define MOWGLI_CPU_ENDIAN_BIG
-#define MOWGLI_CPU_ENDIAN big
-#endif
+# define MOWGLI_OS_HPUX
+# define MOWGLI_OS hpux
+# define MOWGLI_OS_THREADS_POSIX
+# define MOWGLI_OS_THREADS posix
+# define MOWGLI_OS_MUTEX_POSIX
+# define MOWGLI_OS_MUTEX posix
+# define MOWGLI_OS_UNIX_TYPE
+# if defined MOWGLI_CPU_ITANIUM
+# define MOWGLI_CPU_ENDIAN_BIG
+# define MOWGLI_CPU_ENDIAN big
+# endif
#elif defined __QNX__ || defined __QNXNTO__
-#define MOWGLI_OS_QNX
-#define MOWGLI_OS qnx
-#define MOWGLI_OS_THREADS_QNX
-#define MOWGLI_OS_THREADS qnx
-#define MOWGLI_OS_MUTEX_POSIX
-#define MOWGLI_OS_MUTEX posix
+# define MOWGLI_OS_QNX
+# define MOWGLI_OS qnx
+# define MOWGLI_OS_THREADS_QNX
+# define MOWGLI_OS_THREADS qnx
+# define MOWGLI_OS_MUTEX_POSIX
+# define MOWGLI_OS_MUTEX posix
#elif defined __vms || defined __VMS
-#define MOWGLI_OS_THREADS_POSIX
-#define MOWGLI_OS_THREADS posix
-#define MOWGLI_OS_MUTEX_POSIX
-#define MOWGLI_OS_MUTEX posix
-#if defined MOWGLI_CPU_ITANIUM
-#define MOWGLI_CPU_ENDIAN_LITTLE
-#define MOWGLI_CPU_ENDIAN little
-#endif
+# define MOWGLI_OS_THREADS_POSIX
+# define MOWGLI_OS_THREADS posix
+# define MOWGLI_OS_MUTEX_POSIX
+# define MOWGLI_OS_MUTEX posix
+# if defined MOWGLI_CPU_ITANIUM
+# define MOWGLI_CPU_ENDIAN_LITTLE
+# define MOWGLI_CPU_ENDIAN little
+# endif
#endif
#ifndef MOWGLI_OS
-#if defined __unix__ || __unix || unix
-#define MOWGLI_OS_UNIX
-#define MOWGLI_OS unix
-#define MOWGLI_OS_THREADS_POSIX
-#define MOWGLI_OS_THREADS posix
-#define MOWGLI_OS_MUTEX_POSIX
-#define MOWGLI_OS_MUTEX posix
-#define MOWGLI_OS_UNIX_TYPE
-#endif
-#define MOWGLI_OS_UNKNOWN
-#define MOWGLI_OS unknown
-#warning OS unsupported/unknown
+# if defined __unix__ || __unix || unix
+# define MOWGLI_OS_UNIX
+# define MOWGLI_OS unix
+# define MOWGLI_OS_THREADS_POSIX
+# define MOWGLI_OS_THREADS posix
+# define MOWGLI_OS_MUTEX_POSIX
+# define MOWGLI_OS_MUTEX posix
+# define MOWGLI_OS_UNIX_TYPE
+# endif
+# define MOWGLI_OS_UNKNOWN
+# define MOWGLI_OS unknown
+# warning OS unsupported/unknown
#endif
#ifndef MOWGLI_OS_THREADS
-#define MOWGLI_OS_THREADS_NULL
-#define MOWGLI_OS_THREADS null
+# define MOWGLI_OS_THREADS_NULL
+# define MOWGLI_OS_THREADS null
#endif
#ifndef MOWGLI_OS_MUTEX
-#define MOWGLI_OS_MUTEX_NULL
-#define MOWGLI_OS_MUTEX null
+# define MOWGLI_OS_MUTEX_NULL
+# define MOWGLI_OS_MUTEX null
#endif
#ifndef MOWGLI_CPU_ENDIAN
-#if defined __BIG_ENDIAN__ || defined __ARMEB__ || defined __THUMBEB__ || defined _MIPSEB || defined __MIPSEB || defined __MIPSEB__ || __BYTE_ORDER == __BIG_ENDIAN
-#define MOWGLI_CPU_ENDIAN_BIG
-#define MOWGLI_CPU_ENDIAN big
-#elif defined __LITTLE_ENDIAN__ || defined __ARMEL__ || defined __THUMBEL__ || defined _MIPSEL || defined __MIPSEL || defined __MIPSEL__ || __BYTE_ORDER == __LITTLE_ENDIAN
-#define MOWGLI_CPU_ENDIAN_LITTLE
-#define MOWGLI_CPU_ENDIAN little
-#else
-#warning CPU endianness unknown, some functions of libmowgli will not work
-#endif
+# if defined __BIG_ENDIAN__ || defined __ARMEB__ || defined __THUMBEB__ || defined _MIPSEB || defined __MIPSEB || defined __MIPSEB__ || __BYTE_ORDER == __BIG_ENDIAN
+# define MOWGLI_CPU_ENDIAN_BIG
+# define MOWGLI_CPU_ENDIAN big
+# elif defined __LITTLE_ENDIAN__ || defined __ARMEL__ || defined __THUMBEL__ || defined _MIPSEL || defined __MIPSEL || defined __MIPSEL__ || __BYTE_ORDER == __LITTLE_ENDIAN
+# define MOWGLI_CPU_ENDIAN_LITTLE
+# define MOWGLI_CPU_ENDIAN little
+# else
+# warning CPU endianness unknown, some functions of libmowgli will not work
+# endif
#endif
#endif
diff --git a/src/libmowgli/platform/win32/Makefile b/src/libmowgli/platform/win32/Makefile
index 653bf2d..73e7c74 100644
--- a/src/libmowgli/platform/win32/Makefile
+++ b/src/libmowgli/platform/win32/Makefile
@@ -3,7 +3,7 @@ include ../../../../extra.mk
STATIC_PIC_LIB_NOINST = ${LIBMOWGLI_SHARED_PLATFORM_WIN32}
STATIC_LIB_NOINST = ${LIBMOWGLI_STATIC_PLATFORM_WIN32}
-SRCS = fork.c gettimeofday.c inet.c pipe.c socketpair.c setenv.c
+SRCS = fork.c inet.c pipe.c socketpair.c setenv.c
INCLUDES = win32_stdinc.h
diff --git a/src/libmowgli/platform/win32/fork.c b/src/libmowgli/platform/win32/fork.c
index c644122..a55d99c 100644
--- a/src/libmowgli/platform/win32/fork.c
+++ b/src/libmowgli/platform/win32/fork.c
@@ -31,17 +31,18 @@
#ifdef NOTYET
-#ifdef _WIN32
+# ifdef _WIN32
-#ifndef _WIN32_WINNT
+# ifndef _WIN32_WINNT
-int fork(void)
+int
+fork(void)
{
-#warning fork is not possible on your platform in any sane way, sorry :(
+# warning fork is not possible on your platform in any sane way, sorry :(
return -ENOSYS;
}
-#else
+# else
extern NTSTATUS NTAPI CsrCallClientServer(void *message, void *userdata, uint32_t opcode, uint32_t size);
@@ -50,7 +51,8 @@ extern NTSTATUS NTAPI CsrCallClientServer(void *message, void *userdata, uint32_
*
* Not sure what dummy1/dummy2 do, but they're junk as far as I can see.
*/
-struct csrss_message {
+struct csrss_message
+{
uint32_t dummy1;
uint32_t opcode;
uint32_t status;
@@ -77,10 +79,8 @@ inherit_handles(void)
pid = GetCurrentProcessId();
for (i = 0; i < *p; i++)
- {
if (info[i].ProcessId == pid)
SetHandleInformation((HANDLE) h[i].Handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
- }
mowgli_free(p);
}
@@ -88,27 +88,34 @@ inherit_handles(void)
static inline void
request_csrss_session(HANDLE proc_handle, HANDLE thread_handle, uint32_t pid, uint32_t tid)
{
- struct {
+ struct
+ {
PORT_MESSAGE port_message;
struct csrss_message csrss_message;
+
PROCESS_INFORMATION process_information;
CLIENT_ID debugger;
uint32_t flags;
uint32_t vdminfo[2];
- } csrmsg = {{0}, {0}, {proc_handle, thread_handle, pid, tid}, {0}, 0, {0}};
+ } csrmsg =
+ {
+ { 0 }, { 0 }, { proc_handle, thread_handle, pid, tid }, { 0 }, 0, { 0 }
+ };
CsrCallClientServer(&csrmsg, NULL, 0x10000, sizeof csrmsg);
}
-int child(void)
+int
+child(void)
{
typedef BOOL (*CsrpConnectToServer)(PWSTR);
- CsrpConnectToServer (0x77F8F65D) (L"\\Windows");
+ CsrpConnectToServer(0x77F8F65D) (L"\\Windows");
__asm__("mov eax, 0; mov esp, ebp; pop ebp; ret");
}
-int fork(void)
+int
+fork(void)
{
HANDLE proc_handle, thread_handle;
OBJECT_ATTRIBUTES oa = { sizeof(oa) };
@@ -133,8 +140,8 @@ int fork(void)
ZwQueryVirtualMemory(NtCurrentProcess(), (void *) context.Esp, MemoryBasicInformation,
&mbi, sizeof mbi, 0);
- stack = (USER_STACK){0, 0, ((char *) mbi.BaseAddress) + mbi.RegionSize,
- mbi.BaseAddress, mbi.AllocationBase};
+ stack = (USER_STACK) { 0, 0, ((char *) mbi.BaseAddress) + mbi.RegionSize,
+ mbi.BaseAddress, mbi.AllocationBase };
/* now spawn the thread! */
ZwCreateThread(&thread_handle, THREAD_ALL_ACCESS, &oa, proc_handle, &cid, &context, &stack, TRUE);
@@ -159,8 +166,8 @@ int fork(void)
return (int) cid.UniqueProcess;
}
-#endif
+# endif
-#endif
+# endif
#endif
diff --git a/src/libmowgli/platform/win32/inet.c b/src/libmowgli/platform/win32/inet.c
index 051ae7f..eb0b1fc 100644
--- a/src/libmowgli/platform/win32/inet.c
+++ b/src/libmowgli/platform/win32/inet.c
@@ -22,37 +22,39 @@
#ifdef _WIN32
-int inet_pton(int af, const char *src, void *dst)
+int
+inet_pton(int af, const char *src, void *dst)
{
struct sockaddr_storage ss;
+
int size = sizeof(struct sockaddr_storage);
char src_copy[INET6_ADDRSTRLEN + 1];
mowgli_strlcpy(src_copy, src, sizeof src_copy);
if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *) &ss, &size) != SOCKET_ERROR)
- {
switch (af)
{
case AF_INET:
- *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
+ *(struct in_addr *) dst = ((struct sockaddr_in *) &ss)->sin_addr;
return 1;
case AF_INET6:
- *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
+ *(struct in6_addr *) dst = ((struct sockaddr_in6 *) &ss)->sin6_addr;
return 1;
default:
return 0;
}
- }
return -1;
}
-const char *inet_ntop(int af, const void *addr, char *host, size_t hostlen)
+const char *
+inet_ntop(int af, const void *addr, char *host, size_t hostlen)
{
struct sockaddr_storage ss;
+
int size = sizeof(struct sockaddr_storage);
ss.ss_family = af;
@@ -60,11 +62,11 @@ const char *inet_ntop(int af, const void *addr, char *host, size_t hostlen)
switch (af)
{
case AF_INET:
- memcpy(&(((struct sockaddr_in *) &ss)->sin_addr), (struct in_addr *) addr, sizeof (struct in_addr));
+ memcpy(&(((struct sockaddr_in *) &ss)->sin_addr), (struct in_addr *) addr, sizeof(struct in_addr));
break;
case AF_INET6:
- memcpy(&(((struct sockaddr_in6 *) &ss)->sin6_addr), (struct in6_addr *) addr, sizeof (struct in6_addr));
+ memcpy(&(((struct sockaddr_in6 *) &ss)->sin6_addr), (struct in6_addr *) addr, sizeof(struct in6_addr));
break;
default:
diff --git a/src/libmowgli/platform/win32/pipe.c b/src/libmowgli/platform/win32/pipe.c
index 5da3dd2..38d3d16 100644
--- a/src/libmowgli/platform/win32/pipe.c
+++ b/src/libmowgli/platform/win32/pipe.c
@@ -24,8 +24,10 @@
#include "mowgli.h"
#ifdef _WIN32
-int pipe(int pipefd[2])
+int
+pipe(int pipefd[2])
{
return socketpair(AF_INET, SOCK_STREAM, 0, pipefd);
}
+
#endif
diff --git a/src/libmowgli/platform/win32/setenv.c b/src/libmowgli/platform/win32/setenv.c
index f80a574..2854ddf 100644
--- a/src/libmowgli/platform/win32/setenv.c
+++ b/src/libmowgli/platform/win32/setenv.c
@@ -24,8 +24,10 @@
#include "mowgli.h"
#ifdef _WIN32
-int setenv(const char *name, const char *value, int overwrite)
+int
+setenv(const char *name, const char *value, int overwrite)
{
return !SetEnvironmentVariable(name, value);
}
+
#endif
diff --git a/src/libmowgli/platform/win32/socketpair.c b/src/libmowgli/platform/win32/socketpair.c
index 6ede51e..b641838 100644
--- a/src/libmowgli/platform/win32/socketpair.c
+++ b/src/libmowgli/platform/win32/socketpair.c
@@ -1,11 +1,11 @@
/* socketpair.c
* Copyright 2007, 2010 by Nathan C. Myers <ncm@cantrip.org>
- * This code is Free Software. It may be copied freely, in original or
+ * This code is Free Software. It may be copied freely, in original or
* modified form, subject only to the restrictions that (1) the author is
* relieved from all responsibilities for any use for any purpose, and (2)
* this copyright notice must be retained, unchanged, in its entirety. If
* for any reason the author might be held responsible for any consequences
- * of copying or use, license is withheld.
+ * of copying or use, license is withheld.
*/
/* Changes:
@@ -13,8 +13,8 @@
* set addr to 127.0.0.1 because win32 getsockname does not always set it.
* 2010-02-25:
* set SO_REUSEADDR option to avoid leaking some windows resource.
- * Windows System Error 10049, "Event ID 4226 TCP/IP has reached
- * the security limit imposed on the number of concurrent TCP connect
+ * Windows System Error 10049, "Event ID 4226 TCP/IP has reached
+ * the security limit imposed on the number of concurrent TCP connect
* attempts." Bleah.
* 2007-04-25:
* preserve value of WSAGetLastError() on all error returns.
@@ -32,78 +32,91 @@
/* dumb_socketpair:
* If make_overlapped is nonzero, both sockets created will be usable for
* "overlapped" operations via WSASend etc. If make_overlapped is zero,
- * socks[0] (only) will be usable with regular ReadFile etc., and thus
+ * socks[0] (only) will be usable with regular ReadFile etc., and thus
* suitable for use as stdin or stdout of a child process. Note that the
* sockets must be closed with closesocket() regardless.
*/
-int socketpair(int domain, int type, int protocol, int socks[2])
+int
+socketpair(int domain, int type, int protocol, int socks[2])
{
- union {
- struct sockaddr_in inaddr;
- struct sockaddr addr;
- } a;
- SOCKET listener;
- int e;
- socklen_t addrlen = sizeof(a.inaddr);
- int make_overlapped = 0;
- DWORD flags = (make_overlapped ? WSA_FLAG_OVERLAPPED : 0);
- int reuse = 1;
-
- if (socks == NULL) {
- WSASetLastError(WSAEINVAL);
- return SOCKET_ERROR;
- }
-
- listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (listener == INVALID_SOCKET)
- return SOCKET_ERROR;
-
- memset(&a, 0, sizeof(a));
- a.inaddr.sin_family = AF_INET;
- a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- a.inaddr.sin_port = 0;
-
- socks[0] = socks[1] = INVALID_SOCKET;
- do {
- if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
- (char*) &reuse, (socklen_t) sizeof(reuse)) == -1)
- break;
- if (bind(listener, &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
- break;
-
- memset(&a, 0, sizeof(a));
- if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR)
- break;
- // win32 getsockname may only set the port number, p=0.0005.
- // ( http://msdn.microsoft.com/library/ms738543.aspx ):
- a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- a.inaddr.sin_family = AF_INET;
-
- if (listen(listener, 1) == SOCKET_ERROR)
- break;
-
- socks[0] = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, flags);
- if (socks[0] == (int) INVALID_SOCKET)
- break;
- if (connect(socks[0], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
- break;
-
- socks[1] = accept(listener, NULL, NULL);
- if (socks[1] == (int) INVALID_SOCKET)
- break;
-
- closesocket(listener);
- return 0;
-
- } while (0);
-
- e = WSAGetLastError();
- closesocket(listener);
- closesocket(socks[0]);
- closesocket(socks[1]);
- WSASetLastError(e);
- return SOCKET_ERROR;
+ union
+ {
+ struct sockaddr_in inaddr;
+
+ struct sockaddr addr;
+ } a;
+
+ SOCKET listener;
+ int e;
+ socklen_t addrlen = sizeof(a.inaddr);
+ int make_overlapped = 0;
+ DWORD flags = (make_overlapped ? WSA_FLAG_OVERLAPPED : 0);
+ int reuse = 1;
+
+ if (socks == NULL)
+ {
+ WSASetLastError(WSAEINVAL);
+ return SOCKET_ERROR;
+ }
+
+ listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if (listener == INVALID_SOCKET)
+ return SOCKET_ERROR;
+
+ memset(&a, 0, sizeof(a));
+ a.inaddr.sin_family = AF_INET;
+ a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ a.inaddr.sin_port = 0;
+
+ socks[0] = socks[1] = INVALID_SOCKET;
+
+ do
+ {
+ if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &reuse, (socklen_t) sizeof(reuse)) == -1)
+ break;
+
+ if (bind(listener, &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
+ break;
+
+ memset(&a, 0, sizeof(a));
+
+ if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR)
+ break;
+
+ // win32 getsockname may only set the port number, p=0.0005.
+ // ( http://msdn.microsoft.com/library/ms738543.aspx ):
+ a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ a.inaddr.sin_family = AF_INET;
+
+ if (listen(listener, 1) == SOCKET_ERROR)
+ break;
+
+ socks[0] = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, flags);
+
+ if (socks[0] == (int) INVALID_SOCKET)
+ break;
+
+ if (connect(socks[0], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR)
+ break;
+
+ socks[1] = accept(listener, NULL, NULL);
+
+ if (socks[1] == (int) INVALID_SOCKET)
+ break;
+
+ closesocket(listener);
+ return 0;
+ } while (0);
+
+ e = WSAGetLastError();
+ closesocket(listener);
+ closesocket(socks[0]);
+ closesocket(socks[1]);
+ WSASetLastError(e);
+ return SOCKET_ERROR;
}
#endif
diff --git a/src/libmowgli/platform/win32/win32_stdinc.h b/src/libmowgli/platform/win32/win32_stdinc.h
index 1360a4a..e4e1d05 100644
--- a/src/libmowgli/platform/win32/win32_stdinc.h
+++ b/src/libmowgli/platform/win32/win32_stdinc.h
@@ -26,24 +26,18 @@
#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <time.h>
-
-#define strcasecmp _stricmp
-#define strdup _strdup
-#define usleep(_usecs) Sleep((_usecs)/1000L)
-#ifdef _MSC_VER
-# define snprintf _snprintf
-#endif
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <time.h>
-struct timezone {
- int tz_minuteswest;
- int tz_dsttime;
-};
+# define strcasecmp _stricmp
+# define strdup _strdup
+# ifdef _MSC_VER
+# define snprintf _snprintf
+# endif
-extern int gettimeofday(struct timeval *tv, struct timezone *tz);
extern int setenv(const char *name, const char *value, int overwrite);
+
extern int pipe(int pipefd[2]);
extern int socketpair(int domain, int type, int protocol, int pipefd[2]);
extern int fork(void);
@@ -51,11 +45,11 @@ extern int inet_pton(int af, const char *src, void *dst);
extern const char *inet_ntop(int af, const void *addr, char *host, size_t hostlen);
/* MSYS autoconf is fucko. */
-#ifndef HAVE_WINSOCK2_H
-#define HAVE_WINSOCK2_H
-#endif
+# ifndef HAVE_WINSOCK2_H
+# define HAVE_WINSOCK2_H
+# endif
-#define HAVE_SELECT
+# define HAVE_SELECT
#endif
diff --git a/src/libmowgli/thread/mutex.c b/src/libmowgli/thread/mutex.c
index 1d5d480..c60902a 100644
--- a/src/libmowgli/thread/mutex.c
+++ b/src/libmowgli/thread/mutex.c
@@ -25,8 +25,6 @@
#if defined(_WIN32)
extern const mowgli_mutex_ops_t _mowgli_win32_mutex_ops;
-#elif defined(_sun) || defined(_sco)
-extern const mowgli_mutex_ops_t _mowgli_sun_mutex_ops;
#else
extern const mowgli_mutex_ops_t _mowgli_posix_mutex_ops;
#endif
@@ -35,7 +33,8 @@ extern const mowgli_mutex_ops_t _mowgli_null_mutex_ops;
static const mowgli_mutex_ops_t *_mowgli_mutex_ops = NULL;
-static inline const mowgli_mutex_ops_t *get_mutex_platform(void)
+static inline const mowgli_mutex_ops_t *
+get_mutex_platform(void)
{
/* allow for threading policy to set custom mutex ops */
if (_mowgli_mutex_ops != NULL)
@@ -45,10 +44,6 @@ static inline const mowgli_mutex_ops_t *get_mutex_platform(void)
return &_mowgli_win32_mutex_ops;
#endif
-#if defined(_sun) || defined(_sco)
- return &_mowgli_sun_mutex_ops;
-#endif
-
#if !defined(MOWGLI_FEATURE_HAVE_NATIVE_MUTEXES)
return &_mowgli_posix_mutex_ops;
#endif
@@ -56,14 +51,17 @@ static inline const mowgli_mutex_ops_t *get_mutex_platform(void)
return &_mowgli_null_mutex_ops;
}
-mowgli_mutex_t *mowgli_mutex_create(void)
+mowgli_mutex_t *
+mowgli_mutex_create(void)
{
mowgli_mutex_t *mutex = mowgli_alloc(sizeof(mowgli_mutex_t));
return_val_if_fail(mutex != NULL, NULL);
if (mowgli_mutex_init(mutex))
+ {
return mutex;
+ }
else
{
mowgli_free(mutex);
@@ -71,7 +69,8 @@ mowgli_mutex_t *mowgli_mutex_create(void)
}
}
-int mowgli_mutex_init(mowgli_mutex_t *mutex)
+int
+mowgli_mutex_init(mowgli_mutex_t *mutex)
{
return_val_if_fail(mutex != NULL, -1);
@@ -80,7 +79,8 @@ int mowgli_mutex_init(mowgli_mutex_t *mutex)
return mutex->ops->mutex_create(mutex);
}
-int mowgli_mutex_lock(mowgli_mutex_t *mutex)
+int
+mowgli_mutex_lock(mowgli_mutex_t *mutex)
{
return_val_if_fail(mutex != NULL, -1);
return_val_if_fail(mutex->ops != NULL, -1);
@@ -88,7 +88,8 @@ int mowgli_mutex_lock(mowgli_mutex_t *mutex)
return mutex->ops->mutex_lock(mutex);
}
-int mowgli_mutex_trylock(mowgli_mutex_t *mutex)
+int
+mowgli_mutex_trylock(mowgli_mutex_t *mutex)
{
return_val_if_fail(mutex != NULL, -1);
return_val_if_fail(mutex->ops != NULL, -1);
@@ -96,7 +97,8 @@ int mowgli_mutex_trylock(mowgli_mutex_t *mutex)
return mutex->ops->mutex_trylock(mutex);
}
-int mowgli_mutex_unlock(mowgli_mutex_t *mutex)
+int
+mowgli_mutex_unlock(mowgli_mutex_t *mutex)
{
return_val_if_fail(mutex != NULL, -1);
return_val_if_fail(mutex->ops != NULL, -1);
@@ -104,7 +106,8 @@ int mowgli_mutex_unlock(mowgli_mutex_t *mutex)
return mutex->ops->mutex_unlock(mutex);
}
-int mowgli_mutex_uninit(mowgli_mutex_t *mutex)
+int
+mowgli_mutex_uninit(mowgli_mutex_t *mutex)
{
return_val_if_fail(mutex != NULL, -1);
return_val_if_fail(mutex->ops != NULL, -1);
@@ -112,7 +115,8 @@ int mowgli_mutex_uninit(mowgli_mutex_t *mutex)
return mutex->ops->mutex_destroy(mutex);
}
-void mowgli_mutex_destroy(mowgli_mutex_t *mutex)
+void
+mowgli_mutex_destroy(mowgli_mutex_t *mutex)
{
return_if_fail(mutex != NULL);
@@ -120,7 +124,8 @@ void mowgli_mutex_destroy(mowgli_mutex_t *mutex)
mowgli_free(mutex);
}
-void mowgli_mutex_set_policy(mowgli_thread_policy_t policy)
+void
+mowgli_mutex_set_policy(mowgli_thread_policy_t policy)
{
switch (policy)
{
diff --git a/src/libmowgli/thread/mutex.h b/src/libmowgli/thread/mutex.h
index f08013d..94ead78 100644
--- a/src/libmowgli/thread/mutex.h
+++ b/src/libmowgli/thread/mutex.h
@@ -28,17 +28,18 @@
# include <thread.h>
# include <synch.h>
# define MOWGLI_FEATURE_HAVE_NATIVE_MUTEXES
-# define MOWGLI_NATIVE_MUTEX_DECL(name) mutex_t (name)
+# define MOWGLI_NATIVE_MUTEX_DECL(name) mutex_t(name)
#elif defined MOWGLI_OS_WIN
# define MOWGLI_FEATURE_HAVE_NATIVE_MUTEXES
-# define MOWGLI_NATIVE_MUTEX_DECL(name) HANDLE (name)
+# define MOWGLI_NATIVE_MUTEX_DECL(name) HANDLE(name)
#else
# include <pthread.h>
#endif
typedef struct mowgli_mutex_ mowgli_mutex_t;
-typedef struct {
+typedef struct
+{
int (*mutex_create)(mowgli_mutex_t *mutex);
int (*mutex_lock)(mowgli_mutex_t *mutex);
int (*mutex_trylock)(mowgli_mutex_t *mutex);
@@ -46,7 +47,8 @@ typedef struct {
int (*mutex_destroy)(mowgli_mutex_t *mutex);
} mowgli_mutex_ops_t;
-struct mowgli_mutex_ {
+struct mowgli_mutex_
+{
#ifdef MOWGLI_FEATURE_HAVE_NATIVE_MUTEXES
MOWGLI_NATIVE_MUTEX_DECL(mutex);
#else
@@ -60,7 +62,7 @@ struct mowgli_mutex_ {
#endif
mowgli_mutex_t *mowgli_mutex_create(void);
-int mowgli_mutex_init(mowgli_mutex_t* mutex);
+int mowgli_mutex_init(mowgli_mutex_t *mutex);
int mowgli_mutex_lock(mowgli_mutex_t *mutex);
int mowgli_mutex_trylock(mowgli_mutex_t *mutex);
int mowgli_mutex_unlock(mowgli_mutex_t *mutex);
@@ -70,10 +72,10 @@ void mowgli_mutex_destroy(mowgli_mutex_t *mutex);
void mowgli_mutex_set_policy(mowgli_thread_policy_t policy);
/* simple dispatch function to set the ops up for the various subsystems. */
-static inline void mowgli_thread_set_policy(mowgli_thread_policy_t policy)
+static inline void
+mowgli_thread_set_policy(mowgli_thread_policy_t policy)
{
mowgli_mutex_set_policy(policy);
}
#endif
-
diff --git a/src/libmowgli/thread/null_mutexops.c b/src/libmowgli/thread/null_mutexops.c
index 2750add..7a84c01 100644
--- a/src/libmowgli/thread/null_mutexops.c
+++ b/src/libmowgli/thread/null_mutexops.c
@@ -23,32 +23,38 @@
#include "mowgli.h"
-static int mowgli_null_mutex_create(mowgli_mutex_t *mutex)
+static int
+mowgli_null_mutex_create(mowgli_mutex_t *mutex)
{
return 0;
}
-static int mowgli_null_mutex_lock(mowgli_mutex_t *mutex)
+static int
+mowgli_null_mutex_lock(mowgli_mutex_t *mutex)
{
return 0;
}
-static int mowgli_null_mutex_trylock(mowgli_mutex_t *mutex)
+static int
+mowgli_null_mutex_trylock(mowgli_mutex_t *mutex)
{
return 0;
}
-static int mowgli_null_mutex_unlock(mowgli_mutex_t *mutex)
+static int
+mowgli_null_mutex_unlock(mowgli_mutex_t *mutex)
{
return 0;
}
-static int mowgli_null_mutex_destroy(mowgli_mutex_t *mutex)
+static int
+mowgli_null_mutex_destroy(mowgli_mutex_t *mutex)
{
return 0;
}
-const mowgli_mutex_ops_t _mowgli_null_mutex_ops = {
+const mowgli_mutex_ops_t _mowgli_null_mutex_ops =
+{
.mutex_create = mowgli_null_mutex_create,
.mutex_lock = mowgli_null_mutex_lock,
.mutex_trylock = mowgli_null_mutex_trylock,
diff --git a/src/libmowgli/thread/posix_mutexops.c b/src/libmowgli/thread/posix_mutexops.c
index 5fb64e9..dbb7be2 100644
--- a/src/libmowgli/thread/posix_mutexops.c
+++ b/src/libmowgli/thread/posix_mutexops.c
@@ -26,83 +26,48 @@
#ifndef _WIN32
/*************
- * This implements native Sun/UnixWare threads. Some other SVR4-based
- * environments attempted to make work-alikes, but those aren't guaranteed
- * to be supported. This should work on SunOS 5.2 and UnixWare 7, and
- * anything later.
- *************/
-#if defined(__sun) || defined(__sco)
-
-static int mowgli_sun_mutex_create(mowgli_mutex_t *mutex)
-{
- return mutex_init(&mutex->mutex, USYNC_THREAD, NULL);
-}
-
-static int mowgli_sun_mutex_lock(mowgli_mutex_t *mutex)
-{
- return mutex_lock(&mutex->mutex);
-}
-
-static int mowgli_sun_mutex_trylock(mowgli_mutex_t *mutex)
-{
- return mutex_trylock(&mutex->mutex);
-}
-
-static int mowgli_sun_mutex_unlock(mowgli_mutex_t *mutex)
-{
- return mutex_unlock(&mutex->mutex);
-}
-
-static int mowgli_sun_mutex_destroy(mowgli_mutex_t *mutex)
-{
- return mutex_destroy(&mutex->mutex);
-}
-
-const mowgli_mutex_ops_t _mowgli_sun_mutex_ops = {
- .mutex_create = mowgli_sun_mutex_create,
- .mutex_lock = mowgli_sun_mutex_lock,
- .mutex_trylock = mowgli_sun_mutex_trylock,
- .mutex_unlock = mowgli_sun_mutex_unlock,
- .mutex_destroy = mowgli_sun_mutex_destroy,
-};
-
-/*************
- * This "default" implementation uses pthreads. Care has been taken to
- * ensure it runs on POSIX 1003.4a (draft 4, aka DECthreads, aka what OSF/1,
- * Tru64, Ultrix, CMU Mach, and HP-UX use) as well as POSIX 1003.1c-1995.
- * As long as you don't try playing with the pthread_attr module or the
- * scheduler routines (which are non-standard and broken anyway, IMO) then
- * it should be relatively easy to maintian d4 compatibility without
- * sacrificing any functionality.
- *************/
-#elif !defined(MOWGLI_FEATURE_HAVE_NATIVE_MUTEXES)
-
-static int mowgli_posix_mutex_create(mowgli_mutex_t *mutex)
+* This "default" implementation uses pthreads. Care has been taken to
+* ensure it runs on POSIX 1003.4a (draft 4, aka DECthreads, aka what OSF/1,
+* Tru64, Ultrix, CMU Mach, and HP-UX use) as well as POSIX 1003.1c-1995.
+* As long as you don't try playing with the pthread_attr module or the
+* scheduler routines (which are non-standard and broken anyway, IMO) then
+* it should be relatively easy to maintian d4 compatibility without
+* sacrificing any functionality.
+*************/
+# if !defined(MOWGLI_FEATURE_HAVE_NATIVE_MUTEXES)
+
+static int
+mowgli_posix_mutex_create(mowgli_mutex_t *mutex)
{
return pthread_mutex_init(&mutex->mutex, NULL);
}
-static int mowgli_posix_mutex_lock(mowgli_mutex_t *mutex)
+static int
+mowgli_posix_mutex_lock(mowgli_mutex_t *mutex)
{
return pthread_mutex_lock(&mutex->mutex);
}
-static int mowgli_posix_mutex_trylock(mowgli_mutex_t *mutex)
+static int
+mowgli_posix_mutex_trylock(mowgli_mutex_t *mutex)
{
return pthread_mutex_trylock(&mutex->mutex);
}
-static int mowgli_posix_mutex_unlock(mowgli_mutex_t *mutex)
+static int
+mowgli_posix_mutex_unlock(mowgli_mutex_t *mutex)
{
return pthread_mutex_unlock(&mutex->mutex);
}
-static int mowgli_posix_mutex_destroy(mowgli_mutex_t *mutex)
+static int
+mowgli_posix_mutex_destroy(mowgli_mutex_t *mutex)
{
return pthread_mutex_destroy(&mutex->mutex);
}
-const mowgli_mutex_ops_t _mowgli_posix_mutex_ops = {
+const mowgli_mutex_ops_t _mowgli_posix_mutex_ops =
+{
.mutex_create = mowgli_posix_mutex_create,
.mutex_lock = mowgli_posix_mutex_lock,
.mutex_trylock = mowgli_posix_mutex_trylock,
@@ -110,6 +75,6 @@ const mowgli_mutex_ops_t _mowgli_posix_mutex_ops = {
.mutex_destroy = mowgli_posix_mutex_destroy,
};
-#endif
+# endif
#endif
diff --git a/src/libmowgli/thread/thread.h b/src/libmowgli/thread/thread.h
index f063217..88939eb 100644
--- a/src/libmowgli/thread/thread.h
+++ b/src/libmowgli/thread/thread.h
@@ -28,15 +28,20 @@
#ifdef MOWGLI_OS_UNIX_TYPE
# include <thread.h>
# define MOWGLI_FEATURE_HAVE_NATIVE_THREADS
-# define MOWGLI_NATIVE_THREAD_DECL(name) thread_t (name)
+# ifdef MOWGLI_OS_THREADS_SOLARIS
+# define MOWGLI_NATIVE_THREAD_DECL(name) pthread_t(name)
+# else
+# define MOWGLI_NATIVE_THREAD_DECL(name) thread_t(name)
+# endif
#elif defined MOWGLI_OS_WIN
# define MOWGLI_FEATURE_HAVE_NATIVE_THREADS
-# define MOWGLI_NATIVE_THREAD_DECL(name) HANDLE (name)
+# define MOWGLI_NATIVE_THREAD_DECL(name) HANDLE(name)
#else
# include <pthread.h>
#endif
-typedef struct {
+typedef struct
+{
#ifdef MOWGLI_FEATURE_HAVE_NATIVE_THREADS
MOWGLI_NATIVE_THREAD_DECL(thread);
#else
@@ -55,10 +60,11 @@ typedef void *(*mowgli_thread_start_fn_t)(mowgli_thread_t *thread, void *userdat
* portability. Creating, ending, killing and cleanup functions are presently implemented,
* and cover approximately 99.999% of uses of thread APIs. --nenolod
*/
-typedef struct {
+typedef struct
+{
int (*thread_create)(mowgli_thread_t *thread, mowgli_thread_start_fn_t start_fn, void *userdata);
void (*thread_exit)(mowgli_thread_t *thread);
- void *(*thread_join)(mowgli_thread_t *thread);
+ void *(*thread_join)(mowgli_thread_t * thread);
void (*thread_kill)(mowgli_thread_t *thread);
void (*thread_destroy)(mowgli_thread_t *thread);
} mowgli_thread_ops_t;
@@ -69,10 +75,10 @@ void *mowgli_thread_join(mowgli_thread_t *thread);
void mowgli_thread_kill(mowgli_thread_t *thread);
void mowgli_thread_destroy(mowgli_thread_t *thread);
-typedef enum {
+typedef enum
+{
MOWGLI_THREAD_POLICY_DEFAULT,
MOWGLI_THREAD_POLICY_DISABLED,
} mowgli_thread_policy_t;
#endif
-
diff --git a/src/libmowgli/thread/win32_mutexops.c b/src/libmowgli/thread/win32_mutexops.c
index 486992f..1e1bf5f 100644
--- a/src/libmowgli/thread/win32_mutexops.c
+++ b/src/libmowgli/thread/win32_mutexops.c
@@ -23,47 +23,53 @@
#include "mowgli.h"
-
/*************
- * This Windows implementation is guaranteed to work on Windows 95,
- * Windows NT 4, and anything later.
- *************/
+* This Windows implementation is guaranteed to work on Windows 95,
+* Windows NT 4, and anything later.
+*************/
#if defined(_WIN32)
-static int mowgli_win32_mutex_create(mowgli_mutex_t *mutex)
+static int
+mowgli_win32_mutex_create(mowgli_mutex_t *mutex)
{
mutex->mutex = CreateMutex(NULL, FALSE, NULL);
- if(mutex->mutex == NULL)
+
+ if (mutex->mutex == NULL)
return GetLastError();
return 0;
}
-static int mowgli_win32_mutex_lock(mowgli_mutex_t *mutex)
+static int
+mowgli_win32_mutex_lock(mowgli_mutex_t *mutex)
{
return WaitForSingleObject(mutex->mutex, INFINITE);
}
-static int mowgli_win32_mutex_trylock(mowgli_mutex_t *mutex)
+static int
+mowgli_win32_mutex_trylock(mowgli_mutex_t *mutex)
{
return WaitForSingleObject(mutex->mutex, 0);
}
-static int mowgli_win32_mutex_unlock(mowgli_mutex_t *mutex)
+static int
+mowgli_win32_mutex_unlock(mowgli_mutex_t *mutex)
{
- if(ReleaseMutex(mutex->mutex) != 0)
+ if (ReleaseMutex(mutex->mutex) != 0)
return 0;
return GetLastError();
}
-static int mowgli_win32_mutex_destroy(mowgli_mutex_t *mutex)
+static int
+mowgli_win32_mutex_destroy(mowgli_mutex_t *mutex)
{
CloseHandle(mutex->mutex);
return 0;
}
-const mowgli_mutex_ops_t _mowgli_win32_mutex_ops = {
+const mowgli_mutex_ops_t _mowgli_win32_mutex_ops =
+{
.mutex_create = mowgli_win32_mutex_create,
.mutex_lock = mowgli_win32_mutex_lock,
.mutex_trylock = mowgli_win32_mutex_trylock,
diff --git a/src/libmowgli/vio/vio.c b/src/libmowgli/vio/vio.c
index ef4fb90..2570e22 100644
--- a/src/libmowgli/vio/vio.c
+++ b/src/libmowgli/vio/vio.c
@@ -36,11 +36,13 @@
static mowgli_heap_t *vio_heap = NULL;
/* Change these to suit your needs for new VIO objects */
-mowgli_vio_ops_t mowgli_vio_default_ops = {
+mowgli_vio_ops_t mowgli_vio_default_ops =
+{
.socket = mowgli_vio_default_socket,
.bind = mowgli_vio_default_bind,
.listen = mowgli_vio_default_listen,
.accept = mowgli_vio_default_accept,
+ .reuseaddr = mowgli_vio_default_reuseaddr,
.connect = mowgli_vio_default_connect,
.read = mowgli_vio_default_read,
.write = mowgli_vio_default_write,
@@ -52,7 +54,20 @@ mowgli_vio_ops_t mowgli_vio_default_ops = {
.tell = mowgli_vio_default_tell,
};
-mowgli_vio_t * mowgli_vio_create(void *userdata)
+/* Null ops */
+mowgli_vio_evops_t mowgli_vio_default_evops =
+{
+ .read_cb = NULL,
+ .write_cb = NULL
+};
+
+/* mowgli_vio_create - create a VIO object on the heap
+ *
+ * inputs - userdata for the VIO object
+ * outputs - a VIO object
+ */
+mowgli_vio_t *
+mowgli_vio_create(void *userdata)
{
mowgli_vio_t *vio;
@@ -68,59 +83,138 @@ mowgli_vio_t * mowgli_vio_create(void *userdata)
return vio;
}
-void mowgli_vio_init(mowgli_vio_t *vio, void *userdata)
+/* mowgli_vio_init - initalise a VIO object previously allocated
+ * only use this if you know what you're doing, otherwise use mowgli_vio_create
+ *
+ * inputs - VIO object, userdata
+ * outputs - None
+ */
+void
+mowgli_vio_init(mowgli_vio_t *vio, void *userdata)
{
- vio->fd = -1;
+ return_if_fail(vio);
+
+ vio->io.fd = -1;
vio->flags = 0;
/* Default ops */
- vio->ops = mowgli_vio_default_ops;
+ vio->ops = &mowgli_vio_default_ops;
vio->userdata = userdata;
}
-void mowgli_vio_eventloop_attach(mowgli_vio_t *vio, mowgli_eventloop_t *eventloop)
+/* mowgli_vio_eventloop_attach - attach a VIO object to an eventloop
+ *
+ * inputs - VIO object, eventloop, ops to use for the eventloop (optional but recommended)
+ * outputs - None
+ */
+void
+mowgli_vio_eventloop_attach(mowgli_vio_t *vio, mowgli_eventloop_t *eventloop, mowgli_vio_evops_t *evops)
{
- vio->io = mowgli_pollable_create(eventloop, vio->fd, vio->userdata);
- if (vio->io != NULL)
+ return_if_fail(vio);
+ return_if_fail(eventloop);
+
+ const int fd = vio->io.fd;
+
+ /* Check for previous attachment */
+ if (vio->eventloop)
+ {
+ mowgli_log("VIO object [%p] is already attached to eventloop [%p]; attempted to attach new eventloop [%p]", (void *) vio, (void *) vio->eventloop, (void *) eventloop);
+ return;
+ }
+
+ if ((vio->io.e = mowgli_pollable_create(eventloop, fd, vio->userdata)) != NULL)
{
vio->eventloop = eventloop;
+
/* You're probably going to want this */
- mowgli_pollable_set_nonblocking(vio->io, true);
+ mowgli_pollable_set_nonblocking(vio->io.e, true);
+
+ if (evops)
+ vio->evops = evops;
+ else
+ /* Default NULL ops */
+ vio->evops = &mowgli_vio_default_evops;
}
else
- mowgli_log("Unable to create pollable with VIO object [%p], expect problems.", vio);
+ {
+ mowgli_log("Unable to create pollable with VIO object [%p], expect problems.", (void *) vio);
+ vio->io.fd = fd;/* May have been clobbered */
+ }
}
-void mowgli_vio_eventloop_detach(mowgli_vio_t *vio)
+/* mowgli_vio_eventloop_detach - detach VIO object from eventloop
+ *
+ * inputs - VIO object
+ * output - None
+ */
+void
+mowgli_vio_eventloop_detach(mowgli_vio_t *vio)
{
- return_if_fail(vio->io != NULL);
+ const int fd = mowgli_vio_getfd(vio);
+
+ return_if_fail(fd != -1);
+
+ return_if_fail(vio != NULL);
+ return_if_fail(vio->io.e != NULL);
return_if_fail(vio->eventloop != NULL);
- mowgli_pollable_destroy(vio->eventloop, vio->io);
+ mowgli_pollable_destroy(vio->eventloop, vio->io.e);
+
+ vio->eventloop = NULL;
+ vio->io.fd = fd;
}
-void mowgli_vio_destroy(mowgli_vio_t *vio)
+/* mowgli_vio_destroy - eliminate a VIO object
+ *
+ * inputs - VIO object
+ * output - None
+ */
+void
+mowgli_vio_destroy(mowgli_vio_t *vio)
{
- mowgli_vio_eventloop_detach(vio);
+ return_if_fail(vio);
+
+ if (vio->eventloop != NULL)
+ mowgli_vio_eventloop_detach(vio);
+
+ if (!MOWGLI_VIO_IS_CLOSED(vio))
+ mowgli_vio_close(vio);
if (mowgli_vio_hasflag(vio, MOWGLI_VIO_FLAGS_ISONHEAP))
mowgli_heap_free(vio_heap, vio);
}
-int mowgli_vio_err_errcode(mowgli_vio_t *vio, char *(*int_to_error)(int), int errcode)
+/* mowgli_vio_err_errcode - Signal an error using the specified char *foo(int err) callback
+ * Usually the callback can be strerror, but it can use anything else that fits the mould.
+ *
+ * inputs - VIO object, callback, error code.
+ * outputs - Error code from mowgli_vio_error function, any output to terminal/log files/etc.
+ */
+int
+mowgli_vio_err_errcode(mowgli_vio_t *vio, char *(*int_to_error)(int), int errcode)
{
+ return_val_if_fail(vio, -255);
+
vio->error.type = MOWGLI_VIO_ERR_ERRCODE;
vio->error.code = errcode;
mowgli_strlcpy(vio->error.string, int_to_error(errcode), sizeof(vio->error.string));
return mowgli_vio_error(vio);
}
+/* mowgli_vio_err_sslerrcode - Signal an SSL error
+ *
+ * inputs - VIO object, error code
+ * outputs - Error code from mowgli_vio_error function, any output to terminal/log files/etc.
+ */
#ifdef HAVE_OPENSSL
-int mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, int errcode)
+int
+mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, unsigned long int errcode)
{
+ return_val_if_fail(vio, -255);
+
vio->error.type = MOWGLI_VIO_ERR_ERRCODE;
vio->error.code = errcode;
ERR_error_string_n(errcode, vio->error.string, sizeof(vio->error.string));
@@ -129,8 +223,11 @@ int mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, int errcode)
#else
-int mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, int errcode)
+int
+mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, unsigned long int errcode)
{
+ return_if_fail(vio);
+
vio->error.type = MOWGLI_VIO_ERR_ERRCODE;
vio->error.code = errcode;
mowgli_strlcpy(vio->error.string, "Unknown SSL error", sizeof(vio->error.string));
diff --git a/src/libmowgli/vio/vio.h b/src/libmowgli/vio/vio.h
index 37b5c37..aafab2a 100644
--- a/src/libmowgli/vio/vio.h
+++ b/src/libmowgli/vio/vio.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Elizabeth J. Myers. All rights reserved.
+ * Copyright (c) 2012 Elizabeth J. Myers. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -22,19 +22,25 @@
/* Types and structs */
typedef struct _mowgli_vio mowgli_vio_t;
-typedef enum {
- MOWGLI_VIO_ERR_NONE,
- MOWGLI_VIO_ERR_REMOTE_HANGUP,
- MOWGLI_VIO_ERR_ERRCODE,
- MOWGLI_VIO_ERR_API,
- MOWGLI_VIO_ERR_CUSTOM,
+/* Error type */
+typedef enum
+{
+ MOWGLI_VIO_ERR_NONE = 0,/* Wat, no error. */
+ MOWGLI_VIO_ERR_REMOTE_HANGUP, /* Remote end hung up on us, how rude */
+ MOWGLI_VIO_ERR_ERRCODE, /* An errno error or something like that */
+ MOWGLI_VIO_ERR_API, /* Programmer was a dumbass */
+ MOWGLI_VIO_ERR_CUSTOM, /* Use this for custom errors */
} mowgli_vio_error_type_t;
-typedef enum {
- MOWGLI_VIO_ERR_OP_NONE,
+/* Errors with specific functions correspondng to the VIO op it's named
+ * after */
+typedef enum
+{
+ MOWGLI_VIO_ERR_OP_NONE = 0, /* Wat. */
MOWGLI_VIO_ERR_OP_SOCKET,
MOWGLI_VIO_ERR_OP_LISTEN,
MOWGLI_VIO_ERR_OP_ACCEPT,
+ MOWGLI_VIO_ERR_OP_REUSEADDR,
MOWGLI_VIO_ERR_OP_CONNECT,
MOWGLI_VIO_ERR_OP_READ,
MOWGLI_VIO_ERR_OP_WRITE,
@@ -44,41 +50,59 @@ typedef enum {
MOWGLI_VIO_ERR_OP_OTHER,
} mowgli_vio_error_op_t;
-typedef struct _mowgli_vio_error {
+typedef struct _mowgli_vio_error
+{
mowgli_vio_error_op_t op;
mowgli_vio_error_type_t type;
- int code;
- char string[128];
+ unsigned long code; /* Unsigned long for OpenSSL fuckery */
+ char string[128]; /* Friendly name for error */
} mowgli_vio_error_t;
-typedef struct _mowgli_vio_sockaddr {
+/* Custom sockaddr member to have a uniform sockaddr as opposed to the
+ * bullshit in the Berkeley sockets API with struct sockaddr/struct
+ * sockaddr_storage/struct sockaddr_in/struct sockaddr_in6 and associated
+ * API inconsistency and braindamage
+ */
+typedef struct _mowgli_vio_sockaddr
+{
struct sockaddr_storage addr;
+
socklen_t addrlen;
} mowgli_vio_sockaddr_t;
-typedef struct _mowgli_vio_sockdata {
- char host[39]; /* max length of IPv6 address */
+#ifndef INET6_ADDRSTRLEN
+# define INET6_ADDRSTRLEN 46 /* Good enough I tell you */
+#endif
+
+/* Socket data */
+typedef struct _mowgli_vio_sockdata
+{
+ char host[INET6_ADDRSTRLEN]; /* max length of IPv6 address */
uint16_t port;
} mowgli_vio_sockdata_t;
-typedef int mowgli_vio_func_t(mowgli_vio_t *);
-typedef int mowgli_vio_bind_connect_func_t(mowgli_vio_t *, mowgli_vio_sockaddr_t *);
-typedef int mowgli_vio_read_func_t(mowgli_vio_t *, void *, size_t);
-typedef int mowgli_vio_write_func_t(mowgli_vio_t *, const void *, size_t);
-typedef int mowgli_vio_sendto_func_t(mowgli_vio_t *, const void *, size_t, mowgli_vio_sockaddr_t *);
-typedef int mowgli_vio_recvfrom_func_t(mowgli_vio_t *, void *, size_t, mowgli_vio_sockaddr_t *);
-typedef int mowgli_vio_connect_func_t(mowgli_vio_t *);
-typedef int mowgli_vio_accept_func_t(mowgli_vio_t *, mowgli_vio_t *);
-typedef int mowgli_vio_listen_func_t(mowgli_vio_t *, int);
-typedef int mowgli_vio_socket_func_t(mowgli_vio_t *, int, int, int);
-typedef int mowgli_vio_seek_func_t(mowgli_vio_t *, long, int);
-
-typedef struct {
+/* Various typedefs bleh */
+typedef int mowgli_vio_func_t (mowgli_vio_t *);
+typedef int mowgli_vio_bind_connect_func_t (mowgli_vio_t *, mowgli_vio_sockaddr_t *);
+typedef int mowgli_vio_read_func_t (mowgli_vio_t *, void *, size_t);
+typedef int mowgli_vio_write_func_t (mowgli_vio_t *, const void *, size_t);
+typedef int mowgli_vio_sendto_func_t (mowgli_vio_t *, const void *, size_t, mowgli_vio_sockaddr_t *);
+typedef int mowgli_vio_recvfrom_func_t (mowgli_vio_t *, void *, size_t, mowgli_vio_sockaddr_t *);
+typedef int mowgli_vio_connect_func_t (mowgli_vio_t *);
+typedef int mowgli_vio_accept_func_t (mowgli_vio_t *, mowgli_vio_t *);
+typedef int mowgli_vio_listen_func_t (mowgli_vio_t *, int);
+typedef int mowgli_vio_socket_func_t (mowgli_vio_t *, int, int, int);
+typedef int mowgli_vio_seek_func_t (mowgli_vio_t *, long, int);
+
+/* These are workalikes vis-a-vis the Berkeley sockets API */
+typedef struct
+{
mowgli_vio_socket_func_t *socket;
mowgli_vio_bind_connect_func_t *bind;
mowgli_vio_bind_connect_func_t *connect;
mowgli_vio_listen_func_t *listen;
mowgli_vio_accept_func_t *accept;
+ mowgli_vio_func_t *reuseaddr;
mowgli_vio_read_func_t *read;
mowgli_vio_write_func_t *write;
mowgli_vio_sendto_func_t *sendto;
@@ -89,61 +113,89 @@ typedef struct {
mowgli_vio_func_t *tell;
} mowgli_vio_ops_t;
-struct _mowgli_vio {
- mowgli_vio_ops_t ops;
-
- mowgli_eventloop_io_t *io;
- mowgli_descriptor_t fd;
+/* Callbacks for eventloop stuff */
+typedef struct
+{
+ mowgli_eventloop_io_cb_t *read_cb;
+ mowgli_eventloop_io_cb_t *write_cb;
+} mowgli_vio_evops_t;
+struct _mowgli_vio
+{
+ mowgli_vio_ops_t *ops; /* VIO operations */
+ mowgli_vio_evops_t *evops; /* Eventloop operations */
+
+ /* eventloop IO object or descriptor
+ * If the eventloop member is non-null use io
+ * else use fd
+ */
+ union
+ {
+ mowgli_eventloop_io_t *e;
+ mowgli_descriptor_t fd;
+ } io;
+
+ /* Eventloop object we're attached to */
mowgli_eventloop_t *eventloop;
+ /* struct sockaddr portable workalike -- usage is
+ * context specific.
+ *
+ * For accept()'ed VIO objects, this is the client's
+ * struct sockaddr stuff, for connect()'ed objects it
+ * is the remote end's sockaddr (even with previous call
+ * to bind, for bind()'ed objects it is the sockaddr passed
+ * to bind
+ */
mowgli_vio_sockaddr_t addr;
- mowgli_vio_error_t error;
+ mowgli_vio_error_t error; /* Error information lives here */
- int flags;
+ unsigned int flags; /* Connection flags */
- void *userdata;
- void *privdata;
+ void *userdata; /* User data for VIO object */
+ void *privdata; /* Private data for stuff like SSL */
};
-typedef struct _mowgli_vio_ssl_settings {
- char cert_path[FILENAME_MAX];
- char privatekey_path[FILENAME_MAX];
+/* SSL settings... members subject to change */
+typedef struct _mowgli_vio_ssl_settings
+{
+ const char *cert_path;
+ const char *privatekey_path;
int ssl_version;
int (*password_func)(char *, int, int, void *);
int (*verify_func)(int, void *);
} mowgli_vio_ssl_settings_t;
-
/* Flags */
-#define MOWGLI_VIO_FLAGS_ISCONNECTING 0x00001
-#define MOWGLI_VIO_FLAGS_ISSSLCONNECTING 0x00002
-#define MOWGLI_VIO_FLAGS_ISCLOSED 0x00004
+#define MOWGLI_VIO_FLAGS_ISCONNECTING 0x00001
+#define MOWGLI_VIO_FLAGS_ISSSLCONNECTING 0x00002
+#define MOWGLI_VIO_FLAGS_ISCLOSED 0x00004
-#define MOWGLI_VIO_FLAGS_ISCLIENT 0x00008
-#define MOWGLI_VIO_FLAGS_ISSERVER 0x00010
+#define MOWGLI_VIO_FLAGS_ISCLIENT 0x00008
+#define MOWGLI_VIO_FLAGS_ISSERVER 0x00010
-#define MOWGLI_VIO_FLAGS_ISONHEAP 0x00020
+#define MOWGLI_VIO_FLAGS_ISONHEAP 0x00020
-#define MOWGLI_VIO_FLAGS_NEEDREAD 0x00040
-#define MOWGLI_VIO_FLAGS_NEEDWRITE 0x00080
+#define MOWGLI_VIO_FLAGS_NEEDREAD 0x00040
+#define MOWGLI_VIO_FLAGS_NEEDWRITE 0x00080
/* SSL flags */
-#define MOWGLI_VIO_SSLFLAGS_SSLV2 0x00001
-#define MOWGLI_VIO_SSLFLAGS_SSLV3 0x00002
-#define MOWGLI_VIO_SSLFLAGS_TLSV10 0x00004
-#define MOWGLI_VIO_SSLFLAGS_TLSV11 0x00008
-#define MOWGLI_VIO_SSLFLAGS_TLSV12 0x00010
-
+#define MOWGLI_VIO_SSLFLAGS_SSLV2 0x00001
+#define MOWGLI_VIO_SSLFLAGS_SSLV3 0x00002
+#define MOWGLI_VIO_SSLFLAGS_TLSV10 0x00004
+#define MOWGLI_VIO_SSLFLAGS_TLSV11 0x00008
+#define MOWGLI_VIO_SSLFLAGS_TLSV12 0x00010
/* Flag setting/getting */
-static inline bool mowgli_vio_hasflag(mowgli_vio_t *vio, int flag)
+static inline bool
+mowgli_vio_hasflag(mowgli_vio_t *vio, int flag)
{
return (vio->flags & flag) != 0 ? true : false;
}
-static inline void mowgli_vio_setflag(mowgli_vio_t *vio, int flag, bool setting)
+static inline void
+mowgli_vio_setflag(mowgli_vio_t *vio, int flag, bool setting)
{
if (setting)
vio->flags |= flag;
@@ -151,32 +203,68 @@ static inline void mowgli_vio_setflag(mowgli_vio_t *vio, int flag, bool setting)
vio->flags &= ~flag;
}
+/* Get file descriptor */
+static inline mowgli_descriptor_t
+mowgli_vio_getfd(mowgli_vio_t *vio)
+{
+ return_val_if_fail(vio, -1);
+
+ if (vio->eventloop)
+ {
+ mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(vio->io.e);
+
+ if (pollable)
+ return pollable->fd;
+ }
+
+ return vio->io.fd;
+}
/* Macros */
-#define MOWGLI_VIO_SET_CLOSED(v) \
- mowgli_vio_setflag(v, MOWGLI_VIO_FLAGS_ISCONNECTING, false); \
- mowgli_vio_setflag(v, MOWGLI_VIO_FLAGS_ISCLOSED, true); \
+#define MOWGLI_VIO_SET_CLOSED(v) \
+ mowgli_vio_setflag(v, MOWGLI_VIO_FLAGS_ISCONNECTING, false); \
+ mowgli_vio_setflag(v, MOWGLI_VIO_FLAGS_ISCLOSED, true); \
mowgli_vio_setflag(v, MOWGLI_VIO_FLAGS_ISSSLCONNECTING, false); \
- mowgli_vio_setflag(v, MOWGLI_VIO_FLAGS_NEEDREAD, false); \
- mowgli_vio_setflag(v, MOWGLI_VIO_FLAGS_NEEDWRITE, false);
+ mowgli_vio_setflag(v, MOWGLI_VIO_FLAGS_NEEDREAD, false); \
+ mowgli_vio_setflag(v, MOWGLI_VIO_FLAGS_NEEDWRITE, false)
+#define MOWGLI_VIO_IS_CLOSED(v) mowgli_vio_hasflag(v, MOWGLI_VIO_FLAGS_ISCLOSED)
+
+#define MOWGLI_VIO_SETREAD(vio) \
+ if (vio->eventloop && vio->io.e && vio->evops && vio->evops->read_cb) \
+ { \
+ mowgli_pollable_setselect(vio->eventloop, vio->io.e, MOWGLI_EVENTLOOP_IO_READ, vio->evops->read_cb); \
+ }
+
+#define MOWGLI_VIO_SETWRITE(vio) \
+ if (vio->eventloop && vio->io.e && vio->evops && vio->evops->write_cb) \
+ { \
+ mowgli_pollable_setselect(vio->eventloop, vio->io.e, MOWGLI_EVENTLOOP_IO_WRITE, vio->evops->write_cb); \
+ }
+
+#define MOWGLI_VIO_UNSETWRITE(vio) \
+ if (vio->eventloop && vio->io.e) \
+ { \
+ mowgli_pollable_setselect(vio->eventloop, vio->io.e, MOWGLI_EVENTLOOP_IO_WRITE, NULL); \
+ }
/* Decls */
-extern mowgli_vio_t * mowgli_vio_create(void *userdata);
+extern mowgli_vio_t *mowgli_vio_create(void *userdata);
extern void mowgli_vio_init(mowgli_vio_t *vio, void *userdata);
extern void mowgli_vio_destroy(mowgli_vio_t *vio);
-extern void mowgli_vio_eventloop_attach(mowgli_vio_t *vio, mowgli_eventloop_t *eventloop);
+extern void mowgli_vio_eventloop_attach(mowgli_vio_t *vio, mowgli_eventloop_t *eventloop, mowgli_vio_evops_t *evops);
extern void mowgli_vio_eventloop_detach(mowgli_vio_t *vio);
-extern mowgli_vio_sockaddr_t * mowgli_vio_sockaddr_create(mowgli_vio_sockaddr_t *naddr, int proto, const char *addr, int port);
-extern mowgli_vio_sockaddr_t * mowgli_vio_sockaddr_from_struct(mowgli_vio_sockaddr_t *naddr, const void *addr, socklen_t size);
+extern mowgli_vio_sockaddr_t *mowgli_vio_sockaddr_create(mowgli_vio_sockaddr_t *naddr, int proto, const char *addr, int port);
+extern mowgli_vio_sockaddr_t *mowgli_vio_sockaddr_from_struct(mowgli_vio_sockaddr_t *naddr, const void *addr, socklen_t size);
extern int mowgli_vio_sockaddr_info(const mowgli_vio_sockaddr_t *addr, mowgli_vio_sockdata_t *data);
extern int mowgli_vio_default_socket(mowgli_vio_t *vio, int family, int type, int proto);
extern int mowgli_vio_default_bind(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr);
extern int mowgli_vio_default_listen(mowgli_vio_t *vio, int backlog);
extern int mowgli_vio_default_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio);
+extern int mowgli_vio_default_reuseaddr(mowgli_vio_t *vio);
extern int mowgli_vio_default_connect(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr);
extern int mowgli_vio_default_read(mowgli_vio_t *vio, void *buffer, size_t len);
extern int mowgli_vio_default_write(mowgli_vio_t *vio, const void *buffer, size_t len);
@@ -188,32 +276,55 @@ extern int mowgli_vio_default_seek(mowgli_vio_t *vio, long offset, int whence);
extern int mowgli_vio_default_tell(mowgli_vio_t *vio);
extern int mowgli_vio_err_errcode(mowgli_vio_t *vio, char *(*int_to_error)(int), int errcode);
-extern int mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, int errcode);
+extern int mowgli_vio_err_sslerrcode(mowgli_vio_t *vio, unsigned long int errcode);
+
+extern int mowgli_vio_openssl_setssl(mowgli_vio_t *vio, mowgli_vio_ssl_settings_t *settings, mowgli_vio_ops_t *ops);
-extern int mowgli_vio_openssl_setssl(mowgli_vio_t *vio, mowgli_vio_ssl_settings_t *settings);
/* These are void ptr's so they can be null ops if SSL isn't available */
-extern void * mowgli_vio_openssl_getsslhandle(mowgli_vio_t *vio);
-extern void * mowgli_vio_openssl_getsslcontext(mowgli_vio_t *vio);
+extern void *mowgli_vio_openssl_getsslhandle(mowgli_vio_t *vio);
+extern void *mowgli_vio_openssl_getsslcontext(mowgli_vio_t *vio);
+
+#ifdef HAVE_OPENSSL
+extern int mowgli_vio_openssl_default_connect(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr);
+extern int mowgli_vio_openssl_default_listen(mowgli_vio_t *vio, int backlog);
+extern int mowgli_vio_openssl_default_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio);
+extern int mowgli_vio_openssl_default_read(mowgli_vio_t *vio, void *buffer, size_t len);
+extern int mowgli_vio_openssl_default_write(mowgli_vio_t *vio, const void *buffer, size_t len);
+extern int mowgli_vio_openssl_default_close(mowgli_vio_t *vio);
+
+#else
+# define NOSSLSUPPORT { mowgli_log("Attempting to use default OpenSSL op with no SSL support; this will not work!"); return -255; }
+static inline int mowgli_vio_openssl_default_connect(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr) NOSSLSUPPORT
+static inline int mowgli_vio_openssl_default_listen(mowgli_vio_t *vio, int backlog) NOSSLSUPPORT
+static inline int mowgli_vio_openssl_default_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio) NOSSLSUPPORT
+static inline int mowgli_vio_openssl_default_read(mowgli_vio_t *vio, void *buffer, size_t len) NOSSLSUPPORT
+static inline int mowgli_vio_openssl_default_write(mowgli_vio_t *vio, const void *buffer, size_t len) NOSSLSUPPORT
+static inline int mowgli_vio_openssl_default_close(mowgli_vio_t *vio) NOSSLSUPPORT
+#endif
+/* Default ops -- change these if you want something besides the default */
extern mowgli_vio_ops_t mowgli_vio_default_ops;
+/* Default evops -- they do nothing unless you change them */
+extern mowgli_vio_evops_t mowgli_vio_default_evops;
/* Sundry operations on vio functables */
-#define mowgli_vio_set_op(vio, op, func) vio->ops.op = func;
-
-#define mowgli_vio_socket(vio, ...) vio->ops.socket(vio, __VA_ARGS__)
-#define mowgli_vio_listen(vio, ...) vio->ops.listen(vio, __VA_ARGS__)
-#define mowgli_vio_bind(vio, ...) vio->ops.bind(vio, __VA_ARGS__)
-#define mowgli_vio_accept(vio, ...) vio->ops.accept(vio, __VA_ARGS__)
-#define mowgli_vio_connect(vio, ...) vio->ops.connect(vio, __VA_ARGS__)
-#define mowgli_vio_read(vio, ...) vio->ops.read(vio, __VA_ARGS__)
-#define mowgli_vio_write(vio, ...) vio->ops.write(vio, __VA_ARGS__)
-#define mowgli_vio_sendto(vio, ...) vio->ops.sendto(vio, __VA_ARGS__)
-#define mowgli_vio_recvfrom(vio, ...) vio->ops.recvfrom(vio, __VA_ARGS__)
-#define mowgli_vio_error(vio) vio->ops.error(vio);
-#define mowgli_vio_close(vio) vio->ops.close(vio);
-#define mowgli_vio_seek(vio, ...) vio->ops.seek(vio, __VA_ARGS__)
-#define mowgli_vio_tell(vio) vio->ops.tell(vio)
+#define mowgli_vio_ops_set_op(ops, op, func) ops->op = func
+
+/* Wrappers for the VIO ops */
+#define mowgli_vio_socket(vio, ...) vio->ops->socket(vio, __VA_ARGS__)
+#define mowgli_vio_listen(vio, ...) vio->ops->listen(vio, __VA_ARGS__)
+#define mowgli_vio_bind(vio, ...) vio->ops->bind(vio, __VA_ARGS__)
+#define mowgli_vio_accept(vio, ...) vio->ops->accept(vio, __VA_ARGS__)
+#define mowgli_vio_reuseaddr(vio) vio->ops->reuseaddr(vio)
+#define mowgli_vio_connect(vio, ...) vio->ops->connect(vio, __VA_ARGS__)
+#define mowgli_vio_read(vio, ...) vio->ops->read(vio, __VA_ARGS__)
+#define mowgli_vio_write(vio, ...) vio->ops->write(vio, __VA_ARGS__)
+#define mowgli_vio_sendto(vio, ...) vio->ops->sendto(vio, __VA_ARGS__)
+#define mowgli_vio_recvfrom(vio, ...) vio->ops->recvfrom(vio, __VA_ARGS__)
+#define mowgli_vio_error(vio) vio->ops->error(vio)
+#define mowgli_vio_close(vio) vio->ops->close(vio)
+#define mowgli_vio_seek(vio, ...) vio->ops->seek(vio, __VA_ARGS__)
+#define mowgli_vio_tell(vio) vio->ops->tell(vio)
#endif
-
diff --git a/src/libmowgli/vio/vio_openssl.c b/src/libmowgli/vio/vio_openssl.c
index 75c83e4..d492c9f 100644
--- a/src/libmowgli/vio/vio_openssl.c
+++ b/src/libmowgli/vio/vio_openssl.c
@@ -30,28 +30,28 @@
#ifdef HAVE_OPENSSL
-typedef struct {
+typedef struct
+{
SSL *ssl_handle;
SSL_CTX *ssl_context;
mowgli_vio_ssl_settings_t settings;
} mowgli_ssl_connection_t;
-static int mowgli_vio_openssl_connect(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr);
-static int mowgli_vio_openssl_listen(mowgli_vio_t *vio, int backlog);
-static int mowgli_vio_openssl_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio);
static int mowgli_vio_openssl_client_handshake(mowgli_vio_t *vio, mowgli_ssl_connection_t *connection);
-static int mowgli_vio_openssl_read(mowgli_vio_t *vio, void *buffer, size_t len);
-static int mowgli_vio_openssl_write(mowgli_vio_t *vio, const void *buffer, size_t len);
static int mowgli_openssl_read_or_write(bool read, mowgli_vio_t *vio, void *readbuf, const void *writebuf, size_t len);
-static int mowgli_vio_openssl_close(mowgli_vio_t *vio);
static mowgli_heap_t *ssl_heap = NULL;
static bool openssl_init = false;
-int mowgli_vio_openssl_setssl(mowgli_vio_t *vio, mowgli_vio_ssl_settings_t *settings)
+static mowgli_vio_ops_t *openssl_ops = NULL;
+
+int
+mowgli_vio_openssl_setssl(mowgli_vio_t *vio, mowgli_vio_ssl_settings_t *settings, mowgli_vio_ops_t *ops)
{
- mowgli_ssl_connection_t *connection;
+ mowgli_ssl_connection_t *connection;
+
+ return_val_if_fail(vio, -255);
if (!ssl_heap)
ssl_heap = mowgli_heap_create(sizeof(mowgli_ssl_connection_t), 64, BH_NOW);
@@ -65,13 +65,28 @@ int mowgli_vio_openssl_setssl(mowgli_vio_t *vio, mowgli_vio_ssl_settings_t *sett
/* Greatest compat without being terribly insecure */
connection->settings.ssl_version = MOWGLI_VIO_SSLFLAGS_SSLV3;
+ if (ops == NULL)
+ {
+ if (!openssl_ops)
+ {
+ openssl_ops = mowgli_alloc(sizeof(mowgli_vio_ops_t));
+ memcpy(openssl_ops, &mowgli_vio_default_ops, sizeof(mowgli_vio_ops_t));
+ }
+
+ vio->ops = openssl_ops;
+ }
+ else
+ {
+ vio->ops = ops;
+ }
+
/* Change ops */
- mowgli_vio_set_op(vio, connect, mowgli_vio_openssl_connect);
- mowgli_vio_set_op(vio, read, mowgli_vio_openssl_read);
- mowgli_vio_set_op(vio, write, mowgli_vio_openssl_write);
- mowgli_vio_set_op(vio, close, mowgli_vio_openssl_close);
- mowgli_vio_set_op(vio, accept, mowgli_vio_openssl_accept);
- mowgli_vio_set_op(vio, listen, mowgli_vio_openssl_listen);
+ mowgli_vio_ops_set_op(vio->ops, connect, mowgli_vio_openssl_default_connect);
+ mowgli_vio_ops_set_op(vio->ops, read, mowgli_vio_openssl_default_read);
+ mowgli_vio_ops_set_op(vio->ops, write, mowgli_vio_openssl_default_write);
+ mowgli_vio_ops_set_op(vio->ops, close, mowgli_vio_openssl_default_close);
+ mowgli_vio_ops_set_op(vio->ops, accept, mowgli_vio_openssl_default_accept);
+ mowgli_vio_ops_set_op(vio->ops, listen, mowgli_vio_openssl_default_listen);
/* SSL setup */
if (!openssl_init)
@@ -87,27 +102,39 @@ int mowgli_vio_openssl_setssl(mowgli_vio_t *vio, mowgli_vio_ssl_settings_t *sett
}
/* Returns void so they can be stubs */
-void * mowgli_vio_openssl_getsslhandle(mowgli_vio_t *vio)
+void *
+mowgli_vio_openssl_getsslhandle(mowgli_vio_t *vio)
{
+ return_val_if_fail(vio, NULL);
mowgli_ssl_connection_t *connection = vio->privdata;
return connection->ssl_handle;
}
-void * mowgli_vio_openssl_getsslcontext(mowgli_vio_t *vio)
+void *
+mowgli_vio_openssl_getsslcontext(mowgli_vio_t *vio)
{
+ return_val_if_fail(vio, NULL);
mowgli_ssl_connection_t *connection = vio->privdata;
return connection->ssl_context;
}
-static int mowgli_vio_openssl_connect(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr)
+int
+mowgli_vio_openssl_default_connect(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr)
{
- vio->error.op = MOWGLI_VIO_ERR_OP_CONNECT;
+ const int fd = mowgli_vio_getfd(vio);
+
+ return_val_if_fail(fd != -1, -255);
+
mowgli_ssl_connection_t *connection = vio->privdata;
- if (connect(vio->fd, (struct sockaddr *)&addr->addr, addr->addrlen) < 0)
+ vio->error.op = MOWGLI_VIO_ERR_OP_CONNECT;
+
+ if (connect(fd, (struct sockaddr *) &addr->addr, addr->addrlen) < 0)
{
if (!mowgli_eventloop_ignore_errno(errno))
+ {
return mowgli_vio_err_errcode(vio, strerror, errno);
+ }
else
{
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCONNECTING, true);
@@ -128,11 +155,16 @@ static int mowgli_vio_openssl_connect(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *
return mowgli_vio_openssl_client_handshake(vio, connection);
}
-static int mowgli_vio_openssl_listen(mowgli_vio_t *vio, int backlog)
+int
+mowgli_vio_openssl_default_listen(mowgli_vio_t *vio, int backlog)
{
- vio->error.op = MOWGLI_VIO_ERR_OP_LISTEN;
+ return_val_if_fail(vio, -255);
+
mowgli_ssl_connection_t *connection = vio->privdata;
const SSL_METHOD *method;
+ const int fd = mowgli_vio_getfd(vio);
+
+ vio->error.op = MOWGLI_VIO_ERR_OP_LISTEN;
switch (connection->settings.ssl_version)
{
@@ -148,21 +180,24 @@ static int mowgli_vio_openssl_listen(mowgli_vio_t *vio, int backlog)
method = TLSv1_server_method();
break;
default:
+
/* Compat method */
method = SSLv23_server_method();
}
-
- connection->ssl_context = SSL_CTX_new((SSL_METHOD *)method);
+
+ connection->ssl_context = SSL_CTX_new((SSL_METHOD *) method);
+
if (connection->ssl_context == NULL)
return mowgli_vio_err_sslerrcode(vio, ERR_get_error());
connection->ssl_handle = SSL_new(connection->ssl_context);
+
if (connection->ssl_handle == NULL)
return mowgli_vio_err_sslerrcode(vio, ERR_get_error());
SSL_set_accept_state(connection->ssl_handle);
SSL_CTX_set_options(connection->ssl_context, SSL_OP_SINGLE_DH_USE);
-
+
if (connection->settings.password_func)
{
SSL_CTX_set_default_passwd_cb(connection->ssl_context, connection->settings.password_func);
@@ -175,10 +210,10 @@ static int mowgli_vio_openssl_listen(mowgli_vio_t *vio, int backlog)
if (SSL_CTX_use_PrivateKey_file(connection->ssl_context, connection->settings.privatekey_path, SSL_FILETYPE_PEM) != 1)
return mowgli_vio_err_sslerrcode(vio, ERR_get_error());
- if (listen(vio->fd, backlog) != 0)
+ if (listen(fd, backlog) != 0)
return mowgli_vio_err_errcode(vio, strerror, errno);
- if (!SSL_set_fd(connection->ssl_handle, vio->fd))
+ if (!SSL_set_fd(connection->ssl_handle, fd))
return mowgli_vio_err_sslerrcode(vio, ERR_get_error());
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISSERVER, true);
@@ -187,10 +222,15 @@ static int mowgli_vio_openssl_listen(mowgli_vio_t *vio, int backlog)
return 0;
}
-static int mowgli_vio_openssl_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
+int
+mowgli_vio_openssl_default_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
{
- int fd;
+ const int fd = mowgli_vio_getfd(vio);
+ int afd;
int ret;
+
+ return_val_if_fail(fd != -1, -255);
+
mowgli_ssl_connection_t *connection = vio->privdata;
mowgli_ssl_connection_t *newconnection;
@@ -204,7 +244,7 @@ static int mowgli_vio_openssl_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
return mowgli_vio_error(vio);
}
- if ((fd = accept(vio->fd, (struct sockaddr *)&newvio->addr.addr, &(newvio->addr.addrlen))) < 0)
+ if ((afd = accept(fd, (struct sockaddr *) &newvio->addr.addr, &(newvio->addr.addrlen))) < 0)
{
if (!mowgli_eventloop_ignore_errno(errno))
return mowgli_vio_err_errcode(vio, strerror, errno);
@@ -212,14 +252,14 @@ static int mowgli_vio_openssl_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
return 0;
}
- newvio->fd = fd;
+ newvio->io.fd = afd;
- mowgli_vio_openssl_setssl(newvio, &connection->settings);
+ mowgli_vio_openssl_setssl(newvio, &connection->settings, vio->ops);
newconnection = newvio->privdata;
newconnection->ssl_context = connection->ssl_context;
newconnection->ssl_handle = SSL_new(newconnection->ssl_context);
-
- if (!SSL_set_fd(newconnection->ssl_handle, fd))
+
+ if (!SSL_set_fd(newconnection->ssl_handle, afd))
return mowgli_vio_err_sslerrcode(newvio, ERR_get_error());
if ((ret = SSL_accept(newconnection->ssl_handle)) != 1)
@@ -230,9 +270,11 @@ static int mowgli_vio_openssl_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
{
case SSL_ERROR_WANT_READ:
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDREAD, true);
+ MOWGLI_VIO_SETREAD(vio)
return 0;
case SSL_ERROR_WANT_WRITE:
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, true);
+ MOWGLI_VIO_SETWRITE(vio)
return 0;
case SSL_ERROR_ZERO_RETURN:
return 0;
@@ -243,7 +285,7 @@ static int mowgli_vio_openssl_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
break;
}
- if(err > 0)
+ if (err > 0)
{
errno = EIO;
return mowgli_vio_err_errcode(vio, strerror, errno);
@@ -259,8 +301,10 @@ static int mowgli_vio_openssl_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
return 0;
}
-static int mowgli_vio_openssl_client_handshake(mowgli_vio_t *vio, mowgli_ssl_connection_t *connection)
+static int
+mowgli_vio_openssl_client_handshake(mowgli_vio_t *vio, mowgli_ssl_connection_t *connection)
{
+ const int fd = mowgli_vio_getfd(vio);
int ret;
const SSL_METHOD *method;
@@ -280,41 +324,56 @@ static int mowgli_vio_openssl_client_handshake(mowgli_vio_t *vio, mowgli_ssl_con
method = TLSv1_client_method();
break;
default:
+
/* Compat method */
method = SSLv23_client_method();
}
/* Cast is to eliminate an excessively bogus warning on old OpenSSL --Elizacat */
- connection->ssl_context = SSL_CTX_new((SSL_METHOD *)method);
+ connection->ssl_context = SSL_CTX_new((SSL_METHOD *) method);
+
if (connection->ssl_context == NULL)
return mowgli_vio_err_sslerrcode(vio, ERR_get_error());
connection->ssl_handle = SSL_new(connection->ssl_context);
+
if (connection->ssl_handle == NULL)
return mowgli_vio_err_sslerrcode(vio, ERR_get_error());
-
+
SSL_set_connect_state(connection->ssl_handle);
-
- if (!SSL_set_fd(connection->ssl_handle, vio->fd))
+
+ if (!SSL_set_fd(connection->ssl_handle, fd))
return mowgli_vio_err_sslerrcode(vio, ERR_get_error());
- /* XXX not what we want for blocking sockets if they're in use! */
- SSL_CTX_set_mode(connection->ssl_context, SSL_MODE_ENABLE_PARTIAL_WRITE);
+ if (vio->eventloop)
+ SSL_CTX_set_mode(connection->ssl_context, SSL_MODE_ENABLE_PARTIAL_WRITE);
if ((ret = SSL_connect(connection->ssl_handle)) != 1)
{
- int err = SSL_get_error(connection->ssl_handle, ret);
+ unsigned long err = SSL_get_error(connection->ssl_handle, ret);
+
if (err == SSL_ERROR_WANT_READ)
+ {
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDREAD, true);
+ MOWGLI_VIO_SETREAD(vio)
+ }
else if (err == SSL_ERROR_WANT_WRITE)
+ {
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, true);
+ MOWGLI_VIO_SETWRITE(vio)
+ }
else if (err == SSL_ERROR_WANT_CONNECT)
{
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCONNECTING, true);
return 0;
}
else
+ {
return mowgli_vio_err_sslerrcode(vio, err);
+ }
+
+ mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISSSLCONNECTING, false);
+ return 0;
}
/* Connected */
@@ -324,22 +383,25 @@ static int mowgli_vio_openssl_client_handshake(mowgli_vio_t *vio, mowgli_ssl_con
return 0;
}
-#define MOWGLI_VIO_SSL_DOREAD true
-#define MOWGLI_VIO_SSL_DOWRITE false
+# define MOWGLI_VIO_SSL_DOREAD true
+# define MOWGLI_VIO_SSL_DOWRITE false
-static int mowgli_vio_openssl_read(mowgli_vio_t *vio, void *buffer, size_t len)
+int
+mowgli_vio_openssl_default_read(mowgli_vio_t *vio, void *buffer, size_t len)
{
vio->error.op = MOWGLI_VIO_ERR_OP_READ;
return mowgli_openssl_read_or_write(MOWGLI_VIO_SSL_DOREAD, vio, buffer, NULL, len);
}
-static int mowgli_vio_openssl_write(mowgli_vio_t *vio, const void *buffer, size_t len)
+int
+mowgli_vio_openssl_default_write(mowgli_vio_t *vio, const void *buffer, size_t len)
{
vio->error.op = MOWGLI_VIO_ERR_OP_WRITE;
return mowgli_openssl_read_or_write(MOWGLI_VIO_SSL_DOWRITE, vio, NULL, buffer, len);
}
-static int mowgli_openssl_read_or_write(bool read, mowgli_vio_t *vio, void *readbuf, const void *writebuf, size_t len)
+static int
+mowgli_openssl_read_or_write(bool read, mowgli_vio_t *vio, void *readbuf, const void *writebuf, size_t len)
{
mowgli_ssl_connection_t *connection = vio->privdata;
int ret;
@@ -353,10 +415,15 @@ static int mowgli_openssl_read_or_write(bool read, mowgli_vio_t *vio, void *read
return_val_if_fail(connection->ssl_handle != NULL, -1);
- if(read)
- ret = (int)SSL_read(connection->ssl_handle, readbuf, len);
+ if (read)
+ {
+ ret = (int) SSL_read(connection->ssl_handle, readbuf, len);
+ }
else
- ret = (int)SSL_write(connection->ssl_handle, writebuf, len);
+ {
+ ret = (int) SSL_write(connection->ssl_handle, writebuf, len);
+ MOWGLI_VIO_UNSETWRITE(vio)
+ }
if (ret < 0)
{
@@ -364,32 +431,34 @@ static int mowgli_openssl_read_or_write(bool read, mowgli_vio_t *vio, void *read
{
case SSL_ERROR_WANT_READ:
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDREAD, true);
+ MOWGLI_VIO_SETREAD(vio)
return 0;
case SSL_ERROR_WANT_WRITE:
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, true);
+ MOWGLI_VIO_SETWRITE(vio)
return 0;
case SSL_ERROR_ZERO_RETURN:
return 0;
case SSL_ERROR_SYSCALL:
- if((err = ERR_get_error()) == 0)
+
+ if ((err = ERR_get_error()) == 0)
{
vio->error.type = MOWGLI_VIO_ERR_REMOTE_HANGUP;
mowgli_strlcpy(vio->error.string, "Remote host closed the socket", sizeof(vio->error.string));
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCONNECTING, false);
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCLOSED, true);
-
+ MOWGLI_VIO_SET_CLOSED(vio);
+
return mowgli_vio_error(vio);
}
break;
-
+
default:
err = ERR_get_error();
break;
}
- if(err > 0)
+ if (err > 0)
{
errno = EIO;
return mowgli_vio_err_errcode(vio, strerror, errno);
@@ -405,8 +474,10 @@ static int mowgli_openssl_read_or_write(bool read, mowgli_vio_t *vio, void *read
return ret;
}
-static int mowgli_vio_openssl_close(mowgli_vio_t *vio)
+int
+mowgli_vio_openssl_default_close(mowgli_vio_t *vio)
{
+ const int fd = mowgli_vio_getfd(vio);
mowgli_ssl_connection_t *connection = vio->privdata;
return_val_if_fail(connection->ssl_handle != NULL, -1);
@@ -419,29 +490,32 @@ static int mowgli_vio_openssl_close(mowgli_vio_t *vio)
MOWGLI_VIO_SET_CLOSED(vio);
- close(vio->fd);
+ /* FIXME - doesn't verify a proper SSL shutdown! */
+ close(fd);
return 0;
}
#else
-int mowgli_vio_openssl_setssl(mowgli_vio_t *vio, mowgli_vio_ssl_settings_t *settings)
+int
+mowgli_vio_openssl_setssl(mowgli_vio_t *vio, mowgli_vio_ssl_settings_t *settings, mowgli_vio_ops_t *ops)
{
mowgli_log("OpenSSL requested on a VIO object, but mowgli was built without OpenSSL support...");
return -1;
}
-void * mowgli_vio_openssl_getsslhandle(mowgli_vio_t *vio)
+void *
+mowgli_vio_openssl_getsslhandle(mowgli_vio_t *vio)
{
mowgli_log("Cannot get VIO SSL handle as libmowgli was built without OpenSSL support");
return NULL;
}
-void * mowgli_vio_openssl_getsslcontext(mowgli_vio_t *vio)
+void *
+mowgli_vio_openssl_getsslcontext(mowgli_vio_t *vio)
{
mowgli_log("Cannot get VIO SSL context as libmowgli was built without OpenSSL support");
return NULL;
}
#endif
-
diff --git a/src/libmowgli/vio/vio_sockets.c b/src/libmowgli/vio/vio_sockets.c
index e36080b..b741113 100644
--- a/src/libmowgli/vio/vio_sockets.c
+++ b/src/libmowgli/vio/vio_sockets.c
@@ -23,10 +23,13 @@
#include "mowgli.h"
-int mowgli_vio_default_socket(mowgli_vio_t *vio, int family, int type, int proto)
+int
+mowgli_vio_default_socket(mowgli_vio_t *vio, int family, int type, int proto)
{
int fd;
+ return_val_if_fail(vio, -255);
+
vio->error.op = MOWGLI_VIO_ERR_OP_SOCKET;
/* We can't call socket with AF_UNSPEC on most platforms >_> */
@@ -36,9 +39,9 @@ int mowgli_vio_default_socket(mowgli_vio_t *vio, int family, int type, int proto
if ((fd = socket(family, type, proto)) == -1)
return mowgli_vio_err_errcode(vio, strerror, errno);
- vio->fd = fd;
+ vio->io.fd = fd;
- if (family == SOCK_STREAM)
+ if (type == SOCK_STREAM)
{
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCONNECTING, false);
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCLOSED, false);
@@ -48,11 +51,16 @@ int mowgli_vio_default_socket(mowgli_vio_t *vio, int family, int type, int proto
return 0;
}
-int mowgli_vio_default_bind(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr)
+int
+mowgli_vio_default_bind(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr)
{
+ const int fd = mowgli_vio_getfd(vio);
+
+ return_val_if_fail(fd != -1, -255);
+
vio->error.op = MOWGLI_VIO_ERR_OP_BIND;
- if (bind(vio->fd, (struct sockaddr *)&addr->addr, addr->addrlen) != 0)
+ if (bind(fd, (struct sockaddr *) &addr->addr, addr->addrlen) != 0)
return mowgli_vio_err_errcode(vio, strerror, errno);
memcpy(&vio->addr.addr, &addr->addr, sizeof(struct sockaddr_storage));
@@ -61,11 +69,16 @@ int mowgli_vio_default_bind(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr)
return 0;
}
-int mowgli_vio_default_listen(mowgli_vio_t *vio, int backlog)
+int
+mowgli_vio_default_listen(mowgli_vio_t *vio, int backlog)
{
+ const int fd = mowgli_vio_getfd(vio);
+
+ return_val_if_fail(fd != -1, -255);
+
vio->error.op = MOWGLI_VIO_ERR_OP_LISTEN;
- if (listen(vio->fd, backlog) < 0)
+ if (listen(fd, backlog) < 0)
return mowgli_vio_err_errcode(vio, strerror, errno);
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISSERVER, true);
@@ -76,9 +89,13 @@ int mowgli_vio_default_listen(mowgli_vio_t *vio, int backlog)
return 0;
}
-int mowgli_vio_default_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
+int
+mowgli_vio_default_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
{
- int fd;
+ const int fd = mowgli_vio_getfd(vio);
+ int afd;
+
+ return_val_if_fail(fd != -1, -255);
vio->error.op = MOWGLI_VIO_ERR_OP_ACCEPT;
@@ -90,7 +107,7 @@ int mowgli_vio_default_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
return mowgli_vio_error(vio);
}
- if ((fd = accept(vio->fd, (struct sockaddr *)&newvio->addr.addr, &(newvio->addr.addrlen))) < 0)
+ if ((afd = accept(fd, (struct sockaddr *) &newvio->addr.addr, &(newvio->addr.addrlen))) < 0)
{
if (!mowgli_eventloop_ignore_errno(errno))
return mowgli_vio_err_errcode(vio, strerror, errno);
@@ -98,7 +115,7 @@ int mowgli_vio_default_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
return 0;
}
- newvio->fd = fd;
+ newvio->io.fd = afd;
/* The new VIO object is most certainly not a server */
mowgli_vio_setflag(newvio, MOWGLI_VIO_FLAGS_ISCLIENT, true);
@@ -108,11 +125,33 @@ int mowgli_vio_default_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio)
return 0;
}
-int mowgli_vio_default_connect(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr)
+int
+mowgli_vio_default_reuseaddr(mowgli_vio_t *vio)
+{
+ int fd = mowgli_vio_getfd(vio);
+ int reuse = 1;
+
+ return_val_if_fail(fd != -1, -255);
+
+ vio->error.op = MOWGLI_VIO_ERR_OP_REUSEADDR;
+
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
+ return mowgli_vio_err_errcode(vio, strerror, errno);
+
+ vio->error.op = MOWGLI_VIO_ERR_OP_NONE;
+ return 0;
+}
+
+int
+mowgli_vio_default_connect(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr)
{
+ const int fd = mowgli_vio_getfd(vio);
+
+ return_val_if_fail(fd != -1, -255);
+
vio->error.op = MOWGLI_VIO_ERR_OP_CONNECT;
- if (connect(vio->fd, (struct sockaddr *)&addr->addr, addr->addrlen) < 0)
+ if (connect(fd, (struct sockaddr *) &addr->addr, addr->addrlen) < 0)
{
if (!mowgli_eventloop_ignore_errno(errno))
return mowgli_vio_err_errcode(vio, strerror, errno);
@@ -134,29 +173,31 @@ int mowgli_vio_default_connect(mowgli_vio_t *vio, mowgli_vio_sockaddr_t *addr)
return 0;
}
-int mowgli_vio_default_read(mowgli_vio_t *vio, void *buffer, size_t len)
+int
+mowgli_vio_default_read(mowgli_vio_t *vio, void *buffer, size_t len)
{
+ const int fd = mowgli_vio_getfd(vio);
int ret;
+ return_val_if_fail(fd != -1, -255);
+
vio->error.op = MOWGLI_VIO_ERR_OP_READ;
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCONNECTING, false);
- if ((ret = (int)recv(vio->fd, buffer, len, 0)) < 0)
+ if ((ret = (int) recv(fd, buffer, len, 0)) <= 0)
{
- if (!mowgli_eventloop_ignore_errno(errno))
- {
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDREAD, false);
- return mowgli_vio_err_errcode(vio, strerror, errno);
- }
- else if (errno != 0)
+ mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDREAD, false);
+
+ if (ret < 0)
{
- /* Further reads unnecessary */
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDREAD, false);
- return 0;
+ if (!mowgli_eventloop_ignore_errno(errno))
+ return mowgli_vio_err_errcode(vio, strerror, errno);
+ else if (errno != 0)
+ /* Further reads unnecessary */
+ return 0;
}
-
- if (ret == 0)
+ else
{
vio->error.type = MOWGLI_VIO_ERR_REMOTE_HANGUP;
mowgli_strlcpy(vio->error.string, "Remote host closed the socket", sizeof(vio->error.string));
@@ -174,94 +215,105 @@ int mowgli_vio_default_read(mowgli_vio_t *vio, void *buffer, size_t len)
return ret;
}
-int mowgli_vio_default_write(mowgli_vio_t *vio, const void *buffer, size_t len)
+int
+mowgli_vio_default_write(mowgli_vio_t *vio, const void *buffer, size_t len)
{
+ const int fd = mowgli_vio_getfd(vio);
int ret;
+ return_val_if_fail(fd != -1, -255);
+
vio->error.op = MOWGLI_VIO_ERR_OP_WRITE;
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCONNECTING, false);
- if ((ret = (int)send(vio->fd, buffer, len, 0)) == -1)
+ if ((ret = (int) send(fd, buffer, len, 0)) == -1)
{
+ mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, false);
+ MOWGLI_VIO_UNSETWRITE(vio)
+
if (!mowgli_eventloop_ignore_errno(errno))
- {
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, false);
return mowgli_vio_err_errcode(vio, strerror, errno);
- }
else
- {
/* Further writes unnecessary */
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, false);
return 0;
- }
}
/* Set this for edge-triggered interfaces */
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, true);
+ if (ret < (int) len)
+ {
+ mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, true);
+ MOWGLI_VIO_SETWRITE(vio)
+ }
vio->error.op = MOWGLI_VIO_ERR_OP_NONE;
return ret;
}
-int mowgli_vio_default_sendto(mowgli_vio_t *vio, const void *buffer, size_t len, mowgli_vio_sockaddr_t *addr)
+int
+mowgli_vio_default_sendto(mowgli_vio_t *vio, const void *buffer, size_t len, mowgli_vio_sockaddr_t *addr)
{
+ const int fd = mowgli_vio_getfd(vio);
int ret;
+ return_val_if_fail(fd != -1, -255);
+
vio->error.op = MOWGLI_VIO_ERR_OP_WRITE;
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCONNECTING, false);
- if ((ret = (int)sendto(vio->fd, buffer, len, 0, (struct sockaddr *)&addr->addr, addr->addrlen)) == -1)
+ if ((ret = (int) sendto(fd, buffer, len, 0, (struct sockaddr *) &addr->addr, addr->addrlen)) == -1)
{
+ mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, false);
+ MOWGLI_VIO_UNSETWRITE(vio)
+
if (!mowgli_eventloop_ignore_errno(errno))
- {
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, false);
return mowgli_vio_err_errcode(vio, strerror, errno);
- }
else
- {
/* Further writes unnecessary */
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, false);
return 0;
- }
}
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, true);
+ if (ret < (int) len)
+ {
+ mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, true);
+ MOWGLI_VIO_SETWRITE(vio)
+ }
vio->error.op = MOWGLI_VIO_ERR_OP_NONE;
return ret;
}
-int mowgli_vio_default_recvfrom(mowgli_vio_t *vio, void *buffer, size_t len, mowgli_vio_sockaddr_t *addr)
+int
+mowgli_vio_default_recvfrom(mowgli_vio_t *vio, void *buffer, size_t len, mowgli_vio_sockaddr_t *addr)
{
+ const int fd = mowgli_vio_getfd(vio);
int ret;
+ return_val_if_fail(fd != -1, -255);
+
vio->error.op = MOWGLI_VIO_ERR_OP_READ;
mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCONNECTING, false);
- if ((ret = (int)recvfrom(vio->fd, buffer, len, 0, (struct sockaddr *)&addr->addr, &addr->addrlen)) < 0)
+ if ((ret = (int) recvfrom(fd, buffer, len, 0, (struct sockaddr *) &addr->addr, &addr->addrlen)) < 0)
{
- if (!mowgli_eventloop_ignore_errno(errno))
- {
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDREAD, false);
- return mowgli_vio_err_errcode(vio, strerror, errno);
- }
- else if (errno != 0)
+ mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDREAD, false);
+
+ if (ret < 0)
{
- /* Further reads unnecessary */
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDREAD, false);
- return 0;
+ if (!mowgli_eventloop_ignore_errno(errno))
+ return mowgli_vio_err_errcode(vio, strerror, errno);
+ else if (errno != 0)
+ /* Further reads unnecessary */
+ return 0;
}
-
- if (ret == 0)
+ else
{
vio->error.type = MOWGLI_VIO_ERR_REMOTE_HANGUP;
mowgli_strlcpy(vio->error.string, "Remote host closed the socket", sizeof(vio->error.string));
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCONNECTING, false);
- mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISCLOSED, true);
+ MOWGLI_VIO_SET_CLOSED(vio);
return mowgli_vio_error(vio);
}
@@ -273,7 +325,8 @@ int mowgli_vio_default_recvfrom(mowgli_vio_t *vio, void *buffer, size_t len, mow
return ret;
}
-int mowgli_vio_default_error(mowgli_vio_t *vio)
+int
+mowgli_vio_default_error(mowgli_vio_t *vio)
{
const char *errtype;
@@ -312,76 +365,90 @@ int mowgli_vio_default_error(mowgli_vio_t *vio)
return -1;
}
-int mowgli_vio_default_close(mowgli_vio_t *vio)
+int
+mowgli_vio_default_close(mowgli_vio_t *vio)
{
+ const int fd = mowgli_vio_getfd(vio);
+
+ return_val_if_fail(fd != -1, -255);
+
MOWGLI_VIO_SET_CLOSED(vio);
#ifndef _WIN32
- close(vio->fd);
+ close(fd);
#else
- closesocket(vio->fd);
+ closesocket(fd);
#endif
return 0;
}
-int mowgli_vio_default_seek(mowgli_vio_t *vio, long offset, int whence)
+int
+mowgli_vio_default_seek(mowgli_vio_t *vio, long offset, int whence)
{
+ return_val_if_fail(vio, -255);
vio->error.op = MOWGLI_VIO_ERR_OP_SEEK;
errno = ENOSYS;
return mowgli_vio_err_errcode(vio, strerror, errno);
}
-int mowgli_vio_default_tell(mowgli_vio_t *vio)
+int
+mowgli_vio_default_tell(mowgli_vio_t *vio)
{
+ return_val_if_fail(vio, -255);
vio->error.op = MOWGLI_VIO_ERR_OP_TELL;
errno = ENOSYS;
return mowgli_vio_err_errcode(vio, strerror, errno);
}
/* Generate a mowgli_sockaddr_t struct */
-mowgli_vio_sockaddr_t * mowgli_vio_sockaddr_create(mowgli_vio_sockaddr_t *naddr, int proto, const char *addr, int port)
+mowgli_vio_sockaddr_t *
+mowgli_vio_sockaddr_create(mowgli_vio_sockaddr_t *naddr, int proto, const char *addr, int port)
{
struct sockaddr_storage saddr;
+ return_val_if_fail(naddr, NULL);
+ return_val_if_fail(addr, NULL);
+
if (naddr == NULL)
naddr = mowgli_alloc(sizeof(mowgli_vio_sockaddr_t));
if (proto == AF_INET)
{
- struct sockaddr_in *addr_in = (struct sockaddr_in *)&saddr;
+ struct sockaddr_in *addr_in = (struct sockaddr_in *) &saddr;
addr_in->sin_family = proto;
addr_in->sin_port = htons(port);
+
if (addr != NULL)
- {
if (inet_pton(proto, addr, &addr_in->sin_addr) != 1)
mowgli_log("Error with inet_pton!");
- }
memcpy(&naddr->addr, &saddr, sizeof(struct sockaddr_in));
naddr->addrlen = sizeof(struct sockaddr_in);
}
else if (proto == AF_INET6)
{
- struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&saddr;
+ struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *) &saddr;
addr_in6->sin6_family = proto;
addr_in6->sin6_port = htons(port);
+
if (addr != NULL)
- {
if (inet_pton(proto, addr, &addr_in6->sin6_addr) != 1)
mowgli_log("Error with inet_pton!");
- }
memcpy(&naddr->addr, &saddr, sizeof(struct sockaddr_in6));
naddr->addrlen = sizeof(struct sockaddr_in6);
}
else
+ {
naddr = NULL;
+ }
return naddr;
}
-mowgli_vio_sockaddr_t * mowgli_vio_sockaddr_from_struct(mowgli_vio_sockaddr_t *naddr, const void *addr, socklen_t size)
+mowgli_vio_sockaddr_t *
+mowgli_vio_sockaddr_from_struct(mowgli_vio_sockaddr_t *naddr, const void *addr, socklen_t size)
{
const struct sockaddr_storage *saddr = addr;
@@ -390,31 +457,39 @@ mowgli_vio_sockaddr_t * mowgli_vio_sockaddr_from_struct(mowgli_vio_sockaddr_t *n
if (naddr == NULL)
naddr = mowgli_alloc(sizeof(mowgli_vio_sockaddr_t));
+
memcpy(&naddr->addr, saddr, size);
naddr->addrlen = size;
return naddr;
}
-int mowgli_vio_sockaddr_info(const mowgli_vio_sockaddr_t *addr, mowgli_vio_sockdata_t *data)
+int
+mowgli_vio_sockaddr_info(const mowgli_vio_sockaddr_t *addr, mowgli_vio_sockdata_t *data)
{
const void *sockptr;
- const struct sockaddr *saddr = (const struct sockaddr *)&addr->addr;
+
+ return_val_if_fail(addr, -255);
+ return_val_if_fail(data, -255);
+
+ const struct sockaddr *saddr = (const struct sockaddr *) &addr->addr;
if (saddr->sa_family == AF_INET)
{
- const struct sockaddr_in *saddr = (const struct sockaddr_in *)&addr->addr;
+ const struct sockaddr_in *saddr = (const struct sockaddr_in *) &addr->addr;
data->port = ntohs(saddr->sin_port);
sockptr = &saddr->sin_addr;
}
else if (saddr->sa_family == AF_INET6)
{
- const struct sockaddr_in6 *saddr = (const struct sockaddr_in6 *)&addr->addr;
+ const struct sockaddr_in6 *saddr = (const struct sockaddr_in6 *) &addr->addr;
data->port = ntohs(saddr->sin6_port);
sockptr = &saddr->sin6_addr;
}
else
+ {
return -1;
+ }
if (inet_ntop(saddr->sa_family, sockptr, data->host, sizeof(data->host)) == NULL)
return -1;
diff --git a/uncrustify.cfg b/uncrustify.cfg
new file mode 100644
index 0000000..74b1d3c
--- /dev/null
+++ b/uncrustify.cfg
@@ -0,0 +1,1578 @@
+# Uncrustify 0.60
+
+#
+# General options
+#
+
+# The type of line endings
+newlines = lf # auto/lf/crlf/cr
+
+# The original size of tabs in the input
+input_tab_size = 8 # number
+
+# The size of tabs in the output (only used if align_with_tabs=true)
+output_tab_size = 8 # number
+
+# The ASCII value of the string escape char, usually 92 (\) or 94 (^). (Pawn)
+string_escape_char = 92 # number
+
+# Alternate string escape char for Pawn. Only works right before the quote char.
+string_escape_char2 = 0 # number
+
+# Allow interpreting '>=' and '>>=' as part of a template in 'void f(list<list<B>>=val);'.
+# If true (default), 'assert(x<0 && y>=3)' will be broken.
+# Improvements to template detection may make this option obsolete.
+tok_split_gte = false # false/true
+
+# Control what to do with the UTF-8 BOM (recommend 'remove')
+utf8_bom = remove # ignore/add/remove/force
+
+# If the file contains bytes with values between 128 and 255, but is not UTF-8, then output as UTF-8
+utf8_byte = true # false/true
+
+# Force the output encoding to UTF-8
+utf8_force = false # false/true
+
+#
+# Indenting
+#
+
+# The number of columns to indent per level.\Uffffffff
+# Usually 2, 3, 4, or 8.
+indent_columns = 8 # number
+
+# The continuation indent. If non-zero, this overrides the indent of '(' and '=' continuation indents.
+# For FreeBSD, this is set to 4. Negative value is absolute and not increased for each ( level
+indent_continue = 0 # number
+
+# How to use tabs when indenting code
+# 0=spaces only
+# 1=indent with tabs to brace level, align with spaces
+# 2=indent and align with tabs, using spaces when not on a tabstop
+indent_with_tabs = 2 # number
+
+# Comments that are not a brace level are indented with tabs on a tabstop.
+# Requires indent_with_tabs=2. If false, will use spaces.
+indent_cmt_with_tabs = true # false/true
+
+# Whether to indent strings broken by '\' so that they line up
+indent_align_string = false # false/true
+
+# The number of spaces to indent multi-line XML strings.
+# Requires indent_align_string=True
+indent_xml_string = 0 # number
+
+# Spaces to indent '{' from level
+indent_brace = 0 # number
+
+# Whether braces are indented to the body level
+indent_braces = false # false/true
+
+# Disabled indenting function braces if indent_braces is true
+indent_braces_no_func = false # false/true
+
+# Disabled indenting class braces if indent_braces is true
+indent_braces_no_class = false # false/true
+
+# Disabled indenting struct braces if indent_braces is true
+indent_braces_no_struct = false # false/true
+
+# Indent based on the size of the brace parent, i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc.
+indent_brace_parent = false # false/true
+
+# Whether the 'namespace' body is indented
+indent_namespace = false # false/true
+
+# The number of spaces to indent a namespace block
+indent_namespace_level = 0 # number
+
+# If the body of the namespace is longer than this number, it won't be indented.
+# Requires indent_namespace=true. Default=0 (no limit)
+indent_namespace_limit = 0 # number
+
+# Whether the 'extern "C"' body is indented
+indent_extern = false # false/true
+
+# Whether the 'class' body is indented
+indent_class = false # false/true
+
+# Whether to indent the stuff after a leading class colon
+indent_class_colon = false # false/true
+
+# Virtual indent from the ':' for member initializers. Default is 2
+indent_ctor_init_leading = 2 # number
+
+# Additional indenting for constructor initializer list
+indent_ctor_init = 0 # number
+
+# False=treat 'else\nif' as 'else if' for indenting purposes
+# True=indent the 'if' one level
+indent_else_if = false # false/true
+
+# Amount to indent variable declarations after a open brace. neg=relative, pos=absolute
+indent_var_def_blk = 0 # number
+
+# Indent continued variable declarations instead of aligning.
+indent_var_def_cont = false # false/true
+
+# True: force indentation of function definition to start in column 1
+# False: use the default behavior
+indent_func_def_force_col1 = false # false/true
+
+# True: indent continued function call parameters one indent level
+# False: align parameters under the open paren
+indent_func_call_param = false # false/true
+
+# Same as indent_func_call_param, but for function defs
+indent_func_def_param = false # false/true
+
+# Same as indent_func_call_param, but for function protos
+indent_func_proto_param = false # false/true
+
+# Same as indent_func_call_param, but for class declarations
+indent_func_class_param = false # false/true
+
+# Same as indent_func_call_param, but for class variable constructors
+indent_func_ctor_var_param = false # false/true
+
+# Same as indent_func_call_param, but for templates
+indent_template_param = false # false/true
+
+# Double the indent for indent_func_xxx_param options
+indent_func_param_double = false # false/true
+
+# Indentation column for standalone 'const' function decl/proto qualifier
+indent_func_const = 0 # number
+
+# Indentation column for standalone 'throw' function decl/proto qualifier
+indent_func_throw = 0 # number
+
+# The number of spaces to indent a continued '->' or '.'
+# Usually set to 0, 1, or indent_columns.
+indent_member = 0 # number
+
+# Spaces to indent single line ('//') comments on lines before code
+indent_sing_line_comments = 0 # number
+
+# If set, will indent trailing single line ('//') comments relative
+# to the code instead of trying to keep the same absolute column
+indent_relative_single_line_comments = false # false/true
+
+# Spaces to indent 'case' from 'switch'
+# Usually 0 or indent_columns.
+indent_switch_case = 0 # number
+
+# Spaces to shift the 'case' line, without affecting any other lines
+# Usually 0.
+indent_case_shift = 0 # number
+
+# Spaces to indent '{' from 'case'.
+# By default, the brace will appear under the 'c' in case.
+# Usually set to 0 or indent_columns.
+indent_case_brace = 0 # number
+
+# Whether to indent comments found in first column
+indent_col1_comment = false # false/true
+
+# How to indent goto labels
+# >0 : absolute column where 1 is the leftmost column
+# <=0 : subtract from brace indent
+indent_label = 1 # number
+
+# Same as indent_label, but for access specifiers that are followed by a colon
+indent_access_spec = 1 # number
+
+# Indent the code after an access specifier by one level.
+# If set, this option forces 'indent_access_spec=0'
+indent_access_spec_body = false # false/true
+
+# If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended)
+indent_paren_nl = false # false/true
+
+# Controls the indent of a close paren after a newline.
+# 0: Indent to body level
+# 1: Align under the open paren
+# 2: Indent to the brace level
+indent_paren_close = 0 # number
+
+# Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren
+indent_comma_paren = false # false/true
+
+# Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren
+indent_bool_paren = false # false/true
+
+# If 'indent_bool_paren' is true, controls the indent of the first expression. If TRUE, aligns the first expression to the following ones
+indent_first_bool_expr = false # false/true
+
+# If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended)
+indent_square_nl = false # false/true
+
+# Don't change the relative indent of ESQL/C 'EXEC SQL' bodies
+indent_preserve_sql = false # false/true
+
+# Align continued statements at the '='. Default=True
+# If FALSE or the '=' is followed by a newline, the next line is indent one tab.
+indent_align_assign = true # false/true
+
+# Indent OC blocks at brace level instead of usual rules.
+indent_oc_block = false # false/true
+
+# Indent OC blocks in a message relative to the parameter name.
+# 0=use indent_oc_block rules, 1+=spaces to indent
+indent_oc_block_msg = 0 # number
+
+# Minimum indent for subsequent parameters
+indent_oc_msg_colon = 0 # number
+
+#
+# Spacing options
+#
+
+# Add or remove space around arithmetic operator '+', '-', '/', '*', etc
+sp_arith = force # ignore/add/remove/force
+
+# Add or remove space around assignment operator '=', '+=', etc
+sp_assign = force # ignore/add/remove/force
+
+# Add or remove space around '=' in C++11 lambda capture specifications. Overrides sp_assign
+sp_cpp_lambda_assign = ignore # ignore/add/remove/force
+
+# Add or remove space after the capture specification in C++11 lambda.
+sp_cpp_lambda_paren = ignore # ignore/add/remove/force
+
+# Add or remove space around assignment operator '=' in a prototype
+sp_assign_default = force # ignore/add/remove/force
+
+# Add or remove space before assignment operator '=', '+=', etc. Overrides sp_assign.
+sp_before_assign = force # ignore/add/remove/force
+
+# Add or remove space after assignment operator '=', '+=', etc. Overrides sp_assign.
+sp_after_assign = force # ignore/add/remove/force
+
+# Add or remove space around assignment '=' in enum
+sp_enum_assign = force # ignore/add/remove/force
+
+# Add or remove space before assignment '=' in enum. Overrides sp_enum_assign.
+sp_enum_before_assign = force # ignore/add/remove/force
+
+# Add or remove space after assignment '=' in enum. Overrides sp_enum_assign.
+sp_enum_after_assign = force # ignore/add/remove/force
+
+# Add or remove space around preprocessor '##' concatenation operator. Default=Add
+sp_pp_concat = remove # ignore/add/remove/force
+
+# Add or remove space after preprocessor '#' stringify operator. Also affects the '#@' charizing operator.
+sp_pp_stringify = remove # ignore/add/remove/force
+
+# Add or remove space before preprocessor '#' stringify operator as in '#define x(y) L#y'.
+sp_before_pp_stringify = remove # ignore/add/remove/force
+
+# Add or remove space around boolean operators '&&' and '||'
+sp_bool = force # ignore/add/remove/force
+
+# Add or remove space around compare operator '<', '>', '==', etc
+sp_compare = force # ignore/add/remove/force
+
+# Add or remove space inside '(' and ')'
+sp_inside_paren = remove # ignore/add/remove/force
+
+# Add or remove space between nested parens
+sp_paren_paren = remove # ignore/add/remove/force
+
+# Whether to balance spaces inside nested parens
+sp_balance_nested_parens = false # false/true
+
+# Add or remove space between ')' and '{'
+sp_paren_brace = force # ignore/add/remove/force
+
+# Add or remove space before pointer star '*'
+sp_before_ptr_star = force # ignore/add/remove/force
+
+# Add or remove space before pointer star '*' that isn't followed by a variable name
+# If set to 'ignore', sp_before_ptr_star is used instead.
+sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force
+
+# Add or remove space between pointer stars '*'
+sp_between_ptr_star = remove # ignore/add/remove/force
+
+# Add or remove space after pointer star '*', if followed by a word.
+sp_after_ptr_star = remove # ignore/add/remove/force
+
+# Add or remove space after a pointer star '*', if followed by a func proto/def.
+sp_after_ptr_star_func = remove # ignore/add/remove/force
+
+# Add or remove space after a pointer star '*', if followed by an open paren (function types).
+sp_ptr_star_paren = remove # ignore/add/remove/force
+
+# Add or remove space before a pointer star '*', if followed by a func proto/def.
+sp_before_ptr_star_func = add # ignore/add/remove/force
+
+# Add or remove space before a reference sign '&'
+sp_before_byref = add # ignore/add/remove/force
+
+# Add or remove space before a reference sign '&' that isn't followed by a variable name
+# If set to 'ignore', sp_before_byref is used instead.
+sp_before_unnamed_byref = ignore # ignore/add/remove/force
+
+# Add or remove space after reference sign '&', if followed by a word.
+sp_after_byref = remove # ignore/add/remove/force
+
+# Add or remove space after a reference sign '&', if followed by a func proto/def.
+sp_after_byref_func = remove # ignore/add/remove/force
+
+# Add or remove space before a reference sign '&', if followed by a func proto/def.
+sp_before_byref_func = remove # ignore/add/remove/force
+
+# Add or remove space between type and word. Default=Force
+sp_after_type = force # ignore/add/remove/force
+
+# Add or remove space before the paren in the D constructs 'template Foo(' and 'class Foo('.
+sp_before_template_paren = remove # ignore/add/remove/force
+
+# Add or remove space in 'template <' vs 'template<'.
+# If set to ignore, sp_before_angle is used.
+sp_template_angle = remove # ignore/add/remove/force
+
+# Add or remove space before '<>'
+sp_before_angle = remove # ignore/add/remove/force
+
+# Add or remove space inside '<' and '>'
+sp_inside_angle = remove # ignore/add/remove/force
+
+# Add or remove space after '<>'
+sp_after_angle = remove # ignore/add/remove/force
+
+# Add or remove space between '<>' and '(' as found in 'new List<byte>();'
+sp_angle_paren = remove # ignore/add/remove/force
+
+# Add or remove space between '<>' and a word as in 'List<byte> m;'
+sp_angle_word = force # ignore/add/remove/force
+
+# Add or remove space between '>' and '>' in '>>' (template stuff C++/C# only). Default=Add
+sp_angle_shift = force # ignore/add/remove/force
+
+# Permit removal of the space between '>>' in 'foo<bar<int> >' (C++11 only). Default=False
+# sp_angle_shift cannot remove the space without this option.
+sp_permit_cpp11_shift = false # false/true
+
+# Add or remove space before '(' of 'if', 'for', 'switch', and 'while'
+sp_before_sparen = force # ignore/add/remove/force
+
+# Add or remove space inside if-condition '(' and ')'
+sp_inside_sparen = remove # ignore/add/remove/force
+
+# Add or remove space before if-condition ')'. Overrides sp_inside_sparen.
+sp_inside_sparen_close = remove # ignore/add/remove/force
+
+# Add or remove space before if-condition '('. Overrides sp_inside_sparen.
+sp_inside_sparen_open = remove # ignore/add/remove/force
+
+# Add or remove space after ')' of 'if', 'for', 'switch', and 'while'
+sp_after_sparen = remove # ignore/add/remove/force
+
+# Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while'
+sp_sparen_brace = force # ignore/add/remove/force
+
+# Add or remove space between 'invariant' and '(' in the D language.
+sp_invariant_paren = remove # ignore/add/remove/force
+
+# Add or remove space after the ')' in 'invariant (C) c' in the D language.
+sp_after_invariant_paren = remove # ignore/add/remove/force
+
+# Add or remove space before empty statement ';' on 'if', 'for' and 'while'
+sp_special_semi = remove # ignore/add/remove/force
+
+# Add or remove space before ';'. Default=Remove
+sp_before_semi = remove # ignore/add/remove/force
+
+# Add or remove space before ';' in non-empty 'for' statements
+sp_before_semi_for = remove # ignore/add/remove/force
+
+# Add or remove space before a semicolon of an empty part of a for statement.
+sp_before_semi_for_empty = ignore # ignore/add/remove/force
+
+# Add or remove space after ';', except when followed by a comment. Default=Add
+sp_after_semi = force # ignore/add/remove/force
+
+# Add or remove space after ';' in non-empty 'for' statements. Default=Force
+sp_after_semi_for = force # ignore/add/remove/force
+
+# Add or remove space after the final semicolon of an empty part of a for statement: for ( ; ; <here> ).
+sp_after_semi_for_empty = remove # ignore/add/remove/force
+
+# Add or remove space before '[' (except '[]')
+sp_before_square = remove # ignore/add/remove/force
+
+# Add or remove space before '[]'
+sp_before_squares = remove # ignore/add/remove/force
+
+# Add or remove space inside a non-empty '[' and ']'
+sp_inside_square = remove # ignore/add/remove/force
+
+# Add or remove space after ','
+sp_after_comma = force # ignore/add/remove/force
+
+# Add or remove space before ','
+sp_before_comma = remove # ignore/add/remove/force
+
+# Add or remove space between an open paren and comma: '(,' vs '( ,'
+sp_paren_comma = remove # ignore/add/remove/force
+
+# Add or remove space before the variadic '...' when preceded by a non-punctuator
+sp_before_ellipsis = ignore # ignore/add/remove/force
+
+# Add or remove space after class ':'
+sp_after_class_colon = remove # ignore/add/remove/force
+
+# Add or remove space before class ':'
+sp_before_class_colon = remove # ignore/add/remove/force
+
+# Add or remove space before case ':'. Default=Remove
+sp_before_case_colon = remove # ignore/add/remove/force
+
+# Add or remove space between 'operator' and operator sign
+sp_after_operator = force # ignore/add/remove/force
+
+# Add or remove space between the operator symbol and the open paren, as in 'operator ++('
+sp_after_operator_sym = remove # ignore/add/remove/force
+
+# Add or remove space after C/D cast, i.e. 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a'
+sp_after_cast = force # ignore/add/remove/force
+
+# Add or remove spaces inside cast parens
+sp_inside_paren_cast = remove # ignore/add/remove/force
+
+# Add or remove space between the type and open paren in a C++ cast, i.e. 'int(exp)' vs 'int (exp)'
+sp_cpp_cast_paren = remove # ignore/add/remove/force
+
+# Add or remove space between 'sizeof' and '('
+sp_sizeof_paren = remove # ignore/add/remove/force
+
+# Add or remove space after the tag keyword (Pawn)
+sp_after_tag = ignore # ignore/add/remove/force
+
+# Add or remove space inside enum '{' and '}'
+sp_inside_braces_enum = remove # ignore/add/remove/force
+
+# Add or remove space inside struct/union '{' and '}'
+sp_inside_braces_struct = remove # ignore/add/remove/force
+
+# Add or remove space inside '{' and '}'
+sp_inside_braces = force # ignore/add/remove/force
+
+# Add or remove space inside '{}'
+sp_inside_braces_empty = force # ignore/add/remove/force
+
+# Add or remove space between return type and function name
+# A minimum of 1 is forced except for pointer return types.
+sp_type_func = force # ignore/add/remove/force
+
+# Add or remove space between function name and '(' on function declaration
+sp_func_proto_paren = remove # ignore/add/remove/force
+
+# Add or remove space between function name and '(' on function definition
+sp_func_def_paren = remove # ignore/add/remove/force
+
+# Add or remove space inside empty function '()'
+sp_inside_fparens = remove # ignore/add/remove/force
+
+# Add or remove space inside function '(' and ')'
+sp_inside_fparen = remove # ignore/add/remove/force
+
+# Add or remove space inside the first parens in the function type: 'void (*x)(...)'
+sp_inside_tparen = remove # ignore/add/remove/force
+
+# Add or remove between the parens in the function type: 'void (*x)(...)'
+sp_after_tparen_close = remove # ignore/add/remove/force
+
+# Add or remove space between ']' and '(' when part of a function call.
+sp_square_fparen = remove # ignore/add/remove/force
+
+# Add or remove space between ')' and '{' of function
+sp_fparen_brace = force # ignore/add/remove/force
+
+# Add or remove space between function name and '(' on function calls
+sp_func_call_paren = remove # ignore/add/remove/force
+
+# Add or remove space between function name and '()' on function calls without parameters.
+# If set to 'ignore' (the default), sp_func_call_paren is used.
+sp_func_call_paren_empty = remove # ignore/add/remove/force
+
+# Add or remove space between the user function name and '(' on function calls
+# You need to set a keyword to be a user function, like this: 'set func_call_user _' in the config file.
+sp_func_call_user_paren = ignore # ignore/add/remove/force
+
+# Add or remove space between a constructor/destructor and the open paren
+sp_func_class_paren = remove # ignore/add/remove/force
+
+# Add or remove space between 'return' and '('
+sp_return_paren = force # ignore/add/remove/force
+
+# Add or remove space between '__attribute__' and '('
+sp_attribute_paren = remove # ignore/add/remove/force
+
+# Add or remove space between 'defined' and '(' in '#if defined (FOO)'
+sp_defined_paren = remove # ignore/add/remove/force
+
+# Add or remove space between 'throw' and '(' in 'throw (something)'
+sp_throw_paren = remove # ignore/add/remove/force
+
+# Add or remove space between 'throw' and anything other than '(' as in '@throw [...];'
+sp_after_throw = remove # ignore/add/remove/force
+
+# Add or remove space between 'catch' and '(' in 'catch (something) { }'
+# If set to ignore, sp_before_sparen is used.
+sp_catch_paren = remove # ignore/add/remove/force
+
+# Add or remove space between 'version' and '(' in 'version (something) { }' (D language)
+# If set to ignore, sp_before_sparen is used.
+sp_version_paren = remove # ignore/add/remove/force
+
+# Add or remove space between 'scope' and '(' in 'scope (something) { }' (D language)
+# If set to ignore, sp_before_sparen is used.
+sp_scope_paren = remove # ignore/add/remove/force
+
+# Add or remove space between macro and value
+sp_macro = remove # ignore/add/remove/force
+
+# Add or remove space between macro function ')' and value
+sp_macro_func = remove # ignore/add/remove/force
+
+# Add or remove space between 'else' and '{' if on the same line
+sp_else_brace = force # ignore/add/remove/force
+
+# Add or remove space between '}' and 'else' if on the same line
+sp_brace_else = force # ignore/add/remove/force
+
+# Add or remove space between '}' and the name of a typedef on the same line
+sp_brace_typedef = force # ignore/add/remove/force
+
+# Add or remove space between 'catch' and '{' if on the same line
+sp_catch_brace = force # ignore/add/remove/force
+
+# Add or remove space between '}' and 'catch' if on the same line
+sp_brace_catch = force # ignore/add/remove/force
+
+# Add or remove space between 'finally' and '{' if on the same line
+sp_finally_brace = force # ignore/add/remove/force
+
+# Add or remove space between '}' and 'finally' if on the same line
+sp_brace_finally = force # ignore/add/remove/force
+
+# Add or remove space between 'try' and '{' if on the same line
+sp_try_brace = force # ignore/add/remove/force
+
+# Add or remove space between get/set and '{' if on the same line
+sp_getset_brace = force # ignore/add/remove/force
+
+# Add or remove space before the '::' operator
+sp_before_dc = remove # ignore/add/remove/force
+
+# Add or remove space after the '::' operator
+sp_after_dc = remove # ignore/add/remove/force
+
+# Add or remove around the D named array initializer ':' operator
+sp_d_array_colon = ignore # ignore/add/remove/force
+
+# Add or remove space after the '!' (not) operator. Default=Remove
+sp_not = remove # ignore/add/remove/force
+
+# Add or remove space after the '~' (invert) operator. Default=Remove
+sp_inv = remove # ignore/add/remove/force
+
+# Add or remove space after the '&' (address-of) operator. Default=Remove
+# This does not affect the spacing after a '&' that is part of a type.
+sp_addr = remove # ignore/add/remove/force
+
+# Add or remove space around the '.' or '->' operators. Default=Remove
+sp_member = remove # ignore/add/remove/force
+
+# Add or remove space after the '*' (dereference) operator. Default=Remove
+# This does not affect the spacing after a '*' that is part of a type.
+sp_deref = remove # ignore/add/remove/force
+
+# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. Default=Remove
+sp_sign = remove # ignore/add/remove/force
+
+# Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'. Default=Remove
+sp_incdec = remove # ignore/add/remove/force
+
+# Add or remove space before a backslash-newline at the end of a line. Default=Add
+sp_before_nl_cont = force # ignore/add/remove/force
+
+# Add or remove space after the scope '+' oo '-', as in '-(void) foo;' or '+(int) bar;'
+sp_after_oc_scope = remove # ignore/add/remove/force
+
+# Add or remove space after the colon in message specs
+# '-(int) f:(int) x;' vs '-(int) f: (int) x;'
+sp_after_oc_colon = force # ignore/add/remove/force
+
+# Add or remove space before the colon in message specs
+# '-(int) f: (int) x;' vs '-(int) f : (int) x;'
+sp_before_oc_colon = force # ignore/add/remove/force
+
+# Add or remove space after the colon in immutable dictionary expression
+# 'NSDictionary *test = @{@"foo" :@"bar"};'
+sp_after_oc_dict_colon = force # ignore/add/remove/force
+
+# Add or remove space before the colon in immutable dictionary expression
+# 'NSDictionary *test = @{@"foo" :@"bar"};'
+sp_before_oc_dict_colon = force # ignore/add/remove/force
+
+# Add or remove space after the colon in message specs
+# '[object setValue:1];' vs '[object setValue: 1];'
+sp_after_send_oc_colon = force # ignore/add/remove/force
+
+# Add or remove space before the colon in message specs
+# '[object setValue:1];' vs '[object setValue :1];'
+sp_before_send_oc_colon = force # ignore/add/remove/force
+
+# Add or remove space after the (type) in message specs
+# '-(int)f: (int) x;' vs '-(int)f: (int)x;'
+sp_after_oc_type = remove # ignore/add/remove/force
+
+# Add or remove space after the first (type) in message specs
+# '-(int) f:(int)x;' vs '-(int)f:(int)x;'
+sp_after_oc_return_type = force # ignore/add/remove/force
+
+# Add or remove space between '@selector' and '('
+# '@selector(msgName)' vs '@selector (msgName)'
+# Also applies to @protocol() constructs
+sp_after_oc_at_sel = remove # ignore/add/remove/force
+
+# Add or remove space between '@selector(x)' and the following word
+# '@selector(foo) a:' vs '@selector(foo)a:'
+sp_after_oc_at_sel_parens = force # ignore/add/remove/force
+
+# Add or remove space inside '@selector' parens
+# '@selector(foo)' vs '@selector( foo )'
+# Also applies to @protocol() constructs
+sp_inside_oc_at_sel_parens = remove # ignore/add/remove/force
+
+# Add or remove space before a block pointer caret
+# '^int (int arg){...}' vs. ' ^int (int arg){...}'
+sp_before_oc_block_caret = remove # ignore/add/remove/force
+
+# Add or remove space after a block pointer caret
+# '^int (int arg){...}' vs. '^ int (int arg){...}'
+sp_after_oc_block_caret = remove # ignore/add/remove/force
+
+# Add or remove space between the receiver and selector in a message.
+# '[receiver selector ...]'
+sp_after_oc_msg_receiver = force # ignore/add/remove/force
+
+# Add or remove space after @property.
+sp_after_oc_property = remove # ignore/add/remove/force
+
+# Add or remove space around the ':' in 'b ? t : f'
+sp_cond_colon = force # ignore/add/remove/force
+
+# Add or remove space around the '?' in 'b ? t : f'
+sp_cond_question = force # ignore/add/remove/force
+
+# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make sense here.
+sp_case_label = force # ignore/add/remove/force
+
+# Control the space around the D '..' operator.
+sp_range = force # ignore/add/remove/force
+
+# Control the spacing after ':' in 'for (TYPE VAR : EXPR)' (Java)
+sp_after_for_colon = force # ignore/add/remove/force
+
+# Control the spacing before ':' in 'for (TYPE VAR : EXPR)' (Java)
+sp_before_for_colon = force # ignore/add/remove/force
+
+# Control the spacing in 'extern (C)' (D)
+sp_extern_paren = remove # ignore/add/remove/force
+
+# Control the space after the opening of a C++ comment '// A' vs '//A'
+sp_cmt_cpp_start = force # ignore/add/remove/force
+
+# Controls the spaces between #else or #endif and a trailing comment
+sp_endif_cmt = force # ignore/add/remove/force
+
+# Controls the spaces after 'new', 'delete', and 'delete[]'
+sp_after_new = force # ignore/add/remove/force
+
+# Controls the spaces before a trailing or embedded comment
+sp_before_tr_emb_cmt = force # ignore/add/remove/force
+
+# Number of spaces before a trailing or embedded comment
+sp_num_before_tr_emb_cmt = 1 # number
+
+# Control space between a Java annotation and the open paren.
+sp_annotation_paren = remove # ignore/add/remove/force
+
+#
+# Code alignment (not left column spaces/tabs)
+#
+
+# Whether to keep non-indenting tabs
+align_keep_tabs = false # false/true
+
+# Whether to use tabs for aligning
+align_with_tabs = true # false/true
+
+# Whether to bump out to the next tab when aligning
+align_on_tabstop = true # false/true
+
+# Whether to left-align numbers
+align_number_left = false # false/true
+
+# Align variable definitions in prototypes and functions
+align_func_params = false # false/true
+
+# Align parameters in single-line functions that have the same name.
+# The function names must already be aligned with each other.
+align_same_func_call_params = false # false/true
+
+# The span for aligning variable definitions (0=don't align)
+align_var_def_span = 0 # number
+
+# How to align the star in variable definitions.
+# 0=Part of the type 'void * foo;'
+# 1=Part of the variable 'void *foo;'
+# 2=Dangling 'void *foo;'
+align_var_def_star_style = 2 # number
+
+# How to align the '&' in variable definitions.
+# 0=Part of the type
+# 1=Part of the variable
+# 2=Dangling
+align_var_def_amp_style = 2 # number
+
+# The threshold for aligning variable definitions (0=no limit)
+align_var_def_thresh = 0 # number
+
+# The gap for aligning variable definitions
+align_var_def_gap = 0 # number
+
+# Whether to align the colon in struct bit fields
+align_var_def_colon = false # false/true
+
+# Whether to align any attribute after the variable name
+align_var_def_attribute = false # false/true
+
+# Whether to align inline struct/enum/union variable definitions
+align_var_def_inline = false # false/true
+
+# The span for forceing on '=' in assignments (0=don't align)
+align_assign_span = 0 # number
+
+# The threshold for aligning on '=' in assignments (0=no limit)
+align_assign_thresh = 0 # number
+
+# The span for aligning on '=' in enums (0=don't align)
+align_enum_equ_span = 0 # number
+
+# The threshold for aligning on '=' in enums (0=no limit)
+align_enum_equ_thresh = 0 # number
+
+# The span for aligning struct/union (0=don't align)
+align_var_struct_span = 0 # number
+
+# The threshold for aligning struct/union member definitions (0=no limit)
+align_var_struct_thresh = 0 # number
+
+# The gap for aligning struct/union member definitions
+align_var_struct_gap = 0 # number
+
+# The span for aligning struct initializer values (0=don't align)
+align_struct_init_span = 0 # number
+
+# The minimum space between the type and the synonym of a typedef
+align_typedef_gap = 0 # number
+
+# The span for aligning single-line typedefs (0=don't align)
+align_typedef_span = 0 # number
+
+# How to align typedef'd functions with other typedefs
+# 0: Don't mix them at all
+# 1: align the open paren with the types
+# 2: align the function type name with the other type names
+align_typedef_func = 0 # number
+
+# Controls the positioning of the '*' in typedefs. Just try it.
+# 0: Align on typedef type, ignore '*'
+# 1: The '*' is part of type name: typedef int *pint;
+# 2: The '*' is part of the type, but dangling: typedef int *pint;
+align_typedef_star_style = 0 # number
+
+# Controls the positioning of the '&' in typedefs. Just try it.
+# 0: Align on typedef type, ignore '&'
+# 1: The '&' is part of type name: typedef int &pint;
+# 2: The '&' is part of the type, but dangling: typedef int &pint;
+align_typedef_amp_style = 0 # number
+
+# The span for aligning comments that end lines (0=don't align)
+align_right_cmt_span = 0 # number
+
+# If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment
+align_right_cmt_mix = false # false/true
+
+# If a trailing comment is more than this number of columns away from the text it follows,
+# it will qualify for being aligned. This has to be > 0 to do anything.
+align_right_cmt_gap = 0 # number
+
+# Align trailing comment at or beyond column N; 'pulls in' comments as a bonus side effect (0=ignore)
+align_right_cmt_at_col = 0 # number
+
+# The span for aligning function prototypes (0=don't align)
+align_func_proto_span = 0 # number
+
+# Minimum gap between the return type and the function name.
+align_func_proto_gap = 0 # number
+
+# Align function protos on the 'operator' keyword instead of what follows
+align_on_operator = false # false/true
+
+# Whether to mix aligning prototype and variable declarations.
+# If true, align_var_def_XXX options are used instead of align_func_proto_XXX options.
+align_mix_var_proto = false # false/true
+
+# Align single-line functions with function prototypes, uses align_func_proto_span
+align_single_line_func = false # false/true
+
+# Aligning the open brace of single-line functions.
+# Requires align_single_line_func=true, uses align_func_proto_span
+align_single_line_brace = false # false/true
+
+# Gap for align_single_line_brace.
+align_single_line_brace_gap = 0 # number
+
+# The span for aligning ObjC msg spec (0=don't align)
+align_oc_msg_spec_span = 0 # number
+
+# Whether to align macros wrapped with a backslash and a newline.
+# This will not work right if the macro contains a multi-line comment.
+align_nl_cont = false # false/true
+
+# # Align macro functions and variables together
+align_pp_define_together = false # false/true
+
+# The minimum space between label and value of a preprocessor define
+align_pp_define_gap = 0 # number
+
+# The span for aligning on '#define' bodies (0=don't align)
+align_pp_define_span = 0 # number
+
+# Align lines that start with '<<' with previous '<<'. Default=true
+align_left_shift = true # false/true
+
+# Span for aligning parameters in an Obj-C message call on the ':' (0=don't align)
+align_oc_msg_colon_span = 0 # number
+
+# If true, always align with the first parameter, even if it is too short.
+align_oc_msg_colon_first = false # false/true
+
+# Aligning parameters in an Obj-C '+' or '-' declaration on the ':'
+align_oc_decl_colon = false # false/true
+
+#
+# Newline adding and removing options
+#
+
+# Whether to collapse empty blocks between '{' and '}'
+nl_collapse_empty_body = true # false/true
+
+# Don't split one-line braced assignments - 'foo_t f = { 1, 2 };'
+nl_assign_leave_one_liners = true # false/true
+
+# Don't split one-line braced statements inside a class xx { } body
+nl_class_leave_one_liners = true # false/true
+
+# Don't split one-line enums: 'enum foo { BAR = 15 };'
+nl_enum_leave_one_liners = true # false/true
+
+# Don't split one-line get or set functions
+nl_getset_leave_one_liners = true # false/true
+
+# Don't split one-line function definitions - 'int foo() { return 0; }'
+nl_func_leave_one_liners = true # false/true
+
+# Don't split one-line if/else statements - 'if(a) b++;'
+nl_if_leave_one_liners = false # false/true
+
+# Don't split one-line OC messages
+nl_oc_msg_leave_one_liner = false # false/true
+
+# Add or remove newlines at the start of the file
+nl_start_of_file = remove # ignore/add/remove/force
+
+# The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force'
+nl_start_of_file_min = 0 # number
+
+# Add or remove newline at the end of the file
+nl_end_of_file = force # ignore/add/remove/force
+
+# The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force')
+nl_end_of_file_min = 1 # number
+
+# Add or remove newline between '=' and '{'
+nl_assign_brace = force # ignore/add/remove/force
+
+# Add or remove newline between '=' and '[' (D only)
+nl_assign_square = force # ignore/add/remove/force
+
+# Add or remove newline after '= [' (D only). Will also affect the newline before the ']'
+nl_after_square_assign = ignore # ignore/add/remove/force
+
+# The number of blank lines after a block of variable definitions at the top of a function body
+# 0 = No change (default)
+nl_func_var_def_blk = 2 # number
+
+# The number of newlines before a block of typedefs
+# 0 = No change (default)
+nl_typedef_blk_start = 0 # number
+
+# The number of newlines after a block of typedefs
+# 0 = No change (default)
+nl_typedef_blk_end = 2 # number
+
+# The maximum consecutive newlines within a block of typedefs
+# 0 = No change (default)
+nl_typedef_blk_in = 0 # number
+
+# The number of newlines before a block of variable definitions not at the top of a function body
+# 0 = No change (default)
+nl_var_def_blk_start = 2 # number
+
+# The number of newlines after a block of variable definitions not at the top of a function body
+# 0 = No change (default)
+nl_var_def_blk_end = 2 # number
+
+# The maximum consecutive newlines within a block of variable definitions
+# 0 = No change (default)
+nl_var_def_blk_in = 0 # number
+
+# Add or remove newline between a function call's ')' and '{', as in:
+# list_for_each(item, &list) { }
+nl_fcall_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'enum' and '{'
+nl_enum_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'struct and '{'
+nl_struct_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'union' and '{'
+nl_union_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'if' and '{'
+nl_if_brace = force # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'else'
+nl_brace_else = force # ignore/add/remove/force
+
+# Add or remove newline between 'else if' and '{'
+# If set to ignore, nl_if_brace is used instead
+nl_elseif_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'else' and '{'
+nl_else_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'else' and 'if'
+nl_else_if = remove # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'finally'
+nl_brace_finally = force # ignore/add/remove/force
+
+# Add or remove newline between 'finally' and '{'
+nl_finally_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'try' and '{'
+nl_try_brace = force # ignore/add/remove/force
+
+# Add or remove newline between get/set and '{'
+nl_getset_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'for' and '{'
+nl_for_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'catch' and '{'
+nl_catch_brace = force # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'catch'
+nl_brace_catch = force # ignore/add/remove/force
+
+# Add or remove newline between 'while' and '{'
+nl_while_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'scope (x)' and '{' (D)
+nl_scope_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'unittest' and '{' (D)
+nl_unittest_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'version (x)' and '{' (D)
+nl_version_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'using' and '{'
+nl_using_brace = force # ignore/add/remove/force
+
+# Add or remove newline between two open or close braces.
+# Due to general newline/brace handling, REMOVE may not work.
+nl_brace_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'do' and '{'
+nl_do_brace = force # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'while' of 'do' statement
+nl_brace_while = remove # ignore/add/remove/force
+
+# Add or remove newline between 'switch' and '{'
+nl_switch_brace = add # ignore/add/remove/force
+
+# Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc.
+# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch, and nl_catch_brace.
+nl_multi_line_cond = false # false/true
+
+# Force a newline in a define after the macro name for multi-line defines.
+nl_multi_line_define = false # false/true
+
+# Whether to put a newline before 'case' statement
+nl_before_case = false # false/true
+
+# Add or remove newline between ')' and 'throw'
+nl_before_throw = remove # ignore/add/remove/force
+
+# Whether to put a newline after 'case' statement
+nl_after_case = false # false/true
+
+# Add or remove a newline between a case ':' and '{'. Overrides nl_after_case.
+nl_case_colon_brace = force # ignore/add/remove/force
+
+# Newline between namespace and {
+nl_namespace_brace = force # ignore/add/remove/force
+
+# Add or remove newline between 'template<>' and whatever follows.
+nl_template_class = remove # ignore/add/remove/force
+
+# Add or remove newline between 'class' and '{'
+nl_class_brace = force # ignore/add/remove/force
+
+# Add or remove newline after each ',' in the constructor member initialization
+nl_class_init_args = remove # ignore/add/remove/force
+
+# Add or remove newline between return type and function name in a function definition
+nl_func_type_name = force # ignore/add/remove/force
+
+# Add or remove newline between return type and function name inside a class {}
+# Uses nl_func_type_name or nl_func_proto_type_name if set to ignore.
+nl_func_type_name_class = force # ignore/add/remove/force
+
+# Add or remove newline between function scope and name in a definition
+# Controls the newline after '::' in 'void A::f() { }'
+nl_func_scope_name = force # ignore/add/remove/force
+
+# Add or remove newline between return type and function name in a prototype
+nl_func_proto_type_name = remove # ignore/add/remove/force
+
+# Add or remove newline between a function name and the opening '('
+nl_func_paren = remove # ignore/add/remove/force
+
+# Add or remove newline between a function name and the opening '(' in the definition
+nl_func_def_paren = remove # ignore/add/remove/force
+
+# Add or remove newline after '(' in a function declaration
+nl_func_decl_start = remove # ignore/add/remove/force
+
+# Add or remove newline after '(' in a function definition
+nl_func_def_start = remove # ignore/add/remove/force
+
+# Overrides nl_func_decl_start when there is only one parameter.
+nl_func_decl_start_single = remove # ignore/add/remove/force
+
+# Overrides nl_func_def_start when there is only one parameter.
+nl_func_def_start_single = remove # ignore/add/remove/force
+
+# Add or remove newline after each ',' in a function declaration
+nl_func_decl_args = remove # ignore/add/remove/force
+
+# Add or remove newline after each ',' in a function definition
+nl_func_def_args = remove # ignore/add/remove/force
+
+# Add or remove newline before the ')' in a function declaration
+nl_func_decl_end = remove # ignore/add/remove/force
+
+# Add or remove newline before the ')' in a function definition
+nl_func_def_end = remove # ignore/add/remove/force
+
+# Overrides nl_func_decl_end when there is only one parameter.
+nl_func_decl_end_single = remove # ignore/add/remove/force
+
+# Overrides nl_func_def_end when there is only one parameter.
+nl_func_def_end_single = remove # ignore/add/remove/force
+
+# Add or remove newline between '()' in a function declaration.
+nl_func_decl_empty = remove # ignore/add/remove/force
+
+# Add or remove newline between '()' in a function definition.
+nl_func_def_empty = remove # ignore/add/remove/force
+
+# Whether to put each OC message parameter on a separate line
+# See nl_oc_msg_leave_one_liner
+nl_oc_msg_args = false # false/true
+
+# Add or remove newline between function signature and '{'
+nl_fdef_brace = force # ignore/add/remove/force
+
+# Add or remove a newline between the return keyword and return expression.
+nl_return_expr = remove # ignore/add/remove/force
+
+# Whether to put a newline after semicolons, except in 'for' statements
+nl_after_semicolon = false # false/true
+
+# Whether to put a newline after brace open.
+# This also adds a newline before the matching brace close.
+nl_after_brace_open = false # false/true
+
+# If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is
+# placed between the open brace and a trailing single-line comment.
+nl_after_brace_open_cmt = false # false/true
+
+# Whether to put a newline after a virtual brace open with a non-empty body.
+# These occur in un-braced if/while/do/for statement bodies.
+nl_after_vbrace_open = false # false/true
+
+# Whether to put a newline after a virtual brace open with an empty body.
+# These occur in un-braced if/while/do/for statement bodies.
+nl_after_vbrace_open_empty = false # false/true
+
+# Whether to put a newline after a brace close.
+# Does not apply if followed by a necessary ';'.
+nl_after_brace_close = false # false/true
+
+# Whether to put a newline after a virtual brace close.
+# Would add a newline before return in: 'if (foo) a++; return;'
+nl_after_vbrace_close = true # false/true
+
+# Control the newline between the close brace and 'b' in: 'struct { int a; } b;'
+# Affects enums, unions, and structures. If set to ignore, uses nl_after_brace_close
+nl_brace_struct_var = remove # ignore/add/remove/force
+
+# Whether to alter newlines in '#define' macros
+nl_define_macro = true # false/true
+
+# Whether to not put blanks after '#ifxx', '#elxx', or before '#endif'
+nl_squeeze_ifdef = false # false/true
+
+# Add or remove blank line before 'if'
+nl_before_if = force # ignore/add/remove/force
+
+# Add or remove blank line after 'if' statement
+nl_after_if = force # ignore/add/remove/force
+
+# Add or remove blank line before 'for'
+nl_before_for = force # ignore/add/remove/force
+
+# Add or remove blank line after 'for' statement
+nl_after_for = force # ignore/add/remove/force
+
+# Add or remove blank line before 'while'
+nl_before_while = force # ignore/add/remove/force
+
+# Add or remove blank line after 'while' statement
+nl_after_while = force # ignore/add/remove/force
+
+# Add or remove blank line before 'switch'
+nl_before_switch = force # ignore/add/remove/force
+
+# Add or remove blank line after 'switch' statement
+nl_after_switch = force # ignore/add/remove/force
+
+# Add or remove blank line before 'do'
+nl_before_do = force # ignore/add/remove/force
+
+# Add or remove blank line after 'do/while' statement
+nl_after_do = force # ignore/add/remove/force
+
+# Whether to double-space commented-entries in struct/enum
+nl_ds_struct_enum_cmt = false # false/true
+
+# Whether to double-space before the close brace of a struct/union/enum
+# (lower priority than 'eat_blanks_before_close_brace')
+nl_ds_struct_enum_close_brace = false # false/true
+
+# Add or remove a newline around a class colon.
+# Related to pos_class_colon, nl_class_init_args, and pos_comma.
+nl_class_colon = ignore # ignore/add/remove/force
+
+# Change simple unbraced if statements into a one-liner
+# 'if(b)\n i++;' => 'if(b) i++;'
+nl_create_if_one_liner = false # false/true
+
+# Change simple unbraced for statements into a one-liner
+# 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);'
+nl_create_for_one_liner = false # false/true
+
+# Change simple unbraced while statements into a one-liner
+# 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);'
+nl_create_while_one_liner = false # false/true
+
+#
+# Positioning options
+#
+
+# The position of arithmetic operators in wrapped expressions
+pos_arith = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of assignment in wrapped expressions.
+# Do not affect '=' followed by '{'
+pos_assign = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of boolean operators in wrapped expressions
+pos_bool = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of comparison operators in wrapped expressions
+pos_compare = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of conditional (b ? t : f) operators in wrapped expressions
+pos_conditional = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of the comma in wrapped expressions
+pos_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of the comma in the constructor initialization list
+pos_class_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of colons between constructor and member initialization
+pos_class_colon = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+#
+# Line Splitting options
+#
+
+# Try to limit code width to N number of columns
+code_width = 0 # number
+
+# Whether to fully split long 'for' statements at semi-colons
+ls_for_split_full = false # false/true
+
+# Whether to fully split long function protos/calls at commas
+ls_func_split_full = false # false/true
+
+# Whether to split lines as close to code_width as possible and ignore some groupings
+ls_code_width = false # false/true
+
+#
+# Blank line options
+#
+
+# The maximum consecutive newlines
+nl_max = 2 # number
+
+# The number of newlines after a function prototype, if followed by another function prototype
+nl_after_func_proto = 1 # number
+
+# The number of newlines after a function prototype, if not followed by another function prototype
+nl_after_func_proto_group = 2 # number
+
+# The number of newlines after '}' of a multi-line function body
+nl_after_func_body = 2 # number
+
+# The number of newlines after '}' of a multi-line function body in a class declaration
+nl_after_func_body_class = 2 # number
+
+# The number of newlines after '}' of a single line function body
+nl_after_func_body_one_liner = 2 # number
+
+# The minimum number of newlines before a multi-line comment.
+# Doesn't apply if after a brace open or another multi-line comment.
+nl_before_block_comment = 2 # number
+
+# The minimum number of newlines before a single-line C comment.
+# Doesn't apply if after a brace open or other single-line C comments.
+nl_before_c_comment = 2 # number
+
+# The minimum number of newlines before a CPP comment.
+# Doesn't apply if after a brace open or other CPP comments.
+nl_before_cpp_comment = 2 # number
+
+# Whether to force a newline after a multi-line comment.
+nl_after_multiline_comment = true # false/true
+
+# The number of newlines after '}' or ';' of a struct/enum/union definition
+nl_after_struct = 2 # number
+
+# The number of newlines after '}' or ';' of a class definition
+nl_after_class = 2 # number
+
+# The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label.
+# Will not change the newline count if after a brace open.
+# 0 = No change.
+nl_before_access_spec = 1 # number
+
+# The number of newlines after a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label.
+# 0 = No change.
+nl_after_access_spec = 2 # number
+
+# The number of newlines between a function def and the function comment.
+# 0 = No change.
+nl_comment_func_def = 0 # number
+
+# The number of newlines after a try-catch-finally block that isn't followed by a brace close.
+# 0 = No change.
+nl_after_try_catch_finally = 2 # number
+
+# The number of newlines before and after a property, indexer or event decl.
+# 0 = No change.
+nl_around_cs_property = 0 # number
+
+# The number of newlines between the get/set/add/remove handlers in C#.
+# 0 = No change.
+nl_between_get_set = 0 # number
+
+# Add or remove newline between C# property and the '{'
+nl_property_brace = force # ignore/add/remove/force
+
+# Whether to remove blank lines after '{'
+eat_blanks_after_open_brace = true # false/true
+
+# Whether to remove blank lines before '}'
+eat_blanks_before_close_brace = true # false/true
+
+# How aggressively to remove extra newlines not in preproc.
+# 0: No change
+# 1: Remove most newlines not handled by other config
+# 2: Remove all newlines and reformat completely by config
+nl_remove_extra_newlines = 2 # number
+
+# Whether to put a blank line before 'return' statements, unless after an open brace.
+nl_before_return = true # false/true
+
+# Whether to put a blank line after 'return' statements, unless followed by a close brace.
+nl_after_return = false # false/true
+
+# Whether to put a newline after a Java annotation statement.
+# Only affects annotations that are after a newline.
+nl_after_annotation = remove # ignore/add/remove/force
+
+# Controls the newline between two annotations.
+nl_between_annotation = ignore # ignore/add/remove/force
+
+#
+# Code modifying options (non-whitespace)
+#
+
+# Add or remove braces on single-line 'do' statement
+mod_full_brace_do = remove # ignore/add/remove/force
+
+# Add or remove braces on single-line 'for' statement
+mod_full_brace_for = remove # ignore/add/remove/force
+
+# Add or remove braces on single-line function definitions. (Pawn)
+mod_full_brace_function = force # ignore/add/remove/force
+
+# Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'.
+mod_full_brace_if = remove # ignore/add/remove/force
+
+# Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if.
+# If any must be braced, they are all braced. If all can be unbraced, then the braces are removed.
+mod_full_brace_if_chain = true # false/true
+
+# Don't remove braces around statements that span N newlines
+mod_full_brace_nl = 0 # number
+
+# Add or remove braces on single-line 'while' statement
+mod_full_brace_while = force # ignore/add/remove/force
+
+# Add or remove braces on single-line 'using ()' statement
+mod_full_brace_using = remove # ignore/add/remove/force
+
+# Add or remove unnecessary paren on 'return' statement
+mod_paren_on_return = remove # ignore/add/remove/force
+
+# Whether to change optional semicolons to real semicolons
+mod_pawn_semicolon = false # false/true
+
+# Add parens on 'while' and 'if' statement around bools
+mod_full_paren_if_bool = true # false/true
+
+# Whether to remove superfluous semicolons
+mod_remove_extra_semicolon = true # false/true
+
+# If a function body exceeds the specified number of newlines and doesn't have a comment after
+# the close brace, a comment will be added.
+mod_add_long_function_closebrace_comment = 0 # number
+
+# If a switch body exceeds the specified number of newlines and doesn't have a comment after
+# the close brace, a comment will be added.
+mod_add_long_switch_closebrace_comment = 0 # number
+
+# If an #ifdef body exceeds the specified number of newlines and doesn't have a comment after
+# the #endif, a comment will be added.
+mod_add_long_ifdef_endif_comment = 0 # number
+
+# If an #ifdef or #else body exceeds the specified number of newlines and doesn't have a comment after
+# the #else, a comment will be added.
+mod_add_long_ifdef_else_comment = 0 # number
+
+# If TRUE, will sort consecutive single-line 'import' statements [Java, D]
+mod_sort_import = true # false/true
+
+# If TRUE, will sort consecutive single-line 'using' statements [C#]
+mod_sort_using = true # false/true
+
+# If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C]
+# This is generally a bad idea, as it may break your code.
+mod_sort_include = false # false/true
+
+# If TRUE, it will move a 'break' that appears after a fully braced 'case' before the close brace.
+mod_move_case_break = true # false/true
+
+# Will add or remove the braces around a fully braced case statement.
+# Will only remove the braces if there are no variable declarations in the block.
+mod_case_brace = remove # ignore/add/remove/force
+
+# If TRUE, it will remove a void 'return;' that appears as the last statement in a function.
+mod_remove_empty_return = false # false/true
+
+#
+# Comment modifications
+#
+
+# Try to wrap comments at cmt_width columns
+cmt_width = 0 # number
+
+# Set the comment reflow mode (default: 0)
+# 0: no reflowing (apart from the line wrapping due to cmt_width)
+# 1: no touching at all
+# 2: full reflow
+cmt_reflow_mode = 0 # number
+
+# If false, disable all multi-line comment changes, including cmt_width. keyword substitution, and leading chars.
+# Default is true.
+cmt_indent_multi = true # false/true
+
+# Whether to group c-comments that look like they are in a block
+cmt_c_group = false # false/true
+
+# Whether to put an empty '/*' on the first line of the combined c-comment
+cmt_c_nl_start = false # false/true
+
+# Whether to put a newline before the closing '*/' of the combined c-comment
+cmt_c_nl_end = false # false/true
+
+# Whether to group cpp-comments that look like they are in a block
+cmt_cpp_group = false # false/true
+
+# Whether to put an empty '/*' on the first line of the combined cpp-comment
+cmt_cpp_nl_start = false # false/true
+
+# Whether to put a newline before the closing '*/' of the combined cpp-comment
+cmt_cpp_nl_end = false # false/true
+
+# Whether to change cpp-comments into c-comments
+cmt_cpp_to_c = false # false/true
+
+# Whether to put a star on subsequent comment lines
+cmt_star_cont = false # false/true
+
+# The number of spaces to insert at the start of subsequent comment lines
+cmt_sp_before_star_cont = 0 # number
+
+# The number of spaces to insert after the star on subsequent comment lines
+cmt_sp_after_star_cont = 1 # number
+
+# For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of
+# the comment are the same length. Default=True
+cmt_multi_check_last = true # false/true
+
+# The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment.
+# Will substitute $(filename) with the current file's name.
+cmt_insert_file_header = "" # string
+
+# The filename that contains text to insert at the end of a file if the file doesn't end with a C/C++ comment.
+# Will substitute $(filename) with the current file's name.
+cmt_insert_file_footer = "" # string
+
+# The filename that contains text to insert before a function implementation if the function isn't preceded with a C/C++ comment.
+# Will substitute $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff.
+# Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... }
+cmt_insert_func_header = "" # string
+
+# The filename that contains text to insert before a class if the class isn't preceded with a C/C++ comment.
+# Will substitute $(class) with the class name.
+cmt_insert_class_header = "" # string
+
+# The filename that contains text to insert before a Obj-C message specification if the method isn't preceeded with a C/C++ comment.
+# Will substitute $(message) with the function name and $(javaparam) with the javadoc @param and @return stuff.
+cmt_insert_oc_msg_header = "" # string
+
+# If a preprocessor is encountered when stepping backwards from a function name, then
+# this option decides whether the comment should be inserted.
+# Affects cmt_insert_oc_msg_header, cmt_insert_func_header and cmt_insert_class_header.
+cmt_insert_before_preproc = false # false/true
+
+#
+# Preprocessor options
+#
+
+# Control indent of preprocessors inside #if blocks at brace level 0
+pp_indent = remove # ignore/add/remove/force
+
+# Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false)
+pp_indent_at_level = false # false/true
+
+# If pp_indent_at_level=false, specifies the number of columns to indent per level. Default=1.
+pp_indent_count = 1 # number
+
+# Add or remove space after # based on pp_level of #if blocks
+pp_space = force # ignore/add/remove/force
+
+# Sets the number of spaces added with pp_space
+pp_space_count = 1 # number
+
+# The indent for #region and #endregion in C# and '#pragma region' in C/C++
+pp_indent_region = 0 # number
+
+# Whether to indent the code between #region and #endregion
+pp_region_indent_code = false # false/true
+
+# If pp_indent_at_level=true, sets the indent for #if, #else, and #endif when not at file-level
+pp_indent_if = 0 # number
+
+# Control whether to indent the code between #if, #else and #endif when not at file-level
+pp_if_indent_code = false # false/true
+
+# Whether to indent '#define' at the brace level (true) or from column 1 (false)
+pp_define_at_level = false # false/true
+
+# You can force a token to be a type with the 'type' option.
+# Example:
+# type myfoo1 myfoo2
+#
+# You can create custom macro-based indentation using macro-open,
+# macro-else and macro-close.
+# Example:
+# macro-open BEGIN_TEMPLATE_MESSAGE_MAP
+# macro-open BEGIN_MESSAGE_MAP
+# macro-close END_MESSAGE_MAP
+#
+# You can assign any keyword to any type with the set option.
+# set func_call_user _ N_
+#
+# The full syntax description of all custom definition config entries
+# is shown below:
+#
+# define custom tokens as:
+# - embed whitespace in token using '' escape character, or
+# put token in quotes
+# - these: ' " and ` are recognized as quote delimiters
+#
+# type token1 token2 token3 ...
+# ^ optionally specify multiple tokens on a single line
+# define def_token output_token
+# ^ output_token is optional, then NULL is assumed
+# macro-open token
+# macro-close token
+# macro-else token
+# set id token1 token2 ...
+# ^ optionally specify multiple tokens on a single line
+# ^ id is one of the names in token_enum.h sans the CT_ prefix,
+# e.g. PP_PRAGMA
+#
+# all tokens are separated by any mix of ',' commas, '=' equal signs
+# and whitespace (space, tab)
+#