Import proplib-0.6.1.

This commit is contained in:
Juan RP 2012-07-10 23:33:19 +02:00
parent 34697e8022
commit 11ecf5438f
18 changed files with 2101 additions and 1459 deletions

View File

@ -17,5 +17,5 @@ internal use in the code:
- libfetch-2.31 from NetBSD: lib/fetch
- portableproplib-0.4.1 (lib/portableproplib) from
- portableproplib-0.6.1 (lib/portableproplib) from
http://code.google.com/p/portableproplib

2
NEWS
View File

@ -1,5 +1,7 @@
xbps-0.16.4 (???):
* Imported proplib 0.6.1 from http://code.google.com/p/portableproplib.
* libxbps: when finding obsolete files also match against sha256, not
just the filename. Also ignore symlinks found in rootfs to make
the system transition to /usr fully work.

View File

@ -9,10 +9,10 @@ LDFLAGS += $(LIBXBPS_LDFLAGS) -shared -Wl,-soname,libxbps.so.$(LIBXBPS_MAJOR)
# portableproplib
LIBPROP_OBJS = portableproplib/prop_array.o portableproplib/prop_bool.o
LIBPROP_OBJS += portableproplib/prop_dictionary.o portableproplib/prop_ingest.o
LIBPROP_OBJS += portableproplib/prop_object.o portableproplib/prop_rb.o
LIBPROP_OBJS += portableproplib/prop_object.o portableproplib/rb.o
LIBPROP_OBJS += portableproplib/prop_stack.o portableproplib/prop_string.o
LIBPROP_OBJS += portableproplib/prop_array_util.o portableproplib/prop_number.o
LIBPROP_OBJS += portableproplib/prop_dictionary_util.o
LIBPROP_OBJS += portableproplib/prop_dictionary_util.o portableproplib/prop_zlib.o
LIBPROP_OBJS += portableproplib/prop_data.o
LIBPROP_CPPFLAGS = -D_GNU_SOURCE
LIBPROP_CFLAGS = -Wno-old-style-definition -Wno-cast-qual -Wno-unused-parameter

View File

@ -129,13 +129,16 @@ bool prop_array_get_cstring(prop_array_t, unsigned int,
char **);
bool prop_array_set_cstring(prop_array_t, unsigned int,
const char *);
bool prop_array_add_cstring(prop_array_t, const char *);
bool prop_array_add_cstring_nocopy(prop_array_t,
const char *);
bool prop_array_get_cstring_nocopy(prop_array_t,
unsigned int,
const char **);
bool prop_array_set_cstring_nocopy(prop_array_t,
unsigned int,
const char *);
bool prop_array_add_and_rel(prop_array_t, prop_object_t);
__END_DECLS

View File

@ -90,6 +90,8 @@ bool prop_dictionary_keysym_equals(prop_dictionary_keysym_t,
* Utility routines to make it more convenient to work with values
* stored in dictionaries.
*/
bool prop_dictionary_get_dict(prop_dictionary_t, const char *,
prop_dictionary_t *);
bool prop_dictionary_get_bool(prop_dictionary_t, const char *,
bool *);
bool prop_dictionary_set_bool(prop_dictionary_t, const char *,
@ -142,6 +144,9 @@ bool prop_dictionary_get_cstring_nocopy(prop_dictionary_t,
bool prop_dictionary_set_cstring_nocopy(prop_dictionary_t,
const char *,
const char *);
bool prop_dictionary_set_and_rel(prop_dictionary_t,
const char *,
prop_object_t);
__END_DECLS

View File

@ -0,0 +1,210 @@
/* $NetBSD: rbtree.h,v 1.1 2010/09/25 01:42:40 matt Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas <matt@3am-software.com>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SYS_RBTREE_H_
#define _SYS_RBTREE_H_
#if defined(_KERNEL) || defined(_STANDALONE)
#include <sys/types.h>
#else
#include <stdbool.h>
#include <inttypes.h>
#endif
#include <queue.h>
#if __GNUC_PREREQ(2, 96)
# ifndef __predict_true
# define __predict_true(exp) __builtin_expect((exp), 1)
# endif
# ifndef __predict_false
# define __predict_false(exp) __builtin_expect((exp), 0)
# endif
#else
# ifndef __predict_true
# define __predict_true(exp) (exp)
# endif
# ifndef __predict_false
# define __predict_false(exp) (exp)
# endif
#endif
__BEGIN_DECLS
typedef struct rb_node {
struct rb_node *rb_nodes[2];
#define RB_DIR_LEFT 0
#define RB_DIR_RIGHT 1
#define RB_DIR_OTHER 1
#define rb_left rb_nodes[RB_DIR_LEFT]
#define rb_right rb_nodes[RB_DIR_RIGHT]
/*
* rb_info contains the two flags and the parent back pointer.
* We put the two flags in the low two bits since we know that
* rb_node will have an alignment of 4 or 8 bytes.
*/
uintptr_t rb_info;
#define RB_FLAG_POSITION 0x2
#define RB_FLAG_RED 0x1
#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED)
#define RB_FATHER(rb) \
((struct rb_node *)((rb)->rb_info & ~RB_FLAG_MASK))
#define RB_SET_FATHER(rb, father) \
((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK)))
#define RB_SENTINEL_P(rb) ((rb) == NULL)
#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left)
#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right)
#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb)))
#define RB_CHILDLESS_P(rb) \
(RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb)))
#define RB_TWOCHILDREN_P(rb) \
(!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb))
#define RB_POSITION(rb) \
(((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT)
#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT)
#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT)
#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0)
#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0)
#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED))
#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED))
#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED))
#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb))
#define RB_SET_POSITION(rb, position) \
((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \
((rb)->rb_info &= ~RB_FLAG_POSITION)))
#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK))
#define RB_COPY_PROPERTIES(dst, src) \
((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK))
#define RB_SWAP_PROPERTIES(a, b) do { \
uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \
(a)->rb_info ^= xorinfo; \
(b)->rb_info ^= xorinfo; \
} while (/*CONSTCOND*/ 0)
#ifdef RBDEBUG
TAILQ_ENTRY(rb_node) rb_link;
#endif
} rb_node_t;
#define RB_TREE_MIN(T) rb_tree_iterate((T), NULL, RB_DIR_LEFT)
#define RB_TREE_MAX(T) rb_tree_iterate((T), NULL, RB_DIR_RIGHT)
#define RB_TREE_FOREACH(N, T) \
for ((N) = RB_TREE_MIN(T); (N); \
(N) = rb_tree_iterate((T), (N), RB_DIR_RIGHT))
#define RB_TREE_FOREACH_REVERSE(N, T) \
for ((N) = RB_TREE_MAX(T); (N); \
(N) = rb_tree_iterate((T), (N), RB_DIR_LEFT))
#ifdef RBDEBUG
TAILQ_HEAD(rb_node_qh, rb_node);
#define RB_TAILQ_REMOVE(a, b, c) TAILQ_REMOVE(a, b, c)
#define RB_TAILQ_INIT(a) TAILQ_INIT(a)
#define RB_TAILQ_INSERT_HEAD(a, b, c) TAILQ_INSERT_HEAD(a, b, c)
#define RB_TAILQ_INSERT_BEFORE(a, b, c) TAILQ_INSERT_BEFORE(a, b, c)
#define RB_TAILQ_INSERT_AFTER(a, b, c, d) TAILQ_INSERT_AFTER(a, b, c, d)
#else
#define RB_TAILQ_REMOVE(a, b, c) do { } while (/*CONSTCOND*/0)
#define RB_TAILQ_INIT(a) do { } while (/*CONSTCOND*/0)
#define RB_TAILQ_INSERT_HEAD(a, b, c) do { } while (/*CONSTCOND*/0)
#define RB_TAILQ_INSERT_BEFORE(a, b, c) do { } while (/*CONSTCOND*/0)
#define RB_TAILQ_INSERT_AFTER(a, b, c, d) do { } while (/*CONSTCOND*/0)
#endif /* RBDEBUG */
/*
* rbto_compare_nodes_fn:
* return a positive value if the first node > the second node.
* return a negative value if the first node < the second node.
* return 0 if they are considered same.
*
* rbto_compare_key_fn:
* return a positive value if the node > the key.
* return a negative value if the node < the key.
* return 0 if they are considered same.
*/
typedef signed int (*const rbto_compare_nodes_fn)(void *,
const void *, const void *);
typedef signed int (*const rbto_compare_key_fn)(void *,
const void *, const void *);
typedef struct {
rbto_compare_nodes_fn rbto_compare_nodes;
rbto_compare_key_fn rbto_compare_key;
size_t rbto_node_offset;
void *rbto_context;
} rb_tree_ops_t;
typedef struct rb_tree {
struct rb_node *rbt_root;
const rb_tree_ops_t *rbt_ops;
struct rb_node *rbt_minmax[2];
#ifdef RBDEBUG
struct rb_node_qh rbt_nodes;
#endif
#ifdef RBSTATS
unsigned int rbt_count;
unsigned int rbt_insertions;
unsigned int rbt_removals;
unsigned int rbt_insertion_rebalance_calls;
unsigned int rbt_insertion_rebalance_passes;
unsigned int rbt_removal_rebalance_calls;
unsigned int rbt_removal_rebalance_passes;
#endif
} rb_tree_t;
#ifdef RBSTATS
#define RBSTAT_INC(v) ((void)((v)++))
#define RBSTAT_DEC(v) ((void)((v)--))
#else
#define RBSTAT_INC(v) do { } while (/*CONSTCOND*/0)
#define RBSTAT_DEC(v) do { } while (/*CONSTCOND*/0)
#endif
void rb_tree_init(rb_tree_t *, const rb_tree_ops_t *);
void * rb_tree_insert_node(rb_tree_t *, void *);
void * rb_tree_find_node(rb_tree_t *, const void *);
void * rb_tree_find_node_geq(rb_tree_t *, const void *);
void * rb_tree_find_node_leq(rb_tree_t *, const void *);
void rb_tree_remove_node(rb_tree_t *, void *);
void * rb_tree_iterate(rb_tree_t *, void *, const unsigned int);
#ifdef RBDEBUG
void rb_tree_check(const rb_tree_t *, bool);
#endif
#ifdef RBSTATS
void rb_tree_depths(const rb_tree_t *, size_t *);
#endif
__END_DECLS
#endif /* _SYS_RBTREE_H_*/

View File

@ -1,30 +1,5 @@
/* $NetBSD: prop_array.c,v 1.20 2008/08/11 05:54:21 christos Exp $ */
/*-
* Copyright (c) 2010 Juan Romero Pardines (zlib/gzip support).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*-
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
* All rights reserved.
@ -56,9 +31,11 @@
#include <prop/prop_array.h>
#include "prop_object_impl.h"
#include <errno.h>
#include <zlib.h>
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <errno.h>
#define __unused /* empty */
#endif
struct _prop_array {
struct _prop_object pa_obj;
@ -364,7 +341,7 @@ static prop_object_t
_prop_array_iterator_next_object(void *v)
{
struct _prop_array_iterator *pai = v;
prop_array_t pa = pai->pai_base.pi_obj;
prop_array_t pa __unused = pai->pai_base.pi_obj;
prop_object_t po;
_PROP_ASSERT(prop_object_is_array(pa));
@ -391,7 +368,7 @@ static void
_prop_array_iterator_reset(void *v)
{
struct _prop_array_iterator *pai = v;
prop_array_t pa = pai->pai_base.pi_obj;
prop_array_t pa __unused = pai->pai_base.pi_obj;
_PROP_ASSERT(prop_object_is_array(pa));
@ -889,6 +866,7 @@ prop_array_internalize(const char *xml)
return _prop_generic_internalize(xml, "array");
}
#if !defined(_KERNEL) && !defined(_STANDALONE)
/*
* prop_array_externalize_to_file --
* Externalize an array to the specified file.
@ -903,8 +881,7 @@ prop_array_externalize_to_file(prop_array_t array, const char *fname)
xml = prop_array_externalize(array);
if (xml == NULL)
return (false);
rv = _prop_object_externalize_write_file(fname, xml,
strlen(xml), false);
rv = _prop_object_externalize_write_file(fname, xml, strlen(xml), false);
if (rv == false)
save_errno = errno;
_PROP_FREE(xml, M_TEMP);
@ -914,31 +891,6 @@ prop_array_externalize_to_file(prop_array_t array, const char *fname)
return (rv);
}
/*
* prop_array_externalize_to_zfile ---
* Externalize an array to the specified file, and on the fly
* compressing the result with gzip (via zlib).
*/
bool
prop_array_externalize_to_zfile(prop_array_t array, const char *fname)
{
char *xml;
bool rv;
int save_errno = 0;
xml = prop_array_externalize(array);
if (xml == NULL)
return false;
rv = _prop_object_externalize_write_file(fname, xml, strlen(xml), true);
if (rv == false)
save_errno = errno;
_PROP_FREE(xml, M_TEMP);
if (rv == false)
errno = save_errno;
return rv;
}
/*
* prop_array_internalize_from_file --
* Internalize an array from a file.
@ -957,88 +909,4 @@ prop_array_internalize_from_file(const char *fname)
return (array);
}
#define _READ_CHUNK 512
/*
* prop_array_internalize_from_zfile ---
* Internalize an array from a compressed gzip file.
*/
prop_array_t
prop_array_internalize_from_zfile(const char *fname)
{
struct _prop_object_internalize_mapped_file *mf;
prop_array_t array;
z_stream strm;
unsigned char out[_READ_CHUNK];
char *uncomp_xml = NULL;
size_t have;
ssize_t totalsize = 0;
int rv = 0;
mf = _prop_object_internalize_map_file(fname);
if (mf == NULL)
return NULL;
/* Decompress the mmap'ed buffer with zlib */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
/* 15+16 to use gzip method */
if (inflateInit2(&strm, 15+16) != Z_OK) {
_prop_object_internalize_unmap_file(mf);
return NULL;
}
strm.avail_in = mf->poimf_mapsize;
strm.next_in = (unsigned char *)mf->poimf_xml;
/* Output buffer (decompressed) */
uncomp_xml = _PROP_MALLOC(_READ_CHUNK, M_TEMP);
if (uncomp_xml == NULL) {
_prop_object_internalize_unmap_file(mf);
(void)inflateEnd(&strm);
return NULL;
}
/* Inflate the input buffer and copy into 'dest' */
do {
strm.avail_out = _READ_CHUNK;
strm.next_out = out;
rv = inflate(&strm, Z_NO_FLUSH);
switch (rv) {
case Z_DATA_ERROR:
/*
* Wrong compressed data or uncompressed, try
* normal method as last resort.
*/
(void)inflateEnd(&strm);
_PROP_FREE(uncomp_xml, M_TEMP);
array = prop_array_internalize(mf->poimf_xml);
_prop_object_internalize_unmap_file(mf);
return array;
case Z_STREAM_ERROR:
case Z_NEED_DICT:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
_PROP_FREE(uncomp_xml, M_TEMP);
_prop_object_internalize_unmap_file(mf);
errno = rv;
return NULL;
}
have = _READ_CHUNK - strm.avail_out;
totalsize += have;
uncomp_xml = _PROP_REALLOC(uncomp_xml, totalsize, M_TEMP);
memcpy(uncomp_xml + totalsize - have, out, have);
} while (strm.avail_out == 0);
/* we are done */
(void)inflateEnd(&strm);
array = prop_array_internalize(uncomp_xml);
_PROP_FREE(uncomp_xml, M_TEMP);
_prop_object_internalize_unmap_file(mf);
return array;
}
#endif /* _KERNEL && !_STANDALONE */

View File

@ -218,6 +218,21 @@ prop_array_get_cstring ## variant (prop_array_t array, \
} \
\
bool \
prop_array_add_cstring ## variant (prop_array_t array, \
const char *cp) \
{ \
prop_string_t str; \
bool rv; \
\
str = prop_string_create_cstring ## variant (cp); \
if (str == NULL) \
return false; \
rv = prop_array_add(array, str); \
prop_object_release(str); \
return rv; \
} \
\
bool \
prop_array_set_cstring ## variant (prop_array_t array, \
unsigned int indx, \
const char *cp) \
@ -238,3 +253,14 @@ TEMPLATE(,)
TEMPLATE(_nocopy,const)
#undef TEMPLATE
bool
prop_array_add_and_rel(prop_array_t array, prop_object_t po)
{
bool ret;
if (po == NULL)
return false;
ret = prop_array_add(array, po);
prop_object_release(po);
return ret;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_bool.c,v 1.16 2008/08/03 04:00:12 thorpej Exp $ */
/* $NetBSD: prop_bool.c,v 1.17 2009/01/03 18:31:33 pooka Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -40,9 +40,6 @@ struct _prop_bool {
static struct _prop_bool _prop_bool_true;
static struct _prop_bool _prop_bool_false;
_PROP_MUTEX_DECL_STATIC(_prop_bool_initialized_mutex)
static bool _prop_bool_initialized;
static _prop_object_free_rv_t
_prop_bool_free(prop_stack_t, prop_object_t *);
static bool _prop_bool_externalize(
@ -109,27 +106,29 @@ _prop_bool_equals(prop_object_t v1, prop_object_t v2,
return (_PROP_OBJECT_EQUALS_FALSE);
}
_PROP_ONCE_DECL(_prop_bool_init_once)
static int
_prop_bool_init(void)
{
_prop_object_init(&_prop_bool_true.pb_obj,
&_prop_object_type_bool);
_prop_bool_true.pb_value = true;
_prop_object_init(&_prop_bool_false.pb_obj,
&_prop_object_type_bool);
_prop_bool_false.pb_value = false;
return 0;
}
static prop_bool_t
_prop_bool_alloc(bool val)
{
prop_bool_t pb;
if (! _prop_bool_initialized) {
_PROP_MUTEX_LOCK(_prop_bool_initialized_mutex);
if (! _prop_bool_initialized) {
_prop_object_init(&_prop_bool_true.pb_obj,
&_prop_object_type_bool);
_prop_bool_true.pb_value = true;
_prop_object_init(&_prop_bool_false.pb_obj,
&_prop_object_type_bool);
_prop_bool_false.pb_value = false;
_prop_bool_initialized = true;
}
_PROP_MUTEX_UNLOCK(_prop_bool_initialized_mutex);
}
_PROP_ONCE_RUN(_prop_bool_init_once, _prop_bool_init);
pb = val ? &_prop_bool_true : &_prop_bool_false;
prop_object_retain(pb);

View File

@ -1,29 +1,4 @@
/* $NetBSD: prop_dictionary.c,v 1.33 2008/11/30 00:17:07 haad Exp $ */
/*-
* Copyright (c) 2010 Juan Romero Pardines (zlib/gzip support).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $NetBSD: prop_dictionary.c,v 1.37 2011/04/20 19:40:00 martin Exp $ */
/*-
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
@ -54,12 +29,16 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <prop/proplib.h>
#include <prop/prop_array.h>
#include <prop/prop_dictionary.h>
#include <prop/prop_string.h>
#include "prop_object_impl.h"
#include "prop_rb_impl.h"
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <errno.h>
#include <zlib.h>
#define __unused /* empty */
#endif
/*
* We implement these like arrays, but we keep them sorted by key.
@ -88,10 +67,6 @@ struct _prop_dictionary_keysym {
/* actually variable length */
};
#define RBNODE_TO_PDK(n) \
((struct _prop_dictionary_keysym *) \
((uintptr_t)n - offsetof(struct _prop_dictionary_keysym, pdk_link)))
/* pdk_key[1] takes care of the NUL */
#define PDK_SIZE_16 (sizeof(struct _prop_dictionary_keysym) + 16)
#define PDK_SIZE_32 (sizeof(struct _prop_dictionary_keysym) + 32)
@ -198,35 +173,49 @@ struct _prop_dictionary_iterator {
*/
static int
_prop_dict_keysym_rb_compare_nodes(const struct rb_node *n1,
const struct rb_node *n2)
/*ARGSUSED*/
_prop_dict_keysym_rb_compare_nodes(void *ctx __unused,
const void *n1, const void *n2)
{
const prop_dictionary_keysym_t pdk1 = RBNODE_TO_PDK(n1);
const prop_dictionary_keysym_t pdk2 = RBNODE_TO_PDK(n2);
const struct _prop_dictionary_keysym *pdk1 = n1;
const struct _prop_dictionary_keysym *pdk2 = n2;
return (strcmp(pdk1->pdk_key, pdk2->pdk_key));
return strcmp(pdk1->pdk_key, pdk2->pdk_key);
}
static int
_prop_dict_keysym_rb_compare_key(const struct rb_node *n,
const void *v)
/*ARGSUSED*/
_prop_dict_keysym_rb_compare_key(void *ctx __unused,
const void *n, const void *v)
{
const prop_dictionary_keysym_t pdk = RBNODE_TO_PDK(n);
const struct _prop_dictionary_keysym *pdk = n;
const char *cp = v;
return (strcmp(pdk->pdk_key, cp));
return strcmp(pdk->pdk_key, cp);
}
static const struct rb_tree_ops _prop_dict_keysym_rb_tree_ops = {
static const rb_tree_ops_t _prop_dict_keysym_rb_tree_ops = {
.rbto_compare_nodes = _prop_dict_keysym_rb_compare_nodes,
.rbto_compare_key = _prop_dict_keysym_rb_compare_key,
.rbto_compare_key = _prop_dict_keysym_rb_compare_key,
.rbto_node_offset = offsetof(struct _prop_dictionary_keysym, pdk_link),
.rbto_context = NULL
};
static struct rb_tree _prop_dict_keysym_tree;
static bool _prop_dict_keysym_tree_initialized;
_PROP_ONCE_DECL(_prop_dict_init_once)
_PROP_MUTEX_DECL_STATIC(_prop_dict_keysym_tree_mutex)
static int
_prop_dict_init(void)
{
_PROP_MUTEX_INIT(_prop_dict_keysym_tree_mutex);
_prop_rb_tree_init(&_prop_dict_keysym_tree,
&_prop_dict_keysym_rb_tree_ops);
return 0;
}
static void
_prop_dict_keysym_put(prop_dictionary_keysym_t pdk)
{
@ -247,7 +236,7 @@ _prop_dict_keysym_free(prop_stack_t stack, prop_object_t *obj)
{
prop_dictionary_keysym_t pdk = *obj;
_prop_rb_tree_remove_node(&_prop_dict_keysym_tree, &pdk->pdk_link);
_prop_rb_tree_remove_node(&_prop_dict_keysym_tree, pdk);
_prop_dict_keysym_put(pdk);
return _PROP_OBJECT_FREE_DONE;
@ -294,28 +283,21 @@ _prop_dict_keysym_equals(prop_object_t v1, prop_object_t v2,
static prop_dictionary_keysym_t
_prop_dict_keysym_alloc(const char *key)
{
prop_dictionary_keysym_t opdk, pdk;
const struct rb_node *n;
prop_dictionary_keysym_t opdk, pdk, rpdk;
size_t size;
bool rv;
_PROP_ONCE_RUN(_prop_dict_init_once, _prop_dict_init);
/*
* Check to see if this already exists in the tree. If it does,
* we just retain it and return it.
*/
_PROP_MUTEX_LOCK(_prop_dict_keysym_tree_mutex);
if (! _prop_dict_keysym_tree_initialized) {
_prop_rb_tree_init(&_prop_dict_keysym_tree,
&_prop_dict_keysym_rb_tree_ops);
_prop_dict_keysym_tree_initialized = true;
} else {
n = _prop_rb_tree_find(&_prop_dict_keysym_tree, key);
if (n != NULL) {
opdk = RBNODE_TO_PDK(n);
prop_object_retain(opdk);
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
return (opdk);
}
opdk = _prop_rb_tree_find(&_prop_dict_keysym_tree, key);
if (opdk != NULL) {
prop_object_retain(opdk);
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
return (opdk);
}
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
@ -347,16 +329,15 @@ _prop_dict_keysym_alloc(const char *key)
* we have to check again if it is in the tree.
*/
_PROP_MUTEX_LOCK(_prop_dict_keysym_tree_mutex);
n = _prop_rb_tree_find(&_prop_dict_keysym_tree, key);
if (n != NULL) {
opdk = RBNODE_TO_PDK(n);
opdk = _prop_rb_tree_find(&_prop_dict_keysym_tree, key);
if (opdk != NULL) {
prop_object_retain(opdk);
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
_prop_dict_keysym_put(pdk);
return (opdk);
}
rv = _prop_rb_tree_insert_node(&_prop_dict_keysym_tree, &pdk->pdk_link);
_PROP_ASSERT(rv == true);
rpdk = _prop_rb_tree_insert_node(&_prop_dict_keysym_tree, pdk);
_PROP_ASSERT(rpdk == pdk);
_PROP_MUTEX_UNLOCK(_prop_dict_keysym_tree_mutex);
return (pdk);
}
@ -416,6 +397,9 @@ _prop_dictionary_free(prop_stack_t stack, prop_object_t *obj)
static void
_prop_dictionary_lock(void)
{
/* XXX: once necessary or paranoia? */
_PROP_ONCE_RUN(_prop_dict_init_once, _prop_dict_init);
_PROP_MUTEX_LOCK(_prop_dict_keysym_tree_mutex);
}
@ -540,8 +524,8 @@ _prop_dictionary_equals(prop_object_t v1, prop_object_t v2,
*stored_pointer1 = (void *)(idx + 1);
*stored_pointer2 = (void *)(idx + 1);
*next_obj1 = &dict1->pd_array[idx].pde_objref;
*next_obj2 = &dict2->pd_array[idx].pde_objref;
*next_obj1 = dict1->pd_array[idx].pde_objref;
*next_obj2 = dict2->pd_array[idx].pde_objref;
if (!prop_dictionary_keysym_equals(dict1->pd_array[idx].pde_key,
dict2->pd_array[idx].pde_key))
@ -645,7 +629,7 @@ static prop_object_t
_prop_dictionary_iterator_next_object(void *v)
{
struct _prop_dictionary_iterator *pdi = v;
prop_dictionary_t pd = pdi->pdi_base.pi_obj;
prop_dictionary_t pd __unused = pdi->pdi_base.pi_obj;
prop_dictionary_keysym_t pdk;
_PROP_ASSERT(prop_object_is_dictionary(pd));
@ -672,7 +656,7 @@ static void
_prop_dictionary_iterator_reset(void *v)
{
struct _prop_dictionary_iterator *pdi = v;
prop_dictionary_t pd = pdi->pdi_base.pi_obj;
prop_dictionary_t pd __unused = pdi->pdi_base.pi_obj;
_PROP_RWLOCK_RDLOCK(pd->pd_rwlock);
_prop_dictionary_iterator_reset_locked(pdi);
@ -949,7 +933,10 @@ _prop_dictionary_get(prop_dictionary_t pd, const char *key, bool locked)
prop_object_t
prop_dictionary_get(prop_dictionary_t pd, const char *key)
{
prop_object_t po;
prop_object_t po = NULL;
if (! prop_object_is_dictionary(pd))
return (NULL);
_PROP_RWLOCK_RDLOCK(pd->pd_rwlock);
po = _prop_dictionary_get(pd, key, true);
@ -1388,6 +1375,7 @@ prop_dictionary_internalize(const char *xml)
return _prop_generic_internalize(xml, "dict");
}
#if !defined(_KERNEL) && !defined(_STANDALONE)
/*
* prop_dictionary_externalize_to_file --
* Externalize a dictionary to the specified file.
@ -1402,8 +1390,8 @@ prop_dictionary_externalize_to_file(prop_dictionary_t dict, const char *fname)
xml = prop_dictionary_externalize(dict);
if (xml == NULL)
return (false);
rv = _prop_object_externalize_write_file(fname, xml,
strlen(xml), false);
rv = _prop_object_externalize_write_file(fname, xml, strlen(xml),
false);
if (rv == false)
save_errno = errno;
_PROP_FREE(xml, M_TEMP);
@ -1413,31 +1401,6 @@ prop_dictionary_externalize_to_file(prop_dictionary_t dict, const char *fname)
return (rv);
}
/*
* prop_dictionary_externalize_to_zfile ---
* Externalize a dictionary to the specified file and on the fly
* compressing the result with gzip (via zlib).
*/
bool
prop_dictionary_externalize_to_zfile(prop_dictionary_t dict, const char *fname)
{
char *xml;
bool rv;
int save_errno = 0;
xml = prop_dictionary_externalize(dict);
if (xml == NULL)
return false;
rv = _prop_object_externalize_write_file(fname, xml, strlen(xml), true);
if (rv == false)
save_errno = errno;
_PROP_FREE(xml, M_TEMP);
if (rv == false)
errno = save_errno;
return rv;
}
/*
* prop_dictionary_internalize_from_file --
* Internalize a dictionary from a file.
@ -1456,87 +1419,4 @@ prop_dictionary_internalize_from_file(const char *fname)
return (dict);
}
#define _READ_CHUNK 512
/*
* prop_dictionary_internalize_from_zfile ---
* Internalize a dictionary from a compressed gzip file.
*/
prop_dictionary_t
prop_dictionary_internalize_from_zfile(const char *fname)
{
struct _prop_object_internalize_mapped_file *mf;
prop_dictionary_t dict;
z_stream strm;
unsigned char out[_READ_CHUNK];
char *uncomp_xml = NULL;
size_t have;
ssize_t totalsize = 0;
int rv = 0;
mf = _prop_object_internalize_map_file(fname);
if (mf == NULL)
return NULL;
/* Decompress the mmap'ed buffer with zlib */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
/* 15+16 to use gzip method */
if (inflateInit2(&strm, 15+16) != Z_OK) {
_prop_object_internalize_unmap_file(mf);
return NULL;
}
strm.avail_in = mf->poimf_mapsize;
strm.next_in = (unsigned char *)mf->poimf_xml;
/* Output buffer (uncompressed) */
uncomp_xml = _PROP_MALLOC(_READ_CHUNK, M_TEMP);
if (uncomp_xml == NULL) {
(void)inflateEnd(&strm);
_prop_object_internalize_unmap_file(mf);
return NULL;
}
/* Inflate the input buffer and copy into 'uncomp_xml' */
do {
strm.avail_out = _READ_CHUNK;
strm.next_out = out;
rv = inflate(&strm, Z_NO_FLUSH);
switch (rv) {
case Z_DATA_ERROR:
/*
* Wrong compressed data or uncompressed, try
* normal method as last resort.
*/
(void)inflateEnd(&strm);
_PROP_FREE(uncomp_xml, M_TEMP);
dict = prop_dictionary_internalize(mf->poimf_xml);
_prop_object_internalize_unmap_file(mf);
return dict;
case Z_STREAM_ERROR:
case Z_NEED_DICT:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
_PROP_FREE(uncomp_xml, M_TEMP);
_prop_object_internalize_unmap_file(mf);
errno = rv;
return NULL;
}
have = _READ_CHUNK - strm.avail_out;
totalsize += have;
uncomp_xml = _PROP_REALLOC(uncomp_xml, totalsize, M_TEMP);
memcpy(uncomp_xml + totalsize - have, out, have);
} while (strm.avail_out == 0);
/* we are done */
(void)inflateEnd(&strm);
dict = prop_dictionary_internalize(uncomp_xml);
_PROP_FREE(uncomp_xml, M_TEMP);
_prop_object_internalize_unmap_file(mf);
return dict;
}
#endif /* !_KERNEL && !_STANDALONE */

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_dictionary_util.c,v 1.3 2008/04/28 20:22:53 martin Exp $ */
/* $NetBSD: prop_dictionary_util.c,v 1.4 2011/03/24 17:05:39 bouyer Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -41,6 +41,18 @@
#include <prop/proplib.h>
#include "prop_object_impl.h" /* only to hide kernel vs. not-kernel */
bool
prop_dictionary_get_dict(prop_dictionary_t dict, const char *key, prop_dictionary_t *dp)
{
prop_object_t o;
o = prop_dictionary_get(dict, key);
if (o == NULL || prop_object_type(o) != PROP_TYPE_DICTIONARY)
return false;
*dp = o;
return true;
}
bool
prop_dictionary_get_bool(prop_dictionary_t dict,
const char *key,
@ -206,3 +218,15 @@ TEMPLATE(,)
TEMPLATE(_nocopy,const)
#undef TEMPLATE
bool
prop_dictionary_set_and_rel(prop_dictionary_t dict, const char *key,
prop_object_t po)
{
bool ret;
if (po == NULL)
return false;
ret = prop_dictionary_set(dict, key, po);
prop_object_release(po);
return ret;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_number.c,v 1.20 2008/11/30 00:17:07 haad Exp $ */
/* $NetBSD: prop_number.c,v 1.23 2010/09/24 22:51:52 rmind Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -33,8 +33,16 @@
#include "prop_object_impl.h"
#include "prop_rb_impl.h"
#if defined(_KERNEL)
#include <sys/systm.h>
#elif defined(_STANDALONE)
#include <sys/param.h>
#include <lib/libkern/libkern.h>
#else
#include <errno.h>
#include <stdlib.h>
#define __unused /* empty */
#endif
struct _prop_number {
struct _prop_object pn_obj;
@ -51,10 +59,6 @@ struct _prop_number {
} pn_value;
};
#define RBNODE_TO_PN(n) \
((struct _prop_number *) \
((uintptr_t)n - offsetof(struct _prop_number, pn_link)))
_PROP_POOL_INIT(_prop_number_pool, sizeof(struct _prop_number), "propnmbr")
static _prop_object_free_rv_t
@ -115,33 +119,34 @@ _prop_number_compare_values(const struct _prop_number_value *pnv1,
}
static int
_prop_number_rb_compare_nodes(const struct rb_node *n1,
const struct rb_node *n2)
/*ARGSUSED*/
_prop_number_rb_compare_nodes(void *ctx __unused,
const void *n1, const void *n2)
{
const prop_number_t pn1 = RBNODE_TO_PN(n1);
const prop_number_t pn2 = RBNODE_TO_PN(n2);
const struct _prop_number *pn1 = n1;
const struct _prop_number *pn2 = n2;
return (_prop_number_compare_values(&pn1->pn_value, &pn2->pn_value));
return _prop_number_compare_values(&pn1->pn_value, &pn2->pn_value);
}
static int
_prop_number_rb_compare_key(const struct rb_node *n,
const void *v)
/*ARGSUSED*/
_prop_number_rb_compare_key(void *ctx __unused, const void *n, const void *v)
{
const prop_number_t pn = RBNODE_TO_PN(n);
const struct _prop_number *pn = n;
const struct _prop_number_value *pnv = v;
return (_prop_number_compare_values(&pn->pn_value, pnv));
return _prop_number_compare_values(&pn->pn_value, pnv);
}
static const struct rb_tree_ops _prop_number_rb_tree_ops = {
static const rb_tree_ops_t _prop_number_rb_tree_ops = {
.rbto_compare_nodes = _prop_number_rb_compare_nodes,
.rbto_compare_key = _prop_number_rb_compare_key,
.rbto_compare_key = _prop_number_rb_compare_key,
.rbto_node_offset = offsetof(struct _prop_number, pn_link),
.rbto_context = NULL
};
static struct rb_tree _prop_number_tree;
static bool _prop_number_tree_initialized;
_PROP_MUTEX_DECL_STATIC(_prop_number_tree_mutex)
/* ARGSUSED */
@ -150,21 +155,34 @@ _prop_number_free(prop_stack_t stack, prop_object_t *obj)
{
prop_number_t pn = *obj;
_prop_rb_tree_remove_node(&_prop_number_tree, &pn->pn_link);
_prop_rb_tree_remove_node(&_prop_number_tree, pn);
_PROP_POOL_PUT(_prop_number_pool, pn);
return (_PROP_OBJECT_FREE_DONE);
}
static void
_prop_number_lock()
_PROP_ONCE_DECL(_prop_number_init_once)
static int
_prop_number_init(void)
{
_PROP_MUTEX_INIT(_prop_number_tree_mutex);
_prop_rb_tree_init(&_prop_number_tree, &_prop_number_rb_tree_ops);
return 0;
}
static void
_prop_number_lock(void)
{
/* XXX: init necessary? */
_PROP_ONCE_RUN(_prop_number_init_once, _prop_number_init);
_PROP_MUTEX_LOCK(_prop_number_tree_mutex);
}
static void
_prop_number_unlock()
_prop_number_unlock(void)
{
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
}
@ -178,8 +196,9 @@ _prop_number_externalize(struct _prop_object_externalize_context *ctx,
/*
* For the record:
* The original implementation used hex for signed numbers,
* but we changed it to be human readable.
* the original NetBSD implementation used hexadecimal for unsigned
* numbers, but in the portable proplib we changed it to be human
* readable (base 10).
*/
if (pn->pn_value.pnv_is_unsigned)
sprintf(tmpstr, "%" PRIu64, pn->pn_value.pnv_unsigned);
@ -253,27 +272,20 @@ _prop_number_equals(prop_object_t v1, prop_object_t v2,
static prop_number_t
_prop_number_alloc(const struct _prop_number_value *pnv)
{
prop_number_t opn, pn;
struct rb_node *n;
bool rv;
prop_number_t opn, pn, rpn;
_PROP_ONCE_RUN(_prop_number_init_once, _prop_number_init);
/*
* Check to see if this already exists in the tree. If it does,
* we just retain it and return it.
*/
_PROP_MUTEX_LOCK(_prop_number_tree_mutex);
if (! _prop_number_tree_initialized) {
_prop_rb_tree_init(&_prop_number_tree,
&_prop_number_rb_tree_ops);
_prop_number_tree_initialized = true;
} else {
n = _prop_rb_tree_find(&_prop_number_tree, pnv);
if (n != NULL) {
opn = RBNODE_TO_PN(n);
prop_object_retain(opn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
return (opn);
}
opn = _prop_rb_tree_find(&_prop_number_tree, pnv);
if (opn != NULL) {
prop_object_retain(opn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
return (opn);
}
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
@ -294,16 +306,15 @@ _prop_number_alloc(const struct _prop_number_value *pnv)
* we have to check again if it is in the tree.
*/
_PROP_MUTEX_LOCK(_prop_number_tree_mutex);
n = _prop_rb_tree_find(&_prop_number_tree, pnv);
if (n != NULL) {
opn = RBNODE_TO_PN(n);
opn = _prop_rb_tree_find(&_prop_number_tree, pnv);
if (opn != NULL) {
prop_object_retain(opn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
_PROP_POOL_PUT(_prop_number_pool, pn);
return (opn);
}
rv = _prop_rb_tree_insert_node(&_prop_number_tree, &pn->pn_link);
_PROP_ASSERT(rv == true);
rpn = _prop_rb_tree_insert_node(&_prop_number_tree, pn);
_PROP_ASSERT(rpn == pn);
_PROP_MUTEX_UNLOCK(_prop_number_tree_mutex);
return (pn);
}
@ -501,10 +512,14 @@ _prop_number_internalize_unsigned(struct _prop_object_internalize_context *ctx,
_PROP_ASSERT(/*CONSTCOND*/sizeof(unsigned long long) ==
sizeof(uint64_t));
#ifndef _KERNEL
errno = 0;
#endif
pnv->pnv_unsigned = (uint64_t) strtoull(ctx->poic_cp, &cp, 0);
#ifndef _KERNEL /* XXX can't check for ERANGE in the kernel */
if (pnv->pnv_unsigned == UINT64_MAX && errno == ERANGE)
return (false);
#endif
pnv->pnv_is_unsigned = true;
ctx->poic_cp = cp;
@ -519,11 +534,15 @@ _prop_number_internalize_signed(struct _prop_object_internalize_context *ctx,
_PROP_ASSERT(/*CONSTCOND*/sizeof(long long) == sizeof(int64_t));
#ifndef _KERNEL
errno = 0;
#endif
pnv->pnv_signed = (int64_t) strtoll(ctx->poic_cp, &cp, 0);
#ifndef _KERNEL /* XXX can't check for ERANGE in the kernel */
if ((pnv->pnv_signed == INT64_MAX || pnv->pnv_signed == INT64_MIN) &&
errno == ERANGE)
return (false);
#endif
pnv->pnv_is_unsigned = false;
ctx->poic_cp = cp;

View File

@ -41,10 +41,6 @@
#include <zlib.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/*
* _prop_object_init --
* Initialize an object. Called when sub-classes create
@ -816,10 +812,7 @@ _prop_object_externalize_write_file(const char *fname, const char *xml,
size_t len, bool do_compress)
{
gzFile gzf = NULL;
char tname[PATH_MAX];
#ifndef HAVE_STRLCAT
char *otname;
#endif
char tname[PATH_MAX], *otname;
int fd;
int save_errno;
mode_t myumask;
@ -865,7 +858,11 @@ _prop_object_externalize_write_file(const char *fname, const char *xml,
goto bad;
}
#ifdef HAVE_FDATASYNC
if (fdatasync(fd) == -1)
#else
if (fsync(fd) == -1)
#endif
goto bad;
myumask = umask(0);
@ -1190,6 +1187,8 @@ prop_object_equals_with_error(prop_object_t obj1, prop_object_t obj2,
if (!_prop_stack_pop(&stack, &obj1, &obj2,
&stored_pointer1, &stored_pointer2))
return true;
po1 = obj1;
po2 = obj2;
goto continue_subtree;
}
_PROP_ASSERT(ret == _PROP_OBJECT_EQUALS_RECURSE);

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_object_impl.h,v 1.28 2008/11/30 00:17:07 haad Exp $ */
/* $NetBSD: prop_object_impl.h,v 1.30 2009/09/13 18:45:10 pooka Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -32,7 +32,11 @@
#ifndef _PROPLIB_PROP_OBJECT_IMPL_H_
#define _PROPLIB_PROP_OBJECT_IMPL_H_
#if defined(_KERNEL) || defined(_STANDALONE)
#include <lib/libkern/libkern.h>
#else
#include <inttypes.h>
#endif
#include "prop_stack.h"
@ -143,9 +147,9 @@ struct _prop_object_internalize_context *
void _prop_object_internalize_context_free(
struct _prop_object_internalize_context *);
#if !defined(_KERNEL) && !defined(_STANDALONE)
bool _prop_object_externalize_write_file(const char *,
const char *,
size_t, bool);
const char *, size_t, bool);
struct _prop_object_internalize_mapped_file {
char * poimf_xml;
@ -156,6 +160,7 @@ struct _prop_object_internalize_mapped_file *
_prop_object_internalize_map_file(const char *);
void _prop_object_internalize_unmap_file(
struct _prop_object_internalize_mapped_file *);
#endif /* !_KERNEL && !_STANDALONE */
typedef bool (*prop_object_internalizer_t)(prop_stack_t, prop_object_t *,
struct _prop_object_internalize_context *);
@ -226,6 +231,110 @@ struct _prop_object_iterator {
uint32_t pi_version;
};
#define _PROP_NOTHREAD_ONCE_DECL(x) static bool x = false;
#define _PROP_NOTHREAD_ONCE_RUN(x,f) \
do { \
if ((x) == false) { \
f(); \
x = true; \
} \
} while (/*CONSTCOND*/0)
#if defined(_KERNEL)
/*
* proplib in the kernel...
*/
#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/pool.h>
#include <sys/systm.h>
#include <sys/rwlock.h>
#include <sys/once.h>
#define _PROP_ASSERT(x) KASSERT(x)
#define _PROP_MALLOC(s, t) malloc((s), (t), M_WAITOK)
#define _PROP_CALLOC(s, t) malloc((s), (t), M_WAITOK | M_ZERO)
#define _PROP_REALLOC(v, s, t) realloc((v), (s), (t), M_WAITOK)
#define _PROP_FREE(v, t) free((v), (t))
#define _PROP_POOL_GET(p) pool_get(&(p), PR_WAITOK)
#define _PROP_POOL_PUT(p, v) pool_put(&(p), (v))
struct prop_pool_init {
struct pool *pp;
size_t size;
const char *wchan;
};
#define _PROP_POOL_INIT(pp, size, wchan) \
struct pool pp; \
static const struct prop_pool_init _link_ ## pp[1] = { \
{ &pp, size, wchan } \
}; \
__link_set_add_rodata(prop_linkpools, _link_ ## pp);
#define _PROP_MALLOC_DEFINE(t, s, l) \
MALLOC_DEFINE(t, s, l);
#define _PROP_MUTEX_DECL_STATIC(x) static kmutex_t x;
#define _PROP_MUTEX_INIT(x) mutex_init(&(x),MUTEX_DEFAULT,IPL_NONE)
#define _PROP_MUTEX_LOCK(x) mutex_enter(&(x))
#define _PROP_MUTEX_UNLOCK(x) mutex_exit(&(x))
#define _PROP_RWLOCK_DECL(x) krwlock_t x ;
#define _PROP_RWLOCK_INIT(x) rw_init(&(x))
#define _PROP_RWLOCK_RDLOCK(x) rw_enter(&(x), RW_READER)
#define _PROP_RWLOCK_WRLOCK(x) rw_enter(&(x), RW_WRITER)
#define _PROP_RWLOCK_UNLOCK(x) rw_exit(&(x))
#define _PROP_RWLOCK_DESTROY(x) rw_destroy(&(x))
#define _PROP_ONCE_DECL(x) static ONCE_DECL(x);
#define _PROP_ONCE_RUN(x,f) RUN_ONCE(&(x), f)
#elif defined(_STANDALONE)
/*
* proplib in a standalone environment...
*/
#include <lib/libsa/stand.h>
void * _prop_standalone_calloc(size_t);
void * _prop_standalone_realloc(void *, size_t);
#define _PROP_ASSERT(x) /* nothing */
#define _PROP_MALLOC(s, t) alloc((s))
#define _PROP_CALLOC(s, t) _prop_standalone_calloc((s))
#define _PROP_REALLOC(v, s, t) _prop_standalone_realloc((v), (s))
#define _PROP_FREE(v, t) dealloc((v), 0) /* XXX */
#define _PROP_POOL_GET(p) alloc((p))
#define _PROP_POOL_PUT(p, v) dealloc((v), (p))
#define _PROP_POOL_INIT(p, s, d) static const size_t p = s;
#define _PROP_MALLOC_DEFINE(t, s, l) /* nothing */
#define _PROP_MUTEX_DECL_STATIC(x) /* nothing */
#define _PROP_MUTEX_INIT(x) /* nothing */
#define _PROP_MUTEX_LOCK(x) /* nothing */
#define _PROP_MUTEX_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DECL(x) /* nothing */
#define _PROP_RWLOCK_INIT(x) /* nothing */
#define _PROP_RWLOCK_RDLOCK(x) /* nothing */
#define _PROP_RWLOCK_WRLOCK(x) /* nothing */
#define _PROP_RWLOCK_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DESTROY(x) /* nothing */
#define _PROP_ONCE_DECL(x) _PROP_NOTHREAD_ONCE_DECL(x)
#define _PROP_ONCE_RUN(x,f) _PROP_NOTHREAD_ONCE_RUN(x,f)
#else
/*
* proplib in user space...
*/
@ -250,12 +359,53 @@ struct _prop_object_iterator {
#define _PROP_MALLOC_DEFINE(t, s, l) /* nothing */
#if defined(__NetBSD__) && defined(_LIBPROP)
/*
* Use the same mechanism as libc; we get pthread mutexes for threaded
* programs and do-nothing stubs for non-threaded programs.
*/
#include "reentrant.h"
#define _PROP_MUTEX_DECL_STATIC(x) static mutex_t x;
#define _PROP_MUTEX_INIT(x) mutex_init(&(x), NULL)
#define _PROP_MUTEX_LOCK(x) mutex_lock(&(x))
#define _PROP_MUTEX_UNLOCK(x) mutex_unlock(&(x))
#define _PROP_RWLOCK_DECL(x) rwlock_t x ;
#define _PROP_RWLOCK_INIT(x) rwlock_init(&(x), NULL)
#define _PROP_RWLOCK_RDLOCK(x) rwlock_rdlock(&(x))
#define _PROP_RWLOCK_WRLOCK(x) rwlock_wrlock(&(x))
#define _PROP_RWLOCK_UNLOCK(x) rwlock_unlock(&(x))
#define _PROP_RWLOCK_DESTROY(x) rwlock_destroy(&(x))
#define _PROP_ONCE_DECL(x) \
static pthread_once_t x = PTHREAD_ONCE_INIT;
#define _PROP_ONCE_RUN(x,f) thr_once(&(x), (void(*)(void))f);
#elif defined(HAVE_NBTOOL_CONFIG_H)
/*
* None of NetBSD's build tools are multi-threaded.
*/
#define _PROP_MUTEX_DECL_STATIC(x) /* nothing */
#define _PROP_MUTEX_INIT(x) /* nothing */
#define _PROP_MUTEX_LOCK(x) /* nothing */
#define _PROP_MUTEX_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DECL(x) /* nothing */
#define _PROP_RWLOCK_INIT(x) /* nothing */
#define _PROP_RWLOCK_RDLOCK(x) /* nothing */
#define _PROP_RWLOCK_WRLOCK(x) /* nothing */
#define _PROP_RWLOCK_UNLOCK(x) /* nothing */
#define _PROP_RWLOCK_DESTROY(x) /* nothing */
#define _PROP_ONCE_DECL(x) _PROP_NOTHREAD_ONCE_DECL(x)
#define _PROP_ONCE_RUN(x,f) _PROP_NOTHREAD_ONCE_RUN(x,f)
#else
/*
* Use pthread mutexes everywhere else.
*/
#include <pthread.h>
#define _PROP_MUTEX_DECL_STATIC(x) \
static pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
#define _PROP_MUTEX_DECL_STATIC(x) static pthread_mutex_t x;
#define _PROP_MUTEX_INIT(x) pthread_mutex_init(&(x), NULL)
#define _PROP_MUTEX_LOCK(x) pthread_mutex_lock(&(x))
#define _PROP_MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
@ -266,9 +416,21 @@ struct _prop_object_iterator {
#define _PROP_RWLOCK_UNLOCK(x) pthread_rwlock_unlock(&(x))
#define _PROP_RWLOCK_DESTROY(x) pthread_rwlock_destroy(&(x))
#define _PROP_ONCE_DECL(x) \
static pthread_once_t x = PTHREAD_ONCE_INIT;
#define _PROP_ONCE_RUN(x,f) pthread_once(&(x),(void(*)(void))f)
#endif
#endif /* _KERNEL */
/*
* Language features.
*/
#if defined(__NetBSD__)
#include <sys/cdefs.h>
#define _PROP_ARG_UNUSED __unused
#else
#define _PROP_ARG_UNUSED /* delete */
#endif /* __NetBSD__ */
#endif /* _PROPLIB_PROP_OBJECT_IMPL_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: prop_rb_impl.h,v 1.7 2008/06/30 20:14:09 matt Exp $ */
/* $NetBSD: prop_rb_impl.h,v 1.8 2010/09/25 01:42:38 matt Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -32,8 +32,23 @@
#ifndef _PROP_RB_IMPL_H_
#define _PROP_RB_IMPL_H_
#if 1
#include <prop/rbtree.h>
/*
* Define local names for common rb_tree functions.
*/
#define _prop_rb_tree_init rb_tree_init
#define _prop_rb_tree_insert_node rb_tree_insert_node
#define _prop_rb_tree_find rb_tree_find_node
#define _prop_rb_tree_remove_node rb_tree_remove_node
#define _prop_rb_tree_iterate rb_tree_iterate
#else /* __NetBSD__ */
#include <sys/types.h>
#include "queue.h"
#include <sys/queue.h>
#include <machine/endian.h>
struct rb_node {
struct rb_node *rb_nodes[3];
@ -134,4 +149,6 @@ void _prop_rb_tree_check(const struct rb_tree *, bool);
struct rb_node *
_prop_rb_tree_iterate(struct rb_tree *, struct rb_node *, unsigned int);
#endif /* __NetBSD__ */
#endif /* _PROP_RB_IMPL_H_*/

View File

@ -0,0 +1,146 @@
/*-
* Copyright (c) 2010-2012 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <prop/proplib.h>
#include "prop_object_impl.h"
#include <errno.h>
#include <zlib.h>
#define _READ_CHUNK 8192
#define TEMPLATE(type) \
bool \
prop ## type ## _externalize_to_zfile(prop ## type ## _t obj, const char *fname) \
{ \
char *xml; \
bool rv; \
int save_errno = 0; \
\
xml = prop ## type ## _externalize(obj); \
if (xml == NULL) \
return false; \
rv = _prop_object_externalize_write_file(fname, xml, strlen(xml), true); \
if (rv == false) \
save_errno = errno; \
_PROP_FREE(xml, M_TEMP); \
if (rv == false) \
errno = save_errno; \
\
return rv; \
} \
\
prop ## type ## _t \
prop ## type ## _internalize_from_zfile(const char *fname) \
{ \
struct _prop_object_internalize_mapped_file *mf; \
prop ## type ## _t obj; \
z_stream strm; \
unsigned char *out; \
char *uncomp_xml = NULL; \
size_t have; \
ssize_t totalsize = 0; \
int rv = 0; \
\
mf = _prop_object_internalize_map_file(fname); \
if (mf == NULL) \
return NULL; \
\
/* Output buffer (uncompressed) */ \
uncomp_xml = _PROP_MALLOC(_READ_CHUNK, M_TEMP); \
if (uncomp_xml == NULL) { \
_prop_object_internalize_unmap_file(mf); \
return NULL; \
} \
\
/* temporary output buffer for inflate */ \
out = _PROP_MALLOC(_READ_CHUNK, M_TEMP); \
if (out == NULL) { \
_PROP_FREE(uncomp_xml, M_TEMP); \
_prop_object_internalize_unmap_file(mf); \
return NULL; \
} \
\
/* Decompress the mmap'ed buffer with zlib */ \
strm.zalloc = Z_NULL; \
strm.zfree = Z_NULL; \
strm.opaque = Z_NULL; \
strm.avail_in = 0; \
strm.next_in = Z_NULL; \
\
/* 15+16 to use gzip method */ \
if (inflateInit2(&strm, 15+16) != Z_OK) { \
_PROP_FREE(out, M_TEMP); \
_PROP_FREE(uncomp_xml, M_TEMP); \
_prop_object_internalize_unmap_file(mf); \
return NULL; \
} \
strm.avail_in = mf->poimf_mapsize; \
strm.next_in = (unsigned char *)mf->poimf_xml; \
\
/* Inflate the input buffer and copy into 'uncomp_xml' */ \
do { \
strm.avail_out = _READ_CHUNK; \
strm.next_out = out; \
rv = inflate(&strm, Z_NO_FLUSH); \
switch (rv) { \
case Z_DATA_ERROR: \
/* Wrong compressed data or uncompressed, try normal method. */ \
(void)inflateEnd(&strm); \
_PROP_FREE(out, M_TEMP); \
_PROP_FREE(uncomp_xml, M_TEMP); \
obj = prop ## type ## _internalize(mf->poimf_xml); \
_prop_object_internalize_unmap_file(mf); \
return obj; \
case Z_STREAM_ERROR: \
case Z_NEED_DICT: \
case Z_MEM_ERROR: \
(void)inflateEnd(&strm); \
_PROP_FREE(out, M_TEMP); \
_PROP_FREE(uncomp_xml, M_TEMP); \
_prop_object_internalize_unmap_file(mf); \
errno = rv; \
return NULL; \
} \
have = _READ_CHUNK - strm.avail_out; \
totalsize += have; \
uncomp_xml = _PROP_REALLOC(uncomp_xml, totalsize, M_TEMP); \
memcpy(uncomp_xml + totalsize - have, out, have); \
} while (strm.avail_out == 0); \
\
/* we are done */ \
(void)inflateEnd(&strm); \
obj = prop ## type ## _internalize(uncomp_xml); \
_PROP_FREE(out, M_TEMP); \
_PROP_FREE(uncomp_xml, M_TEMP); \
_prop_object_internalize_unmap_file(mf); \
\
return obj; \
}
TEMPLATE(_array)
TEMPLATE(_dictionary)
#undef TEMPLATE

1335
lib/portableproplib/rb.c Normal file

File diff suppressed because it is too large Load Diff