├── ChangeLog ├── INTERFACE_CHANGES ├── LICENSE ├── Makefile ├── Makefile.dist ├── README ├── TODO ├── VERSION ├── build ├── mk_cflags ├── mk_compat ├── mk_modules └── mk_support ├── configure ├── configure.help ├── contrib ├── test_report.css └── test_report.xsl ├── doc ├── Makefile ├── doxy │ ├── DoxygenLayout.xml │ ├── Makefile │ ├── images │ │ └── kl_bg.png │ ├── libu.doxy.in │ └── src │ │ ├── install.txt │ │ ├── kl.css │ │ ├── kl_footer.html │ │ └── toc.txt └── man │ ├── Makefile │ ├── libu.3 │ ├── u_alloc.3 │ ├── u_config.3 │ ├── u_debug.3 │ ├── u_env.3 │ ├── u_log.3 │ ├── u_memory.3 │ ├── u_misc.3 │ ├── u_net.3 │ ├── u_str.3 │ └── u_uri.3 ├── example ├── Makefile ├── array │ ├── Makefile │ └── main.c ├── blocks │ ├── Makefile │ ├── blocks.c │ ├── blocks.h │ └── main.c ├── bst │ ├── Makefile │ ├── bst.c │ ├── bst.h │ └── main.c ├── config │ ├── Makefile │ └── main.c ├── json │ ├── Makefile │ ├── main.c │ └── test │ │ ├── empty-array.json │ │ ├── empty-object.json │ │ ├── fatfree.json │ │ ├── geoson-multipolygon.json │ │ ├── geoson.json │ │ ├── jsonrequest.json │ │ ├── matrix.json │ │ ├── weekdays.json │ │ └── yamatrix.json ├── net │ ├── Makefile │ ├── cli │ │ ├── Makefile │ │ └── main.c │ └── srv │ │ ├── Makefile │ │ └── main.c ├── pqueue │ ├── Makefile │ ├── main.c │ ├── pqueue.c │ └── pqueue.h ├── pwd │ ├── Makefile │ ├── main.c │ └── passwd ├── rb │ ├── Makefile │ └── main.c ├── unitest │ ├── Makefile │ ├── main.c │ ├── test.c │ └── test.h └── uri │ ├── Makefile │ └── main.c ├── include ├── Makefile ├── missing │ ├── Makefile │ ├── daemon.h │ ├── fnmatch.h │ ├── getpid.h │ ├── gettimeofday.h │ ├── mkstemps.h │ ├── setenv.h │ ├── strlcat.h │ ├── strlcpy.h │ ├── strsep.h │ ├── strtok_r.h │ ├── syslog.h │ ├── timegm.h │ ├── unlink.h │ └── va.h ├── toolbox │ ├── Makefile │ ├── array.h │ ├── b64.h │ ├── bst.h │ ├── buf.h │ ├── carpal.h │ ├── config.h │ ├── env.h │ ├── fs.h │ ├── hmap.h │ ├── json.h │ ├── lexer.h │ ├── list.h │ ├── log.h │ ├── logprv.h │ ├── memory.h │ ├── misc.h │ ├── net.h │ ├── pqueue.h │ ├── pwd.h │ ├── queue.h │ ├── rb.h │ ├── str.h │ ├── test.h │ └── uri.h └── u │ ├── Makefile │ ├── compat.h │ ├── libu.h │ ├── missing.h │ └── toolbox.h ├── pkg ├── Makefile.doc └── Makefile.doxy.doc ├── pkgs └── rel-git.sh ├── srcs ├── Makefile ├── missing │ ├── daemon.c │ ├── fnmatch.c │ ├── getpid.c │ ├── gettimeofday.c │ ├── mkstemps.c │ ├── setenv.c │ ├── strlcat.c │ ├── strlcpy.c │ ├── strsep.c │ ├── strtok_r.c │ ├── syslog.c │ ├── timegm.c │ ├── unlink.c │ └── vsyslog.c └── toolbox │ ├── array.c │ ├── b64.c │ ├── bst.c │ ├── buf.c │ ├── config.c │ ├── config_fs.c │ ├── env.c │ ├── facility.c │ ├── fs.c │ ├── hmap.c │ ├── json.c │ ├── lexer.c │ ├── list.c │ ├── log.c │ ├── memory.c │ ├── misc.c │ ├── net.c │ ├── pqueue.c │ ├── pwd.c │ ├── rb.c │ ├── str.c │ ├── test.c │ └── uri.c └── test ├── Makefile ├── array.c ├── b64.c ├── bst.c ├── hmap.c ├── json.c ├── lexer.c ├── list.c ├── main.c ├── misc.c ├── passwd ├── pqueue.c ├── pwd.c ├── rb.c ├── string.c └── uri.c /INTERFACE_CHANGES: -------------------------------------------------------------------------------- 1 | 2 | TODO: document --compat_1x effects 3 | 4 | [uri]: 5 | This module has been completely rewritten for RFC 3986 conformance. 6 | 7 | u_uri_parse has been removed: the new parsing interface, which also takes 8 | a bitmask of parsing options as its second parameter, is: 9 | * int u_uri_crumble (const char *s, u_uri_opts_t opts, u_uri_t **pu) 10 | instead of the old: 11 | * int u_uri_parse (const char *s, u_uri_t **pu) 12 | 13 | Also, u_uri_t is now opaque type and its attributes can be accessed only 14 | through their getter methods: 15 | * const char *u_uri_get_scheme (u_uri_t *u) 16 | * const char *u_uri_get_user (u_uri_t *u) 17 | * const char *u_uri_get_pwd (u_uri_t *u) 18 | * const char *u_uri_get_host (u_uri_t *u) 19 | * const char *u_uri_get_port (u_uri_t *u) 20 | * const char *u_uri_get_authority (u_uri_t *u) 21 | * const char *u_uri_get_path (u_uri_t *u) 22 | * const char *u_uri_get_query (u_uri_t *u) 23 | * const char *u_uri_get_fragment (u_uri_t *u) 24 | * const char *u_uri_get_userinfo (u_uri_t *u); 25 | 26 | A new interface for building conformant URI string as been added: 27 | * int u_uri_knead (u_uri_t *u, char s[U_URI_STRMAX]) 28 | 29 | together with the needed setter methods: 30 | * int u_uri_set_scheme (u_uri_t *u, const char *val) 31 | * int u_uri_set_user (u_uri_t *u, const char *val) 32 | * int u_uri_set_pwd (u_uri_t *u, const char *val) 33 | * int u_uri_set_host (u_uri_t *u, const char *val) 34 | * int u_uri_set_port (u_uri_t *u, const char *val) 35 | * int u_uri_set_authority (u_uri_t *u, const char *val) 36 | * int u_uri_set_path (u_uri_t *u, const char *val) 37 | * int u_uri_set_query (u_uri_t *u, const char *val) 38 | * int u_uri_set_fragment (u_uri_t *u, const char *val) 39 | * int u_uri_set_userinfo (u_uri_t *u, const char *val); 40 | 41 | The u_uri_parse function accepts as last optional argument a bitmask of 42 | U_URI_OPTS_* to tweak some parsing choices. 43 | 44 | [buf]: 45 | u_buf_t is now opaque. Type attributes can be accessed only through their 46 | getter methods, which where already present in 1.x: 47 | * void *u_buf_ptr (u_buf_t *buf); 48 | * size_t u_buf_len (u_buf_t *buf); 49 | * size_t u_buf_size (u_buf_t *buf); 50 | 51 | [net]: 52 | This module has been completely revamped, both implementation and 53 | interfaces have changed dramatically, the rationale being "more simplicity": 54 | the creation of sockets using UNIX IPC, TCP, UDP and SCTP over IPv4 and 55 | IPv6 is carried out through the very same interface. 56 | The sole chance for your application to be backwards compatible is in case 57 | it used the u_net_sock() only (which is indeed likely to happen). 58 | 59 | Interfaces removed: 60 | * u_net_sock_tcp 61 | * u_net_sock_udp 62 | * u_net_sock_unix 63 | * u_net_tcp4_ssock 64 | * u_net_tcp4_csock 65 | * u_net_tcp6_ssock 66 | * u_net_tcp6_csock 67 | * u_net_unix_ssock 68 | * u_net_unix_csock 69 | * u_net_uri2sin 70 | * u_net_uri2sun 71 | * u_net_addr_new 72 | 73 | Interfaces changed: 74 | * u_net_uri2addr 75 | the socket 'mode' has been added as a mandatory input parameter 76 | * u_net_sock (XXX u_net_sd, see compat.h) 77 | the socket 'mode' has been added as an optional input parameter in 78 | a backwards-compatible way 79 | 80 | Newly added interfaces: 81 | * u_net_sock_by_addr 82 | * u_net_addr_set_opts 83 | * u_net_addr_add_opts 84 | * u_net_addr_can_accept 85 | * u_socket 86 | * u_connect 87 | * u_listen 88 | * u_bind 89 | * u_setsockopt 90 | * u_getsockopt 91 | * u_sa_ntop 92 | * u_inet_ntop 93 | 94 | [array] 95 | The setter/getter methods for generic pointers have been restyled. See 96 | http://coding.derkeiler.com/Archive/C_CPP/comp.lang.c/2008-10/msg01683.html 97 | for details about the reason why we had to move. The following interfaces 98 | have been modified: they give back the error code through a result argument, 99 | and the generic (ie. void*) pointer as the returned value: 100 | 101 | New interfaces: 102 | * void *u_array_get_ptr (u_array_t *da, size_t idx, int *prc); 103 | * void *u_array_set_ptr (u_array_t *da, size_t idx, void *v, int *prc); 104 | 105 | Old (removed) interfaces: 106 | * int u_array_get_ptr (u_array_t *da, size_t idx, void **pv); 107 | * int u_array_set_ptr (u_array_t *da, size_t idx, void *v, void **pold); 108 | 109 | Note that the returned pointer is not sufficient to point out a failure in 110 | the get/set operation, since a NULL value could be perfectly valid: 111 | *always* use '*prc' to discriminate between a good (i.e. *prc == 0) and bad 112 | (i.e. *prc == -1) run. 113 | 114 | [misc] 115 | The following interfaces have been deprecated: 116 | * u_tokenize in favour of u_strtok 117 | * u_strncpy in favour of u_strlcpy 118 | 119 | [carpal] 120 | The following macros have been renamed to avoid name clash with 121 | functions: 122 | * dbg() becomes u_dbg() 123 | * info() becomes u_info() 124 | * notice() becomes u_notice() 125 | * warn() becomes u_warn() 126 | * err() becomes u_err() 127 | * crit() becomes u_crit() 128 | * alert() becomes u_alert() 129 | * emerg() becomes u_emerg() 130 | 131 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | LibU - Copyright (c) 2005-2012 by KoanLogic srl 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | Neither the name of the KoanLogic srl nor the names of its contributors may 16 | be used to endorse or promote products derived from this software without 17 | specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.8 2008/07/04 10:55:37 tho Exp $ 2 | 3 | include Makefile.conf 4 | 5 | SUBDIR = include 6 | SUBDIR += srcs 7 | 8 | ifndef NO_DOCS 9 | SUBDIR += doc 10 | endif 11 | 12 | ifdef DO_TEST 13 | SUBDIR += test 14 | endif 15 | 16 | include subdir.mk 17 | -------------------------------------------------------------------------------- /Makefile.dist: -------------------------------------------------------------------------------- 1 | # $Id: Makefile.dist,v 1.18 2010/03/23 18:22:32 tho Exp $ 2 | 3 | include common.mk 4 | 5 | PKG_NAME = libu 6 | PKG_VERSION = $(shell cat VERSION) 7 | 8 | ZIP ?= gzip 9 | ZIPEXT ?= gz 10 | 11 | # top level build and configuration drivers 12 | DISTFILES = Makefile LICENSE ChangeLog README VERSION configure configure.help 13 | 14 | # configure command line args and handlers 15 | DISTFILES += $(wildcard build/mk_*) 16 | 17 | # headers (include/{u,missing,toolbox}) 18 | DISTFILES += include/Makefile 19 | DISTFILES += $(wildcard include/missing/*.h) include/missing/Makefile 20 | DISTFILES += $(wildcard include/toolbox/*.h) include/toolbox/Makefile 21 | DISTFILES += include/u/libu.h include/u/missing.h include/u/toolbox.h 22 | DISTFILES += include/u/compat.h 23 | DISTFILES += include/u/Makefile 24 | 25 | # sources (srcs/{missing,toolbox}) 26 | DISTFILES += srcs/Makefile 27 | DISTFILES += $(wildcard srcs/missing/*.c) 28 | DISTFILES += $(wildcard srcs/toolbox/*.c) 29 | 30 | # test 31 | DISTFILES += test/Makefile test/passwd 32 | DISTFILES += $(wildcard test/*.c) 33 | 34 | # man pages 35 | DISTFILES += $(wildcard doc/man/*.3) doc/man/Makefile 36 | 37 | # doxy bits 38 | DISTREMAP += pkg/Makefile.doc doc/Makefile 39 | DISTREMAP += pkg/Makefile.doxy.doc doc/html/Makefile 40 | DISTREMAP += $(foreach f, $(notdir $(wildcard doc/doxy/html/*.html)), \ 41 | doc/doxy/html/$f doc/html/$f) 42 | DISTREMAP += $(foreach f, $(notdir $(wildcard doc/doxy/html/*.css)), \ 43 | doc/doxy/html/$f doc/html/$f) 44 | DISTREMAP += $(foreach f, $(notdir $(wildcard doc/doxy/html/*.gif)), \ 45 | doc/doxy/html/$f doc/html/$f) 46 | 47 | # contrib files 48 | DISTFILES += $(wildcard contrib/test_report.*) 49 | 50 | dist-hook-pre: 51 | @echo "Processing HTML documentation..." && cd doc/doxy && $(MAKE) 52 | 53 | include dist.mk 54 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | == MaKL is a Prerequisite == 2 | 3 | LibU needs http://koanlogic.com/makl to configure and build. 4 | 5 | The following commands should be sufficient to get MaKL installed on any Linux 6 | flavour or Darwin/MacOSX: 7 | 8 | $ wget http://koanlogic.com/download/makl/makl-${VERSION}.tar.gz 9 | $ tar zxf makl-${VERSION}.tar.gz && cd makl-${VERSION} 10 | $ sh configure.sh 11 | $ su 12 | Password: **** 13 | # make install 14 | 15 | Should your platform be one of Solaris, OpenSolaris, FreeBSD, PC-BSD, OpenBSD, 16 | NetBSD, DragonflyBSD, Minix or Windows (MinGW or Gygwin) take a look at the 17 | INSTALL file in the top-level MaKL sources directory to track down specific 18 | variations on the theme. 19 | 20 | == Download == 21 | 22 | Once MaKL is there, you can start downloading the package (always check the 23 | official http://koanlogic.com/libu page for the latest version and related 24 | ChangeLog) and tailor it to your specific needs: 25 | 26 | $ wget http://koanlogic.com/download/libu/libu-${VERSION}.tar.gz 27 | $ tar zxf libu-${VERSION}.tar.gz && cd libu-${VERSION} 28 | 29 | 30 | == Configure == 31 | 32 | E.g. should you need to change the default installation path (i.e. /usr/local), 33 | use: 34 | 35 | $ makl-conf --prefix="/my/install/base/dir" 36 | 37 | 38 | Debug symbols and warnings from the compiler can be switched on via 39 | --enable_debug and --enable_warns (use --enable_icc_warns instead when 40 | working with the Intel C compiler): 41 | 42 | $ makl-conf --enable_debug --enable_warns 43 | 44 | 45 | Code profiling using gprof(1) can be activated via --enable_profile, and, 46 | more generally, any compiler flag can be passed to the build stage in the 47 | following way: 48 | 49 | $ makl-conf --extra-cflags="-Wformat -Wno-format-extra-args -Wformat-security -Wformat-nonliteral -Wformat=2" 50 | 51 | The --extra-xxx="val" is indeed a powerful mechanism by which any Makefile 52 | variable 'XXX' (uppercase!) can be given an additional value 'val': (ab)use 53 | it to tweak LDFLAGS, SHLIB_LDFLAGS, etc. as needed. Anyway if in doubt, 54 | or in search for exotic features, type makl-conf -h to display the complete 55 | list of options: it's likely that what you are trying to achieve is already 56 | there. 57 | 58 | By default LibU is compiled as static library, to also enable shared library 59 | build, supply the --enable_shared flag. 60 | 61 | == Pick Up What Needs to be Included == 62 | 63 | The default is to build all the modules, but you can disable the 64 | inclusion of specific bits selectively using the following switches: 65 | - --no_hmap: to disable the hmap module 66 | - --no_config: to disable the config module 67 | - --no_net: to disable the net module 68 | - --no_env: to disable the env module 69 | - --no_fs: to disable the fs module 70 | - --no_pwd: to disable the pwd module 71 | - --no_list: to disable the list module 72 | - --no_array: to disable the array module 73 | - --no_ringbuffer: to disable the rb module 74 | - --no_pqueue: to disable the pq module 75 | - --no_json: to disable the json module 76 | - --no_bst: to disable the bst module 77 | 78 | Also, some specific features regarding the networking code can be disabled 79 | at configuration: 80 | - --no_ipv6: to disable IPv6 protocol support 81 | - --no_sctp: to disable SCTP protocol support 82 | - --no_unixsock: to disable UNIX IPC support 83 | 84 | If you need to enable compatibility with (some, not all) 1.X interfaces, 85 | specify the --compat_1x command line switch. 86 | 87 | == Build, Test and Install == 88 | 89 | When you are done with the configure step, you can build LibU bits and 90 | optionally test them: 91 | 92 | $ makl 93 | $ makl -C test 94 | 95 | 96 | And finally install it: 97 | 98 | $ su 99 | Password: **** 100 | # makl install 101 | 102 | 103 | == Hello LibU ! == 104 | 105 | You now are ready to play with your first LibU program: 106 | 107 | $ cat main.c 108 | #include 109 | 110 | int facility = LOG_LOCAL0; 111 | 112 | int main (void) 113 | { 114 | u_con("Hello LibU world !"); 115 | return 0; 116 | } 117 | 118 | Write a Makefile like the following: 119 | 120 | $ cat Makefile 121 | include common.mk 122 | 123 | PROG = hellolibu 124 | SRCS = main.c 125 | 126 | LDADD += /path/to/install/prefix/lib/libu.a 127 | CFLAGS += -I/path/to/install/prefix/include 128 | 129 | include prog.mk 130 | 131 | Then type: 132 | 133 | $ makl && ./hellolibu 134 | 135 | and enjoy ! 136 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | # $Id: TODO,v 1.6 2009/12/29 20:14:34 tho Exp $ 2 | 3 | = u_config "listener" feature (http://koanlogic.com/pipermail/klone-users/2010-June/000930.html) 4 | ? u_config_t multi-line values 5 | 6 | - implement json-templates 7 | * http://code.google.com/p/json-template/wiki/Reference 8 | * http://chubot.org/json-template/test-cases/ 9 | 10 | - add time-constrained tests + TIMEOUTED exit status 11 | 12 | - json: improve error reporting (context++) 13 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 2.3.0rc3 2 | -------------------------------------------------------------------------------- /build/mk_cflags: -------------------------------------------------------------------------------- 1 | # $Id: mk_cflags,v 1.4 2008/11/06 11:02:36 tho Exp $ 2 | 3 | # 4 | # --enable_debug 5 | # 6 | makl_args_def \ 7 | "enable_debug" \ 8 | "" "" \ 9 | "enables debugging support: carpal verbose output and CC debug flags" 10 | 11 | __makl_enable_debug () 12 | { 13 | makl_set_var_mk "LIBU_DEBUG" ; 14 | makl_append_var_mk "CFLAGS" "-g -DDEBUG" ; 15 | } 16 | 17 | # 18 | # --enable_profile 19 | # 20 | makl_args_def \ 21 | "enable_profile" \ 22 | "" "" \ 23 | "enables profiling via gprof (GCC only)" 24 | 25 | __makl_enable_profile () 26 | { 27 | makl_append_var_mk "CFLAGS" "-pg" ; 28 | } 29 | 30 | # 31 | # --enable_warns 32 | # 33 | makl_args_def \ 34 | "enable_warns" \ 35 | "" "" \ 36 | "set CFLAGS for extra warnings" 37 | 38 | __makl_enable_warns () 39 | { 40 | makl_append_var_mk "CFLAGS" "-std=c99 -W -Wall -Wstrict-prototypes " \ 41 | "-Wmissing-prototypes -Wpointer-arith " \ 42 | "-Wno-uninitialized -Wreturn-type " \ 43 | "-Wwrite-strings -Wswitch -Wshadow " \ 44 | "-Wunreachable-code -Wunused " \ 45 | "-Wcast-qual -pedantic " 46 | } 47 | 48 | # 49 | # --enable_icc_warns 50 | # 51 | makl_args_def \ 52 | "enable_icc_warns" \ 53 | "" "" \ 54 | "set CFLAGS for extra warnings by ICC" 55 | 56 | __makl_enable_icc_warns () 57 | { 58 | makl_append_var_mk "CFLAGS" "-w2" 59 | } 60 | 61 | # 62 | # --extra-xxx=... 63 | # 64 | makl_args_def "extra" "" "" "add the supplied args to XXX (uppercase) variable" 65 | __makl_extra () 66 | { 67 | makl_add_var_mk `makl_upper "$1"` "$2" 68 | } 69 | -------------------------------------------------------------------------------- /build/mk_compat: -------------------------------------------------------------------------------- 1 | # $Id: mk_compat,v 1.1 2010/01/15 17:47:56 tho Exp $ 2 | 3 | # 4 | # --compat_1x 5 | # 6 | makl_args_def \ 7 | "compat_1x" \ 8 | "" "" \ 9 | "enable compatibility with libu 1.X" 10 | 11 | __makl_compat_1X () 12 | { 13 | makl_set_var "LIBU_1X_COMPAT" ; 14 | } 15 | -------------------------------------------------------------------------------- /build/mk_modules: -------------------------------------------------------------------------------- 1 | # $Id: mk_modules,v 1.10 2010/05/27 08:35:12 tho Exp $ 2 | 3 | # 4 | # --no_hmap 5 | # 6 | makl_args_def \ 7 | "no_hmap" \ 8 | "" "" \ 9 | "disable hmap module" 10 | 11 | __makl_no_hmap () 12 | { 13 | makl_set_var "NO_HMAP" ; 14 | } 15 | 16 | # 17 | # --no_config 18 | # 19 | makl_args_def \ 20 | "no_config" \ 21 | "" "" \ 22 | "disable config module" 23 | 24 | __makl_no_config () 25 | { 26 | makl_set_var "NO_CONFIG" ; 27 | } 28 | 29 | # 30 | # --no_net 31 | # 32 | makl_args_def \ 33 | "no_net" \ 34 | "" "" \ 35 | "disable net module" 36 | 37 | __makl_no_net () 38 | { 39 | makl_set_var "NO_NET" ; 40 | } 41 | 42 | # 43 | # --no_env 44 | # 45 | makl_args_def \ 46 | "no_env" \ 47 | "" "" \ 48 | "disable env module" 49 | 50 | __makl_no_env () 51 | { 52 | makl_set_var "NO_ENV" ; 53 | } 54 | 55 | # 56 | # --no_fs 57 | # 58 | makl_args_def \ 59 | "no_fs" \ 60 | "" "" \ 61 | "disable fs module" 62 | 63 | __makl_no_fs () 64 | { 65 | makl_set_var "NO_FS" ; 66 | } 67 | 68 | # 69 | # --no_pwd 70 | # 71 | makl_args_def \ 72 | "no_pwd" \ 73 | "" "" \ 74 | "disable pwd module" 75 | 76 | __makl_no_pwd () 77 | { 78 | makl_set_var "NO_PWD" ; 79 | } 80 | 81 | # 82 | # --no_list 83 | # 84 | makl_args_def \ 85 | "no_list" \ 86 | "" "" \ 87 | "disable list module" 88 | 89 | __makl_no_list () 90 | { 91 | makl_set_var "NO_LIST" ; 92 | } 93 | 94 | # 95 | # --no_array 96 | # 97 | makl_args_def \ 98 | "no_array" \ 99 | "" "" \ 100 | "disable array module" 101 | 102 | __makl_no_array () 103 | { 104 | makl_set_var "NO_ARRAY" ; 105 | } 106 | 107 | # 108 | # --no_ringbuffer 109 | # 110 | makl_args_def \ 111 | "no_ringbuffer" \ 112 | "" "" \ 113 | "disable ring buffer module" 114 | 115 | __makl_no_ringbuffer () 116 | { 117 | makl_set_var "NO_RB" ; 118 | } 119 | 120 | # 121 | # --no_pqueue 122 | # 123 | makl_args_def \ 124 | "no_pqueue" \ 125 | "" "" \ 126 | "disable priority queue module" 127 | 128 | __makl_no_pqueue () 129 | { 130 | makl_set_var "NO_PQUEUE" ; 131 | } 132 | 133 | # 134 | # --no_bst 135 | # 136 | makl_args_def \ 137 | "no_bst" \ 138 | "" "" \ 139 | "disable binary search tree module" 140 | 141 | __makl_no_bst () 142 | { 143 | makl_set_var "NO_BST" ; 144 | } 145 | 146 | # 147 | # --no_b64 148 | # 149 | makl_args_def \ 150 | "no_b64" \ 151 | "" "" \ 152 | "disable base64 codec module" 153 | 154 | __makl_no_b64 () 155 | { 156 | makl_set_var "NO_B64" ; 157 | } 158 | 159 | # 160 | # --no_json 161 | # 162 | makl_args_def \ 163 | "no_json" \ 164 | "" "" \ 165 | "disable JSON module" 166 | 167 | __makl_no_json () 168 | { 169 | makl_set_var "NO_JSON" ; 170 | } 171 | 172 | # 173 | # --no_test 174 | # 175 | makl_args_def \ 176 | "no_test" \ 177 | "" "" \ 178 | "disable unit test module" 179 | 180 | __makl_no_test () 181 | { 182 | makl_set_var "NO_TEST" ; 183 | } 184 | 185 | # 186 | # --no_docs 187 | # 188 | makl_args_def \ 189 | "no_docs" \ 190 | "" "" \ 191 | "avoid documentation" 192 | 193 | __makl_no_docs () 194 | { 195 | makl_set_var "NO_DOCS" ; 196 | } 197 | 198 | # 199 | # --do_test 200 | # 201 | makl_args_def \ 202 | "do_test" \ 203 | "" "" \ 204 | "run unit test" 205 | 206 | __makl_do_test () 207 | { 208 | makl_set_var "DO_TEST" ; 209 | } 210 | -------------------------------------------------------------------------------- /build/mk_support: -------------------------------------------------------------------------------- 1 | # $Id: mk_support,v 1.2 2009/12/24 18:04:36 tho Exp $ 2 | 3 | # 4 | # --no_ipv6 5 | # 6 | makl_args_def \ 7 | "no_ipv6" \ 8 | "" "" \ 9 | "disable IPv6 support" 10 | 11 | __makl_no_ipv6 () 12 | { 13 | makl_set_var "NO_IPV6" ; 14 | } 15 | 16 | # 17 | # --no_unixsock 18 | # 19 | makl_args_def \ 20 | "no_unixsock" \ 21 | "" "" \ 22 | "disable Unix socket support" 23 | 24 | __makl_no_unixsock () 25 | { 26 | makl_set_var "NO_UNIXSOCK" ; 27 | } 28 | 29 | # 30 | # --no_sctp 31 | # 32 | makl_args_def \ 33 | "no_sctp" \ 34 | "" "" \ 35 | "disable SCTP protocol support" 36 | 37 | __makl_no_sctp () 38 | { 39 | makl_set_var "NO_SCTP" ; 40 | } 41 | -------------------------------------------------------------------------------- /configure.help: -------------------------------------------------------------------------------- 1 | 2 | 'MaKL' - a painless C project configuration tool 3 | 4 | Usage: ./CONFIGURE_SCRIPT [OPTION] ... 5 | 6 | OPTION can be defined as follows: 7 | 8 | --help [-h] display this help 9 | --help_gen [-g] generate new configure.help based on configuration 10 | --verbose [-v] show verbose debugging output 11 | --version [-V] display MaKL version 12 | --cross_compile configure for cross-compilation (no execution tests) 13 | --noclean do not clean cache at end of execution (testing only) 14 | --prefix=BASE set BASE directory for installation [BASE=/usr/local] 15 | --dir-bin=BASE set BASE directory for binaries [BASE=/usr/local/bin] 16 | --dir-sbin=BASE set BASE directory for sys binaries [BASE=/usr/local/sbin] 17 | --dir-conf=BASE set BASE directory for configuration [BASE=/usr/local/conf] 18 | --dir-inc=BASE set BASE directory for includes [BASE=/usr/local/includes] 19 | --dir-lib=BASE set BASE directory for libraries [BASE=/usr/local/lib] 20 | --dir-shlib=BASE set BASE directory for shared libs [BASE=/usr/local/shlib] 21 | --dir-libex=BASE set BASE directory for binaries executed by other programs 22 | [BASE=/usr/local/libexec] 23 | --dir-var=BASE set BASE directory for multi-purpose (log, temp, spool) dir 24 | [BASE=/usr/local/var] 25 | --dir-share=BASE set BASE directory for shared data [BASE=/usr/local/share] 26 | --dir-man=BASE set BASE directory for man pages [BASE=/usr/local/share/man] 27 | --dir-doc=BASE set BASE directory for docs [BASE=/usr/local/share/doc] 28 | 29 | --defown=USERID set default file owner id 30 | --defgrp=GROUPID set default file group id 31 | --defmode=MODE set default mode for regular files 32 | --defbinmode=MODE set default mode for binary files 33 | --lib-X=BASE set libX to have BASE dir [BASE=/usr/local:/usr] 34 | --libs=BASE set all libs to have BASE dir 35 | 36 | --featx-doxygen=BASE set file for execution feature [] 37 | 38 | --enable-X=ID enable feature of type X and id ID 39 | --disable-X=ID disable feature of type X and id ID 40 | --enable_shared enable shared library build 41 | --enable_profile enables profiling via gprof (GCC only) 42 | --enable_warns set CFLAGS for extra warnings 43 | --enable_debug enable debugging support: carpal verbose output and CC 44 | debug flags 45 | 46 | --no_hmap disable hmap module 47 | --no_config disable config module 48 | --no_net disable net module 49 | --no_env disable env module 50 | --no_fs disable fs module 51 | --no_pwd disable pwd module 52 | --no_list disable list module 53 | --no_array disable array module 54 | --no_ringbuffer disable ring buffer module 55 | --no_pqueue disable priority queue module 56 | --no_bst disable binary search tree module 57 | --no_json disable JSON module 58 | --no_test disable unit test module 59 | --no_ipv6 disable IPv6 support 60 | --no_unixsock disable Unix socket support 61 | --no_sctp disable SCTP protocol support 62 | 63 | --no_docs don't build/install documentation 64 | --do_test build and run unit tests 65 | 66 | --compat_1X enable compatibility with libu 1.X 67 | --enable_icc_warns enable Intel CC warnings 68 | 69 | Legend: 70 | <*>: required dependency 71 | : optional dependency 72 | 73 | -------------------------------------------------------------------------------- /contrib/test_report.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | font-family: "Lucida Grande", Sans-Serif; 4 | font-size: 12px; 5 | } 6 | 7 | table 8 | { 9 | border-collapse: collapse; 10 | width: 100%; 11 | } 12 | 13 | td 14 | { 15 | vertical-align: top; 16 | } 17 | 18 | tr.heading 19 | { 20 | font-size: 16px; 21 | text-align: center; 22 | } 23 | 24 | table.syn 25 | { 26 | font-size: 13px; 27 | width: 30%; 28 | height: 50%; 29 | margin: auto; 30 | } 31 | 32 | div.syn 33 | { 34 | padding-top: 20px; 35 | padding-bottom: 20px; 36 | } 37 | 38 | tr.framed 39 | { 40 | border: 2px solid; 41 | } 42 | 43 | tr.PASS 44 | { 45 | background-color: #99CC99; 46 | border: 1px solid; 47 | } 48 | 49 | tr.FAIL 50 | { 51 | background-color: #CC9999; 52 | border: 1px solid; 53 | } 54 | 55 | tr.ABRT 56 | { 57 | background-color: #9999CC; 58 | border: 1px solid; 59 | } 60 | 61 | tr.SKIP 62 | { 63 | background-color: #C9C9C9; 64 | border: 1px solid; 65 | } 66 | 67 | td.ident 68 | { 69 | width: 200px; 70 | vertical-align: middle; 71 | font-weight: bold; 72 | text-align: center; 73 | } 74 | 75 | table.FAIL 76 | { 77 | background-color: #CC9999; 78 | } 79 | 80 | table.PASS 81 | { 82 | background-color: #99CC99; 83 | } 84 | 85 | table.ABRT 86 | { 87 | background-color: #9999CC; 88 | } 89 | 90 | table.SKIP 91 | { 92 | background-color: #C9C9C9; 93 | } 94 | -------------------------------------------------------------------------------- /contrib/test_report.xsl: -------------------------------------------------------------------------------- 1 | 2 | 8 | 14 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | ::<xsl:value-of select="@id" /> @ <xsl:value-of select="host" />:: 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 42 | 43 | 44 | 59 | 60 | 61 |
37 | 38 | 39 |
40 | 41 |
45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |
:
57 |
58 |
62 | 63 | 64 | 65 | 66 | 67 | 68 | 89 | 90 | 115 | 116 | 117 | 118 | 119 | 120 |
69 | 70 | 71 | 72 | 86 | 87 |
73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |
:
85 |
88 |
91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 110 | 111 | 112 | 113 |
99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 |
:
109 |
114 |
121 | 122 | 123 | 124 |
125 |
126 |
127 | 128 | 131 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.1 2005/09/23 13:04:37 tho Exp $ 2 | 3 | SUBDIR = man doxy 4 | 5 | include subdir.mk 6 | -------------------------------------------------------------------------------- /doc/doxy/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.6 2008/04/30 14:29:04 tho Exp $ 2 | 3 | include common.mk 4 | include ../../Makefile.conf 5 | 6 | ifdef HAVE_DOXYGEN 7 | 8 | all: 9 | $(PATH_DOXYGEN) libu.doxy 10 | mkdir -p html/images 11 | cp -r images html 12 | 13 | install: all 14 | mkdir -p ${DESTDIR}/doc/libu/ && cp -r html ${DESTDIR}/doc/libu/ 15 | 16 | uninstall: 17 | rm -rf ${DESTDIR}/doc/libu/ 18 | 19 | clean: 20 | rm -rf html/ 21 | 22 | else 23 | 24 | all clean install uninstall: 25 | 26 | endif 27 | 28 | depend cleandepend: 29 | -------------------------------------------------------------------------------- /doc/doxy/images/kl_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koanlogic/libu/3ea1f2748a3d2fe2f56f9243c73e69785f983822/doc/doxy/images/kl_bg.png -------------------------------------------------------------------------------- /doc/doxy/src/install.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * \page install Installation 3 | 4 | \section makl MaKL is a Prerequisite 5 | 6 | LibU needs MaKL to configure and build. 7 | 8 | The following commands should be sufficient to get MaKL installed on any Linux 9 | flavour or Darwin/MacOSX: 10 | \verbatim 11 | $ wget http://koanlogic.com/download/makl/makl-1.8.1.tar.gz 12 | $ tar zxf makl-1.8.1.tar.gz && cd makl-1.8.1 13 | $ sh configure.sh 14 | $ su 15 | Password: **** 16 | # make install 17 | \endverbatim 18 | Should your platform be one of Solaris, OpenSolaris, FreeBSD, PC-BSD, OpenBSD, 19 | NetBSD, DragonflyBSD or Windows (MinGW or Gygwin) take a look at the \c INSTALL 20 | file in the top-level MaKL sources directory to track down specific variations 21 | on the theme. 22 | 23 | \section download Download 24 | 25 | Once MaKL is there, you can start downloading the package (always check the 26 | official LibU page for the 27 | latest version and related ChangeLog) and tailor it to your specific needs: 28 | \verbatim 29 | $ wget http://koanlogic.com/download/libu/libu-2.0.0.tar.gz 30 | $ tar zxf libu-2.0.0.tar.gz && cd libu-2.0.0 31 | \endverbatim 32 | 33 | \section configure Configure 34 | 35 | E.g. should you need to change the default installation path (which is 36 | /usr/local), use: 37 | \verbatim 38 | $ makl-conf --prefix="/my/install/base/dir" 39 | \endverbatim 40 | 41 | Debug symbols and warnings from the compiler can be switched on via 42 | \c --enable_debug and \c --enable_warns (use \c --enable_icc_warns instead when 43 | working with the Intel C compiler): 44 | \verbatim 45 | $ makl-conf --enable_debug --enable_warns 46 | \endverbatim 47 | 48 | Code profiling using gprof(1) can be activated via \c --enable_profile, and 49 | in general any compiler flag can be passed to the build stage in the following 50 | way: 51 | \verbatim 52 | $ makl-conf --extra-cflags="-Wformat -Wno-format-extra-args -Wformat-security -Wformat-nonliteral -Wformat=2" 53 | \endverbatim 54 | The \c --extra-xxx="val" is indeed a powerful mechanism by which any Makefile 55 | variable \c XXX (uppercase!) can be given an additional value \c val: (ab)use 56 | it to tweak \c LDFLAGS, \c SHLIB_LDFLAGS, etc. as needed. Anyway if in doubt, 57 | or in search for exotic features, type "makl-conf -h" to display 58 | the complete list of options: it's likely that what you are trying to achieve 59 | is already there. 60 | 61 | By default LibU is compiled as static library, to also enable shared library 62 | build, supply the \c --enable_shared flag. 63 | 64 | \subsection modules Pick Up What Needs to be Included 65 | 66 | The default is to build all the modules, but you can disable the 67 | inclusion of specific bits selectively using the following switches: 68 | - \c --no_hmap: to disable the \ref hmap module 69 | - \c --no_config: to disable the \ref config module 70 | - \c --no_net: to disable the \ref net module 71 | - \c --no_env: to disable the \ref env module 72 | - \c --no_fs: to disable the \ref fs module 73 | - \c --no_pwd: to disable the \ref pwd module 74 | - \c --no_list: to disable the \ref list module 75 | - \c --no_array: to disable the \ref array module 76 | - \c --no_ringbuffer: to disable the \ref rb module 77 | - \c --no_pqueue: to disable the \ref pq module 78 | - \c --no_json: to disable the \ref json module 79 | - \c --no_bst: to disable the \ref bst module 80 | 81 | Also, some specific features regarding the networking code can be disabled 82 | at configuration: 83 | - \c --no_ipv6: to disable IPv6 protocol support 84 | - \c --no_sctp: to disable SCTP protocol support 85 | - \c --no_unixsock: to disable UNIX IPC support 86 | 87 | If you need to enable compatibility with (some, not all) 1.X interfaces, 88 | specify the \c --compat_1x command line switch. 89 | 90 | \section build Build, Test and Install 91 | 92 | When you are done with the configure step, you can build LibU bits and 93 | optionally test them: 94 | \verbatim 95 | $ makl 96 | $ makl -C test 97 | \endverbatim 98 | 99 | And finally install it: 100 | \verbatim 101 | $ su 102 | Password: **** 103 | # makl install 104 | \endverbatim 105 | 106 | \section hellolibu Hello LibU ! 107 | 108 | You now are ready to play with your first LibU program: 109 | 110 | \code 111 | $ cat main.c 112 | #include 113 | 114 | int facility = LOG_LOCAL0; 115 | 116 | int main (void) 117 | { 118 | u_con("Hello LibU world !"); 119 | return 0; 120 | } 121 | \endcode 122 | 123 | Write a Makefile like the following: 124 | 125 | \code 126 | $ cat Makefile 127 | include common.mk 128 | 129 | PROG = hellolibu 130 | SRCS = main.c 131 | 132 | LDADD += /path/to/install/prefix/lib/libu.a 133 | CFLAGS += -I/path/to/install/prefix/include 134 | 135 | include prog.mk 136 | \endcode 137 | 138 | Then type: 139 | \code 140 | $ makl && ./hellolibu 141 | \endcode 142 | 143 | and enjoy ! 144 | 145 | */ 146 | -------------------------------------------------------------------------------- /doc/doxy/src/kl_footer.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | ←Products 5 |
6 |
7 | © 2005-2012 - KoanLogic S.r.l. - All rights reserved 8 |
9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /doc/doxy/src/toc.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * \mainpage LibU 3 | 4 | LibU is a multiplatform C library which comes under a BSD-style license. This 5 | means that you are allowed unlimited redistribution for any purpose of LibU 6 | bits (in source or binary form), as long as you retain the copyright notices 7 | and the license's disclaimers of warranty: 8 | 9 | \code 10 | LibU - Copyright (c) 2005-2012 by KoanLogic srl 11 | All rights reserved. 12 | ... 13 | \endcode 14 | 15 | That said, LibU includes many interdependent modules for accomplishing several 16 | tasks: \ref alloc, \ref net and \ref uri parsing (as per RFC 3986), \ref json 17 | parsing (as per RFC 4627) \ref string manipulation, \ref carpal (with bundled 18 | debugging and logging functionalities) of C/C++ programs in a very compact way, 19 | plus many other \ref misc tasks. 20 | 21 | Also, it has built-in support for tree-structured \ref config files, or flat 22 | configuration files which are supplied through the running process \ref env. 23 | 24 | \ref hmap s using separate (sorted) chaining or linear probing, linked \ref 25 | list, an efficient \ref rb implementation, \ref array, \ref bst and \ref pq are 26 | all provided as building blocks for your custom data structures. 27 | 28 | A complete framework for handling authentication via \ref pwd like files, data 29 | \ref buf manipulation, a module for \ref test of C/C++ programs, and some 30 | commodity interfaces for playing safe with the \ref fs, completes the list of 31 | functionality. 32 | 33 | Also, a portability layer is included which gives replacement for functions 34 | that could be missing on some platforms, e.g. strlcat(3), strlcpy(3), 35 | gettimeofday(2), etc.; it provides uniform naming to absorb minor interface 36 | deltas between different platforms. 37 | 38 | Check the \ref install instructions and happy hacking ! 39 | 40 | */ 41 | -------------------------------------------------------------------------------- /doc/man/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.2 2006/01/31 17:08:13 tho Exp $ 2 | 3 | include common.mk 4 | include ../../Makefile.conf 5 | 6 | MANFILES = libu.3 u_alloc.3 u_config.3 u_debug.3 u_env.3 u_log.3 u_misc.3 \ 7 | u_net.3 u_str.3 u_uri.3 8 | 9 | include man.mk 10 | -------------------------------------------------------------------------------- /doc/man/libu.3: -------------------------------------------------------------------------------- 1 | .\" $Id: libu.3,v 1.1 2005/09/23 13:04:38 tho Exp $ 2 | -------------------------------------------------------------------------------- /doc/man/u_alloc.3: -------------------------------------------------------------------------------- 1 | .\" $Id: u_alloc.3,v 1.3 2005/10/01 17:04:51 tho Exp $ 2 | -------------------------------------------------------------------------------- /doc/man/u_config.3: -------------------------------------------------------------------------------- 1 | .\" $Id: u_config.3,v 1.1 2005/09/23 13:04:38 tho Exp $ 2 | -------------------------------------------------------------------------------- /doc/man/u_debug.3: -------------------------------------------------------------------------------- 1 | .\" $Id: u_debug.3,v 1.1 2005/09/23 13:04:38 tho Exp $ 2 | -------------------------------------------------------------------------------- /doc/man/u_env.3: -------------------------------------------------------------------------------- 1 | .\" $Id: u_env.3,v 1.1 2005/10/01 17:04:51 tho Exp $ 2 | -------------------------------------------------------------------------------- /doc/man/u_log.3: -------------------------------------------------------------------------------- 1 | .\" $Id: u_log.3,v 1.1 2005/10/01 17:04:51 tho Exp $ 2 | -------------------------------------------------------------------------------- /doc/man/u_memory.3: -------------------------------------------------------------------------------- 1 | .\" $Id: u_memory.3,v 1.1 2005/09/23 16:10:32 tho Exp $ 2 | -------------------------------------------------------------------------------- /doc/man/u_misc.3: -------------------------------------------------------------------------------- 1 | .\" $Id: u_misc.3,v 1.1 2005/09/23 13:04:38 tho Exp $ 2 | -------------------------------------------------------------------------------- /doc/man/u_net.3: -------------------------------------------------------------------------------- 1 | .\" $Id: u_net.3,v 1.1 2005/09/23 13:04:38 tho Exp $ 2 | -------------------------------------------------------------------------------- /doc/man/u_str.3: -------------------------------------------------------------------------------- 1 | .\" $Id: u_str.3,v 1.1 2005/09/23 13:04:38 tho Exp $ 2 | -------------------------------------------------------------------------------- /doc/man/u_uri.3: -------------------------------------------------------------------------------- 1 | .\" $Id: u_uri.3,v 1.1 2005/09/23 13:04:38 tho Exp $ 2 | -------------------------------------------------------------------------------- /example/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIR = net pwd config array uri rb 2 | 3 | include subdir.mk 4 | -------------------------------------------------------------------------------- /example/array/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.2 2008/06/26 16:03:39 tho Exp $ 2 | 3 | include common.mk 4 | include ../../Makefile.conf 5 | 6 | PROG = dynarray 7 | SRCS = main.c 8 | 9 | CFLAGS += -ggdb -DDEBUG 10 | CFLAGS += -W -Wall 11 | CFLAGS += -I../../include 12 | LDADD += ../../srcs/libu.a 13 | 14 | include prog.mk 15 | -------------------------------------------------------------------------------- /example/array/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int facility = LOG_LOCAL0; 4 | 5 | int main (void) 6 | { 7 | u_array_t *a = NULL; 8 | size_t idx; 9 | long double _Complex c0, c1; 10 | 11 | con_err_if (u_array_create(U_ARRAY_TYPE_LONG_DOUBLE_COMPLEX, 0, &a)); 12 | 13 | for (idx = 0; idx < 10; idx++) 14 | { 15 | c0 = idx + idx * _Complex_I; 16 | con_err_if (u_array_set_long_double_complex(a, idx, c0, NULL)); 17 | con_err_if (u_array_get_long_double_complex(a, idx, &c1)); 18 | con_err_if (creal(c0) != creal(c1) || cimag(c0) != cimag(c1)); 19 | } 20 | 21 | for (idx = 0; idx < 10; idx++) 22 | { 23 | long double _Complex c2; 24 | 25 | c0 = (idx + 10) + (idx + 10) * _Complex_I; 26 | con_err_if (u_array_set_long_double_complex(a, idx, c0, &c2)); 27 | u_con("overwrite %lf + %lfi at %zu with %lf + %lfi", 28 | creal(c2), cimag(c2), idx, creal(c0), cimag(c0)); 29 | con_err_if (u_array_get_long_double_complex(a, idx, &c1)); 30 | con_err_if (creal(c0) != creal(c1) || cimag(c0) != cimag(c1)); 31 | } 32 | 33 | /* index too high */ 34 | con_if (u_array_set_long_double_complex(a, 134217727, c0, NULL)); 35 | 36 | u_array_free(a); 37 | 38 | return 0; 39 | err: 40 | return 1; 41 | } 42 | -------------------------------------------------------------------------------- /example/blocks/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.2 2010/05/27 08:35:12 tho Exp $ 2 | 3 | include common.mk 4 | include ../../Makefile.conf 5 | 6 | PROG = blocks 7 | SRCS = main.c 8 | SRCS += blocks.c 9 | 10 | #CFLAGS += -ggdb -DDEBUG 11 | 12 | LDADD += $(SRCDIR)/srcs/libu.a 13 | 14 | include prog.mk 15 | -------------------------------------------------------------------------------- /example/blocks/blocks.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) KoanLogic Srl 2010 3 | */ 4 | 5 | #ifndef _BLOCKS_H_ 6 | #define _BLOCKS_H_ 7 | 8 | struct blocks_s; 9 | 10 | enum { 11 | BLOCKS_OPT_NONE = 0x00, /* Default is one big block of fixed size. */ 12 | BLOCKS_OPT_GROW = 0x01 /* More memory blocks are added if needed. */ 13 | }; 14 | 15 | typedef struct blocks_s blocks_t; 16 | 17 | int blocks_new (size_t blk_sz, unsigned char opts, blocks_t **pblks); 18 | void blocks_free (blocks_t *blks); 19 | void *blocks_alloc (blocks_t *blks, size_t len); 20 | int blocks_clear (blocks_t *blks); 21 | int blocks_copyout (blocks_t *blks, void *src, void *dst, size_t nbytes); 22 | int blocks_info (blocks_t *blks); 23 | 24 | #endif /* !_BLOCKS_H_ */ 25 | -------------------------------------------------------------------------------- /example/blocks/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "blocks.h" 3 | 4 | int facility = LOG_LOCAL0; 5 | 6 | struct alloc_tv_s 7 | { 8 | size_t blk_sz, alloc_sz, count; 9 | ssize_t exp_fail; 10 | const char *id; 11 | } tv_fixed[] = { 12 | { 4096, 10, 411, 410, "One block, tiny allocs (10 bytes each)" }, 13 | { 4096, 1, 4096, -1, "One block, micro allocs (1 byte each)" } 14 | }, tv_grow[] = { 15 | { 4096, 10, 1000, -1, "10 * 1K allocs, auto grow" } 16 | }; 17 | 18 | static int test_alloc (size_t blk_sz, size_t alloc_sz, size_t count, 19 | unsigned char opts, ssize_t exp_fail); 20 | static int test_grow (size_t blk_sz, size_t alloc_sz, size_t count, 21 | ssize_t exp_fail); 22 | static int test_fixed (size_t blk_sz, size_t alloc_sz, size_t count, 23 | ssize_t exp_fail); 24 | static void explain_tv (struct alloc_tv_s *T); 25 | static void br (void); 26 | 27 | int main (void) 28 | { 29 | size_t i; 30 | struct alloc_tv_s *F, *G; 31 | 32 | for (i = 0; i < sizeof(tv_fixed) / sizeof(struct alloc_tv_s); i++) 33 | { 34 | explain_tv((F = &tv_fixed[i])); 35 | con_err_if (test_fixed(F->blk_sz, F->alloc_sz, F->count, F->exp_fail)); 36 | } 37 | 38 | for (i = 0; i < sizeof(tv_grow) / sizeof(struct alloc_tv_s); i++) 39 | { 40 | explain_tv((G = &tv_grow[i])); 41 | con_err_if (test_grow(G->blk_sz, G->alloc_sz, G->count, G->exp_fail)); 42 | } 43 | 44 | return EXIT_SUCCESS; 45 | err: 46 | return EXIT_FAILURE; 47 | } 48 | 49 | static void explain_tv (struct alloc_tv_s *T) 50 | { 51 | u_con("\nTest: %s\n" 52 | " block size: %u\n" 53 | " size of each allocation: %u\n" 54 | " number of allocations: %u", 55 | T->id, T->blk_sz, T->alloc_sz, T->count); 56 | return; 57 | } 58 | 59 | static int test_fixed (size_t blk_sz, size_t alloc_sz, size_t count, 60 | ssize_t exp_fail) 61 | { 62 | return test_alloc(blk_sz, alloc_sz, count, BLOCKS_OPT_NONE, exp_fail); 63 | } 64 | 65 | static int test_grow (size_t blk_sz, size_t alloc_sz, size_t count, 66 | ssize_t exp_fail) 67 | { 68 | return test_alloc(blk_sz, alloc_sz, count, BLOCKS_OPT_GROW, exp_fail); 69 | } 70 | 71 | static int test_alloc (size_t blk_sz, size_t alloc_sz, size_t count, 72 | unsigned char opts, ssize_t exp_fail) 73 | { 74 | size_t i; 75 | unsigned char *p; 76 | blocks_t *blks; 77 | 78 | con_err_if (blocks_new(blk_sz, opts, &blks)); 79 | 80 | for (i = 1; i <= count; i++) 81 | { 82 | p = blocks_alloc(blks, alloc_sz); 83 | //u_con("[%u] %p = block_alloc(%p, %u)", i, p, blks, alloc_sz); 84 | dbg_goto_if (p == NULL, end); 85 | memset(p, 'X', alloc_sz); 86 | } 87 | 88 | end: 89 | err: 90 | (void) blocks_info(blks); 91 | 92 | if (blks) 93 | blocks_free(blks); 94 | 95 | return (exp_fail == -1) 96 | ? ((i != count + 1) ? ~0 : 0) 97 | : ((((size_t) exp_fail != i)) ? ~0 : 0); 98 | } 99 | 100 | static void br (void) { return; } 101 | -------------------------------------------------------------------------------- /example/bst/Makefile: -------------------------------------------------------------------------------- 1 | include common.mk 2 | include ../../Makefile.conf 3 | 4 | PROG = bst 5 | SRCS = main.c 6 | #SRCS += bst.c 7 | 8 | LDADD += $(SRCDIR)/srcs/libu.a 9 | CFLAGS += -ggdb 10 | 11 | include prog.mk 12 | -------------------------------------------------------------------------------- /example/bst/bst.h: -------------------------------------------------------------------------------- 1 | #ifndef _U_BST_H_ 2 | #define _U_BST_H_ 3 | 4 | struct u_bst_s; 5 | typedef struct u_bst_s u_bst_t; 6 | 7 | struct u_bst_node_s; 8 | typedef struct u_bst_node_s u_bst_node_t; 9 | 10 | typedef enum { 11 | U_BST_TYPE_STRING, 12 | U_BST_TYPE_OPAQUE, 13 | U_BST_TYPE_PTR 14 | } u_bst_type_t; 15 | 16 | typedef enum { 17 | U_BST_ROT_LEFT, 18 | U_BST_ROT_RIGHT 19 | } u_bst_rot_t; 20 | 21 | typedef enum { 22 | U_BST_OPT_NONE = 0, 23 | U_BST_OPT_PUSH_TOP = (1 << 0), /* New nodes are put on BST top. */ 24 | U_BST_OPT_PUSH_BOTTOM = (1 << 1), /* New nodes are put at BST bottom. */ 25 | U_BST_OPT_RANDOMIZED = (1 << 2) /* Randomized operations. */ 26 | } u_bst_opt_t; 27 | 28 | /* Base interface. */ 29 | int u_bst_new (int opts, u_bst_t **pbst); 30 | void u_bst_free (u_bst_t *bst); 31 | ssize_t u_bst_count (u_bst_t *bst); 32 | u_bst_node_t *u_bst_search (u_bst_t *bst, const void *key); 33 | int u_bst_push (u_bst_t *bst, const void *key, const void *val); 34 | int u_bst_foreach (u_bst_t *bst, void (*cb)(u_bst_node_t *, void *), 35 | void *cb_args); 36 | u_bst_node_t *u_bst_rotate (u_bst_node_t *node, u_bst_rot_t dir); 37 | int u_bst_empty (u_bst_t *bst); 38 | u_bst_node_t *u_bst_find_nth (u_bst_t *bst, size_t n); 39 | int u_bst_delete (u_bst_t *bst, const void *key); 40 | int u_bst_balance (u_bst_t *bst); 41 | 42 | /* BST configuration. */ 43 | int u_bst_set_cmp (u_bst_t *bst, int (*f)(const void *, const void *)); 44 | int u_bst_set_keyattr (u_bst_t *bst, u_bst_type_t kt, size_t ks); 45 | int u_bst_set_valattr (u_bst_t *bst, u_bst_type_t vt, size_t vs); 46 | int u_bst_set_keyfree (u_bst_t *bst, void (*f)(void *)); 47 | int u_bst_set_valfree (u_bst_t *bst, void (*f)(void *)); 48 | 49 | /* Getters/Setters. */ 50 | const void *u_bst_node_key (u_bst_node_t *node); 51 | const void *u_bst_node_val (u_bst_node_t *node); 52 | ssize_t u_bst_node_count (u_bst_node_t *node); 53 | 54 | #endif /* !_U_BST_H_ */ 55 | -------------------------------------------------------------------------------- /example/bst/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "bst.h" 5 | 6 | #define NELEMS 11 7 | 8 | int facility = LOG_LOCAL0; 9 | 10 | static int intcmp (const void *i, const void *j); 11 | static void print_string (u_bst_node_t *node, void *dummy); 12 | static void print_int (u_bst_node_t *node, void *dummy); 13 | static int sort_random (int howmany); 14 | static int randomized_push (int howmany); 15 | static int search (void); 16 | static int intkeys_balance (void); 17 | 18 | int main (void) 19 | { 20 | srandom((unsigned long) getpid()); 21 | 22 | getchar(); 23 | con_err_if (intkeys_balance()); 24 | con_err_if (sort_random(NELEMS)); 25 | con_err_if (search()); 26 | con_err_if (randomized_push(NELEMS)); 27 | 28 | return 0; 29 | err: 30 | return 1; 31 | } 32 | 33 | /* TODO randomize the push ! */ 34 | static int search (void) 35 | { 36 | char c; 37 | u_bst_t *bst = NULL; 38 | u_bst_node_t *node; 39 | enum { A = 33, B = 125, C = (B - A) }; 40 | 41 | con_err_if (u_bst_new(U_BST_OPT_NONE, &bst)); 42 | 43 | /* printable chars except '~' */ 44 | for (c = B; c >= A; c--) 45 | { 46 | char key[2]; 47 | 48 | // (void) u_snprintf(key, sizeof key, "%c", ((c % C + 11) % C) + A); 49 | (void) u_snprintf(key, sizeof key, "%c", c); 50 | con_err_if (u_bst_push(bst, key, NULL)); 51 | } 52 | 53 | for (c = A; c <= B; c++) 54 | { 55 | char key[2]; 56 | 57 | (void) u_snprintf(key, sizeof key, "%c", c); 58 | con_err_ifm ((node = u_bst_search(bst, key)) == NULL, 59 | "key \'%s\' not found", key); 60 | con_err_if (strcmp((const char *) u_bst_node_key(node), key)); 61 | } 62 | 63 | /* search for '~' that wasn't pushed */ 64 | con_err_if (u_bst_search(bst, "~") != NULL); 65 | 66 | u_bst_free(bst); 67 | 68 | return 0; 69 | err: 70 | u_bst_free(bst); 71 | return ~0; 72 | } 73 | 74 | static int randomized_push (int howmany) 75 | { 76 | int i; 77 | u_bst_t *bst = NULL; 78 | 79 | con_err_if (u_bst_new(U_BST_OPT_RANDOMIZED, &bst)); 80 | 81 | /* see if a sequential insert sequence maps into a fairly balanced bst */ 82 | for (i = 0; i < howmany; i++) 83 | { 84 | char key[128]; 85 | 86 | (void) u_snprintf(key, sizeof key, "%d", i); 87 | con_err_if (u_bst_push(bst, key, NULL)); 88 | } 89 | 90 | (void) u_bst_foreach(bst, print_string, NULL); 91 | 92 | //u_bst_free(bst); 93 | 94 | return 0; 95 | err: 96 | u_bst_free(bst); 97 | return ~0; 98 | } 99 | 100 | static int sort_random (int howmany) 101 | { 102 | int i; 103 | u_bst_t *bst = NULL; 104 | 105 | /* always push new nodes to the top */ 106 | con_err_if (u_bst_new(U_BST_OPT_PUSH_TOP, &bst)); 107 | 108 | for (i = 0; i < howmany; i++) 109 | { 110 | char key[128]; 111 | 112 | (void) u_snprintf(key, sizeof key, "%12.12d", random()); 113 | con_err_if (u_bst_push(bst, key, NULL)); 114 | } 115 | 116 | u_con("number of nodes in BST: %zu", u_bst_count(bst)); 117 | 118 | (void) u_bst_foreach(bst, print_string, NULL); 119 | 120 | u_bst_free(bst); 121 | 122 | return 0; 123 | err: 124 | u_bst_free(bst); 125 | return ~0; 126 | } 127 | 128 | static void print_string (u_bst_node_t *node, void *dummy) 129 | { 130 | u_unused_args(dummy); 131 | 132 | u_con("[SORT] key: %s (weight: %zu)", 133 | (const char *) u_bst_node_key(node), u_bst_node_count(node)); 134 | 135 | return; 136 | } 137 | 138 | static void print_int (u_bst_node_t *node, void *dummy) 139 | { 140 | u_unused_args(dummy); 141 | 142 | u_con("[SORT] key: %d (weight: %zu)", 143 | *((const int *) u_bst_node_key(node)), u_bst_node_count(node)); 144 | 145 | return; 146 | } 147 | 148 | static int intcmp (const void *i, const void *j) 149 | { 150 | return *((const int *) i) - *((const int *) j); 151 | } 152 | 153 | static int intkeys_balance (void) 154 | { 155 | int key; 156 | size_t i; 157 | u_bst_t *bst = NULL; 158 | u_bst_node_t *node; 159 | 160 | con_err_if (u_bst_new(U_BST_OPT_NONE, &bst)); 161 | con_err_if (u_bst_set_cmp(bst, intcmp)); 162 | con_err_if (u_bst_set_keyattr(bst, U_BST_TYPE_OPAQUE, sizeof(int))); 163 | 164 | for (i = 0; i < NELEMS; i++) 165 | { 166 | key = (int) random(); 167 | con_err_if (u_bst_push(bst, (const void *) &key, NULL)); 168 | } 169 | 170 | (void) u_bst_foreach(bst, print_int, NULL); 171 | 172 | /* search 4th and 5th smallest key */ 173 | for (i = 3; i < 5; i++) 174 | { 175 | con_err_if ((node = u_bst_find_nth(bst, i)) == NULL); 176 | u_con("%zu-th key is %d", i + 1, *((const int *) u_bst_node_key(node))); 177 | } 178 | 179 | /* delete last inserted key */ 180 | u_con("deleting %d", key); 181 | con_err_if (u_bst_delete(bst, (const void *) &key)); 182 | 183 | /* try again (should fail) */ 184 | con_err_if (!u_bst_delete(bst, (const void *) &key)); 185 | 186 | (void) u_bst_foreach(bst, print_int, NULL); 187 | 188 | u_con("balance!"); 189 | con_err_if (u_bst_balance(bst)); 190 | 191 | (void) u_bst_foreach(bst, print_int, NULL); 192 | 193 | u_bst_free(bst); 194 | 195 | return 0; 196 | err: 197 | u_bst_free(bst); 198 | return ~0; 199 | } 200 | -------------------------------------------------------------------------------- /example/config/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.1 2008/04/30 16:12:54 tat Exp $ 2 | 3 | include common.mk 4 | 5 | PROG = uconfig 6 | SRCS = main.c 7 | 8 | CFLAGS += -ggdb -DDEBUG 9 | CFLAGS += -W -Wall -Wextra 10 | CFLAGS += -I../../include 11 | #LDFLAGS += -L../../srcs -lu 12 | LDADD += ../../srcs/libu.a 13 | 14 | include prog.mk 15 | -------------------------------------------------------------------------------- /example/config/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int facility = LOG_LOCAL0; 5 | 6 | static void usage(void) 7 | { 8 | u_con("usage: uconfig [-s] FILE"); 9 | exit(1); 10 | } 11 | 12 | static int cmp_by_key(u_config_t **pa, u_config_t **pb) 13 | { 14 | u_config_t *a = *pa, *b = *pb; 15 | const char *va, *vb; 16 | 17 | if((va = u_config_get_key(a)) == NULL) 18 | va = ""; 19 | 20 | if((vb = u_config_get_key(b)) == NULL) 21 | vb = ""; 22 | 23 | return strcmp(va, vb); 24 | } 25 | 26 | int main(int argc, char **argv) 27 | { 28 | u_config_t *c = NULL; 29 | const char *filename; 30 | int sort = 0; 31 | 32 | con_err_ifm(argc < 2, "usage: uconfig [-s] FILE"); 33 | 34 | if(argv[1][0] == '-') 35 | { 36 | filename = argv[2]; 37 | if(strcmp(argv[1], "-s")) 38 | usage(); 39 | sort++; 40 | } else 41 | filename = argv[1]; 42 | 43 | con_err_if(u_config_load_from_file(filename, &c)); 44 | 45 | if(sort) 46 | u_config_sort_children(c, cmp_by_key); 47 | 48 | u_config_print(c, 0); 49 | 50 | u_config_free(c); 51 | 52 | return 0; 53 | err: 54 | return 1; 55 | } 56 | -------------------------------------------------------------------------------- /example/json/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.2 2010/05/27 08:35:12 tho Exp $ 2 | 3 | include common.mk 4 | include ../../Makefile.conf 5 | 6 | PROG = json 7 | SRCS = main.c 8 | #SRCS += json.c 9 | 10 | #CFLAGS += -DJSON_LEX_DEBUG 11 | #CFLAGS += -DJSON_OBJ_DEBUG 12 | 13 | LDADD += $(SRCDIR)/srcs/libu.a 14 | LDFLAGS += -lm 15 | 16 | include prog.mk 17 | -------------------------------------------------------------------------------- /example/json/test/empty-array.json: -------------------------------------------------------------------------------- 1 | [ ] 2 | -------------------------------------------------------------------------------- /example/json/test/empty-object.json: -------------------------------------------------------------------------------- 1 | { } 2 | -------------------------------------------------------------------------------- /example/json/test/fatfree.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Jack (\"Bee\") Nimble", 3 | "format": { 4 | "type": "rect", 5 | "width": 1920, 6 | "height": 1080, 7 | "interlace": false, 8 | "frame rate": 24 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /example/json/test/geoson-multipolygon.json: -------------------------------------------------------------------------------- 1 | { "type": "MultiPolygon", 2 | "coordinates": [ 3 | [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], 4 | [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], 5 | [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example/json/test/geoson.json: -------------------------------------------------------------------------------- 1 | { "type": "FeatureCollection", 2 | "features": [ 3 | { "type": "Feature", 4 | "geometry": {"type": "Point", "coordinates": [102.0, 0.5]}, 5 | "properties": {"prop0": "value0"} 6 | }, 7 | { "type": "Feature", 8 | "geometry": { 9 | "type": "LineString", 10 | "coordinates": [ 11 | [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0] 12 | ] 13 | }, 14 | "properties": { 15 | "prop0": "value0", 16 | "prop1": 0.0 17 | } 18 | }, 19 | { "type": "Feature", 20 | "geometry": { 21 | "type": "Polygon", 22 | "coordinates": [ 23 | [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], 24 | [100.0, 1.0], [100.0, 0.0] ] 25 | ] 26 | }, 27 | "properties": { 28 | "prop0": "value0", 29 | "prop1": {"this": "that"} 30 | } 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /example/json/test/jsonrequest.json: -------------------------------------------------------------------------------- 1 | {"user":"doctoravatar@penzance.com","forecast":7,"t":"vlIj","zip":94089} 2 | -------------------------------------------------------------------------------- /example/json/test/matrix.json: -------------------------------------------------------------------------------- 1 | [ 2 | [0, -1, 0], 3 | [1, 0, 0], 4 | [0, 0, 1] 5 | ] 6 | -------------------------------------------------------------------------------- /example/json/test/weekdays.json: -------------------------------------------------------------------------------- 1 | ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] 2 | -------------------------------------------------------------------------------- /example/json/test/yamatrix.json: -------------------------------------------------------------------------------- 1 | [ 2 | [0, -1, 0], 3 | [1, 0, 0], 4 | [0, 0, 1], 5 | [ 6 | { "Three0": 30 }, 7 | { "Three1": 31 }, 8 | { "Three2_composite": 9 | { 10 | "three": 3, 11 | "two": 2 12 | } 13 | } 14 | ] 15 | ] 16 | 17 | -------------------------------------------------------------------------------- /example/net/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIR = cli 2 | SUBDIR += srv 3 | 4 | include subdir.mk 5 | -------------------------------------------------------------------------------- /example/net/cli/Makefile: -------------------------------------------------------------------------------- 1 | include common.mk 2 | include ../../../Makefile.conf 3 | 4 | PROG = net_c 5 | SRCS = main.c 6 | 7 | CFLAGS += -I$(SRCDIR)/include 8 | 9 | LDADD = $(SRCDIR)/srcs/libu.a 10 | 11 | include prog.mk 12 | -------------------------------------------------------------------------------- /example/net/cli/main.c: -------------------------------------------------------------------------------- 1 | /* $Id: main.c,v 1.7 2009/12/25 19:04:07 tho Exp $ */ 2 | 3 | #include 4 | #include 5 | 6 | int facility = LOG_LOCAL0; 7 | 8 | int main (int argc, char *argv[]) 9 | { 10 | int i, csd = -1; 11 | char s[1024] = { 0 }; 12 | 13 | con_err_ifm (argc < 2, "usage: %s [string...]", argv[0]); 14 | 15 | if (argc > 2) 16 | { 17 | for (i = 2; i < argc; ++i) 18 | con_err_ifm (u_strlcat(s, argv[i], sizeof s) || 19 | u_strlcat(s, " ", sizeof s), "string too long"); 20 | } 21 | else 22 | (void) u_strlcpy(s, "test string", sizeof s); 23 | 24 | con_err_sif ((csd = u_net_sock(argv[1], U_NET_CSOCK)) == -1); 25 | con_err_sif (u_write(csd, s, strlen(s) + 1) == -1); 26 | (void) close(csd); 27 | 28 | return EXIT_SUCCESS; 29 | err: 30 | U_CLOSE(csd); 31 | return EXIT_FAILURE; 32 | } 33 | -------------------------------------------------------------------------------- /example/net/srv/Makefile: -------------------------------------------------------------------------------- 1 | include common.mk 2 | include ../../../Makefile.conf 3 | 4 | PROG = net_s 5 | SRCS = main.c 6 | 7 | CFLAGS += -I$(SRCDIR)/include 8 | 9 | LDADD = $(SRCDIR)/srcs/libu.a 10 | 11 | include prog.mk 12 | -------------------------------------------------------------------------------- /example/net/srv/main.c: -------------------------------------------------------------------------------- 1 | /* $Id: main.c,v 1.8 2010/01/15 17:47:56 tho Exp $ */ 2 | 3 | #include 4 | #include 5 | 6 | int facility = LOG_LOCAL0; 7 | 8 | int main (int argc, char *argv[]) 9 | { 10 | u_net_addr_t *a = NULL; 11 | int sd = -1, asd = -1; 12 | struct sockaddr_storage sa; 13 | socklen_t sa_len = sizeof sa; 14 | char s[1024]; 15 | ssize_t rb; 16 | 17 | con_err_ifm (argc != 2, "usage: %s ", argv[0]); 18 | 19 | con_err_if (u_net_uri2addr(argv[1], U_NET_SSOCK, &a)); 20 | 21 | con_err_sif ((sd = u_net_sd_by_addr(a)) == -1); 22 | 23 | /* only STREAM/SEQPACKET sockets need to call accept(2) */ 24 | asd = u_net_addr_can_accept(a) 25 | ? u_accept(sd, (struct sockaddr *) &sa, &sa_len) : sd; 26 | con_err_sif (asd == -1); 27 | 28 | /* read data */ 29 | con_err_sif ((rb = recvfrom(asd, s, sizeof s, 0, 30 | (struct sockaddr *) &sa, &sa_len)) == -1); 31 | u_con("read: %s", s); 32 | 33 | /* dtors */ 34 | u_net_addr_free(a); 35 | (void) close(sd); 36 | (void) close(asd); 37 | 38 | return EXIT_SUCCESS; 39 | err: 40 | if (a) 41 | u_net_addr_free(a); 42 | U_CLOSE(sd); 43 | U_CLOSE(asd); 44 | return EXIT_FAILURE; 45 | } 46 | -------------------------------------------------------------------------------- /example/pqueue/Makefile: -------------------------------------------------------------------------------- 1 | include common.mk 2 | include ../../Makefile.conf 3 | 4 | PROG = pqueue 5 | SRCS = main.c 6 | SRCS += pqueue.c 7 | 8 | LDADD += $(SRCDIR)/srcs/libu.a 9 | CFLAGS += -fstack-protector 10 | CFLAGS += -ggdb 11 | 12 | include prog.mk 13 | -------------------------------------------------------------------------------- /example/pqueue/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "pqueue.h" 6 | 7 | int facility = LOG_LOCAL0; 8 | 9 | static int sort (void); 10 | static int stack (void); 11 | static int top10 (void); 12 | 13 | int main (void) 14 | { 15 | con_err_if (top10()); 16 | con_err_if (sort()); 17 | con_err_if (stack()); 18 | 19 | return EXIT_SUCCESS; 20 | err: 21 | return EXIT_FAILURE; 22 | } 23 | 24 | static int top10 (void) 25 | { 26 | size_t i; 27 | double key, keymax = DBL_MAX; 28 | pq_t *pq = NULL; 29 | 30 | srandom((unsigned long) getpid()); 31 | 32 | con_err_if (pq_create(10, &pq)); 33 | 34 | for (i = 0; i < 1000000; i++) 35 | { 36 | if (!pq_empty(pq)) 37 | (void) pq_peekmax(pq, &keymax); 38 | 39 | if ((key = (double) random()) > keymax) 40 | continue; 41 | 42 | if (pq_full(pq)) 43 | (void) pq_delmax(pq, NULL); 44 | 45 | con_err_if (pq_push(pq, key, NULL)); 46 | } 47 | 48 | for (i = 0; i < 10; i++) 49 | { 50 | (void) pq_delmax(pq, &key); 51 | u_con("%zu: %lf", i, key); 52 | } 53 | 54 | return 0; 55 | err: 56 | pq_free(pq); 57 | return ~0; 58 | } 59 | 60 | static int sort (void) 61 | { 62 | size_t i; 63 | double key, prev_key = -1; 64 | pq_t *pq = NULL; 65 | 66 | srandom((unsigned long) getpid()); 67 | 68 | con_err_if (pq_create(1000, &pq)); 69 | 70 | for (i = 0; i < 999; i++) 71 | con_err_if (pq_push(pq, (double) random(), NULL)); 72 | 73 | while (!pq_empty(pq)) 74 | { 75 | (void) pq_delmax(pq, &key); 76 | con_err_if (prev_key != -1 && key < prev_key); 77 | prev_key = key; 78 | } 79 | 80 | pq_free(pq); 81 | 82 | return 0; 83 | err: 84 | pq_free(pq); 85 | return ~0; 86 | } 87 | 88 | static int stack (void) 89 | { 90 | double key, key2; 91 | pq_t *pq = NULL; 92 | 93 | con_err_if (pq_create(10, &pq)); 94 | 95 | for (key = 0; key < 1000; key++) 96 | { 97 | con_err_if (pq_push(pq, key, NULL)); 98 | (void) pq_delmax(pq, &key2); 99 | con_err_if (key != key2); 100 | } 101 | 102 | pq_free(pq); 103 | 104 | return 0; 105 | err: 106 | pq_free(pq); 107 | return ~0; 108 | } 109 | -------------------------------------------------------------------------------- /example/pqueue/pqueue.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. 3 | */ 4 | 5 | #include 6 | #include "pqueue.h" 7 | 8 | struct pq_item_s 9 | { 10 | double key; 11 | void *val; 12 | }; 13 | 14 | struct pq_s 15 | { 16 | size_t nelems, nitems; 17 | pq_item_t *q; 18 | }; 19 | 20 | static int pq_item_comp (pq_item_t *pi, pq_item_t *pj); 21 | static void pq_item_swap (pq_item_t *pi, pq_item_t *pj); 22 | static void bubble_up (pq_item_t *pi, size_t k); 23 | static void bubble_down (pq_item_t *pi, size_t k, size_t n); 24 | 25 | int pq_create (size_t nitems, pq_t **ppq) 26 | { 27 | pq_t *pq = NULL; 28 | 29 | dbg_return_if (ppq == NULL, ~0); 30 | dbg_return_if (nitems < 2, ~0); /* Expect at least 2 elements. */ 31 | 32 | /* Make room for both the queue head and items' array. */ 33 | dbg_err_sif ((pq = u_zalloc(sizeof *pq)) == NULL); 34 | dbg_err_sif ((pq->q = u_zalloc((nitems + 1) * sizeof(pq_item_t))) == NULL); 35 | 36 | /* Init the index of last element in array: valid elements are stored 37 | * at index'es [1..nitems]. */ 38 | pq->nelems = 0; 39 | pq->nitems = nitems; 40 | 41 | *ppq = pq; 42 | 43 | return 0; 44 | err: 45 | pq_free(pq); 46 | return ~0; 47 | } 48 | 49 | int pq_empty (pq_t *pq) 50 | { 51 | return (pq->nelems == 0); 52 | } 53 | 54 | int pq_full (pq_t *pq) 55 | { 56 | return (pq->nelems == pq->nitems); 57 | } 58 | 59 | void pq_free (pq_t *pq) 60 | { 61 | dbg_return_if (pq == NULL, ); 62 | 63 | if (pq->q) 64 | u_free(pq->q); 65 | u_free(pq); 66 | 67 | return; 68 | } 69 | 70 | /* -1: error 71 | * -2: would overflow 72 | * 0: ok */ 73 | int pq_push (pq_t *pq, double key, const void *val) 74 | { 75 | pq_item_t *pi; 76 | 77 | dbg_return_if (pq == NULL, -1); 78 | 79 | /* Queue full, would overflow. */ 80 | if (pq_full(pq)) 81 | return -2; 82 | 83 | pq->nelems += 1; 84 | 85 | /* Get next free slot (from heap bottom). */ 86 | pi = &pq->q[pq->nelems]; 87 | 88 | /* Assign element. */ 89 | pi->key = key; 90 | memcpy(&pi->val, &val, sizeof(void **)); 91 | 92 | /* Fix heap condition bottom-up. */ 93 | bubble_up(pq->q, pq->nelems); 94 | 95 | return 0; 96 | } 97 | 98 | /* Is meaningful only when !pq_empty(pq) */ 99 | void *pq_peekmax (pq_t *pq, double *pkey) 100 | { 101 | pq_item_t *pmax = &pq->q[pq->nelems]; 102 | 103 | if (pkey) 104 | *pkey = pmax->key; 105 | 106 | return pmax->val; 107 | } 108 | 109 | /* Is meaningful only when !pq_empty(pq) */ 110 | void *pq_delmax (pq_t *pq, double *pkey) 111 | { 112 | pq_item_t *pmax; 113 | 114 | dbg_return_if (pq == NULL, NULL); 115 | 116 | /* Empty queue. XXX NULL is legitimate ... */ 117 | if (pq->nelems == 0) 118 | return NULL; 119 | 120 | /* Exchange top and bottom items. */ 121 | pq_item_swap(&pq->q[1], &pq->q[pq->nelems]); 122 | 123 | /* Fix heap condition top-down excluding the evicted item. */ 124 | bubble_down(pq->q, 1, pq->nelems - 1); 125 | 126 | pmax = &pq->q[pq->nelems]; 127 | 128 | pq->nelems -= 1; 129 | 130 | /* Copy out the deleted key if requested. */ 131 | if (pkey) 132 | *pkey = pmax->key; 133 | 134 | return pmax->val; 135 | } 136 | 137 | static void pq_item_swap (pq_item_t *pi, pq_item_t *pj) 138 | { 139 | void *tmpval = pi->val; 140 | double tmpkey = pi->key; 141 | 142 | pi->key = pj->key; 143 | pi->val = pj->val; 144 | 145 | pj->key = tmpkey; 146 | pj->val = tmpval; 147 | 148 | return; 149 | } 150 | 151 | static int pq_item_comp (pq_item_t *pi, pq_item_t *pj) 152 | { 153 | return (pi->key > pj->key); 154 | } 155 | 156 | static void bubble_up (pq_item_t *pi, size_t k) 157 | { 158 | /* Move from bottom to top exchanging child with its parent node until 159 | * child is higher than parent, or we've reached the top. */ 160 | while (k > 1 && pq_item_comp(&pi[k / 2], &pi[k])) 161 | { 162 | pq_item_swap(&pi[k], &pi[k / 2]); 163 | k = k / 2; 164 | } 165 | 166 | return; 167 | } 168 | 169 | static void bubble_down (pq_item_t *pi, size_t k, size_t n) 170 | { 171 | size_t j; 172 | 173 | /* Move from top to bottom exchanging the parent node with the highest 174 | * of its children, until the "moving" node is higher then both of them - 175 | * or we've reached the bottom. */ 176 | while (2 * k <= n) 177 | { 178 | j = 2 * k; 179 | 180 | /* Choose to go left or right depending on who's bigger. */ 181 | if (j < n && pq_item_comp(&pi[j], &pi[j + 1])) 182 | j++; 183 | 184 | if (!pq_item_comp(&pi[k], &pi[j])) 185 | break; 186 | 187 | pq_item_swap(&pi[k], &pi[j]); 188 | 189 | k = j; 190 | } 191 | 192 | return; 193 | } 194 | -------------------------------------------------------------------------------- /example/pqueue/pqueue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. 3 | */ 4 | 5 | #ifndef _PQUEUE_H_ 6 | #define _PQUEUE_H_ 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif /* __cplusplus */ 11 | 12 | /** 13 | * \addtogroup grouptag 14 | * \{ 15 | */ 16 | 17 | struct pq_item_s; 18 | struct pq_s; 19 | 20 | typedef struct pq_item_s pq_item_t; 21 | typedef struct pq_s pq_t; 22 | 23 | int pq_create (size_t maxitems, pq_t **ppq); 24 | int pq_push (pq_t *pq, double key, const void *val); 25 | void *pq_delmax (pq_t *pq, double *pkey); 26 | void *pq_peekmax (pq_t *pq, double *pkey); 27 | int pq_empty (pq_t *pq); 28 | int pq_full (pq_t *pq); 29 | void pq_free (pq_t *pq); 30 | 31 | /** 32 | * \} 33 | */ 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif /* __cplusplus */ 38 | 39 | #endif /* !_PQUEUE_H_ */ 40 | -------------------------------------------------------------------------------- /example/pwd/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.2 2008/03/18 10:38:04 tho Exp $ 2 | 3 | include common.mk 4 | 5 | PROG = pwd 6 | SRCS = main.c 7 | 8 | CFLAGS += -ggdb -DDEBUG 9 | CFLAGS += -W -Wall 10 | CFLAGS += -I../../include 11 | #LDFLAGS += -L../../srcs -lu 12 | LDADD += ../../srcs/libu.a 13 | 14 | include prog.mk 15 | -------------------------------------------------------------------------------- /example/pwd/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int facility = LOG_LOCAL0; 6 | 7 | int main (int argc, char *argv[]) 8 | { 9 | char c; 10 | int i, rc, in_memory = 0; 11 | u_pwd_t *pwd = NULL; 12 | char prompt[128]; 13 | 14 | while ((c = getopt(argc, argv, "m")) != -1) 15 | { 16 | switch (c) 17 | { 18 | case 'm': 19 | ++in_memory; 20 | break; 21 | default: 22 | con_err("usage: pwd [-m] user ..."); 23 | } 24 | } 25 | 26 | argc -= optind; 27 | argv += optind; 28 | 29 | con_err_if (u_pwd_init_file("./passwd", NULL, 0, in_memory, &pwd)); 30 | 31 | for (i = 0; i < argc; i++) 32 | { 33 | u_snprintf(prompt, sizeof prompt, "%s: ", argv[i]); 34 | rc = u_pwd_auth_user(pwd, argv[i], getpass(prompt)); 35 | u_con("auth %s", rc ? "failed" : "ok"); 36 | } 37 | 38 | u_pwd_term(pwd); 39 | 40 | return EXIT_SUCCESS; 41 | err: 42 | return EXIT_FAILURE; 43 | } 44 | -------------------------------------------------------------------------------- /example/pwd/passwd: -------------------------------------------------------------------------------- 1 | tho:tho 2 | tat:tat 3 | stewy:stewy 4 | -------------------------------------------------------------------------------- /example/rb/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.2 2010/03/26 21:02:58 tho Exp $ 2 | 3 | include common.mk 4 | include ../../Makefile.conf 5 | 6 | PROG = urb 7 | SRCS = main.c 8 | 9 | CFLAGS += -ggdb -DDEBUG 10 | CFLAGS += -I../../include 11 | LDADD += ../../srcs/libu.a 12 | 13 | include prog.mk 14 | -------------------------------------------------------------------------------- /example/rb/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int facility = LOG_LOCAL0; 5 | 6 | static void dumpbuf (const char *b, size_t blen); 7 | 8 | static int test_full (int opts); 9 | static int test_empty (int opts); 10 | static int test_advance (int opts); 11 | static int test_full_advance (int opts); 12 | 13 | static int readc (u_rb_t *rb, char *pexpected); 14 | 15 | static int writec (u_rb_t *rb, char c); 16 | static int write1 (u_rb_t *rb) { return writec(rb, '1'); } 17 | static int write2 (u_rb_t *rb) { return writec(rb, '2'); } 18 | static int write3 (u_rb_t *rb) { return writec(rb, '3'); } 19 | static const char *bp (const char *s) { return s; } 20 | 21 | int main (void) 22 | { 23 | int opts = U_RB_OPT_IMPL_MALLOC | U_RB_OPT_USE_CONTIGUOUS_MEM; 24 | 25 | con_err_if (test_full(opts)); 26 | con_err_if (test_empty(opts)); 27 | con_err_if (test_advance(opts)); 28 | con_err_if (test_full_advance(opts)); 29 | 30 | return 0; 31 | err: 32 | return 1; 33 | } 34 | 35 | static int test_full (int opts) 36 | { 37 | enum { SZ = 2 }; 38 | u_rb_t *rb = NULL; 39 | 40 | con_err_if (u_rb_create(SZ, opts, &rb)); 41 | con_err_if (write1(rb)); 42 | con_err_if (write2(rb)); 43 | con_err_if (write3(rb) == 0); /* overflow, write3 must fail */ 44 | 45 | return 0; 46 | err: 47 | return 1; 48 | } 49 | 50 | static int test_empty (int opts) 51 | { 52 | enum { SZ = 3 }; 53 | u_rb_t *rb = NULL; 54 | 55 | con_err_if (u_rb_create(SZ, opts, &rb)); 56 | con_err_if (readc(rb, NULL) == 0); /* underflow, readc() must fail */ 57 | 58 | return 0; 59 | err: 60 | return 1; 61 | } 62 | 63 | static int test_advance (int opts) 64 | { 65 | char c; 66 | enum { SZ = 3 }; 67 | u_rb_t *rb = NULL; 68 | 69 | con_err_if (u_rb_create(SZ, opts, &rb)); 70 | 71 | for (c = 0; c < 127; c++) 72 | { 73 | if (!isprint(c)) 74 | continue; 75 | con_err_if (writec(rb, c)); 76 | con_err_if (readc(rb, &c)); 77 | } 78 | 79 | return 0; 80 | err: 81 | return 1; 82 | } 83 | 84 | static int test_full_advance (int opts) 85 | { 86 | int i; 87 | char c, prev, star = '*'; 88 | enum { SZ = 3 }; 89 | u_rb_t *rb = NULL; 90 | 91 | con_err_if (u_rb_create(SZ, opts, &rb)); 92 | 93 | /* fill the rb */ 94 | for (i = 0; i < SZ; i++) 95 | con_err_if (writec(rb, star)); 96 | 97 | for (c = 32; c < 126; c++) 98 | { 99 | if (c < (SZ + 32)) 100 | con_err_if (readc(rb, &star)); 101 | else 102 | { 103 | prev = c - SZ; 104 | con_err_if (readc(rb, &prev)); 105 | } 106 | 107 | con_err_if (writec(rb, c)); 108 | } 109 | 110 | return 0; 111 | err: 112 | return 1; 113 | } 114 | 115 | static int writec (u_rb_t *rb, char c) 116 | { 117 | ssize_t rc; 118 | u_con("writing \'%c\'", c); 119 | rc = u_rb_write(rb, &c, 1); 120 | return (rc != 1); 121 | } 122 | 123 | static int readc (u_rb_t *rb, char *pexpected) 124 | { 125 | char c; 126 | ssize_t rc = u_rb_read(rb, &c, 1); 127 | 128 | if (rc != 1) 129 | return ~0; 130 | else if (pexpected && *pexpected != c) 131 | { 132 | u_con("expect \'%c\', got \'%c\'", *pexpected, c); 133 | return ~0; 134 | } 135 | 136 | u_con("read \'%c\'", pexpected ? *pexpected : '?'); 137 | return 0; 138 | } 139 | 140 | static void dumpbuf (const char *b, size_t blen) 141 | { 142 | size_t i; 143 | 144 | printf("(%p)[%zu]: ", b, blen); 145 | for (i = 0; i < blen; i++) 146 | printf("\'%c\' ", b[i]); 147 | printf("\n"); 148 | 149 | return; 150 | } 151 | -------------------------------------------------------------------------------- /example/unitest/Makefile: -------------------------------------------------------------------------------- 1 | include common.mk 2 | include ../../Makefile.conf 3 | 4 | PROG = test 5 | SRCS = main.c 6 | SRCS += test.c 7 | 8 | LDADD += $(SRCDIR)/srcs/libu.a 9 | CFLAGS += -fstack-protector 10 | 11 | include prog.mk 12 | -------------------------------------------------------------------------------- /example/unitest/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "test.h" 3 | 4 | int facility = LOG_LOCAL0; 5 | 6 | int TC_1_1 (test_case_t *tc); 7 | int TC_1_2 (test_case_t *tc); 8 | int TC_2_1 (test_case_t *tc); 9 | int TC_2_2 (test_case_t *tc); 10 | 11 | int test_suite_TS1_register (test_t *t); 12 | int test_suite_TS2_register (test_t *t); 13 | 14 | int main (int argc, char *argv[]) 15 | { 16 | test_t *t = NULL; 17 | 18 | con_err_if (test_new("MY_TEST", &t)); 19 | con_err_if (test_suite_TS1_register(t)); 20 | con_err_if (test_suite_TS2_register(t)); 21 | con_err_if (test_run(argc, argv, t)); 22 | 23 | test_free(t); 24 | 25 | return EXIT_SUCCESS; 26 | err: 27 | test_free(t); 28 | return EXIT_FAILURE; 29 | } 30 | 31 | /* should go in a separate file */ 32 | 33 | int test_suite_TS1_register (test_t *t) 34 | { 35 | test_suite_t *ts = NULL; 36 | 37 | /* 38 | * - test suite "TS 1": 39 | * - test case "TC 1.1" which depends on "TC 1.2" 40 | * - test case "TC 1.2" 41 | */ 42 | con_err_if (test_suite_new("TS 1", &ts)); 43 | con_err_if (test_case_register("TC 1.1", TC_1_1, ts)); 44 | con_err_if (test_case_register("TC 1.2", TC_1_2, ts)); 45 | con_err_if (test_case_depends_on("TC 1.1", "TC 1.2", ts)); 46 | 47 | return test_suite_add(ts, t); 48 | err: 49 | test_suite_free(ts); 50 | return ~0; 51 | } 52 | 53 | int test_suite_TS2_register (test_t *t) 54 | { 55 | test_suite_t *ts = NULL; 56 | 57 | /* 58 | * - test suite "TS 2" which depends on "TS 1" 59 | * - test case "TC 2.1" 60 | * - test case "TC 2.2" 61 | */ 62 | con_err_if (test_suite_new("TS 2", &ts)); 63 | con_err_if (test_case_register("TC 2.1", TC_2_1, ts)); 64 | con_err_if (test_case_register("TC 2.2", TC_2_2, ts)); 65 | con_err_if (test_suite_dep_register("TS 1", ts)); 66 | 67 | return test_suite_add(ts, t); 68 | err: 69 | test_suite_free(ts); 70 | return ~0; 71 | } 72 | 73 | 74 | 75 | /* 76 | * fake test cases 77 | */ 78 | int TC_1_1 (test_case_t *tc) 79 | { 80 | char *x = malloc(10); 81 | 82 | u_con("hello TC_1_1"); 83 | return TEST_SUCCESS; 84 | } 85 | 86 | int TC_1_2 (test_case_t *tc) 87 | { 88 | unsigned int ts = 5; 89 | char *x = malloc(1000); 90 | 91 | u_con("hello TC_1_2 (sleeping)"); 92 | 93 | again: 94 | ts = sleep(ts); 95 | if (ts > 0 && errno == EINTR) 96 | goto again; 97 | 98 | return TEST_SUCCESS; 99 | } 100 | 101 | int TC_2_1 (test_case_t *tc) 102 | { 103 | unsigned int ts = 2; 104 | char *x = malloc(1000); 105 | 106 | u_con("hello TC_2_1"); 107 | 108 | again: 109 | ts = sleep(ts); 110 | if (ts > 0 && errno == EINTR) 111 | goto again; 112 | 113 | return TEST_SUCCESS; 114 | } 115 | 116 | int TC_2_2 (test_case_t *tc) 117 | { 118 | char r[1]; 119 | char *x = malloc(100); 120 | u_con("hello TC_2_2"); 121 | return TEST_SUCCESS; 122 | } 123 | -------------------------------------------------------------------------------- /example/unitest/test.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ... 3 | */ 4 | 5 | #ifndef _TEST__H_ 6 | #define _TEST__H_ 7 | 8 | struct test_case_s; 9 | typedef struct test_case_s test_case_t; 10 | 11 | struct test_suite_s; 12 | typedef struct test_suite_s test_suite_t; 13 | 14 | struct test_s; 15 | typedef struct test_s test_t; 16 | 17 | /* Exit status of unit tests. */ 18 | enum { 19 | TEST_SUCCESS = 0, /* All test assertions got right */ 20 | TEST_FAILURE = 1, /* Any test assertion has failed */ 21 | TEST_ABORTED = 2, /* Any non-regular execution condition (e.g. SIGSEGV) */ 22 | TEST_SKIPPED = 3 /* A previous dependency failure prevents execution */ 23 | }; 24 | 25 | typedef enum { TEST_CASE_T, TEST_SUITE_T } test_what_t; 26 | typedef enum { TEST_REP_HEAD, TEST_REP_TAIL } test_rep_tag_t; 27 | 28 | /* Unit test function prototype. */ 29 | typedef int (*test_f)(test_case_t *); 30 | 31 | /* Report functions' prototypes. */ 32 | typedef int (*test_rep_f)(FILE *, test_t *, test_rep_tag_t); 33 | typedef int (*test_case_rep_f)(FILE *, test_case_t *); 34 | typedef int (*test_suite_rep_f)(FILE *, test_suite_t *, test_rep_tag_t); 35 | 36 | /* Maximum number of running test cases. */ 37 | #ifndef TEST_MAX_PARALLEL 38 | #define TEST_MAX_PARALLEL 32 39 | #endif /* !TEST_MAX_PARALLEL */ 40 | 41 | /* Max len of a test suite/case identifier */ 42 | #ifndef TEST_ID_MAX 43 | #define TEST_ID_MAX 128 44 | #endif /* !TEST_ID_MAX */ 45 | 46 | /* Default test report file name */ 47 | #ifndef TEST_OUTFN_DFL 48 | #define TEST_OUTFN_DFL "./unitest-report.out" 49 | #endif /* !TEST_OUTFN_DFL */ 50 | 51 | int test_case_new (const char *id, test_f func, test_case_t **ptc); 52 | int test_case_add (test_case_t *tc, test_suite_t *ts); 53 | void test_case_free (test_case_t *tc); 54 | int test_case_register (const char *id, test_f func, test_suite_t *ts); 55 | int test_case_dep_register (const char *id, test_case_t *tc); 56 | int test_case_depends_on (const char *tcid, const char *depid, 57 | test_suite_t *ts); 58 | 59 | int test_suite_add (test_suite_t *to, test_t *t); 60 | void test_suite_free (test_suite_t *ts); 61 | int test_suite_new (const char *id, test_suite_t **pts); 62 | int test_suite_dep_register (const char *id, test_suite_t *ts); 63 | int test_suite_depends_on (const char *tsid, const char *depid, test_t *t); 64 | 65 | int test_new (const char *id, test_t **pt); 66 | int test_set_outfn (test_t *t, const char *outfn); 67 | int test_set_test_suite_rep (test_t *t, test_suite_rep_f func); 68 | int test_set_test_case_rep (test_t *t, test_case_rep_f func); 69 | int test_set_test_rep (test_t *t, test_rep_f func); 70 | 71 | void test_free (test_t *t); 72 | int test_run (int ac, char *av[], test_t *t); 73 | 74 | #endif /* !_TEST__H_ */ 75 | -------------------------------------------------------------------------------- /example/uri/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.1 2010/01/12 17:14:49 tho Exp $ 2 | 3 | include common.mk 4 | 5 | PROG = uuri 6 | SRCS = main.c 7 | 8 | CFLAGS += -ggdb -DDEBUG 9 | CFLAGS += -I../../include 10 | LDADD += ../../srcs/libu.a 11 | 12 | include prog.mk 13 | -------------------------------------------------------------------------------- /example/uri/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int facility = LOG_LOCAL0; 4 | 5 | int main (int ac, char *av[]) 6 | { 7 | u_uri_t *u = NULL; 8 | 9 | con_err_ifm (ac != 2, "uuri "); 10 | 11 | con_err_ifm (u_uri_crumble(av[1], 0, &u), "URI parse error"); 12 | u_uri_print(u, 0); 13 | u_uri_free(u); 14 | 15 | return 0; 16 | err: 17 | if (u) 18 | u_uri_free(u); 19 | return 1; 20 | } 21 | -------------------------------------------------------------------------------- /include/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.1 2006/11/20 13:36:12 tho Exp $ 2 | 3 | include common.mk 4 | include ../Makefile.conf 5 | 6 | SUBDIR = u toolbox missing 7 | 8 | include subdir.mk 9 | -------------------------------------------------------------------------------- /include/missing/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.3 2008/05/09 07:58:15 tho Exp $ 2 | 3 | include common.mk 4 | include ../../Makefile.conf 5 | 6 | INCS = $(wildcard *.h) 7 | INCDIR := $(INCDIR)/missing 8 | 9 | include incs.mk 10 | -------------------------------------------------------------------------------- /include/missing/daemon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _LIBU_DAEMON_H_ 6 | #define _LIBU_DAEMON_H_ 7 | 8 | #include 9 | 10 | #ifdef HAVE_DAEMON 11 | #ifdef HAVE_STDLIB 12 | #include 13 | #endif 14 | #ifdef HAVE_UNISTD 15 | #include 16 | #endif 17 | #else /* !HAVE_DAEMON */ 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | int daemon(int nochdir, int noclose); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif /* HAVE_DAEMON */ 30 | 31 | #endif /* !_LIBU_DAEMON_H_ */ 32 | -------------------------------------------------------------------------------- /include/missing/fnmatch.h: -------------------------------------------------------------------------------- 1 | /* $NetBSD: fnmatch.h,v 1.12 2005/02/03 04:39:32 perry Exp $ */ 2 | 3 | /*- 4 | * Copyright (c) 1992, 1993 5 | * The Regents of the University of California. All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. Neither the name of the University nor the names of its contributors 16 | * may be used to endorse or promote products derived from this software 17 | * without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | * SUCH DAMAGE. 30 | * 31 | * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93 32 | */ 33 | 34 | #ifndef _LIBU_FNMATCH_H_ 35 | #define _LIBU_FNMATCH_H_ 36 | #include 37 | 38 | #ifdef HAVE_FNMATCH 39 | #include 40 | #else 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | #define FNM_NOMATCH 1 /* Match failed. */ 47 | #define FNM_NOSYS 2 /* Function not implemented. */ 48 | 49 | #define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ 50 | #define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ 51 | #define FNM_PERIOD 0x04 /* Period must be matched by period. */ 52 | 53 | #define FNM_CASEFOLD 0x08 /* Pattern is matched case-insensitive */ 54 | #define FNM_LEADING_DIR 0x10 /* Ignore / after Imatch. */ 55 | 56 | int fnmatch(const char *, const char *, int); 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif /* ! HAVE_FNMATCH */ 63 | 64 | #endif /* ! _LIBU_FNMATCH_H_ */ 65 | -------------------------------------------------------------------------------- /include/missing/getpid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _LIBU_GETPID_H_ 6 | #define _LIBU_GETPID_H_ 7 | 8 | #include 9 | 10 | #ifdef HAVE_GETPID 11 | #include 12 | #include 13 | #else /* !HAVE_GETPID */ 14 | 15 | #ifdef OS_WIN 16 | #include 17 | typedef DWORD pid_t; 18 | #else /* !OS_WIN */ 19 | typedef unsigned int pid_t; 20 | #endif 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | pid_t getpid(void); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | #endif /* HAVE_GETPID */ 33 | 34 | #endif /* !_LIBU_GETPID_H_ */ 35 | -------------------------------------------------------------------------------- /include/missing/gettimeofday.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | #ifndef _LIBU_GETTIMEOFDAY_H_ 5 | #define _LIBU_GETTIMEOFDAY_H_ 6 | #include 7 | #include 8 | #include 9 | 10 | #ifndef HAVE_GETTIMEOFDAY 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | struct timezone 17 | { 18 | int tz_minuteswest; 19 | int tz_dsttime; 20 | }; 21 | 22 | int gettimeofday(struct timeval *tp, struct timezone *tzp); 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif 27 | 28 | #endif /* HAVE_GETTIMEOFDAY */ 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/missing/mkstemps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _LIBU_MKSTEMPS_H_ 6 | #define _LIBU_MKSTEMPS_H_ 7 | 8 | #include 9 | 10 | #ifdef HAVE_MKSTEMPS 11 | #include 12 | #else /* !HAVE_MKSTEMPS */ 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | int mkstemps (char *template, int suffixlen); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif /* __cplusplus */ 23 | 24 | #endif /* HAVE_MKTEMP */ 25 | 26 | #endif /* !_LIBU_MKSTEMPS_H_ */ 27 | -------------------------------------------------------------------------------- /include/missing/setenv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _LIBU_SETENV_H_ 6 | #define _LIBU_SETENV_H_ 7 | 8 | #include 9 | 10 | #ifdef HAVE_SETENV 11 | #include 12 | #else /* !HAVE_SETENV */ 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | int setenv(const char *name, const char *value, int overwrite); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif /* HAVE_SETENV */ 25 | #endif /* !_LIBU_SETENV_H_ */ 26 | -------------------------------------------------------------------------------- /include/missing/strlcat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | #ifndef _LIBU_STRLCAT_H_ 5 | #define _LIBU_STRLCAT_H_ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #ifdef HAVE_STRLCAT 12 | #include 13 | #else /* !HAVE_STRLCAT */ 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif /* __cplusplus */ 18 | 19 | size_t strlcat(char *dst, const char *src, size_t siz); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif /* __cplusplus */ 24 | 25 | #endif /* HAVE_STRLCAT */ 26 | 27 | #endif /* !_LIBU_STRLCAT_H_ */ 28 | -------------------------------------------------------------------------------- /include/missing/strlcpy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | #ifndef _LIBU_STRLCPY_H_ 5 | #define _LIBU_STRLCPY_H_ 6 | 7 | #include 8 | #include 9 | 10 | #ifdef HAVE_STRLCPY 11 | #include 12 | #else /* !HAVE_STRLCPY */ 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | size_t strlcpy(char *dst, const char *src, size_t siz); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif /* __cplusplus */ 23 | 24 | #endif /* HAVE_STRLCPY */ 25 | 26 | #endif /* !_LIBU_STRLCPY_H_ */ 27 | -------------------------------------------------------------------------------- /include/missing/strsep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | #ifndef _LIBU_STRSEP_H_ 5 | #define _LIBU_STRSEP_H_ 6 | 7 | #include 8 | 9 | #ifdef HAVE_STRSEP 10 | #include 11 | #else /* !HAVE_STRSEP */ 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif /* __cplusplus */ 16 | 17 | char *strsep(char **, const char *); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif /* __cplusplus */ 22 | 23 | #endif /* HAVE_STRSEP */ 24 | 25 | #endif /* _LIBU_STRSEP_H_ */ 26 | -------------------------------------------------------------------------------- /include/missing/strtok_r.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | #ifndef _LIBU_STRTOK_R_H_ 5 | #define _LIBU_STRTOK_R_H_ 6 | 7 | #include 8 | 9 | #ifdef HAVE_STRTOK_R 10 | #include 11 | #else /* !HAVE_STRTOK_R */ 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif /* __cplusplus */ 16 | 17 | char *strtok_r(char *s, const char *delim, char **last); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif /* __cplusplus */ 22 | 23 | #endif /* HAVE_STRTOK_R */ 24 | 25 | #endif /* !_LIBU_STRTOK_R_H_ */ 26 | -------------------------------------------------------------------------------- /include/missing/syslog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | #ifndef _LIBU_SYSLOG_H_ 5 | #define _LIBU_SYSLOG_H_ 6 | #include 7 | #include 8 | 9 | #ifdef HAVE_SYSLOG 10 | 11 | #include 12 | 13 | #else 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | /* level codes */ 20 | #define LOG_EMERG 0 21 | #define LOG_ALERT 1 22 | #define LOG_CRIT 2 23 | #define LOG_ERR 3 24 | #define LOG_WARNING 4 25 | #define LOG_NOTICE 5 26 | #define LOG_INFO 6 27 | #define LOG_DEBUG 7 28 | 29 | /* facility codes */ 30 | #define LOG_KERN (0<<3) 31 | #define LOG_USER (1<<3) 32 | #define LOG_MAIL (2<<3) 33 | #define LOG_DAEMON (3<<3) 34 | #define LOG_AUTH (4<<3) 35 | #define LOG_SYSLOG (5<<3) 36 | #define LOG_LPR (6<<3) 37 | #define LOG_NEWS (7<<3) 38 | #define LOG_UUCP (8<<3) 39 | #define LOG_CRON (9<<3) 40 | #define LOG_AUTHPRIV (10<<3) 41 | #define LOG_FTP (11<<3) 42 | #define LOG_NETINFO (12<<3) 43 | #define LOG_REMOTEAUTH (13<<3) 44 | #define LOG_INSTALL (14<<3) 45 | #define LOG_LOCAL0 (16<<3) 46 | #define LOG_LOCAL1 (17<<3) 47 | #define LOG_LOCAL2 (18<<3) 48 | #define LOG_LOCAL3 (19<<3) 49 | #define LOG_LOCAL4 (20<<3) 50 | #define LOG_LOCAL5 (21<<3) 51 | #define LOG_LOCAL6 (22<<3) 52 | #define LOG_LOCAL7 (23<<3) 53 | 54 | void syslog(int priority, const char *msg, ...); 55 | void vsyslog(int priority, const char *msg, va_list args); 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif /* !HAVE_SYSLOG */ 62 | 63 | #endif /* !_LIBU_SYSLOG_H_ */ 64 | -------------------------------------------------------------------------------- /include/missing/timegm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | #ifndef _LIBU_TIMEGM_H_ 5 | #define _LIBU_TIMEGM_H_ 6 | #include 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #ifndef HAVE_TIMEGM 14 | time_t timegm(struct tm *tm); 15 | #endif 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/missing/unlink.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | #ifndef _LIBU_UNLINK_H_ 5 | #define _LIBU_UNLINK_H_ 6 | #include 7 | 8 | #ifdef HAVE_UNLINK 9 | #include 10 | #else 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | int unlink(const char *pathname); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/missing/va.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | #ifndef _LIBU_VA_H_ 5 | #define _LIBU_VA_H_ 6 | #include 7 | 8 | #if defined(va_copy) 9 | /* C99 va_copy */ 10 | #define u_va_copy(a, b) va_copy(a, b) 11 | #elif defined(__va_copy) 12 | /* GNU libc va_copy replacement */ 13 | #define u_va_copy(a, b) __va_copy(a, b) 14 | #else 15 | #error "va_copy is not defined" 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/toolbox/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.6 2008/05/09 07:58:15 tho Exp $ 2 | 3 | include common.mk 4 | include ../../Makefile.conf 5 | 6 | INCS = $(wildcard *.h) 7 | INCDIR := $(INCDIR)/toolbox 8 | 9 | include incs.mk 10 | -------------------------------------------------------------------------------- /include/toolbox/b64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_B64_H_ 6 | #define _U_B64_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define U_B64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4) 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | int u_b64_encode (const uint8_t *in, size_t in_sz, char *out, size_t out_sz); 19 | int u_b64_decode (const char *in, size_t in_sz, uint8_t *out, size_t *out_sz); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif /* !_U_B64_H_ */ 26 | -------------------------------------------------------------------------------- /include/toolbox/bst.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_BST_H_ 6 | #define _U_BST_H_ 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif /* __cplusplus */ 14 | 15 | /* forward decls */ 16 | struct u_bst_s; 17 | struct u_bst_node_s; 18 | 19 | /** 20 | * \addtogroup bst 21 | * \{ 22 | */ 23 | 24 | /** \brief The binary search tree type. */ 25 | typedef struct u_bst_s u_bst_t; 26 | 27 | /** \brief The binary search tree node type. */ 28 | typedef struct u_bst_node_s u_bst_node_t; 29 | 30 | 31 | /** \brief Available types for BST containers. */ 32 | typedef enum { 33 | U_BST_TYPE_STRING, /**< String, i.e. NUL-terminated char array. */ 34 | U_BST_TYPE_OPAQUE, /**< Any type, given by its byte size. */ 35 | U_BST_TYPE_PTR /**< Pointer type. */ 36 | } u_bst_type_t; 37 | 38 | /** \brief BST rotation types */ 39 | typedef enum { 40 | U_BST_ROT_LEFT, /**< Left rotation. */ 41 | U_BST_ROT_RIGHT /**< Right rotation. */ 42 | } u_bst_rot_t; 43 | 44 | /** \brief BST customization options. */ 45 | typedef enum { 46 | U_BST_OPT_NONE = 0, 47 | U_BST_OPT_PUSH_TOP = (1 << 0), /**< New nodes added on BST top. */ 48 | U_BST_OPT_PUSH_BOTTOM = (1 << 1), /**< New nodes added at BST bottom. */ 49 | U_BST_OPT_RANDOMIZED = (1 << 2) /**< Operations are randomized. */ 50 | } u_bst_opt_t; 51 | 52 | /* Base interface. */ 53 | int u_bst_new (int opts, u_bst_t **pbst); 54 | void u_bst_free (u_bst_t *bst); 55 | ssize_t u_bst_count (u_bst_t *bst); 56 | u_bst_node_t *u_bst_search (u_bst_t *bst, const void *key); 57 | int u_bst_push (u_bst_t *bst, const void *key, const void *val); 58 | int u_bst_foreach (u_bst_t *bst, void (*cb)(u_bst_node_t *, void *), 59 | void *cb_args); 60 | u_bst_node_t *u_bst_rotate (u_bst_node_t *node, u_bst_rot_t dir); 61 | int u_bst_empty (u_bst_t *bst); 62 | u_bst_node_t *u_bst_find_nth (u_bst_t *bst, size_t n); 63 | int u_bst_delete (u_bst_t *bst, const void *key); 64 | int u_bst_balance (u_bst_t *bst); 65 | 66 | /* BST configuration. */ 67 | int u_bst_set_cmp (u_bst_t *bst, int (*f)(const void *, const void *)); 68 | int u_bst_set_keyattr (u_bst_t *bst, u_bst_type_t kt, size_t ks); 69 | int u_bst_set_valattr (u_bst_t *bst, u_bst_type_t vt, size_t vs); 70 | int u_bst_set_keyfree (u_bst_t *bst, void (*f)(void *)); 71 | int u_bst_set_valfree (u_bst_t *bst, void (*f)(void *)); 72 | 73 | /* Getters/Setters. */ 74 | const void *u_bst_node_key (u_bst_node_t *node); 75 | const void *u_bst_node_val (u_bst_node_t *node); 76 | ssize_t u_bst_node_count (u_bst_node_t *node); 77 | 78 | /** 79 | * \} 80 | */ 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif /* __cplusplus */ 85 | 86 | #endif /* !_U_BST_H_ */ 87 | -------------------------------------------------------------------------------- /include/toolbox/buf.h: -------------------------------------------------------------------------------- 1 | /* $Id: buf.h,v 1.5 2010/01/20 16:04:50 tho Exp $ */ 2 | 3 | #ifndef _U_LIBU_BUF_H_ 4 | #define _U_LIBU_BUF_H_ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /* forward decl */ 16 | struct u_buf_s; 17 | 18 | /** 19 | * \addtogroup buf 20 | * \{ 21 | */ 22 | 23 | /** \brief The basic buffer type. Internally it hides the data buffer 24 | * which can be accessed via ::u_buf_ptr, and related size indicators 25 | * (both total ::u_malloc'd buffer size, and the number of actually 26 | * used bytes) which are accessed via ::u_buf_size and ::u_buf_len 27 | * respectively. */ 28 | typedef struct u_buf_s u_buf_t; 29 | 30 | int u_buf_append (u_buf_t *buf, const void *data, size_t size); 31 | int u_buf_clear (u_buf_t *buf); 32 | int u_buf_create (u_buf_t **pbuf); 33 | int u_buf_detach (u_buf_t *buf); 34 | int u_buf_free (u_buf_t *buf); 35 | int u_buf_load (u_buf_t *buf, const char *fqn); 36 | int u_buf_printf (u_buf_t *ubuf, const char *fmt, ...); 37 | int u_buf_reserve (u_buf_t *buf, size_t size); 38 | int u_buf_save (u_buf_t *ubuf, const char *filename); 39 | int u_buf_set (u_buf_t *buf, const void *data, size_t size); 40 | ssize_t u_buf_len (u_buf_t *buf); 41 | ssize_t u_buf_size (u_buf_t *ubuf); 42 | void *u_buf_ptr (u_buf_t *buf); 43 | int u_buf_shrink(u_buf_t *ubuf, size_t newlen); 44 | 45 | /** 46 | * \} 47 | */ 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif /* !_U_LIBU_BUF_H_ */ 54 | -------------------------------------------------------------------------------- /include/toolbox/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_CONFIG_H_ 6 | #define _U_CONFIG_H_ 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /* forward decl */ 16 | struct u_config_s; 17 | 18 | /** 19 | * \addtogroup config 20 | * \{ 21 | */ 22 | 23 | /** \brief Configuration base type */ 24 | typedef struct u_config_s u_config_t; 25 | 26 | /** \brief Configuration loading driver callbacks */ 27 | struct u_config_driver_s 28 | { 29 | int (*open) (const char *uri, void **parg); 30 | /**< 31 | * Open the the resource pointed by \p uri and return its opaque handler 32 | * through the \p parg result argument. The \p *parg (e.g. a file stream 33 | * pointer in case of a file system ::u_config_driver_t) will be possibly 34 | * used by subsequent u_config_driver_s::close and u_config_driver_s::gets 35 | * callbacks. 36 | * 37 | * \retval 0 on success 38 | * \retval ~0 on failure 39 | */ 40 | 41 | int (*close) (void *arg); 42 | /**< 43 | * Close the (previously u_config_driver_s::open'ed) resource pointed by 44 | * \p arg. 45 | * 46 | * \retval 0 on success 47 | * \retval ~0 on failure 48 | */ 49 | 50 | char *(*gets) (void *arg, char *buf, size_t size); 51 | /**< 52 | * fgets(3)-like function using a generic resource pointer \p arg. 53 | * The function reads at most one less than the number of characters 54 | * specified by \p size from the resource handler pointed by \p arg, 55 | * and stores them in the string \p buf. Reading stops when a newline 56 | * character is found, at end-of-file or error. The newline, if any, 57 | * is retained. If any characters are read and there is no error, a 58 | * \c \\0 character is appended to end the string. 59 | * 60 | * \return Upon successful completion, a pointer to the string is 61 | * returned. If end-of-file occurs before any characters are 62 | * read, return \c NULL and the buffer contents remain 63 | * unchanged. If an error occurs, return \c NULL and the 64 | * buffer contents are indeterminate. 65 | */ 66 | 67 | int (*resolv) (const char *name, char *uri, size_t uri_bufsz); 68 | /**< 69 | * Resolver function for mapping relative to absolute resource names, 70 | * e.g. when handling an \c include directive from within another resource 71 | * object). In case of success, the resolved \p uri can be used as first 72 | * argument to a subsequent u_config_driver_s::open call. 73 | * The \p name argument is the relative resource name, \p uri is a 74 | * pre-alloc'd string of \p uri_bufsz bytes which will store the absolute 75 | * resource name in case the resolution is successful. 76 | * 77 | * \retval 0 on success 78 | * \retval ~0 on failure 79 | */ 80 | }; 81 | 82 | /** \brief Configuration loading driver type */ 83 | typedef struct u_config_driver_s u_config_driver_t; 84 | 85 | /** \brief Configuration tree walking strategies (See ::u_config_walk). */ 86 | typedef enum { 87 | U_CONFIG_WALK_PREORDER, /**< Visit the node, then its children. */ 88 | U_CONFIG_WALK_POSTORDER /**< Visit node's children, then the node. */ 89 | } u_config_walk_t; 90 | 91 | /** 92 | * \} 93 | */ 94 | 95 | int u_config_create(u_config_t **pc); 96 | int u_config_free(u_config_t *c); 97 | int u_config_load(u_config_t *c, int fd, int overwrite); 98 | 99 | int u_config_load_from_file (const char *file, u_config_t **pc); 100 | 101 | int u_config_load_from_drv(const char *uri, u_config_driver_t *drv, 102 | int overwrite, u_config_t **pc); 103 | 104 | typedef char* (*u_config_gets_t)(void *arg, char *buf, size_t size); 105 | int u_config_load_from(u_config_t *c, u_config_gets_t cb, 106 | void *arg, int overwrite); 107 | 108 | const char* u_config_get_key(u_config_t *c); 109 | const char* u_config_get_value(u_config_t *c); 110 | 111 | int u_config_get_subkey(u_config_t *c, const char *subkey, u_config_t **pc); 112 | int u_config_get_subkey_nth(u_config_t *c,const char *subkey, int n, 113 | u_config_t **pc); 114 | 115 | const char* u_config_get_subkey_value(u_config_t *c, const char *subkey); 116 | 117 | int u_config_get_subkey_value_b(u_config_t *c, const char *subkey, int def, 118 | int *out); 119 | int u_config_get_subkey_value_i(u_config_t *c, const char *subkey, int def, 120 | int *out); 121 | 122 | int u_config_add_key(u_config_t *c, const char *key, const char *val); 123 | int u_config_set_key(u_config_t *c, const char *key, const char *val); 124 | 125 | int u_config_add_child(u_config_t *c, const char *key, u_config_t **pc); 126 | int u_config_set_value(u_config_t *c, const char *val); 127 | u_config_t* u_config_get_child_n(u_config_t *c, const char *key, int n); 128 | u_config_t* u_config_get_child(u_config_t *c, const char *key); 129 | int u_config_del_child(u_config_t *c, u_config_t *child); 130 | 131 | int u_config_has_children(u_config_t *c); 132 | int u_config_save_to_buf(u_config_t *c, char *buf, size_t size); 133 | int u_config_load_from_buf(char *buf, size_t len, u_config_t **pc); 134 | 135 | void u_config_print_to_fp(u_config_t *c, FILE *fp, int lev); 136 | void u_config_print(u_config_t *c, int lev); 137 | 138 | int u_config_sort_children(u_config_t *c, int(*)(u_config_t**, u_config_t**)); 139 | void u_config_walk (u_config_t *c, u_config_walk_t s, void (*cb)(u_config_t *)); 140 | 141 | #ifdef __cplusplus 142 | } 143 | #endif 144 | 145 | #endif /* !_U_CONFIG_H_ */ 146 | -------------------------------------------------------------------------------- /include/toolbox/env.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_ENV_H_ 6 | #define _U_ENV_H_ 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | int u_env_init (const char *prefix, const char *cfile); 15 | const char *u_env_var (const char *name); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif /* !_U_ENV_H_ */ 22 | -------------------------------------------------------------------------------- /include/toolbox/fs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_FS_H_ 6 | #define _U_FS_H_ 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | int u_move(const char *src, const char *dst); 15 | int u_copy(const char *src, const char *dst); 16 | int u_remove(const char *file); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | 22 | #endif /* !_U_FS_H_ */ 23 | -------------------------------------------------------------------------------- /include/toolbox/json.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_JSON_H_ 6 | #define _U_JSON_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | /* Forward decls. */ 17 | struct u_json_s; 18 | 19 | /** 20 | * \addtogroup json 21 | * \{ 22 | */ 23 | 24 | /** \brief Internal representation of any JSON object */ 25 | typedef struct u_json_s u_json_t; 26 | 27 | /** \brief Opaque iterator for traversing arrays and objects. */ 28 | typedef struct { u_json_t *cur; } u_json_it_t; 29 | 30 | /** \brief Walk strategy when traversing JSON objects */ 31 | enum { 32 | U_JSON_WALK_PREORDER, /**< pre-order tree walk */ 33 | U_JSON_WALK_POSTORDER /**< post-order tree walk */ 34 | }; 35 | 36 | /** \brief JSON base types */ 37 | typedef enum { 38 | U_JSON_TYPE_UNKNOWN = 0, 39 | U_JSON_TYPE_STRING, /**< string type */ 40 | U_JSON_TYPE_NUMBER, /**< number (i.e. int, frac or exp) type */ 41 | U_JSON_TYPE_OBJECT, /**< object container */ 42 | U_JSON_TYPE_ARRAY, /**< array container */ 43 | U_JSON_TYPE_TRUE, /**< a boolean true value */ 44 | U_JSON_TYPE_FALSE, /**< a boolean false value */ 45 | U_JSON_TYPE_NULL /**< an explicit null value */ 46 | } u_json_type_t; 47 | 48 | 49 | /** \brief Size of access keys to JSON values (can be changed at compile time 50 | * via \c -DU_JSON_FQN_SZ=nnn flag) */ 51 | #ifndef U_JSON_FQN_SZ 52 | #define U_JSON_FQN_SZ 256 53 | #endif /* !U_JSON_FQN_SZ */ 54 | 55 | /** \brief Max nesting of JSON fields (can be changed at compile time 56 | * via \c -DU_JSON_MAX_DEPTH=nnn flag) */ 57 | #ifndef U_JSON_MAX_DEPTH 58 | #define U_JSON_MAX_DEPTH 16 59 | #endif /* !U_JSON_MAX_DEPTH */ 60 | 61 | /* Encode/Decode/Validate. */ 62 | int u_json_decode (const char *json, u_json_t **pjo); 63 | int u_json_encode (u_json_t *jo, char **ps); 64 | int u_json_validate (const char *json, char status[U_LEXER_ERR_SZ]); 65 | 66 | /* Cache creation/destruction. */ 67 | int u_json_index (u_json_t *jo); 68 | int u_json_unindex (u_json_t *jo); 69 | 70 | /* Cache-aided get/set operations. */ 71 | u_json_t *u_json_cache_get (u_json_t *jo, const char *name); 72 | const char *u_json_cache_get_val (u_json_t *jo, const char *name); 73 | int u_json_cache_get_int (u_json_t *jo, const char *name, long *pval); 74 | int u_json_cache_get_real (u_json_t *jo, const char *name, double *pval); 75 | int u_json_cache_get_bool (u_json_t *jo, const char *name, char *pval); 76 | 77 | int u_json_cache_set_tv (u_json_t *jo, const char *name, 78 | u_json_type_t type, const char *val); 79 | 80 | /* JSON base objects [cd]tor. */ 81 | int u_json_new (u_json_t **pjo); 82 | void u_json_free (u_json_t *jo); 83 | 84 | int u_json_new_object (const char *key, u_json_t **pjo); 85 | int u_json_new_array (const char *key, u_json_t **pjo); 86 | int u_json_new_string (const char *key, const char *val, u_json_t **pjo); 87 | int u_json_new_number (const char *key, const char *val, u_json_t **pjo); 88 | int u_json_new_real (const char *key, double val, u_json_t **pjo); 89 | int u_json_new_int (const char *key, long val, u_json_t **pjo); 90 | int u_json_new_null (const char *key, u_json_t **pjo); 91 | int u_json_new_bool (const char *key, char val, u_json_t **pjo); 92 | 93 | /* JSON base objects get/set/add/remove operations. */ 94 | int u_json_set_key (u_json_t *jo, const char *key); 95 | int u_json_set_val (u_json_t *jo, const char *val); 96 | int u_json_set_type (u_json_t *jo, u_json_type_t type); 97 | int u_json_add (u_json_t *head, u_json_t *jo); 98 | int u_json_remove (u_json_t *jo); 99 | const char *u_json_get_val (u_json_t *jo); 100 | int u_json_set_val_ex (u_json_t *jo, const char *val, char validate); 101 | int u_json_get_int (u_json_t *jo, long *pl); 102 | int u_json_get_real (u_json_t *jo, double *pd); 103 | int u_json_get_bool (u_json_t *jo, char *pb); 104 | 105 | /* Access to children of a container object. */ 106 | u_json_t *u_json_child_first (u_json_t *jo); 107 | u_json_t *u_json_child_last (u_json_t *jo); 108 | 109 | /* Array specific ops. */ 110 | unsigned int u_json_array_count (u_json_t *jo); 111 | u_json_t *u_json_array_get_nth (u_json_t *jo, unsigned int n); 112 | 113 | /* Misc. */ 114 | void u_json_print (u_json_t *jo); 115 | void u_json_walk (u_json_t *jo, int strategy, size_t l, 116 | void (*cb)(u_json_t *, size_t, void *), void *cb_args); 117 | 118 | /* Iterators. */ 119 | int u_json_it (u_json_t *jo, u_json_it_t *it); 120 | u_json_t *u_json_it_next (u_json_it_t *it); 121 | u_json_t *u_json_it_prev (u_json_it_t *it); 122 | 123 | /** 124 | * \} 125 | */ 126 | 127 | #ifdef __cplusplus 128 | } 129 | #endif 130 | 131 | #endif /* !_U_JSON_H_ */ 132 | -------------------------------------------------------------------------------- /include/toolbox/lexer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_LEXER_H_ 6 | #define _U_LEXER_H_ 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #ifndef U_LEXER_ERR_SZ 13 | #define U_LEXER_ERR_SZ 512 14 | #endif /* !U_LEXER_ERR_SZ */ 15 | 16 | struct u_lexer_s; 17 | 18 | /** 19 | * \addtogroup lexer 20 | * \{ 21 | */ 22 | 23 | /** \brief Lexer base type. */ 24 | typedef struct u_lexer_s u_lexer_t; 25 | 26 | /** \brief Maximum size of input tokens (can be changed at compile time via 27 | * \c -DU_TOKEN_SZ=nnn compiler flag) */ 28 | #ifndef U_TOKEN_SZ 29 | #define U_TOKEN_SZ 128 30 | #endif /* !U_TOKEN_SZ */ 31 | 32 | /* 33 | * All the following U_LEXER_ macros need the "err" label in scope. 34 | */ 35 | 36 | /** \brief ::u_lexer_pos wrapper. */ 37 | #define U_LEXER_ERR(l, ...) \ 38 | do { \ 39 | (void) u_lexer_seterr(l, __VA_ARGS__); \ 40 | goto err; \ 41 | } while (0) 42 | 43 | /** \brief ::u_lexer_skip wrapper. */ 44 | #define U_LEXER_SKIP(l, pc) \ 45 | do { \ 46 | if (u_lexer_skip(l, pc)) \ 47 | U_LEXER_ERR(l, "EOT at offset %zu", u_lexer_pos(l)); \ 48 | } while (0) 49 | 50 | /** \brief ::u_lexer_next wrapper. */ 51 | #define U_LEXER_NEXT(l, pc) \ 52 | do { \ 53 | if (u_lexer_next(l, pc)) \ 54 | U_LEXER_ERR(l, "EOT at offset %zu", u_lexer_pos(l)); \ 55 | } while (0) 56 | 57 | int u_lexer_new (const char *s, u_lexer_t **pl); 58 | void u_lexer_free (u_lexer_t *l); 59 | const char *u_lexer_geterr (u_lexer_t *l); 60 | 61 | int u_lexer_next (u_lexer_t *l, char *pb); 62 | int u_lexer_skip (u_lexer_t *l, char *pb); 63 | char u_lexer_peek (u_lexer_t *l); 64 | int u_lexer_seterr (u_lexer_t *l, const char *fmt, ...); 65 | void u_lexer_record_lmatch (u_lexer_t *l); 66 | void u_lexer_record_rmatch (u_lexer_t *l); 67 | char *u_lexer_get_match (u_lexer_t *l, char match[U_TOKEN_SZ]); 68 | int u_lexer_eot (u_lexer_t *l); 69 | int u_lexer_eat_ws (u_lexer_t *l); 70 | int u_lexer_expect_char (u_lexer_t *l, char expected); 71 | size_t u_lexer_pos (u_lexer_t *l); 72 | const char *u_lexer_lookahead (u_lexer_t *l); 73 | 74 | /** 75 | * \} 76 | */ 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif /* !_U_LEXER_H_ */ 83 | -------------------------------------------------------------------------------- /include/toolbox/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_LIST_H_ 6 | #define _U_LIST_H_ 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /* forward decl */ 15 | struct u_list_s; 16 | 17 | /** 18 | * \addtogroup list 19 | * \{ 20 | */ 21 | 22 | /** \brief Basic list object type */ 23 | typedef struct u_list_s u_list_t; 24 | 25 | /** \brief List iterator 26 | * 27 | * \param list an ::u_list_t object 28 | * \param n a variable that will get the current value from \p list 29 | * \param it an opaque iterator with type \c void** 30 | */ 31 | #define u_list_foreach(list, n, it) \ 32 | for(n = u_list_first(list, &it); n; n = u_list_next(list, &it)) 33 | 34 | /** \brief List iterator with iteration counter 35 | * 36 | * \param list an ::u_list_t object 37 | * \param n a variable that will get the current value from \p list 38 | * \param it an opaque iterator with type \c void** 39 | * \param i variable of type \c integer that will be get the iteration 40 | * counter (0..i) 41 | */ 42 | #define u_list_iforeach(list, n, it, i) \ 43 | for(i = 0, n = u_list_first(list, &it); n; n = u_list_next(list, &it), ++i) 44 | 45 | int u_list_create (u_list_t **plist); 46 | void u_list_free (u_list_t *list); 47 | int u_list_clear (u_list_t *list); 48 | int u_list_add (u_list_t *list, void *ptr); 49 | int u_list_insert (u_list_t *list, void *ptr, size_t n); 50 | int u_list_del (u_list_t *list, void *ptr); 51 | int u_list_del_n (u_list_t *list, size_t n, void **pptr); 52 | void *u_list_get_n (u_list_t *list, size_t n); 53 | size_t u_list_count (u_list_t *list); 54 | void *u_list_first (u_list_t *list, void **it); 55 | void *u_list_next (u_list_t *list, void **it); 56 | 57 | /** 58 | * \} 59 | */ 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif /* !_U_LIST_H_ */ 66 | -------------------------------------------------------------------------------- /include/toolbox/logprv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_LOGPRV_H_ 6 | #define _U_LOGPRV_H_ 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | enum { 16 | LOG_WRITE_FLAG_NONE, 17 | LOG_WRITE_FLAG_CTX /* include file:line in the output message */ 18 | }; 19 | 20 | #define u_log_write(fac, lev, flags, err, ...) \ 21 | u_log_write_ex(fac, lev, flags, err, __FILE__, __LINE__, __FUNCTION__, \ 22 | __VA_ARGS__) 23 | 24 | #define u_console_write(err, ...) \ 25 | u_console_write_ex(err, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__) 26 | 27 | int u_log_write_ex(int fac, int lev, int flags, int err, const char* file, 28 | int line, const char *func, const char* fmt, ...); 29 | 30 | int u_console_write_ex(int err, const char* file, int line, 31 | const char *func, const char* fmt, ...); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif /* !_U_LOGPRV_H_ */ 38 | -------------------------------------------------------------------------------- /include/toolbox/memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_ALLOC_H_ 6 | #define _U_ALLOC_H_ 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | void u_memory_set_malloc (void *(*f_malloc)(size_t)); 16 | void u_memory_set_calloc (void *(*f_calloc)(size_t, size_t)); 17 | void u_memory_set_realloc (void *(*f_realloc)(void *, size_t)); 18 | void u_memory_set_free (void (*f_free)(void *)); 19 | void *u_malloc (size_t sz); 20 | void *u_calloc (size_t cnt, size_t sz); 21 | void *u_zalloc (size_t sz); 22 | void *u_realloc (void *ptr, size_t sz); 23 | void u_free (void *ptr); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif /* !_U_ALLOC_H_ */ 30 | 31 | -------------------------------------------------------------------------------- /include/toolbox/misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_MISC_H_ 6 | #define _U_MISC_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | /** 20 | * \addtogroup misc 21 | * \{ 22 | */ 23 | 24 | /** \brief Maximum path length */ 25 | #ifndef PATH_MAX 26 | #define U_PATH_MAX 4096 27 | #else 28 | #define U_PATH_MAX PATH_MAX 29 | #endif 30 | 31 | /** \brief Maximum file name length */ 32 | #ifdef NAME_MAX 33 | #define U_NAME_MAX NAME_MAX 34 | #else 35 | #ifdef FILENAME_MAX 36 | #define U_NAME_MAX FILENAME_MAX 37 | #else 38 | #define U_NAME_MAX 512 39 | #endif 40 | #endif 41 | 42 | /** \brief Maximum length for a fully qualified file name */ 43 | #define U_FILENAME_MAX (U_PATH_MAX + U_NAME_MAX) 44 | 45 | #define U_CLOSE(fd) do {if (fd != -1) { close(fd); fd = -1; }} while (0) 46 | #define U_FCLOSE(fp) do {if (fp) { fclose(fp); fp = NULL; }} while (0) 47 | #define U_FREE(ptr) do { u_free(ptr); ptr = NULL; } while (0) 48 | #define U_FREEF(ptr, func) do {if (ptr) { func(ptr); ptr = NULL; }} while (0) 49 | #define U_MAX(a, b) ((a) > (b) ? (a) : (b)) 50 | #define U_MIN(a, b) ((a) < (b) ? (a) : (b)) 51 | #define U_ONCE if (({ static int __x = 0; int __y; __y = __x; __x = 1; !__y;})) 52 | #define U_PCLOSE(pp) do {if (pp) { pclose(pp); pp = NULL; }} while (0) 53 | #define U_SSTRCPY(to, from) u_sstrncpy((to), (from), sizeof(to) - 1) 54 | #define u_unused_args(...) u_use_unused_args(NULL, __VA_ARGS__) 55 | 56 | #define u_timersub(t1, t0, delta) \ 57 | do { \ 58 | (delta)->tv_sec = (t1)->tv_sec - (t0)->tv_sec; \ 59 | (delta)->tv_usec = (t1)->tv_usec - (t0)->tv_usec; \ 60 | if ((delta)->tv_usec < 0) \ 61 | { \ 62 | (delta)->tv_sec--; \ 63 | (delta)->tv_usec += 1000000; \ 64 | } \ 65 | } while (0) 66 | 67 | /** \brief Prototype for an I/O driver function used by ::u_io, e.g. \c read(2) 68 | * or \c write(2) */ 69 | typedef ssize_t (*iof_t) (int, void *, size_t); 70 | 71 | char *u_strdup (const char *s); 72 | char *u_strndup (const char *s, size_t len); 73 | int u_atol (const char *nptr, long *pl); 74 | int u_atoi (const char *nptr, int *pi); 75 | int u_atof (const char *nptr, double *pd); 76 | #ifdef HAVE_STRTOUMAX 77 | #include 78 | int u_atoumax (const char *nptr, uintmax_t *pumax); 79 | #endif /* HAVE_STRTOUMAX */ 80 | int u_data_dump (char *data, size_t sz, const char *file); 81 | int u_data_is_bin (char *data, size_t sz); 82 | int u_io (iof_t f, int sd, void *buf, size_t l, ssize_t *n, int *iseof); 83 | int u_isblank (int c); 84 | int u_isblank_str (const char *ln); 85 | int u_isnl (int c); 86 | int u_load_file (const char *path, size_t sz_max, char **pbuf, size_t *psz); 87 | int u_path_snprintf (char *str, size_t size, char sep, const char *fmt, ...); 88 | int u_savepid (const char *pf); 89 | int u_sleep (unsigned int secs); 90 | int u_snprintf (char *str, size_t size, const char *fmt, ...); 91 | int u_strlcat (char *dst, const char *src, size_t size); 92 | int u_strlcpy (char *dst, const char *src, size_t size); 93 | int u_strtok (const char *s, const char *delim, char ***ptv, size_t *pnelems); 94 | ssize_t u_read (int fd, void *buf, size_t size); 95 | ssize_t u_write (int fd, void *buf, size_t size); 96 | void u_strtok_cleanup (char **tv, size_t nelems); 97 | void u_trim (char *s); 98 | void u_use_unused_args (char *dummy, ...); 99 | void *u_memdup (const void *src, size_t size); 100 | 101 | /* depreacated interfaces */ 102 | int u_tokenize (char *wlist, const char *delim, char **tokv, size_t tokv_sz) \ 103 | __LIBU_DEPRECATED; 104 | char *u_sstrncpy (char *dst, const char *src, size_t size) \ 105 | __LIBU_DEPRECATED; 106 | 107 | /** 108 | * \} 109 | */ 110 | 111 | #ifdef __cplusplus 112 | } 113 | #endif 114 | 115 | #endif /* !_U_MISC_H_ */ 116 | -------------------------------------------------------------------------------- /include/toolbox/pqueue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. 3 | */ 4 | 5 | #ifndef _U_PQUEUE_H_ 6 | #define _U_PQUEUE_H_ 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif /* __cplusplus */ 11 | 12 | /* forward decl */ 13 | struct u_pq_s; 14 | 15 | /** 16 | * \addtogroup pq 17 | * \{ 18 | */ 19 | 20 | /** \brief The priority queue handler. */ 21 | typedef struct u_pq_s u_pq_t; 22 | 23 | int u_pq_create (size_t maxitems, u_pq_t **ppq); 24 | int u_pq_push (u_pq_t *pq, double key, const void *val); 25 | void *u_pq_delmax (u_pq_t *pq, double *pkey); 26 | void *u_pq_peekmax (u_pq_t *pq, double *pkey); 27 | int u_pq_empty (u_pq_t *pq); 28 | int u_pq_full (u_pq_t *pq); 29 | void u_pq_free (u_pq_t *pq); 30 | 31 | /** 32 | * \} 33 | */ 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif /* __cplusplus */ 38 | 39 | #endif /* !_U_PQUEUE_H_ */ 40 | -------------------------------------------------------------------------------- /include/toolbox/pwd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_PWD_H_ 6 | #define _U_PWD_H_ 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | 15 | /* forward decls */ 16 | struct u_pwd_s; 17 | struct u_pwd_rec_s; 18 | 19 | /** 20 | * \addtogroup pwd 21 | * \{ 22 | */ 23 | 24 | /** \brief default length of a password file line (can be changed at 25 | * compile time via \c -DU_PWD_LINE_MAX=nnn flag) */ 26 | #ifndef U_PWD_LINE_MAX 27 | #define U_PWD_LINE_MAX 256 28 | #endif /* !U_PWD_LINE_MAX */ 29 | 30 | /** \brief Base pwd object, mediates all operations over the password DB */ 31 | typedef struct u_pwd_s u_pwd_t; 32 | 33 | /** \brief Carry information about a single password DB record */ 34 | typedef struct u_pwd_rec_s u_pwd_rec_t; 35 | 36 | /** \brief Password hashing callback prototype: accept a string and its 37 | * lenght, return the hashed string */ 38 | typedef int (*u_pwd_hash_cb_t) (const char *, size_t, char []); 39 | 40 | /** \brief Record load callback prototype: has fgets(3)-like prototype with 41 | * generic storage resource handler */ 42 | typedef char *(*u_pwd_load_cb_t) (char *, int, void *); 43 | 44 | /** \brief Master password DB open callback prototype: accepts an uri, return 45 | * the (opaque) resource handler - the same that will be supplied to 46 | * the ::u_pwd_load_cb_t */ 47 | typedef int (*u_pwd_open_cb_t) (const char *, void **); 48 | 49 | /* \brief Master password DB close callback prototype: takes the resource 50 | * handler, return nothing */ 51 | typedef void (*u_pwd_close_cb_t) (void *); 52 | 53 | /** \brief Update notification callback prototype: return true if supplied 54 | * timestamp is older than last modification time (this will force 55 | * a reload for in-memory password DBs) */ 56 | typedef int (*u_pwd_notify_cb_t) (const char *, time_t, time_t *); 57 | 58 | /** 59 | * \} 60 | */ 61 | 62 | /* interface */ 63 | int u_pwd_init (const char *res_uri, u_pwd_open_cb_t cb_open, 64 | u_pwd_load_cb_t cb_load, u_pwd_close_cb_t cb_close, 65 | u_pwd_notify_cb_t cb_notify, u_pwd_hash_cb_t cb_hash, 66 | size_t hash_len, int in_memory, u_pwd_t **ppwd); 67 | int u_pwd_init_file (const char *res_uri, u_pwd_hash_cb_t cb_hash, 68 | size_t hash_len, int in_memory, u_pwd_t **ppwd); 69 | void u_pwd_term (u_pwd_t *pwd); 70 | int u_pwd_in_memory (u_pwd_t *pwd); 71 | int u_pwd_retr (u_pwd_t *pwd, const char *user, u_pwd_rec_t **prec); 72 | int u_pwd_auth_user (u_pwd_t *pwd, const char *user, const char *password); 73 | void u_pwd_rec_free (u_pwd_t *pwd, u_pwd_rec_t *rec); 74 | const char *u_pwd_rec_get_user (u_pwd_rec_t *rec); 75 | const char *u_pwd_rec_get_password (u_pwd_rec_t *rec); 76 | const char *u_pwd_rec_get_opaque (u_pwd_rec_t *rec); 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif /* !_U_PWD_H_ */ 83 | -------------------------------------------------------------------------------- /include/toolbox/rb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_RB_H_ 6 | #define _U_RB_H_ 7 | 8 | #include 9 | 10 | /* Test if we have all the pieces needed to provide the mmap-based 11 | * implementation. */ 12 | #if defined(HAVE_MMAP) && defined(HAVE_MAP_FIXED) && !defined(RB_INHIBIT_MMAP) 13 | #define U_RB_CAN_MMAP 14 | #endif 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif /* __cplusplus */ 19 | 20 | /* forward decl */ 21 | struct u_rb_s; 22 | 23 | /** 24 | * \addtogroup rb 25 | * \{ 26 | */ 27 | 28 | /** \brief The ring buffer type. */ 29 | typedef struct u_rb_s u_rb_t; 30 | 31 | /** \brief Options to tweak the ring buffer implementation */ 32 | typedef enum { 33 | U_RB_OPT_NONE = 0x00, 34 | /**< use default (depending on platform) creation method */ 35 | 36 | U_RB_OPT_USE_CONTIGUOUS_MEM = 0x01, 37 | /**< force implementation to use a contiguous memory buffer to store 38 | * ringbuffer data. This option enables the ::u_rb_fast_read interface. */ 39 | 40 | U_RB_OPT_IMPL_MALLOC = 0x02, 41 | /**< Force use of malloc(3) based implementation. The default is to 42 | * use the mmap(2) implementation on platforms supporting it. */ 43 | } u_rb_opts_t; 44 | 45 | int u_rb_create (size_t hint_sz, int opts, u_rb_t **prb); 46 | int u_rb_clear (u_rb_t *rb); 47 | void u_rb_free (u_rb_t *rb); 48 | size_t u_rb_size (u_rb_t *rb); 49 | 50 | ssize_t u_rb_read (u_rb_t *rb, void *b, size_t b_sz); 51 | void *u_rb_fast_read (u_rb_t *rb, size_t *pb_sz); 52 | ssize_t u_rb_write (u_rb_t *rb, const void *b, size_t b_sz); 53 | size_t u_rb_ready (u_rb_t *rb); 54 | size_t u_rb_avail (u_rb_t *rb); 55 | 56 | /** 57 | * \} 58 | */ 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif /* __cplusplus */ 63 | 64 | #endif /* !_U_RB_H_ */ 65 | -------------------------------------------------------------------------------- /include/toolbox/str.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_LIBU_STRING_H_ 6 | #define _U_LIBU_STRING_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | struct u_string_s; 21 | 22 | /** 23 | * \addtogroup string 24 | * \{ 25 | */ 26 | 27 | /** \brief The base string type */ 28 | typedef struct u_string_s u_string_t; 29 | 30 | /** 31 | * \brief Append at most \p len characters of a NUL-terminated string to a 32 | * string object 33 | * 34 | * Append at most \p len chars from the NUL-terminated string \p buf to the 35 | * given ::u_string_t object \p s 36 | * 37 | * \param s an ::u_string_t object 38 | * \param buf the NUL-terminated string that will be appended to \p s 39 | * \param len length of \a buf 40 | * 41 | * \retval 0 on success 42 | * \retval ~0 on failure 43 | */ 44 | #define u_string_ncat(s, buf, len) u_string_append(s, buf, len) 45 | 46 | /** 47 | * \brief Append a NUL-terminated string to a string object 48 | * 49 | * Append the NUL-terminated string \p buf to the given ::u_string_t object 50 | * \p s 51 | * 52 | * \param s an ::u_string_t object 53 | * \param buf the NUL-terminated string that will be appended to \p s 54 | * 55 | * \retval 0 on success 56 | * \retval ~0 on failure 57 | */ 58 | #define u_string_cat(s, buf) u_string_append(s, buf, strlen(buf)) 59 | 60 | const char *u_string_c (u_string_t *s); 61 | int u_string_append (u_string_t *s, const char *buf, size_t len); 62 | int u_string_aprintf (u_string_t *s, const char *fmt, ...); 63 | int u_string_clear (u_string_t *s); 64 | int u_string_copy (u_string_t *dst, u_string_t *src); 65 | int u_string_create (const char *buf, size_t len, u_string_t **ps); 66 | int u_string_do_printf (u_string_t *s, int clear, const char *fmt, ...); 67 | int u_string_free (u_string_t *s); 68 | int u_string_reserve (u_string_t *s, size_t size); 69 | int u_string_set (u_string_t *s, const char *buf, size_t len); 70 | int u_string_set_length (u_string_t *s, size_t len); 71 | int u_string_sprintf (u_string_t *s, const char *fmt, ...); 72 | int u_string_trim (u_string_t *s); 73 | size_t u_string_len (u_string_t *s); 74 | char *u_string_detach_cstr (u_string_t *s); 75 | 76 | /** 77 | * \} 78 | */ 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | 84 | #endif /* !_U_STRING_H_ */ 85 | -------------------------------------------------------------------------------- /include/toolbox/test.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_TEST_H_ 6 | #define _U_TEST_H_ 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif /* __cplusplus */ 13 | 14 | /** 15 | * \addtogroup test 16 | * \{ 17 | */ 18 | 19 | struct u_test_case_s; 20 | struct u_test_suite_s; 21 | struct u_test_s; 22 | 23 | /** \brief Carpal-like msg_err_if macro. */ 24 | #define u_test_err_if(a) \ 25 | do { if (a) { u_test_case_printf(tc, "%s", #a); goto err; } } while (0) 26 | 27 | /** \brief Carpal-like msg_err_ifm macro. */ 28 | #define u_test_err_ifm(a, ...) \ 29 | do { if (a) { u_test_case_printf(tc, __VA_ARGS__); goto err; } } while (0) 30 | 31 | /** \brief Test case handler. */ 32 | typedef struct u_test_case_s u_test_case_t; 33 | 34 | /** \brief Test suite handler. */ 35 | typedef struct u_test_suite_s u_test_suite_t; 36 | 37 | /** \brief Test handler. */ 38 | typedef struct u_test_s u_test_t; 39 | 40 | /** \brief Exit status of unit tests. */ 41 | enum { 42 | U_TEST_SUCCESS = 0, 43 | /**< All test assertions got right. */ 44 | 45 | U_TEST_FAILURE = 1, 46 | /**< Any test assertion has failed. */ 47 | 48 | U_TEST_ABORTED = 2, 49 | /**< Catch any non-regular execution condition (e.g. SIGSEGV). */ 50 | 51 | U_TEST_SKIPPED = 3 52 | /**< A previous dependency failure prevents test execution. */ 53 | }; 54 | 55 | /** \brief Tags used to tell if the reporter routine has been called 56 | * on element opening or closure. */ 57 | typedef enum { U_TEST_REP_HEAD, U_TEST_REP_TAIL } u_test_rep_tag_t; 58 | 59 | /** \brief Unit test function prototype. */ 60 | typedef int (*u_test_f)(u_test_case_t *); 61 | 62 | /** \brief Report functions' prototypes. */ 63 | typedef int (*u_test_rep_f)(FILE *, u_test_t *, u_test_rep_tag_t); 64 | typedef int (*u_test_case_rep_f)(FILE *, u_test_case_t *); 65 | typedef int (*u_test_suite_rep_f)(FILE *, u_test_suite_t *, u_test_rep_tag_t); 66 | 67 | /** \brief Maximum number of running test cases. */ 68 | #ifndef U_TEST_MAX_PARALLEL 69 | #define U_TEST_MAX_PARALLEL 32 70 | #endif /* !U_TEST_MAX_PARALLEL */ 71 | 72 | /** \brief Maximum length of a test suite/case identifier. */ 73 | #ifndef U_TEST_ID_MAX 74 | #define U_TEST_ID_MAX 128 75 | #endif /* !U_TEST_ID_MAX */ 76 | 77 | /** \brief Default test report file name. */ 78 | #ifndef U_TEST_OUTFN_DFL 79 | #define U_TEST_OUTFN_DFL "./unitest-report.out" 80 | #endif /* !U_TEST_OUTFN_DFL */ 81 | 82 | int u_test_case_new (const char *id, u_test_f func, u_test_case_t **ptc); 83 | int u_test_case_add (u_test_case_t *tc, u_test_suite_t *ts); 84 | void u_test_case_free (u_test_case_t *tc); 85 | int u_test_case_register (const char *id, u_test_f func, u_test_suite_t *ts); 86 | int u_test_case_dep_register (const char *id, u_test_case_t *tc); 87 | int u_test_case_depends_on (const char *tcid, const char *depid, 88 | u_test_suite_t *ts); 89 | int u_test_case_printf (u_test_case_t *tc, const char *fmt, ...); 90 | 91 | int u_test_suite_add (u_test_suite_t *to, u_test_t *t); 92 | void u_test_suite_free (u_test_suite_t *ts); 93 | int u_test_suite_new (const char *id, u_test_suite_t **pts); 94 | int u_test_suite_dep_register (const char *id, u_test_suite_t *ts); 95 | int u_test_suite_depends_on (const char *tsid, const char *depid, u_test_t *t); 96 | 97 | int u_test_new (const char *id, u_test_t **pt); 98 | int u_test_set_outfn (u_test_t *t, const char *outfn); 99 | int u_test_set_u_test_suite_rep (u_test_t *t, u_test_suite_rep_f func); 100 | int u_test_set_u_test_case_rep (u_test_t *t, u_test_case_rep_f func); 101 | int u_test_set_u_test_rep (u_test_t *t, u_test_rep_f func); 102 | 103 | void u_test_free (u_test_t *t); 104 | int u_test_run (int ac, char *av[], u_test_t *t); 105 | 106 | /** 107 | * \} 108 | */ 109 | 110 | #ifdef __cplusplus 111 | } 112 | #endif /* __cplusplus */ 113 | 114 | #endif /* !_U_TEST_H_ */ 115 | -------------------------------------------------------------------------------- /include/toolbox/uri.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_URI_H_ 6 | #define _U_URI_H_ 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | struct u_uri_s; /* fwd decl */ 15 | 16 | /** 17 | * \addtogroup uri 18 | * \{ 19 | */ 20 | 21 | /** \brief Maximum length allowed when encoding an URI string, see 22 | * ::u_uri_knead */ 23 | #define U_URI_STRMAX 4096 24 | 25 | /** \brief Option that can or'ed together and supplied to ::u_uri_crumble or 26 | * ::u_uri_new */ 27 | typedef enum 28 | { 29 | U_URI_OPT_NONE = 0x00, 30 | /**< use default parsing algorithm */ 31 | 32 | U_URI_OPT_DONT_PARSE_USERINFO = 0x01, 33 | /**< do not try to split user":"password in userinfo */ 34 | } u_uri_opts_t; 35 | 36 | /** \brief Flags set by the parsing machinery. */ 37 | typedef enum 38 | { 39 | U_URI_FLAGS_NONE = 0x00, 40 | /**< use default parsing algorithm */ 41 | 42 | U_URI_FLAGS_HOST_IS_IPADDRESS = 0x01, 43 | /**< host is in IP-literal or IPv4address format (otherwise assume 44 | * reg-name.) */ 45 | 46 | U_URI_FLAGS_HOST_IS_IPLITERAL = 0x02, 47 | /**< host is in IP-literal. User must set this flag if she wants to 48 | * correctly knead an IP-literal address, i.e. one surrounded by 49 | * square brackets. */ 50 | } u_uri_flags_t; 51 | 52 | /** \brief Base type for all URI operations */ 53 | typedef struct u_uri_s u_uri_t; 54 | 55 | /* uri ctor/dtor */ 56 | int u_uri_new (u_uri_opts_t opts, u_uri_t **pu); 57 | void u_uri_free (u_uri_t *u); 58 | 59 | /* uri encoder/decoder */ 60 | int u_uri_crumble (const char *s, u_uri_opts_t opts, u_uri_t **pu); 61 | int u_uri_knead (u_uri_t *u, char s[U_URI_STRMAX]); 62 | 63 | /* print u_uri_t internal state */ 64 | void u_uri_print (u_uri_t *u, int extended); 65 | 66 | /* test if supplied URI is absolute (RFC3986, Section 4.3) */ 67 | int u_uri_is_absolute(const char *uri); 68 | 69 | /* getter/setter methods for u_uri_t objects */ 70 | 71 | /** \brief Get the scheme value from the supplied \p uri */ 72 | const char *u_uri_get_scheme (u_uri_t *uri); 73 | 74 | /** \brief Set the scheme value to \p val on the supplied \p uri */ 75 | int u_uri_set_scheme (u_uri_t *uri, const char *val); 76 | 77 | /** \brief Get the userinfo value from the supplied \p uri */ 78 | const char *u_uri_get_userinfo (u_uri_t *uri); 79 | 80 | /** \brief Set the userinfo value to \p val on the supplied \p uri */ 81 | int u_uri_set_userinfo (u_uri_t *uri, const char *val); 82 | 83 | /** \brief Get the user value from the supplied \p uri */ 84 | const char *u_uri_get_user (u_uri_t *uri); 85 | 86 | /** \brief Set the user value to \p val on the supplied \p uri */ 87 | int u_uri_set_user (u_uri_t *uri, const char *val); 88 | 89 | /** \brief Get the pwd value from the supplied \p uri */ 90 | const char *u_uri_get_pwd (u_uri_t *uri); 91 | 92 | /** \brief Set the pwd value to \p val on the supplied \p uri */ 93 | int u_uri_set_pwd (u_uri_t *uri, const char *val); 94 | 95 | /** \brief Get the host value from the supplied \p uri */ 96 | const char *u_uri_get_host (u_uri_t *uri); 97 | 98 | /** \brief Set the host value to \p val on the supplied \p uri */ 99 | int u_uri_set_host (u_uri_t *uri, const char *val); 100 | 101 | /** \brief Get the port value from the supplied \p uri */ 102 | const char *u_uri_get_port (u_uri_t *uri); 103 | 104 | /** \brief Get flags set by the parser (if any.) */ 105 | u_uri_flags_t u_uri_get_flags (u_uri_t *uri); 106 | 107 | /** \brief Set the port value to \p val on the supplied \p uri */ 108 | int u_uri_set_port (u_uri_t *uri, const char *val); 109 | 110 | /** \brief Get the authority value from the supplied \p uri */ 111 | const char *u_uri_get_authority (u_uri_t *uri); 112 | 113 | /** \brief Set the authority value to \p val on the supplied \p uri */ 114 | int u_uri_set_authority (u_uri_t *uri, const char *val); 115 | 116 | /** \brief Get the path value from the supplied \p uri */ 117 | const char *u_uri_get_path (u_uri_t *uri); 118 | 119 | /** \brief Set the path value to \p val on the supplied \p uri */ 120 | int u_uri_set_path (u_uri_t *uri, const char *val); 121 | 122 | /** \brief Get the query value from the supplied \p uri */ 123 | const char *u_uri_get_query (u_uri_t *uri); 124 | 125 | /** \brief Set the query value to \p val on the supplied \p uri */ 126 | int u_uri_set_query (u_uri_t *uri, const char *val); 127 | 128 | /** \brief Get the fragment value from the supplied \p uri */ 129 | const char *u_uri_get_fragment (u_uri_t *uri); 130 | 131 | /** \brief Set the fragment value to \p val on the supplied \p uri */ 132 | int u_uri_set_fragment (u_uri_t *uri, const char *val); 133 | 134 | /** 135 | * \} 136 | */ 137 | 138 | #ifdef __cplusplus 139 | } 140 | #endif 141 | 142 | #endif /* !_U_URI_H_ */ 143 | -------------------------------------------------------------------------------- /include/u/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.6 2010/01/15 17:47:56 tho Exp $ 2 | 3 | include common.mk 4 | include ../../Makefile.conf 5 | 6 | INCS = libu.h missing.h toolbox.h compat.h libu_conf.h 7 | 8 | LINKS = missing toolbox 9 | 10 | depend-hook-pre all-hook-pre: 11 | for d in $(LINKS) ; do rm -f $$d && ln -s ../$$d ; done 12 | 13 | clean-hook-pre: ; rm -rf missing toolbox 14 | 15 | include incs.mk 16 | -------------------------------------------------------------------------------- /include/u/compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _LIBU_COMPAT_H_ 6 | #define _LIBU_COMPAT_H_ 7 | 8 | #include 9 | 10 | #ifdef LIBU_1X_COMPAT 11 | 12 | /* enable compatibility layer with the 1.X branch */ 13 | 14 | /* carpal module */ 15 | #define con(...) u_con(__VA_ARGS__) 16 | #define dbg(...) u_dbg(__VA_ARGS__) 17 | #define info(...) u_info(__VA_ARGS__) 18 | #define notice(...) u_notice(__VA_ARGS__) 19 | #define warn(...) u_warn(__VA_ARGS__) 20 | #define err(...) u_err(__VA_ARGS__) 21 | #define crit(...) u_crit(__VA_ARGS__) 22 | #define alert(...) u_alert(__VA_ARGS__) 23 | #define emerg(...) u_emerg(__VA_ARGS__) 24 | 25 | /* uri module */ 26 | #define u_uri_parse(s, pu) u_uri_crumble(s, 0, pu) 27 | 28 | /* net module */ 29 | #define u_net_sock(uri, mode) u_net_sd(uri, mode, 0) 30 | 31 | #endif /* LIBU_1X_COMPAT */ 32 | 33 | #endif /* !_LIBU_COMPAT_H_ */ 34 | -------------------------------------------------------------------------------- /include/u/libu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _U_LIBU_H_ 6 | #define _U_LIBU_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #ifdef HAVE_STDLIB 13 | #include 14 | #endif 15 | 16 | /* GNUC __attribute__((deprecated)) (gcc 3.1 and later) */ 17 | #if defined(__GNUC__) && ((__GNUC__ >= 4) || \ 18 | ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) 19 | #define __LIBU_DEPRECATED __attribute__((deprecated)) 20 | #else 21 | #define __LIBU_DEPRECATED 22 | #endif 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #endif /* !_U_LIBU_H_ */ 29 | -------------------------------------------------------------------------------- /include/u/missing.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _LIBU_MISSING_H_ 6 | #define _LIBU_MISSING_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #ifdef OS_WIN 24 | #include 25 | #define strcasecmp _stricmp 26 | #define sleep(secs) Sleep( (secs) * 1000 ) 27 | #endif 28 | 29 | #ifndef HAVE_SSIZE_T 30 | typedef int ssize_t; 31 | #endif 32 | 33 | /* on VxWorks/DCC there's not extern declaration (even if the var is available 34 | into library files) */ 35 | extern char *optarg; 36 | extern int optind; 37 | 38 | #endif /* !_LIBU_MISSING_H_ */ 39 | -------------------------------------------------------------------------------- /include/u/toolbox.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #ifndef _LIBU_TOOLBOX_H_ 6 | #define _LIBU_TOOLBOX_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #ifndef NO_NET 22 | #include 23 | #endif /* !NO_NET */ 24 | 25 | #ifndef NO_ENV 26 | #include 27 | #endif /* !NO_ENV */ 28 | 29 | #ifndef NO_HMAP 30 | #include 31 | #endif /* !NO_HMAP */ 32 | 33 | #ifndef NO_CONFIG 34 | #include 35 | #endif /* !NO_CONFIG */ 36 | 37 | #ifndef NO_FS 38 | #include 39 | #endif /* !NO_FS */ 40 | 41 | #ifndef NO_PWD 42 | #ifdef NO_HMAP 43 | #include 44 | #endif /* NO_HMAP */ 45 | #include 46 | #endif /* !NO_PWD */ 47 | 48 | #ifndef NO_LIST 49 | #include 50 | #endif /* !NO_LIST */ 51 | 52 | #ifndef NO_ARRAY 53 | #include 54 | #endif /* !NO_ARRAY */ 55 | 56 | #ifndef NO_RB 57 | #include 58 | #endif /* !NO_RB */ 59 | 60 | #ifndef NO_PQUEUE 61 | #include 62 | #endif /* !NO_PQUEUE */ 63 | 64 | #ifndef NO_BST 65 | #include 66 | #endif /* !NO_BST */ 67 | 68 | #ifndef NO_JSON 69 | #include 70 | #endif /* !NO_JSON */ 71 | 72 | #ifndef NO_B64 73 | #include 74 | #endif /* !NO_B64 */ 75 | 76 | 77 | #endif /* !_LIBU_TOOLBOX_H_ */ 78 | -------------------------------------------------------------------------------- /pkg/Makefile.doc: -------------------------------------------------------------------------------- 1 | # $Id: Makefile.doc,v 1.1 2005/10/01 18:14:05 tho Exp $ 2 | 3 | SUBDIR = man html 4 | 5 | include subdir.mk 6 | -------------------------------------------------------------------------------- /pkg/Makefile.doxy.doc: -------------------------------------------------------------------------------- 1 | # $Id: Makefile.doxy.doc,v 1.7 2007/01/31 15:59:49 tat Exp $ 2 | 3 | include common.mk 4 | include ../../Makefile.conf 5 | 6 | HTMLDOCDIR = ${DOCDIR}/libu/html/ 7 | 8 | all clean depend cleandepend: 9 | 10 | install: 11 | @if [ -f index.html ]; then \ 12 | ${MKINSTALLDIRS} ${HTMLDOCDIR} && cp -r *.html *.css ${HTMLDOCDIR} ; \ 13 | fi 14 | 15 | uninstall: 16 | rm -rf ${HTMLDOCDIR} 17 | -------------------------------------------------------------------------------- /pkgs/rel-git.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # LibU release script 4 | 5 | # set these ! 6 | REL_TAG="LIBU_REL_2_2_0" 7 | REL_VERSION="2.2.0" 8 | 9 | REL_ROOT="libu" 10 | 11 | REL_DIR="/tmp/LIBU_REL" 12 | REL_TMP_DIR="${REL_DIR}/tmp" 13 | REL_OUT_DIR="${REL_DIR}/out" 14 | 15 | REL_HOST="gonzo.koanlogic.com" 16 | REL_HOST_DIR="/var/www-anemic/www/download/libu/" 17 | REL_TARGET="${REL_HOST}:${REL_HOST_DIR}" 18 | 19 | yesno () 20 | { 21 | /bin/echo -n "$1 " 22 | 23 | while [ true ] 24 | do 25 | read answer 26 | case ${answer} in 27 | [Yy]) return 0 ;; 28 | [nN]) return 1 ;; 29 | *) /bin/echo -n "please say [yY] or [nN]: " ;; 30 | esac 31 | done 32 | } 33 | 34 | err () 35 | { 36 | /bin/echo $@ 37 | exit 1 38 | } 39 | 40 | make_pre() 41 | { 42 | rm -rf ${REL_TMP_DIR} 43 | mkdir -p ${REL_TMP_DIR} || err "can't create directory ${REL_TMP_DIR}" 44 | mkdir -p ${REL_OUT_DIR} || err "can't create directory ${REL_OUT_DIR}" 45 | } 46 | 47 | make_tag() 48 | { 49 | yesno "using tag \"${REL_TAG}\", do you want to continue (y/n)?" \ 50 | || err "bailing out on client request" 51 | 52 | echo "==> tagging as \"${REL_TAG}\"" 53 | git tag -f ${REL_TAG} || err "git tag command failed" 54 | git push --tags origin master || err "git push command failed" 55 | } 56 | 57 | make_export() 58 | { 59 | echo "==> exporting tagged tree" 60 | pushd . 61 | cd ${REL_TMP_DIR} || err "can't cd to ${REL_TMP_DIR}" 62 | git clone git://github.com/koanlogic/libu.git || err "git clone failed!" 63 | cd ${REL_ROOT} || err "can't cd to ${REL_ROOT}" 64 | git checkout -b ${REL_TAG} || err "git checkout failed!" 65 | popd 66 | } 67 | 68 | make_dist() 69 | { 70 | echo "==> creating dist" 71 | 72 | pushd . 73 | cd ${REL_TMP_DIR}/${REL_ROOT} \ 74 | || err "can't cd to ${REL_TMP_DIR}/${REL_ROOT}" 75 | 76 | # we need doxygen path 77 | makl-conf || err "makl-conf failed" 78 | makl -f Makefile.dist dist || "dist target failed" 79 | 80 | cp libu-${REL_VERSION}.* ${REL_OUT_DIR} \ 81 | || err "can't copy dist files to ${REL_OUT_DIR}" 82 | popd 83 | } 84 | 85 | make_upload() 86 | { 87 | local rcmd; 88 | 89 | rcmd="cd ${REL_HOST_DIR} && chgrp www-data libu-${REL_VERSION}.* && \ 90 | ../mklatest.sh libu ${REL_VERSION}" 91 | 92 | echo "==> uploading release" 93 | 94 | # upload 95 | scp -r ${REL_OUT_DIR}/libu-${REL_VERSION}.* root@${REL_TARGET} \ 96 | || err "can't copy dist files to ${REL_TARGET}" 97 | 98 | # update -latest (this also extract ChangeLog from package) 99 | ssh root@${REL_HOST} ${rcmd} \ 100 | || err "can't create -latest link on ${REL_HOST}" 101 | } 102 | 103 | make_clean() 104 | { 105 | echo "==> clean up" 106 | rm -rf ${REL_DIR} 107 | } 108 | 109 | make_pre 110 | make_tag 111 | make_export 112 | make_dist 113 | make_upload 114 | make_clean 115 | -------------------------------------------------------------------------------- /srcs/Makefile: -------------------------------------------------------------------------------- 1 | # $Id: Makefile,v 1.22 2010/05/27 08:35:12 tho Exp $ 2 | 3 | include common.mk 4 | include ../Makefile.conf 5 | 6 | LIB = u 7 | 8 | # toolbox core sources 9 | SRCS = toolbox/memory.c 10 | SRCS += toolbox/misc.c 11 | SRCS += toolbox/str.c 12 | SRCS += toolbox/buf.c 13 | SRCS += toolbox/log.c 14 | SRCS += toolbox/lexer.c 15 | 16 | ifndef NO_TEST 17 | SRCS += toolbox/test.c 18 | endif 19 | ifndef NO_HMAP 20 | SRCS += toolbox/hmap.c 21 | endif 22 | ifndef NO_CONFIG 23 | SRCS += toolbox/config.c 24 | SRCS += toolbox/config_fs.c 25 | endif 26 | ifndef NO_ENV 27 | SRCS += toolbox/env.c 28 | endif 29 | ifndef NO_NET 30 | SRCS += toolbox/net.c 31 | SRCS += toolbox/uri.c 32 | endif 33 | ifndef NO_FS 34 | SRCS += toolbox/fs.c 35 | endif 36 | ifndef NO_B64 37 | SRCS += toolbox/b64.c 38 | endif 39 | ifndef NO_PWD 40 | ifdef NO_HMAP # pwd needs hmap 41 | $(warning adding hmap module as a dependency to pwd) 42 | SRCS += toolbox/hmap.c 43 | endif # NO_HMAP (PWD dep) 44 | SRCS += toolbox/pwd.c 45 | endif # !NO_PWD 46 | ifndef NO_LIST 47 | SRCS += toolbox/list.c 48 | endif 49 | ifndef NO_ARRAY 50 | SRCS += toolbox/array.c 51 | endif 52 | ifndef NO_RB 53 | SRCS += toolbox/rb.c 54 | endif 55 | ifndef NO_PQUEUE 56 | SRCS += toolbox/pqueue.c 57 | endif 58 | ifndef NO_BST 59 | SRCS += toolbox/bst.c 60 | endif 61 | ifndef NO_JSON 62 | ifdef NO_HMAP # json needs hmap 63 | $(warning adding hmap module as a dependency to json) 64 | SRCS += toolbox/hmap.c 65 | endif # NO_HMAP (JSON dep) 66 | SRCS += toolbox/json.c 67 | endif 68 | ifdef SHLIB_NO_UNDEFINED_SYMS 69 | SRCS += toolbox/facility.c 70 | endif 71 | 72 | # missing sources 73 | ifndef HAVE_VSYSLOG 74 | SRCS += missing/vsyslog.c 75 | endif 76 | ifndef HAVE_SYSLOG 77 | SRCS += missing/syslog.c 78 | endif 79 | ifndef HAVE_STRTOK_R 80 | SRCS += missing/strtok_r.c 81 | endif 82 | ifndef HAVE_UNLINK 83 | SRCS += missing/unlink.c 84 | endif 85 | ifndef HAVE_GETPID 86 | SRCS += missing/getpid.c 87 | endif 88 | ifndef HAVE_FNMATCH 89 | SRCS += missing/fnmatch.c 90 | endif 91 | ifndef HAVE_TIMEGM 92 | SRCS += missing/timegm.c 93 | endif 94 | ifndef HAVE_STRSEP 95 | SRCS += missing/strsep.c 96 | endif 97 | ifndef HAVE_STRLCPY 98 | SRCS += missing/strlcpy.c 99 | endif 100 | ifndef HAVE_STRLCAT 101 | SRCS += missing/strlcat.c 102 | endif 103 | ifndef HAVE_GETTIMEOFDAY 104 | SRCS += missing/gettimeofday.c 105 | endif 106 | ifndef HAVE_DAEMON 107 | SRCS += missing/daemon.c 108 | endif 109 | ifndef HAVE_MKSTEMPS 110 | SRCS += missing/mkstemps.c 111 | endif 112 | ifndef HAVE_SETENV 113 | SRCS += missing/setenv.c 114 | endif 115 | 116 | include lib.mk 117 | 118 | # MacOSX ld(1) bug workaround 119 | ifdef OS_DARWIN 120 | install-hook-post: 121 | chmod u+w $(LIBDIR)/libu.a && $(RANLIB) $(LIBDIR)/libu.a 122 | endif 123 | -------------------------------------------------------------------------------- /srcs/missing/daemon.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: daemon.c,v 1.9 2003/08/07 16:42:46 agc Exp $ */ 2 | 3 | /*- 4 | * Copyright (c) 1990, 1993 5 | * The Regents of the University of California. All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. Neither the name of the University nor the names of its contributors 16 | * may be used to endorse or promote products derived from this software 17 | * without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | * SUCH DAMAGE. 30 | */ 31 | 32 | #include 33 | 34 | #if !defined(OS_WIN) && defined(HAVE_FORK) 35 | 36 | #ifndef _PATH_DEVNULL 37 | #define _PATH_DEVNULL "/dev/null" 38 | #endif 39 | 40 | #include 41 | #ifdef HAVE_PATHS 42 | #include 43 | #endif 44 | #include 45 | #include 46 | #include 47 | 48 | int daemon(int nochdir, int noclose) 49 | { 50 | int fd; 51 | 52 | switch (fork()) { 53 | case -1: 54 | return (-1); 55 | case 0: 56 | break; 57 | default: 58 | _exit(0); 59 | } 60 | 61 | if (setsid() == -1) 62 | return (-1); 63 | 64 | if (!nochdir) 65 | (void)chdir("/"); 66 | 67 | if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { 68 | (void)dup2(fd, STDIN_FILENO); 69 | (void)dup2(fd, STDOUT_FILENO); 70 | (void)dup2(fd, STDERR_FILENO); 71 | if (fd > STDERR_FILENO) 72 | (void)close(fd); 73 | } 74 | return (0); 75 | } 76 | 77 | #else /* OS_WIN || !HAVE_FORK */ 78 | 79 | int daemon(int nochdir, int noclose) 80 | { 81 | u_unused_args(nochdir, noclose); 82 | u_warn("daemon(3) not implemented: fork(2) is not available on target OS"); 83 | return -1; 84 | } 85 | #endif /* !OS_WIN && HAVE_FORK */ 86 | -------------------------------------------------------------------------------- /srcs/missing/getpid.c: -------------------------------------------------------------------------------- 1 | #include 2 | #ifndef HAVE_GETPID 3 | 4 | pid_t getpid() 5 | { 6 | #ifdef OS_WIN 7 | return GetCurrentProcessId(); 8 | #else 9 | #error "unimplemented" 10 | #endif 11 | } 12 | #else 13 | #include 14 | #include 15 | pid_t getpid(void); 16 | #endif 17 | -------------------------------------------------------------------------------- /srcs/missing/gettimeofday.c: -------------------------------------------------------------------------------- 1 | /* $Id: gettimeofday.c,v 1.1 2006/11/20 13:38:01 tho Exp $ */ 2 | 3 | #include 4 | 5 | #ifndef HAVE_GETTIMEOFDAY 6 | #include 7 | #include 8 | 9 | #ifdef OS_WIN 10 | #include 11 | #include 12 | int gettimeofday(struct timeval *tv, struct timezone *tz) 13 | { 14 | struct _timeb tb; 15 | 16 | dbg_return_if(tv == NULL, -1); 17 | 18 | /* get current time */ 19 | _ftime(&tb); 20 | 21 | /* set the timeval struct */ 22 | tv->tv_sec = tb.time; 23 | tv->tv_usec = 1000 * tb.millitm; 24 | 25 | if(tz == NULL) 26 | return 0; 27 | 28 | /* set the tiemzone struct */ 29 | tz->tz_minuteswest = tb.timezone; 30 | tz->tz_dsttime = tb.dstflag; 31 | 32 | return 0; 33 | } 34 | #else 35 | #warning missing gettimeofday,tv.tv_usec will be always set to zero 36 | int gettimeofday(struct timeval *tv, struct timezone *tzp) 37 | { 38 | if(tzp) 39 | tzp->tz_minuteswest = tzp->tz_dsttime = 0; 40 | 41 | tv->tv_sec = time(0); 42 | tv->tv_usec = 0; 43 | 44 | return 0; 45 | } 46 | #endif 47 | 48 | #else 49 | #include 50 | int gettimeofday(struct timeval *tp, struct timezone *tzp); 51 | #endif /* !HAVE_GETTIMEOFDAY */ 52 | -------------------------------------------------------------------------------- /srcs/missing/setenv.c: -------------------------------------------------------------------------------- 1 | #ifndef HAVE_SETENV 2 | #include 3 | 4 | int setenv (const char *name, const char *value, int overwrite) 5 | { 6 | return SetEnvironmentVariableA(name, value) == 0 ? -1 : 0; 7 | } 8 | #else 9 | int setenv (const char *name, const char *value, int overwrite); 10 | #endif 11 | -------------------------------------------------------------------------------- /srcs/missing/strlcat.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: strlcat.c,v 1.16 2003/10/27 00:12:42 lukem Exp $ */ 2 | /* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */ 3 | 4 | /* 5 | * Copyright (c) 1998 Todd C. Miller 6 | * 7 | * Permission to use, copy, modify, and distribute this software for any 8 | * purpose with or without fee is hereby granted, provided that the above 9 | * copyright notice and this permission notice appear in all copies. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL 12 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 13 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE 14 | * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 16 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 17 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 | */ 19 | 20 | #include 21 | 22 | #ifndef HAVE_STRLCAT 23 | 24 | #include 25 | 26 | /* 27 | * Appends src to string dst of size siz (unlike strncat, siz is the 28 | * full size of dst, not space left). At most siz-1 characters 29 | * will be copied. Always NUL terminates (unless siz <= strlen(dst)). 30 | * Returns strlen(src) + MIN(siz, strlen(initial dst)). 31 | * If retval >= siz, truncation occurred. 32 | */ 33 | size_t strlcat (char *dst, const char *src, size_t siz) 34 | { 35 | char *d = dst; 36 | const char *s = src; 37 | size_t n = siz; 38 | size_t dlen; 39 | 40 | /* Find the end of dst and adjust bytes left but don't go past end */ 41 | while (n-- != 0 && *d != '\0') 42 | d++; 43 | dlen = d - dst; 44 | n = siz - dlen; 45 | 46 | if (n == 0) 47 | return(dlen + strlen(s)); 48 | while (*s != '\0') { 49 | if (n != 1) { 50 | *d++ = *s; 51 | n--; 52 | } 53 | s++; 54 | } 55 | *d = '\0'; 56 | 57 | return(dlen + (s - src)); /* count does not include NUL */ 58 | } 59 | #else /* HAVE_STRLCAT */ 60 | size_t strlcat (char *, const char *, size_t); 61 | #endif /* !HAVE_STRLCAT */ 62 | -------------------------------------------------------------------------------- /srcs/missing/strlcpy.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: strlcpy.c,v 1.14 2003/10/27 00:12:42 lukem Exp $ */ 2 | /* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */ 3 | 4 | /* 5 | * Copyright (c) 1998 Todd C. Miller 6 | * 7 | * Permission to use, copy, modify, and distribute this software for any 8 | * purpose with or without fee is hereby granted, provided that the above 9 | * copyright notice and this permission notice appear in all copies. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL 12 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 13 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE 14 | * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 16 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 17 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 | */ 19 | #include 20 | 21 | #ifndef HAVE_STRLCPY 22 | /* 23 | * Copy src to string dst of size siz. At most siz-1 characters 24 | * will be copied. Always NUL terminates (unless siz == 0). 25 | * Returns strlen(src); if retval >= siz, truncation occurred. 26 | */ 27 | size_t strlcpy(char *dst, const char *src, size_t siz) 28 | { 29 | char *d = dst; 30 | const char *s = src; 31 | size_t n = siz; 32 | 33 | /* Copy as many bytes as will fit */ 34 | if (n != 0 && --n != 0) { 35 | do { 36 | if ((*d++ = *s++) == 0) 37 | break; 38 | } while (--n != 0); 39 | } 40 | 41 | /* Not enough room in dst, add NUL and traverse rest of src */ 42 | if (n == 0) { 43 | if (siz != 0) 44 | *d = '\0'; /* NUL-terminate dst */ 45 | while (*s++) 46 | ; 47 | } 48 | 49 | return(s - src - 1); /* count does not include NUL */ 50 | } 51 | #else /* HAVE_STRLCPY */ 52 | size_t strlcpy (char *, const char *, size_t); 53 | #endif /* !HAVE_STRLCPY */ 54 | -------------------------------------------------------------------------------- /srcs/missing/strsep.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: strsep.c,v 1.14 2003/08/07 16:43:52 agc Exp $ */ 2 | 3 | /*- 4 | * Copyright (c) 1990, 1993 5 | * The Regents of the University of California. All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. Neither the name of the University nor the names of its contributors 16 | * may be used to endorse or promote products derived from this software 17 | * without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | * SUCH DAMAGE. 30 | */ 31 | 32 | #include 33 | 34 | #ifndef HAVE_STRSEP 35 | 36 | #include 37 | 38 | /* 39 | * Get next token from string *stringp, where tokens are possibly-empty 40 | * strings separated by characters from delim. 41 | * 42 | * Writes NULs into the string at *stringp to end tokens. 43 | * delim need not remain constant from call to call. 44 | * On return, *stringp points past the last NUL written (if there might 45 | * be further tokens), or is NULL (if there are definitely no more tokens). 46 | * 47 | * If *stringp is NULL, strsep returns NULL. 48 | */ 49 | char *strsep(char **stringp, const char *delim) 50 | { 51 | char *s; 52 | const char *spanp; 53 | int c, sc; 54 | char *tok; 55 | 56 | if ((s = *stringp) == NULL) 57 | return (NULL); 58 | 59 | for (tok = s;;) { 60 | c = *s++; 61 | spanp = delim; 62 | do { 63 | if ((sc = *spanp++) == c) { 64 | if (c == 0) 65 | s = NULL; 66 | else 67 | s[-1] = 0; 68 | *stringp = s; 69 | return (tok); 70 | } 71 | } while (sc != 0); 72 | } 73 | /* NOTREACHED */ 74 | } 75 | 76 | #else /* HAVE_STRSEP */ 77 | char *strsep(char **, const char *); 78 | #endif /* !HAVE_STRSEP */ 79 | 80 | -------------------------------------------------------------------------------- /srcs/missing/strtok_r.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998 Softweyr LLC. All rights reserved. 3 | * 4 | * strtok_r, from Berkeley strtok 5 | * Oct 13, 1998 by Wes Peters 6 | * 7 | * Copyright (c) 1988, 1993 8 | * The Regents of the University of California. All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notices, this list of conditions and the following disclaimer. 16 | * 17 | * 2. Redistributions in binary form must reproduce the above copyright 18 | * notices, this list of conditions and the following disclaimer in the 19 | * documentation and/or other materials provided with the distribution. 20 | * 21 | * 3. All advertising materials mentioning features or use of this software 22 | * must display the following acknowledgement: 23 | * 24 | * This product includes software developed by Softweyr LLC, the 25 | * University of California, Berkeley, and its contributors. 26 | * 27 | * 4. Neither the name of the University nor the names of its contributors 28 | * may be used to endorse or promote products derived from this software 29 | * without specific prior written permission. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS 32 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 34 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE 35 | * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 36 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 37 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 38 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 39 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 40 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 41 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 | */ 43 | 44 | #include 45 | 46 | #ifndef HAVE_STRTOK_R 47 | 48 | #include 49 | #include 50 | #include 51 | 52 | char *strtok_r(char *s, const char *delim, char **last) 53 | { 54 | char *spanp; 55 | int c, sc; 56 | char *tok; 57 | 58 | if (s == NULL && (s = *last) == NULL) 59 | { 60 | return NULL; 61 | } 62 | 63 | /* 64 | * Skip (span) leading delimiters (s += strspn(s, delim), sort of). 65 | */ 66 | cont: 67 | c = *s++; 68 | for (spanp = (char *)delim; (sc = *spanp++) != 0; ) 69 | { 70 | if (c == sc) 71 | { 72 | goto cont; 73 | } 74 | } 75 | 76 | if (c == 0) /* no non-delimiter characters */ 77 | { 78 | *last = NULL; 79 | return NULL; 80 | } 81 | tok = s - 1; 82 | 83 | /* 84 | * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). 85 | * Note that delim must have one NUL; we stop if we see that, too. 86 | */ 87 | for (;;) 88 | { 89 | c = *s++; 90 | spanp = (char *)delim; 91 | do 92 | { 93 | if ((sc = *spanp++) == c) 94 | { 95 | if (c == 0) 96 | { 97 | s = NULL; 98 | } 99 | else 100 | { 101 | char *w = s - 1; 102 | *w = '\0'; 103 | } 104 | *last = s; 105 | return tok; 106 | } 107 | } 108 | while (sc != 0); 109 | } 110 | /* NOTREACHED */ 111 | } 112 | 113 | #else /* HAVE_STRTOK_R */ 114 | char *strtok_r(char *s, const char *delim, char **last); 115 | #endif /* !HAVE_STRTOK_R */ 116 | -------------------------------------------------------------------------------- /srcs/missing/syslog.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | * syslog(3) drop-in for Windows 6 | */ 7 | 8 | #if !defined(HAVE_SYSLOG) 9 | #if defined(OS_WIN) 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | void syslog(int priority, const char *fmt, ...) 19 | { 20 | va_list ap; 21 | 22 | va_start(ap, fmt); /* init variable list arguments */ 23 | 24 | vsyslog(priority, fmt, ap); 25 | 26 | va_end(ap); 27 | } 28 | 29 | #else /* !OS_WIN */ 30 | #error "We don't have a syslog(3) implementation for this platform" 31 | #endif /* OS_WIN */ 32 | 33 | #else /* HAVE_SYSLOG */ 34 | 35 | #include 36 | void syslog(int priority, const char *fmt, ...); 37 | 38 | #endif /* !HAVE_SYSLOG */ 39 | -------------------------------------------------------------------------------- /srcs/missing/timegm.c: -------------------------------------------------------------------------------- 1 | /* $Id: timegm.c,v 1.1 2006/11/20 13:38:01 tho Exp $ */ 2 | 3 | #include 4 | #include 5 | 6 | #ifndef HAVE_TIMEGM 7 | 8 | #include 9 | #include 10 | 11 | time_t timegm(struct tm *tm) 12 | { 13 | time_t ret; 14 | char *tz; 15 | 16 | /* save current timezone and set UTC */ 17 | tz = getenv("TZ"); 18 | putenv("TZ=UTC"); /* use Coordinated Universal Time (i.e. zero offset) */ 19 | tzset(); 20 | 21 | ret = mktime(tm); 22 | if(tz) 23 | { 24 | char buf[256]; 25 | snprintf(buf, sizeof(buf), "TZ=%s", tz); 26 | putenv(buf); 27 | } else 28 | putenv("TZ="); 29 | tzset(); 30 | 31 | return ret; 32 | } 33 | 34 | #else 35 | time_t timegm(struct tm*); 36 | #endif 37 | -------------------------------------------------------------------------------- /srcs/missing/unlink.c: -------------------------------------------------------------------------------- 1 | /* $Id: unlink.c,v 1.1 2006/11/20 13:38:01 tho Exp $ */ 2 | 3 | #include 4 | 5 | #ifndef HAVE_UNLINK 6 | 7 | int unlink(const char *pathname) 8 | { 9 | #if OS_WIN 10 | return DeleteFile(pathname) ? 0 /* success */: -1 /* failure */; 11 | #else 12 | #error "unimplemented" 13 | #endif 14 | } 15 | 16 | #else 17 | #include 18 | int unlink(const char *); 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /srcs/missing/vsyslog.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | * vsyslog(3) drop-in for Windows and Minix 6 | */ 7 | 8 | #if !defined(HAVE_VSYSLOG) 9 | #if defined(OS_WIN) 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | void vsyslog(int priority, const char *fmt, va_list ap) 19 | { 20 | #define LIBU_WIN_LOGFILE "libu.log" 21 | enum { BUFSZ = 1024 }; 22 | static FILE *df = NULL, *lock = NULL; 23 | char buf[BUFSZ]; 24 | int i; 25 | 26 | /* first time open the log file and the lock file */ 27 | if(df == NULL) 28 | { 29 | df = fopen(LIBU_WIN_LOGFILE, "a+"); 30 | lock = fopen(LIBU_WIN_LOGFILE ".lock", "a+"); 31 | if(df == NULL || lock == NULL) 32 | exit(1); 33 | } 34 | 35 | vsnprintf(buf, BUFSZ, fmt, ap); 36 | 37 | /* get the lock (i.e. lock the first byte of the lock file) */ 38 | for(i = 0; 39 | _locking(fileno(lock), _LK_NBLCK, 1) == EACCES && i < 10; ++i) 40 | Sleep(100); 41 | 42 | if(i < 10) 43 | { /* we have the lock, write the log msg */ 44 | fprintf(df, "%s\n", buf); 45 | fflush(df); 46 | /* unlock the file */ 47 | _locking(fileno(lock), _LK_UNLCK, 1); 48 | } else { 49 | /* file is still locked after 10 attempts, give up */ 50 | ; 51 | } 52 | 53 | return; 54 | } 55 | 56 | #else /* !OS_WIN */ 57 | 58 | #include 59 | #include 60 | 61 | /* Try with this as last resort (MINIX and QNX for SH target will be glad). */ 62 | void vsyslog(int priority, const char *fmt, va_list args) 63 | { 64 | char buf[1024]; 65 | 66 | (void) vsnprintf(buf, sizeof buf, fmt, args); 67 | syslog(priority, "%s", buf); 68 | 69 | return; 70 | } 71 | 72 | #endif /* OS_WIN */ 73 | 74 | #else /* HAVE_VSYSLOG */ 75 | 76 | #include 77 | #include 78 | void vsyslog(int priority, const char *fmt, va_list args); 79 | 80 | #endif /* !HAVE_VSYSLOG */ 81 | -------------------------------------------------------------------------------- /srcs/toolbox/config_fs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | static int drv_fs_open (const char *path, void **parg) 19 | { 20 | int fd = -1; 21 | FILE *file = NULL; 22 | 23 | dbg_return_if (path == NULL, ~0); 24 | dbg_return_if (parg == NULL, ~0); 25 | 26 | /* open the file */ 27 | again: 28 | fd = open(path, O_RDONLY); 29 | if(fd == -1 && (errno == EINTR)) 30 | goto again; /* interrupted */ 31 | 32 | crit_err_sif(fd < 0); 33 | 34 | /* stdio will handle buffering */ 35 | file = fdopen(fd, "r"); 36 | dbg_err_if(file == NULL); 37 | 38 | *parg = file; 39 | 40 | return 0; 41 | err: 42 | if(file) 43 | fclose(file); 44 | if(fd >= 0) 45 | close(fd); 46 | return ~0; 47 | } 48 | 49 | static int drv_fs_close (void *arg) 50 | { 51 | int rc; 52 | FILE *file = (FILE *) arg; 53 | 54 | dbg_return_if (file == NULL, ~0); 55 | 56 | if ((rc = fclose(file)) != 0) 57 | dbg_strerror(errno); 58 | 59 | return (rc == 0) ? 0 : ~0; 60 | } 61 | 62 | static char *drv_fs_gets (void *arg, char *buf, size_t size) 63 | { 64 | FILE *file = (FILE *) arg; 65 | 66 | dbg_return_if (file == NULL, NULL); 67 | dbg_return_if (buf == NULL, NULL); 68 | 69 | return fgets(buf, size, file); 70 | } 71 | 72 | /* pre-set driver for filesystem access */ 73 | u_config_driver_t u_config_drv_fs = 74 | { 75 | drv_fs_open, 76 | drv_fs_close, 77 | drv_fs_gets, 78 | NULL /* no resolver */ 79 | }; 80 | -------------------------------------------------------------------------------- /srcs/toolbox/env.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | /** 17 | \defgroup env Environment 18 | \{ 19 | The basic idea behind the \ref env module is to load configuration 20 | values (i.e. values that a program needs at run-time) from a shell 21 | script which exports some variables in a given namespace (let's say 22 | \c PFX_). 23 | 24 | We let the shell act in the background - using just some \c env(1) and 25 | \c pipe(2) tricks to redirect and capture the variables - which in turn 26 | gives us a great deal of power and flexibility in just a couple of C 27 | lines. 28 | 29 | The following is a very simple configuration file in which three 30 | variables are set and \c export'ed to the environment: 31 | \code 32 | SET_PFX_VAR1="" 33 | 34 | [ ! -z "$SET_PFX_VAR1" ] && export PFX_VAR1="tip" 35 | export PFX_VAR2="tap" 36 | export PFX_VAR3=$((10 * 100 * 1000)) 37 | \endcode 38 | Things worth noting are: 39 | - the conditional behaviour by which single or sets of variables 40 | can be pulled in/out; 41 | - bash does the math to eval \c PFX_VAR3; 42 | - bash can spawn external utilities; 43 | - it is possible to do complex substitutions; 44 | - every information one can get through the shell 45 | (e.g. cat /proc/something) is available; 46 | - aggregation of other configuration modules is trivial via the 47 | \c source (aka \c ".") shell builtin(1). 48 | 49 | The C code needed to access the former configuration file is: 50 | \code 51 | size_t i; 52 | const char *v, *vp[] = { "PFX_VAR1", "PFX_VAR2", "PFX_VAR3" }; 53 | 54 | // load, parse, eval, etc. variables with PFX_ prefix from my.conf 55 | // into the process environment 56 | dbg_err_if (u_env_init("PFX_", "./my.conf")); 57 | 58 | // access PFX_VAR{1,2,3} variables and print their values 59 | for (i = 0; i < 3; ++i) 60 | { 61 | v = u_env_var(vp[i]); 62 | 63 | con("%s = %s", vp[i], v ? v : "UNSET"); 64 | } 65 | \endcode 66 | 67 | \note Configuration files handled by the \ref env module are flat. 68 | If you need tree-like structured configuration files use the 69 | \ref config module instead. 70 | */ 71 | 72 | /** 73 | * \brief Load configuration environment 74 | * 75 | * \param prefix variables namespace 76 | * \param cfile configuration file 77 | * 78 | * Load all configuration variables in the given \p prefix namespace from 79 | * the configuration file \p cfile into the environment of the calling process. 80 | * Complex parameter substitution, conditional evaluations, arithmetics, etc. 81 | * is done by the shell: the caller has a simple name=value view of the 82 | * configuration file. 83 | * 84 | * \retval 0 on success 85 | * \retval ~0 on failure 86 | */ 87 | int u_env_init (const char *prefix, const char *cfile) 88 | { 89 | enum { BUFSZ = 1024 }; 90 | struct stat sb; 91 | char line[BUFSZ], pcmd[BUFSZ], *val; 92 | FILE *pi = NULL; 93 | 94 | dbg_return_if (cfile == NULL || prefix == NULL, ~0); 95 | 96 | /* if 'cfile' does not exist bail out */ 97 | dbg_err_sifm (stat(cfile, &sb) == -1, "%s", cfile); 98 | 99 | dbg_err_if (u_snprintf(pcmd, BUFSZ, ". %s 2>/dev/null && env", cfile)); 100 | 101 | dbg_err_if ((pi = popen(pcmd, "r")) == NULL); 102 | 103 | while(fgets(line, BUFSZ-1, pi)) 104 | { 105 | if(strncmp(line, prefix, strlen(prefix)) == 0) 106 | { 107 | line[strlen(line)-1] = 0; 108 | val = strchr(line, '='); 109 | if(!val) 110 | continue; /* should never happen... */ 111 | *val++ = 0; 112 | /* line is the name and val the value */ 113 | dbg_err_if(setenv(line, val, 1)); 114 | } 115 | } 116 | 117 | pclose(pi); 118 | return 0; 119 | err: 120 | U_PCLOSE(pi); 121 | return ~0; 122 | } 123 | 124 | /** 125 | * \brief Get a configuration variable value 126 | * 127 | * Return a configuration variable by its name \p name 128 | * 129 | * \param name the name of the variable to get 130 | * 131 | * \return the value of the requested variable or \c NULL if the variable 132 | * is not defined 133 | */ 134 | const char *u_env_var (const char *name) 135 | { 136 | return getenv(name); 137 | } 138 | 139 | /** 140 | * \} 141 | */ 142 | -------------------------------------------------------------------------------- /srcs/toolbox/facility.c: -------------------------------------------------------------------------------- 1 | int facility; 2 | -------------------------------------------------------------------------------- /srcs/toolbox/fs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /** 18 | \defgroup fs File system 19 | \{ 20 | The \ref fs module provides a small set of interfaces to do basic 21 | file juggling tasks: move, copy an remove. 22 | */ 23 | 24 | /** 25 | * \brief Copy a file 26 | * 27 | * Copy the file whose path name is \p src to \p dst 28 | * 29 | * \param src source file name 30 | * \param dst destination file name 31 | * 32 | * \retval 0 on success 33 | * \retval ~0 on failure 34 | */ 35 | int u_copy (const char *src, const char *dst) 36 | { 37 | FILE *sfp = NULL, *dfp = NULL; 38 | size_t c; 39 | char buf[4096]; 40 | 41 | dbg_return_if (src == NULL, ~0); 42 | dbg_return_if (dst == NULL, ~0); 43 | 44 | sfp = fopen(src, "rb"); 45 | dbg_err_sifm(sfp == NULL, "unable to open %s for reading", src); 46 | 47 | dfp = fopen(dst, "wb+"); 48 | dbg_err_sifm(dfp == NULL, "unable to open %s for writing", dst); 49 | 50 | while((c = fread(buf, 1, sizeof(buf), sfp)) > 0) 51 | { 52 | dbg_err_sifm(fwrite(buf, 1, c, dfp) == 0, "error writing to %s", dst); 53 | } 54 | 55 | dbg_err_sif(fclose(sfp)); sfp = NULL; 56 | 57 | dbg_err_sifm(fclose(dfp), "error flushing %s", dst); dfp = NULL; 58 | 59 | return 0; 60 | err: 61 | if(sfp) 62 | fclose(sfp); 63 | if(dfp) 64 | fclose(dfp); 65 | return ~0; 66 | } 67 | 68 | /** 69 | * \brief Move a file 70 | * 71 | * Move the file whose path name is \p src to \p dst 72 | * 73 | * \param src source file name 74 | * \param dst destination file name 75 | * 76 | * \retval 0 on success 77 | * \retval ~0 on failure 78 | */ 79 | int u_move(const char *src, const char *dst) 80 | { 81 | int rc; 82 | 83 | dbg_return_if (src == NULL, ~0); 84 | dbg_return_if (dst == NULL, ~0); 85 | 86 | #ifdef HAVE_LINK 87 | dbg_err_sif((rc = link(src, dst)) < 0 && errno != EXDEV); 88 | 89 | if(rc && errno == EXDEV) 90 | dbg_err_if(u_copy(src, dst)); /* deep copy */ 91 | #else 92 | u_unused_args(rc); 93 | 94 | dbg_err_if(u_copy(src, dst)); 95 | #endif 96 | 97 | dbg_if(u_remove(src) < 0); 98 | 99 | return 0; 100 | err: 101 | return ~0; 102 | } 103 | 104 | /** 105 | * \brief Remove a file 106 | * 107 | * Unlink the file whose path name is \p file 108 | * 109 | * \param file the file to remove 110 | * 111 | * \retval 0 on success 112 | * \retval ~0 on failure 113 | */ 114 | int u_remove(const char *file) 115 | { 116 | dbg_return_if (file == NULL, ~0); 117 | 118 | dbg_err_sif(unlink(file) < 0); 119 | 120 | return 0; 121 | err: 122 | return ~0; 123 | } 124 | 125 | /** 126 | * \} 127 | */ 128 | -------------------------------------------------------------------------------- /srcs/toolbox/memory.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | typedef struct u_memory_funcs_s 9 | { 10 | void *(*f_malloc) (size_t); 11 | void *(*f_calloc) (size_t, size_t); 12 | void *(*f_realloc) (void *, size_t); 13 | void (*f_free) (void *); 14 | } u_memory_fns_t; 15 | 16 | /* defaults to LibC memory allocator */ 17 | static u_memory_fns_t u_memory_fns = { malloc, calloc, realloc, free }; 18 | 19 | /** 20 | \defgroup alloc Memory allocation 21 | \{ 22 | The \ref alloc module introduces a number of wrappers to basic memory 23 | management functions which allows to change the underlying memory 24 | allocator in a way that is transparent to the applications built on 25 | LibU. 26 | It is sufficient for an application to only use ::u_malloc/::u_free 27 | and friends (which also include ::u_memdup, ::u_strndup and ::u_strdup 28 | from the \ref misc module) when carrying out memory allocation and 29 | deallocation operations. 30 | In case it'd be needed to change the underlying memory management 31 | facility with a custom one a call to ::u_memory_set_malloc and co. 32 | would be enough to fix it up, provided that the new memory management 33 | system has ISO C-like \c malloc(3) interfaces. 34 | */ 35 | 36 | /** \brief Set \c malloc(3) replacement */ 37 | void u_memory_set_malloc (void *(*f_malloc) (size_t)) 38 | { 39 | u_memory_fns.f_malloc = f_malloc; 40 | } 41 | 42 | /** \brief Set \c calloc(3) replacement */ 43 | void u_memory_set_calloc (void *(*f_calloc) (size_t, size_t)) 44 | { 45 | u_memory_fns.f_calloc = f_calloc; 46 | } 47 | 48 | /** \brief Set \c realloc(3) replacement */ 49 | void u_memory_set_realloc (void *(*f_realloc) (void *, size_t)) 50 | { 51 | u_memory_fns.f_realloc = f_realloc; 52 | } 53 | 54 | /** \brief Set \c free(3) replacement */ 55 | void u_memory_set_free (void (*f_free) (void *)) 56 | { 57 | u_memory_fns.f_free = f_free; 58 | } 59 | 60 | /** \brief Wrapper for malloc-like function */ 61 | void *u_malloc (size_t sz) 62 | { 63 | return u_memory_fns.f_malloc(sz); 64 | } 65 | 66 | /** \brief Wrapper for calloc-like function */ 67 | void *u_calloc (size_t cnt, size_t sz) 68 | { 69 | return u_memory_fns.f_calloc(cnt, sz); 70 | } 71 | 72 | /** \brief Alloc a contiguous region of \p sz bytes and zero-fill it */ 73 | void *u_zalloc (size_t sz) 74 | { 75 | return u_memory_fns.f_calloc(1, sz); 76 | } 77 | 78 | /** \brief Wrapper for realloc-like function */ 79 | void *u_realloc (void *ptr, size_t sz) 80 | { 81 | return u_memory_fns.f_realloc(ptr, sz); 82 | } 83 | 84 | /** \brief Wrapper for free-like function, sanity checks the supplied pointer */ 85 | void u_free (void *ptr) 86 | { 87 | if (ptr) 88 | u_memory_fns.f_free(ptr); 89 | } 90 | 91 | /** 92 | * \} 93 | */ 94 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | include common.mk 2 | include ../Makefile.conf 3 | 4 | PROG = runtest 5 | 6 | SRCS += main.c 7 | SRCS += misc.c 8 | SRCS += string.c 9 | SRCS += lexer.c 10 | 11 | ifndef NO_ARRAY 12 | SRCS += array.c 13 | endif 14 | ifndef NO_LIST 15 | SRCS += list.c 16 | endif 17 | ifndef NO_NET 18 | SRCS += uri.c 19 | endif 20 | ifndef NO_RB 21 | SRCS += rb.c 22 | endif 23 | ifndef NO_PWD 24 | SRCS += pwd.c 25 | endif 26 | ifndef NO_HMAP 27 | SRCS += hmap.c 28 | endif 29 | ifndef NO_PQUEUE 30 | SRCS += pqueue.c 31 | endif 32 | ifndef NO_BST 33 | SRCS += bst.c 34 | endif 35 | ifndef NO_B64 36 | SRCS += b64.c 37 | endif 38 | ifndef NO_JSON 39 | SRCS += json.c 40 | ifdef HAVE_ISFINITE 41 | LDFLAGS += -lm 42 | endif 43 | endif 44 | 45 | LDADD += ../srcs/libu.a 46 | 47 | include prog.mk 48 | 49 | ifndef NO_RUN_TEST 50 | all-hook-post: 51 | @./$(PROG) -o - || echo "unit test execution failed" 52 | endif 53 | -------------------------------------------------------------------------------- /test/array.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | int test_suite_array_register (u_test_t *t); 13 | 14 | static int test_resize (u_test_case_t *tc); 15 | static int test_short (u_test_case_t *tc); 16 | static int test_ptr (u_test_case_t *tc); 17 | static int test_u_short (u_test_case_t *tc); 18 | static int test_char (u_test_case_t *tc); 19 | static int test_u_char (u_test_case_t *tc); 20 | 21 | static int test_resize (u_test_case_t *tc) 22 | { 23 | u_array_t *da = NULL; 24 | size_t idx; 25 | short s, s0; 26 | 27 | u_test_err_if (u_array_create(U_ARRAY_TYPE_SHORT, 100, &da)); 28 | 29 | for (s = SHRT_MIN, idx = 0; s < SHRT_MAX; s++, idx++) 30 | { 31 | u_test_err_if (u_array_set_short(da, idx, s, NULL)); 32 | u_test_err_if (u_array_get_short(da, idx, &s0)); 33 | u_test_err_ifm (s != s0, "s = %d, s0 = %d, idx = %zu", s, s0, idx); 34 | } 35 | 36 | u_array_free(da); 37 | 38 | return U_TEST_SUCCESS; 39 | err: 40 | u_array_free(da); 41 | 42 | return U_TEST_FAILURE; 43 | } 44 | 45 | static int test_short (u_test_case_t *tc) 46 | { 47 | u_array_t *da = NULL; 48 | size_t idx; 49 | short s, s0; 50 | 51 | u_test_err_if (u_array_create(U_ARRAY_TYPE_SHORT, SHRT_MAX * 2 + 1, &da)); 52 | 53 | for (s = SHRT_MIN, idx = 0; s < SHRT_MAX; s++, idx++) 54 | { 55 | u_test_err_if (u_array_set_short(da, idx, s, NULL)); 56 | u_test_err_if (u_array_get_short(da, idx, &s0)); 57 | u_test_err_ifm (s != s0, "s = %d, s0 = %d, idx = %zu", s, s0, idx); 58 | } 59 | 60 | u_array_free(da); 61 | 62 | return U_TEST_SUCCESS; 63 | err: 64 | u_array_free(da); 65 | 66 | return U_TEST_FAILURE; 67 | } 68 | 69 | static int test_ptr (u_test_case_t *tc) 70 | { 71 | int rc = 0; 72 | u_array_t *da = NULL; 73 | size_t idx; 74 | struct S { int i; char c; } s, *s0; 75 | 76 | u_test_err_if (u_array_create(U_ARRAY_TYPE_PTR, 10, &da)); 77 | 78 | for (idx = 0; idx < 100; idx++) 79 | { 80 | s.i = (int) idx; 81 | s.c = (char) idx; 82 | 83 | /* explicitly ignore "old values" */ 84 | (void) u_array_set_ptr(da, idx, &s, &rc); 85 | u_test_err_ifm (rc == -1, "setting %p at idx %zu failed", &s, idx); 86 | 87 | s0 = u_array_get_ptr(da, idx, &rc); 88 | u_test_err_ifm (rc == -1, "getting from idx %zu failed", idx); 89 | 90 | u_test_err_ifm (s.i != s0->i, "%d != %d at index %zu", s.i, s0->i, idx); 91 | u_test_err_ifm (s.c != s0->c, "%c != %c at index %zu", s.c, s0->c, idx); 92 | } 93 | 94 | u_array_free(da); 95 | 96 | return U_TEST_SUCCESS; 97 | err: 98 | u_array_free(da); 99 | 100 | return U_TEST_FAILURE; 101 | } 102 | 103 | static int test_u_short (u_test_case_t *tc) 104 | { 105 | u_array_t *da = NULL; 106 | size_t idx; 107 | unsigned short s, s0; 108 | 109 | u_test_err_if (u_array_create(U_ARRAY_TYPE_U_SHORT, USHRT_MAX + 1, &da)); 110 | 111 | for (s = 0, idx = 0; s < USHRT_MAX; s++, idx++) 112 | { 113 | u_test_err_if (u_array_set_u_short(da, idx, s, NULL)); 114 | u_test_err_if (u_array_get_u_short(da, idx, &s0)); 115 | u_test_err_ifm (s != s0, "s = %d, s0 = %d, idx = %zu", s, s0, idx); 116 | } 117 | 118 | u_array_free(da); 119 | 120 | return U_TEST_SUCCESS; 121 | err: 122 | u_array_free(da); 123 | 124 | return U_TEST_FAILURE; 125 | } 126 | 127 | static int test_char (u_test_case_t *tc) 128 | { 129 | u_array_t *da = NULL; 130 | size_t idx; 131 | char s, s0; 132 | 133 | u_test_err_if (u_array_create(U_ARRAY_TYPE_CHAR, CHAR_MAX * 2 + 1, &da)); 134 | 135 | for (s = CHAR_MIN, idx = 0; s < CHAR_MAX; s++, idx++) 136 | { 137 | u_test_err_if (u_array_set_char(da, idx, s, NULL)); 138 | u_test_err_if (u_array_get_char(da, idx, &s0)); 139 | u_test_err_ifm (s != s0, "s = %d, s0 = %d, idx = %zu", s, s0, idx); 140 | } 141 | 142 | u_array_free(da); 143 | 144 | return U_TEST_SUCCESS; 145 | err: 146 | u_array_free(da); 147 | 148 | return U_TEST_FAILURE; 149 | } 150 | 151 | static int test_u_char (u_test_case_t *tc) 152 | { 153 | size_t idx; 154 | u_array_t *da = NULL; 155 | unsigned char s, s0; 156 | 157 | u_test_err_if (u_array_create(U_ARRAY_TYPE_U_CHAR, UCHAR_MAX + 1, &da)); 158 | 159 | for (s = 0, idx = 0; s < UCHAR_MAX; s++, idx++) 160 | { 161 | u_test_err_if (u_array_set_u_char(da, idx, s, NULL)); 162 | u_test_err_if (u_array_get_u_char(da, idx, &s0)); 163 | u_test_err_ifm (s != s0, "s = %d, s0 = %d, idx = %zu", s, s0, idx); 164 | } 165 | 166 | u_array_free(da); 167 | 168 | return U_TEST_SUCCESS; 169 | err: 170 | u_array_free(da); 171 | 172 | return U_TEST_FAILURE; 173 | } 174 | 175 | int test_suite_array_register (u_test_t *t) 176 | { 177 | u_test_suite_t *ts = NULL; 178 | 179 | con_err_if (u_test_suite_new("Dynamic Arrays", &ts)); 180 | 181 | con_err_if (u_test_case_register("Pointer elements", test_ptr, ts)); 182 | con_err_if (u_test_case_register("Short elements", test_short, ts)); 183 | con_err_if (u_test_case_register("Unsigned short elements", 184 | test_u_short, ts)); 185 | con_err_if (u_test_case_register("Char elements", test_char, ts)); 186 | con_err_if (u_test_case_register("Unsigned char elements", 187 | test_u_char, ts)); 188 | con_err_if (u_test_case_register("Force array resize", test_resize, ts)); 189 | 190 | return u_test_suite_add(ts, t); 191 | err: 192 | u_test_suite_free(ts); 193 | return ~0; 194 | } 195 | -------------------------------------------------------------------------------- /test/b64.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int test_suite_b64_register (u_test_t *t); 4 | 5 | static int test_b64_codec (u_test_case_t *tc) 6 | { 7 | struct 8 | { 9 | const uint8_t *bin; 10 | size_t bin_sz; 11 | const char *str; 12 | size_t str_sz; 13 | } vt[] = { 14 | { 15 | .bin = (const uint8_t *) "f", 16 | .bin_sz = strlen("f"), 17 | .str = "Zg==", 18 | .str_sz = strlen("Zg==") 19 | }, 20 | { 21 | .bin = (const uint8_t *) "fo", 22 | .bin_sz = strlen("fo"), 23 | .str = "Zm8=", 24 | .str_sz = strlen("Zm8=") 25 | }, 26 | { 27 | .bin = (const uint8_t *) "foo", 28 | .bin_sz = strlen("foo"), 29 | .str = "Zm9v", 30 | .str_sz = strlen("Zm9v") 31 | }, 32 | { 33 | .bin = (const uint8_t *) "foob", 34 | .bin_sz = strlen("foob"), 35 | .str = "Zm9vYg==", 36 | .str_sz = strlen("Zm9vYg==") 37 | }, 38 | { 39 | .bin = (const uint8_t *) "fooba", 40 | .bin_sz = strlen("fooba"), 41 | .str = "Zm9vYmE=", 42 | .str_sz = strlen("Zm9vYmE=") 43 | }, 44 | { 45 | .bin = (const uint8_t *) "foobar", 46 | .bin_sz = strlen("foobar"), 47 | .str = "Zm9vYmFy", 48 | .str_sz = strlen("Zm9vYmFy") 49 | }, 50 | { NULL, 0, NULL, 0 } 51 | }; 52 | 53 | int i; 54 | 55 | for (i = 0; vt[i].bin; i++) 56 | { 57 | char s[U_B64_LENGTH(vt[i].bin_sz) + 1]; /* +1 for '\0' */ 58 | uint8_t b[vt[i].bin_sz]; 59 | size_t b_sz = vt[i].bin_sz; 60 | 61 | u_test_err_ifm (u_b64_encode(vt[i].bin, vt[i].bin_sz, s, sizeof s), 62 | "error encoding test vector %zu", i); 63 | 64 | u_test_err_ifm (strcasecmp(s, vt[i].str), 65 | "expecting %s, got %s", vt[i].str, s); 66 | 67 | u_test_err_ifm (u_b64_decode(s, strlen(s), b, &b_sz), 68 | "error decoding test vector %zu", i); 69 | 70 | u_test_err_ifm (vt[i].bin_sz != b_sz || 71 | memcmp(b, vt[i].bin, vt[i].bin_sz), 72 | "run \'gdb --args runtest -s\' and b somewhere before %s:%s", 73 | __FILE__, __LINE__); 74 | } 75 | 76 | return U_TEST_SUCCESS; 77 | err: 78 | return U_TEST_FAILURE; 79 | } 80 | 81 | int test_suite_b64_register (u_test_t *t) 82 | { 83 | u_test_suite_t *ts = NULL; 84 | 85 | con_err_if (u_test_suite_new("Base64", &ts)); 86 | 87 | con_err_if (u_test_case_register("Base64 codec", test_b64_codec, ts)); 88 | 89 | return u_test_suite_add(ts, t); 90 | err: 91 | u_test_suite_free(ts); 92 | return ~0; 93 | } 94 | -------------------------------------------------------------------------------- /test/bst.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define KEY_SZ 128 4 | 5 | int test_suite_bst_register (u_test_t *t); 6 | 7 | static u_bst_t *prepare_bst (u_test_case_t *tc, size_t nelems); 8 | static void cmp_last_string (u_bst_node_t *node, void *dummy); 9 | 10 | static int test_sort (u_test_case_t *tc); 11 | static int test_search (u_test_case_t *tc); 12 | 13 | static int test_sort (u_test_case_t *tc) 14 | { 15 | enum { NELEMS = 1000000 }; 16 | u_bst_t *bst = NULL; 17 | 18 | /* Prepare a BST with 'NELEMS' nodes. */ 19 | u_test_err_if ((bst = prepare_bst(tc, NELEMS)) == NULL); 20 | 21 | u_test_case_printf(tc, "BST sorting %u elements", u_bst_count(bst)); 22 | 23 | /* Check for monotonically increasing key values. */ 24 | (void) u_bst_foreach(bst, cmp_last_string, tc); 25 | 26 | u_bst_free(bst); 27 | 28 | return U_TEST_SUCCESS; 29 | err: 30 | if (bst) 31 | u_bst_free(bst); 32 | 33 | return U_TEST_FAILURE; 34 | } 35 | 36 | static int test_search (u_test_case_t *tc) 37 | { 38 | enum { NELEMS = 1000000 }; 39 | u_bst_t *bst = NULL; 40 | u_bst_node_t *node; 41 | 42 | /* Prepare a BST with 'NELEMS' nodes. */ 43 | u_test_err_if ((bst = prepare_bst(tc, NELEMS)) == NULL); 44 | 45 | /* Push a needle into the haystack. */ 46 | u_test_err_if (u_bst_push(bst, "needle", NULL)); 47 | 48 | /* Search for it. */ 49 | u_test_err_if ((node = u_bst_search(bst, "needle")) == NULL); 50 | 51 | u_test_case_printf(tc, "\'%s\' found !", 52 | (const char *) u_bst_node_key(node)); 53 | 54 | u_bst_free(bst); 55 | 56 | return U_TEST_SUCCESS; 57 | err: 58 | if (bst) 59 | u_bst_free(bst); 60 | 61 | return U_TEST_FAILURE; 62 | } 63 | 64 | static u_bst_t *prepare_bst (u_test_case_t *tc, size_t nelems) 65 | { 66 | size_t i; 67 | char key[KEY_SZ]; 68 | u_bst_t *bst = NULL; 69 | 70 | /* Seed the PRNG. */ 71 | srand((unsigned) getpid()); 72 | 73 | u_test_err_if (u_bst_new(U_BST_OPT_NONE, &bst)); 74 | 75 | /* Push 'nelem' random nodes with string keys. */ 76 | for (i = 0; i < nelems; i++) 77 | { 78 | (void) u_snprintf(key, sizeof key, "%12.12d", rand()); 79 | u_test_err_if (u_bst_push(bst, key, NULL)); 80 | } 81 | 82 | return bst; 83 | err: 84 | if (bst) 85 | u_bst_free(bst); 86 | return NULL; 87 | } 88 | 89 | static void cmp_last_string (u_bst_node_t *node, void *p) 90 | { 91 | u_test_case_t *tc = (u_test_case_t *) p; 92 | const char *key = (const char *) u_bst_node_key(node); 93 | static char last[KEY_SZ] = { '\0' }; 94 | 95 | /* Compare against last saved key. */ 96 | if (strcmp(last, key) > 0) 97 | { 98 | /* FIXME: on failure should fire an abort() or set some global 99 | * to explicitly invalidate the test. */ 100 | u_test_case_printf(tc, "SORT FAILED on key %s", key); 101 | } 102 | 103 | /* Save current node's key to 'last'. */ 104 | (void) u_strlcpy(last, key, sizeof last); 105 | 106 | return ; 107 | } 108 | 109 | int test_suite_bst_register (u_test_t *t) 110 | { 111 | u_test_suite_t *ts = NULL; 112 | 113 | con_err_if (u_test_suite_new("Binary Search Tree", &ts)); 114 | 115 | con_err_if (u_test_case_register("Sort", test_sort, ts)); 116 | con_err_if (u_test_case_register("Search", test_search, ts)); 117 | 118 | return u_test_suite_add(ts, t); 119 | err: 120 | u_test_suite_free(ts); 121 | return ~0; 122 | } 123 | -------------------------------------------------------------------------------- /test/lexer.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int test_suite_lexer_register (u_test_t *t); 4 | 5 | static int test_scan0 (u_test_case_t *tc); 6 | static int test_scan1 (u_test_case_t *tc); 7 | static int test_match (u_test_case_t *tc); 8 | 9 | static int scan (u_test_case_t *tc, int (*f)(u_lexer_t *, char *)); 10 | 11 | /* 'f' is one of u_lexer_next() or u_lexer_skip() */ 12 | static int scan (u_test_case_t *tc, int (*f)(u_lexer_t *, char *)) 13 | { 14 | char c; 15 | int i = 0; 16 | u_lexer_t *l = NULL; 17 | const char *s = "abc AB\tC\n1 2 3 "; 18 | const char *ex0 = "abcABC123", *ex1 = s; 19 | char dest[1024] = { '\0' }; 20 | 21 | u_test_err_if (u_lexer_new(s, &l)); 22 | 23 | /* First char under cursor. */ 24 | c = u_lexer_peek(l); 25 | dest[i] = c; 26 | 27 | while (f(l, &c) != -1) 28 | dest[++i] = c; 29 | 30 | dest[++i] = '\0'; 31 | 32 | if (f == u_lexer_next) 33 | u_test_err_if (strcmp(dest, ex1)); 34 | else if (f == u_lexer_skip) 35 | u_test_err_if (strcmp(dest, ex0)); 36 | else 37 | u_test_err_ifm (1, "uh?"); 38 | 39 | u_lexer_free(l); 40 | return U_TEST_SUCCESS; 41 | err: 42 | u_lexer_free(l); 43 | return U_TEST_FAILURE; 44 | } 45 | 46 | static int test_scan0 (u_test_case_t *tc) 47 | { 48 | return scan(tc, u_lexer_next); 49 | } 50 | 51 | static int test_scan1 (u_test_case_t *tc) 52 | { 53 | return scan(tc, u_lexer_skip); 54 | } 55 | 56 | 57 | static int test_match (u_test_case_t *tc) 58 | { 59 | char c; 60 | u_lexer_t *l = NULL; 61 | char match[U_TOKEN_SZ]; 62 | #define EXP "*match me*" 63 | const char *s = "abc " EXP " ABC"; 64 | 65 | u_test_err_if (u_lexer_new(s, &l)); 66 | 67 | /* get left-hand bookmark, i.e. first '*' */ 68 | while (u_lexer_next(l, &c) != -1) 69 | { 70 | if (c == '*') 71 | { 72 | u_lexer_record_lmatch(l); 73 | break; 74 | } 75 | } 76 | 77 | /* now go for the right-hand bookmark, i.e. second '*' */ 78 | while (u_lexer_next(l, &c) != -1) 79 | { 80 | if (c == '*') 81 | { 82 | u_lexer_record_rmatch(l); 83 | break; 84 | } 85 | } 86 | 87 | u_test_err_if (strcmp(u_lexer_get_match(l, match), EXP)); 88 | #undef EXP 89 | u_lexer_free(l); 90 | return U_TEST_SUCCESS; 91 | err: 92 | u_lexer_free(l); 93 | return U_TEST_FAILURE; 94 | } 95 | 96 | int test_suite_lexer_register (u_test_t *t) 97 | { 98 | u_test_suite_t *ts = NULL; 99 | 100 | con_err_if (u_test_suite_new("Lexer", &ts)); 101 | 102 | con_err_if (u_test_case_register("scan (no skip ws)", test_scan0, ts)); 103 | con_err_if (u_test_case_register("scan (skip ws)", test_scan1, ts)); 104 | con_err_if (u_test_case_register("match", test_match, ts)); 105 | 106 | return u_test_suite_add(ts, t); 107 | err: 108 | u_test_suite_free(ts); 109 | return ~0; 110 | } 111 | -------------------------------------------------------------------------------- /test/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int test_suite_list_register (u_test_t *t); 12 | 13 | static int test_list_iterator (u_test_case_t *tc); 14 | static int test_list_ins (u_test_case_t *tc); 15 | 16 | static int test_list_iterator (u_test_case_t *tc) 17 | { 18 | enum { ITERS = 300 }; 19 | u_list_t *l = NULL; 20 | void *it; 21 | size_t j, c; 22 | intptr_t i, v, tot0, tot1; 23 | 24 | u_test_err_if (u_list_create(&l)); 25 | 26 | u_test_err_ifm (u_list_count(l), "expecting no items!"); 27 | 28 | for (tot0 = 0, i = 1; i < ITERS; ++i) 29 | { 30 | u_test_err_if (u_list_add(l, (void*)i)); 31 | tot0 += i; 32 | } 33 | 34 | for (i = 1; i < ITERS; ++i) 35 | { 36 | u_test_err_if (u_list_insert(l, (void*)i, i)); 37 | tot0 += i; 38 | } 39 | 40 | for (tot1 = 0, v = (intptr_t) u_list_first(l, &it); 41 | v != 0; 42 | v = (intptr_t) u_list_next(l, &it)) 43 | { 44 | tot1 += v; 45 | } 46 | 47 | u_test_err_if (tot0 != tot1); 48 | 49 | /* remove some items */ 50 | c = u_list_count(l)/2; 51 | for (j = 0; j < c; ++j) 52 | { 53 | u_list_del_n(l, 0, (void*)&v); 54 | tot0 -= v; 55 | } 56 | 57 | for (tot1 = 0, v = (intptr_t) u_list_first(l, &it); 58 | v != 0; 59 | v = (intptr_t) u_list_next(l, &it)) 60 | { 61 | tot1 += v; 62 | } 63 | 64 | u_test_err_if (tot0 != tot1); 65 | 66 | u_list_free(l); 67 | 68 | return U_TEST_SUCCESS; 69 | err: 70 | return U_TEST_FAILURE; 71 | } 72 | 73 | static int test_list_ins (u_test_case_t *tc) 74 | { 75 | enum { ITERS = 3 }; 76 | u_list_t *l = NULL; 77 | uintptr_t i; 78 | void* prev; 79 | 80 | u_test_err_if (u_list_create(&l)); 81 | u_test_err_if (u_list_add(l, (void*)1)); 82 | u_test_err_if (u_list_add(l, (void*)2)); 83 | u_test_err_if (u_list_add(l, (void*)99)); 84 | u_test_err_if (u_list_add(l, (void*)2)); 85 | u_test_err_if (u_list_add(l, (void*)4)); 86 | 87 | u_test_err_if (u_list_insert(l, (void*)0, 0)); 88 | u_test_err_if (u_list_insert(l, (void*)3, 3)); 89 | u_test_err_if (u_list_del(l, (void*)99)); 90 | u_test_err_if (u_list_del_n(l, 4, NULL)); 91 | 92 | u_test_err_if (u_list_insert(l, (void*)99, 0)); 93 | u_test_err_if (u_list_insert(l, (void*)99, u_list_count(l))); 94 | 95 | u_test_err_if (u_list_del_n(l, 0, &prev)); 96 | u_test_err_if ((uintptr_t) prev != 99); 97 | 98 | u_test_err_if (u_list_del_n(l, u_list_count(l)-1, &prev)); 99 | u_test_err_if ((uintptr_t) prev != 99); 100 | 101 | for (i = 0; i < ITERS; ++i) 102 | u_test_err_if (u_list_insert(l, (void*)99, 2)); 103 | for (i = 0; i < ITERS; ++i) 104 | u_test_err_if (u_list_del(l, (void*)99)); 105 | 106 | for (i = 0; i < ITERS; ++i) 107 | u_test_err_if (u_list_insert(l, (void*)99, 2)); 108 | 109 | for (i = 0; i < ITERS; ++i) 110 | { 111 | u_test_err_if (u_list_del_n(l, 2, &prev)); 112 | u_test_err_if ((uintptr_t) prev != 99); 113 | } 114 | 115 | for (i = 0; i < (uintptr_t) u_list_count(l); ++i) 116 | u_test_err_if (i != (uintptr_t) u_list_get_n(l, i)); 117 | 118 | u_list_free(l); 119 | 120 | return U_TEST_SUCCESS; 121 | err: 122 | if (l) 123 | u_list_free(l); 124 | 125 | return U_TEST_FAILURE; 126 | } 127 | 128 | int test_suite_list_register (u_test_t *t) 129 | { 130 | u_test_suite_t *ts = NULL; 131 | 132 | con_err_if (u_test_suite_new("Lists", &ts)); 133 | 134 | con_err_if (u_test_case_register("Insertion", test_list_ins, ts)); 135 | con_err_if (u_test_case_register("Iteration", test_list_iterator, ts)); 136 | 137 | return u_test_suite_add(ts, t); 138 | err: 139 | u_test_suite_free(ts); 140 | return ~0; 141 | } 142 | -------------------------------------------------------------------------------- /test/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int facility = LOG_LOCAL0; 4 | 5 | int test_suite_misc_register (u_test_t *t); 6 | int test_suite_string_register (u_test_t *t); 7 | int test_suite_hmap_register (u_test_t *t); 8 | int test_suite_list_register (u_test_t *t); 9 | int test_suite_array_register (u_test_t *t); 10 | int test_suite_uri_register (u_test_t *t); 11 | int test_suite_pqueue_register (u_test_t *t); 12 | int test_suite_rb_register (u_test_t *t); 13 | int test_suite_pwd_register (u_test_t *t); 14 | int test_suite_json_register (u_test_t *t); 15 | int test_suite_lexer_register (u_test_t *t); 16 | int test_suite_bst_register (u_test_t *t); 17 | 18 | int main(int argc, char **argv) 19 | { 20 | int rc; 21 | u_test_t *t = NULL; 22 | 23 | con_err_if (u_test_new("LibU Unit Tests", &t)); 24 | 25 | con_err_if (test_suite_misc_register(t)); 26 | con_err_if (test_suite_string_register(t)); 27 | con_err_if (test_suite_lexer_register(t)); 28 | 29 | #ifndef NO_ARRAY 30 | con_err_if (test_suite_array_register(t)); 31 | #endif /* !NO_ARRAY */ 32 | #ifndef NO_LIST 33 | con_err_if (test_suite_list_register(t)); 34 | #endif /* !NO_LIST */ 35 | #ifndef NO_NET 36 | con_err_if (test_suite_uri_register(t)); 37 | #endif /* !NO_NET */ 38 | #ifndef NO_RB 39 | con_err_if (test_suite_rb_register(t)); 40 | #endif /* !NO_RB */ 41 | #ifndef NO_PWD 42 | con_err_if (test_suite_pwd_register(t)); 43 | #endif /* !NO_PWD */ 44 | #ifndef NO_HMAP 45 | con_err_if (test_suite_hmap_register(t)); 46 | #endif /* !NO_HMAP */ 47 | #ifndef NO_PQUEUE 48 | con_err_if (test_suite_pqueue_register(t)); 49 | #endif /* !NO_PQUEUE */ 50 | #ifndef NO_BST 51 | con_err_if (test_suite_bst_register(t)); 52 | #endif /* !NO_BST */ 53 | #ifndef NO_JSON 54 | con_err_if (test_suite_json_register(t)); 55 | #endif /* !NO_JSON */ 56 | #ifndef NO_BST 57 | con_err_if (test_suite_b64_register(t)); 58 | #endif /* !NO_BST */ 59 | 60 | rc = u_test_run(argc, argv, t); 61 | u_test_free(t); 62 | 63 | return rc; 64 | err: 65 | u_test_free(t); 66 | return EXIT_FAILURE; 67 | } 68 | -------------------------------------------------------------------------------- /test/pqueue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int test_suite_pqueue_register (u_test_t *t); 5 | 6 | static int test_top10 (u_test_case_t *tc); 7 | static int test_heapsort (u_test_case_t *tc); 8 | 9 | static int test_top10 (u_test_case_t *tc) 10 | { 11 | enum { EMAX = 10 }; 12 | size_t i; 13 | double key, keymax = DBL_MAX; 14 | u_pq_t *pq = NULL; 15 | 16 | srand(time(NULL)); 17 | 18 | u_test_err_if (u_pq_create(EMAX, &pq)); 19 | 20 | /* fill the pqueue */ 21 | for (i = 0; i < EMAX; i++) 22 | u_test_err_if (u_pq_push(pq, (double) rand(), NULL)); 23 | 24 | /* del-push cycle */ 25 | for (i = EMAX; i < 10000000; i++) 26 | { 27 | (void) u_pq_peekmax(pq, &keymax); 28 | 29 | if (keymax > (key = (double) rand())) 30 | { 31 | (void) u_pq_delmax(pq, NULL); 32 | u_test_err_if (u_pq_push(pq, key, NULL)); 33 | } 34 | } 35 | 36 | /* print results */ 37 | for (i = 0; !u_pq_empty(pq); i++) 38 | { 39 | (void) u_pq_delmax(pq, &key); 40 | u_test_case_printf(tc, "%zu: %.0lf", EMAX - i, key); 41 | } 42 | 43 | u_pq_free(pq); 44 | return U_TEST_SUCCESS; 45 | err: 46 | u_pq_free(pq); 47 | return U_TEST_FAILURE; 48 | } 49 | 50 | static int test_heapsort (u_test_case_t *tc) 51 | { 52 | size_t i; 53 | enum { EMAX = 1000000 }; 54 | double key, prev_key = -1; 55 | u_pq_t *pq = NULL; 56 | 57 | srand(time(NULL)); 58 | 59 | u_test_err_if (u_pq_create(EMAX, &pq)); 60 | 61 | for (i = 0; i < EMAX - 1; i++) 62 | u_test_err_if (u_pq_push(pq, (double) rand(), NULL)); 63 | 64 | while (!u_pq_empty(pq)) 65 | { 66 | (void) u_pq_delmax(pq, &key); 67 | u_test_err_if (prev_key != -1 && key > prev_key); 68 | prev_key = key; 69 | } 70 | 71 | u_pq_free(pq); 72 | 73 | return U_TEST_SUCCESS; 74 | err: 75 | u_pq_free(pq); 76 | return U_TEST_FAILURE; 77 | } 78 | 79 | int test_suite_pqueue_register (u_test_t *t) 80 | { 81 | u_test_suite_t *ts = NULL; 82 | 83 | con_err_if (u_test_suite_new("Priority Queues", &ts)); 84 | 85 | con_err_if (u_test_case_register("Top 10 (reverse) in 10 million", 86 | test_top10, ts)); 87 | con_err_if (u_test_case_register("Heap sort 1 million random entries", 88 | test_heapsort, ts)); 89 | 90 | return u_test_suite_add(ts, t); 91 | err: 92 | u_test_suite_free(ts); 93 | return ~0; 94 | } 95 | -------------------------------------------------------------------------------- /test/pwd.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int test_suite_pwd_register (u_test_t *t); 4 | 5 | static int test_u_pwd (u_test_case_t *tc); 6 | 7 | static int test_u_pwd (u_test_case_t *tc) 8 | { 9 | enum { 10 | PWD_NUM = 1024, 11 | INT_SZ = 16 12 | }; 13 | u_pwd_t *pwd = NULL; 14 | char user[INT_SZ]; 15 | char pass[INT_SZ]; 16 | int i; 17 | 18 | u_test_err_if (u_pwd_init_file("passwd", NULL, 0, 1, &pwd)); 19 | 20 | for (i = 0; i < PWD_NUM; i++) { 21 | u_test_err_if (u_snprintf(user, INT_SZ, "user%d", i)); 22 | u_test_err_if (u_snprintf(pass, INT_SZ, "pass%d", i)); 23 | u_test_err_if (u_pwd_auth_user(pwd, user, pass)); 24 | } 25 | 26 | u_pwd_term(pwd); 27 | 28 | return U_TEST_SUCCESS; 29 | err: 30 | U_FREEF(pwd, u_pwd_term); 31 | 32 | return U_TEST_FAILURE; 33 | } 34 | 35 | int test_suite_pwd_register (u_test_t *t) 36 | { 37 | u_test_suite_t *ts = NULL; 38 | 39 | con_err_if (u_test_suite_new("Password", &ts)); 40 | 41 | con_err_if (u_test_case_register("Plain text auth", test_u_pwd, ts)); 42 | 43 | return u_test_suite_add(ts, t); 44 | err: 45 | u_test_suite_free(ts); 46 | return ~0; 47 | } 48 | -------------------------------------------------------------------------------- /test/rb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define RB_SZ 4096 5 | 6 | int test_suite_rb_register (u_test_t *t); 7 | 8 | static int rw (u_test_case_t *tc, int malloc_based, int fast); 9 | #ifdef U_RB_CAN_MMAP 10 | static int test_rw (u_test_case_t *tc); 11 | static int test_rw_fast (u_test_case_t *tc); 12 | #endif /* U_RB_CAN_MMAP */ 13 | 14 | static int rw (u_test_case_t *tc, int malloc_based, int fast) 15 | { 16 | enum { BUF_SZ = 1024 }; 17 | int opts; 18 | u_rb_t *rb = NULL; 19 | size_t i, obuf_sz; 20 | char ibuf[BUF_SZ], obuf[BUF_SZ], *obuf_ptr, c; 21 | 22 | opts = fast ? U_RB_OPT_USE_CONTIGUOUS_MEM : U_RB_OPT_NONE; 23 | opts |= malloc_based ? U_RB_OPT_IMPL_MALLOC : U_RB_OPT_NONE; 24 | 25 | u_test_err_if (u_rb_create(RB_SZ, opts, &rb)); 26 | 27 | c = '*'; 28 | memset(ibuf, c, sizeof ibuf); 29 | 30 | /* 4 * 1024 write's => full */ 31 | for (i = 0; i < 4; i++) 32 | u_test_err_if (u_rb_write(rb, ibuf, sizeof ibuf) != sizeof ibuf); 33 | 34 | /* now make offsets advance in the second region to test pairing */ 35 | for (i = 0, c = 0; c < 127; c++) 36 | { 37 | if (!isprint(c)) 38 | continue; 39 | 40 | /* consume 1024 bytes and test whether the read bytes match what was 41 | * written */ 42 | if (fast) 43 | { 44 | obuf_sz = BUF_SZ; 45 | obuf_ptr = u_rb_fast_read(rb, &obuf_sz); 46 | u_test_err_if (obuf_ptr == NULL || obuf_sz != BUF_SZ); 47 | } 48 | else 49 | { 50 | u_test_err_if (u_rb_read(rb, obuf, sizeof obuf) != sizeof obuf); 51 | obuf_ptr = obuf; 52 | } 53 | 54 | /* u_rb_read is (4 * 1024) bytes behind */ 55 | if (++i > 4) 56 | { 57 | u_test_err_ifm (obuf_ptr[0] != (c - 4) || 58 | obuf_ptr[BUF_SZ - 1] != (c - 4), 59 | "expecting \'%c\', got \'%c\'", c - 4, obuf_ptr[0]); 60 | } 61 | else 62 | { 63 | u_test_err_ifm (obuf_ptr[0] != '*' || obuf_ptr[BUF_SZ - 1] != '*', 64 | "expecting \'%c\', got \'%c\'", '*', obuf_ptr[0]); 65 | } 66 | 67 | /* refill */ 68 | memset(ibuf, c, sizeof ibuf); 69 | u_test_err_if (u_rb_write(rb, ibuf, sizeof ibuf) != sizeof ibuf); 70 | } 71 | 72 | u_rb_free(rb); 73 | 74 | return U_TEST_SUCCESS; 75 | err: 76 | if (rb) 77 | u_rb_free(rb); 78 | return U_TEST_FAILURE; 79 | } 80 | 81 | 82 | #ifdef U_RB_CAN_MMAP 83 | static int test_rw (u_test_case_t *tc) { return rw(tc, 0, 0); } 84 | static int test_rw_fast (u_test_case_t *tc) { return rw(tc, 0, 1); } 85 | #endif /* U_RB_CAN_MMAP */ 86 | static int test_rw_malloc (u_test_case_t *tc) { return rw(tc, 1, 0); } 87 | static int test_rw_fast_malloc (u_test_case_t *tc) { return rw(tc, 1, 1); } 88 | 89 | int test_suite_rb_register (u_test_t *t) 90 | { 91 | u_test_suite_t *ts = NULL; 92 | 93 | con_err_if (u_test_suite_new("Ring Buffer", &ts)); 94 | 95 | #ifdef U_RB_CAN_MMAP 96 | con_err_if (u_test_case_register("Read-write (mmap)", test_rw, ts)); 97 | con_err_if (u_test_case_register("Read-write fast (mmap)", 98 | test_rw_fast, ts)); 99 | #endif /* U_RB_CAN_MMAP */ 100 | con_err_if (u_test_case_register("Read-write (malloc)", 101 | test_rw_malloc, ts)); 102 | con_err_if (u_test_case_register("Read-write fast (malloc)", 103 | test_rw_fast_malloc, ts)); 104 | 105 | return u_test_suite_add(ts, t); 106 | err: 107 | u_test_suite_free(ts); 108 | return ~0; 109 | } 110 | -------------------------------------------------------------------------------- /test/string.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int test_suite_string_register (u_test_t *t); 12 | 13 | static int test_u_str (u_test_case_t *tc); 14 | static int test_emptiness (u_test_case_t *tc); 15 | 16 | static int test_u_str (u_test_case_t *tc) 17 | { 18 | u_string_t *s = NULL; 19 | 20 | u_test_err_if (u_string_create("0", 1, &s)); 21 | 22 | u_test_err_if (strcmp(u_string_c(s), "0")); 23 | 24 | u_test_err_if (u_string_sprintf(s, "%s", "1")); 25 | u_test_err_if (strcmp(u_string_c(s), "1")); 26 | 27 | u_test_err_if (u_string_aprintf(s, "%s", "23")); 28 | u_test_err_if (strcmp(u_string_c(s), "123")); 29 | 30 | u_test_err_if (u_string_cat(s, "45")); 31 | u_test_err_if (strcmp(u_string_c(s), "12345")); 32 | 33 | u_test_err_if (u_string_ncat(s, "6777", 2)); 34 | u_test_err_if (strcmp(u_string_c(s), "1234567")); 35 | 36 | u_test_err_if (u_string_sprintf(s, "%s", "reset")); 37 | u_test_err_if (strcmp(u_string_c(s), "reset")); 38 | 39 | u_string_free(s); 40 | 41 | return U_TEST_SUCCESS; 42 | err: 43 | return U_TEST_FAILURE; 44 | } 45 | 46 | static int test_emptiness (u_test_case_t *tc) 47 | { 48 | char *tmp; 49 | u_string_t *s = NULL; 50 | 51 | u_test_err_if (u_string_create(NULL, 0, &s)); 52 | 53 | /* Detach free's the parent string object whie the detached 54 | * buffer is left untouched. */ 55 | u_test_err_ifm ((tmp = u_string_detach_cstr(s)) != NULL, 56 | "an empty string should detach to a NULL pointer"); 57 | 58 | return U_TEST_SUCCESS; 59 | err: 60 | return U_TEST_FAILURE; 61 | } 62 | 63 | int test_suite_string_register (u_test_t *t) 64 | { 65 | u_test_suite_t *ts = NULL; 66 | 67 | con_err_if (u_test_suite_new("Strings", &ts)); 68 | 69 | con_err_if (u_test_case_register("Various functions", test_u_str, ts)); 70 | con_err_if (u_test_case_register("Emptiness" , test_emptiness, ts)); 71 | 72 | return u_test_suite_add(ts, t); 73 | err: 74 | u_test_suite_free(ts); 75 | return ~0; 76 | } 77 | --------------------------------------------------------------------------------