xref: /minix3/common/lib/libprop/prop_bool.c (revision 6b6d114a21a24bee45291fa4af8899e108396c4a)
1*6b6d114aSBen Gras /*	$NetBSD: prop_bool.c,v 1.17 2009/01/03 18:31:33 pooka Exp $	*/
2*6b6d114aSBen Gras 
3*6b6d114aSBen Gras /*-
4*6b6d114aSBen Gras  * Copyright (c) 2006 The NetBSD Foundation, Inc.
5*6b6d114aSBen Gras  * All rights reserved.
6*6b6d114aSBen Gras  *
7*6b6d114aSBen Gras  * This code is derived from software contributed to The NetBSD Foundation
8*6b6d114aSBen Gras  * by Jason R. Thorpe.
9*6b6d114aSBen Gras  *
10*6b6d114aSBen Gras  * Redistribution and use in source and binary forms, with or without
11*6b6d114aSBen Gras  * modification, are permitted provided that the following conditions
12*6b6d114aSBen Gras  * are met:
13*6b6d114aSBen Gras  * 1. Redistributions of source code must retain the above copyright
14*6b6d114aSBen Gras  *    notice, this list of conditions and the following disclaimer.
15*6b6d114aSBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
16*6b6d114aSBen Gras  *    notice, this list of conditions and the following disclaimer in the
17*6b6d114aSBen Gras  *    documentation and/or other materials provided with the distribution.
18*6b6d114aSBen Gras  *
19*6b6d114aSBen Gras  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*6b6d114aSBen Gras  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*6b6d114aSBen Gras  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*6b6d114aSBen Gras  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*6b6d114aSBen Gras  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*6b6d114aSBen Gras  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*6b6d114aSBen Gras  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*6b6d114aSBen Gras  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*6b6d114aSBen Gras  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*6b6d114aSBen Gras  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*6b6d114aSBen Gras  * POSSIBILITY OF SUCH DAMAGE.
30*6b6d114aSBen Gras  */
31*6b6d114aSBen Gras 
32*6b6d114aSBen Gras #include <prop/prop_bool.h>
33*6b6d114aSBen Gras #include "prop_object_impl.h"
34*6b6d114aSBen Gras 
35*6b6d114aSBen Gras struct _prop_bool {
36*6b6d114aSBen Gras 	struct _prop_object	pb_obj;
37*6b6d114aSBen Gras 	bool		pb_value;
38*6b6d114aSBen Gras };
39*6b6d114aSBen Gras 
40*6b6d114aSBen Gras static struct _prop_bool _prop_bool_true;
41*6b6d114aSBen Gras static struct _prop_bool _prop_bool_false;
42*6b6d114aSBen Gras 
43*6b6d114aSBen Gras static _prop_object_free_rv_t
44*6b6d114aSBen Gras 		_prop_bool_free(prop_stack_t, prop_object_t *);
45*6b6d114aSBen Gras static bool	_prop_bool_externalize(
46*6b6d114aSBen Gras 				struct _prop_object_externalize_context *,
47*6b6d114aSBen Gras 				void *);
48*6b6d114aSBen Gras static _prop_object_equals_rv_t
49*6b6d114aSBen Gras 		_prop_bool_equals(prop_object_t, prop_object_t,
50*6b6d114aSBen Gras 				  void **, void **,
51*6b6d114aSBen Gras 				  prop_object_t *, prop_object_t *);
52*6b6d114aSBen Gras 
53*6b6d114aSBen Gras static const struct _prop_object_type _prop_object_type_bool = {
54*6b6d114aSBen Gras 	.pot_type	=	PROP_TYPE_BOOL,
55*6b6d114aSBen Gras 	.pot_free	=	_prop_bool_free,
56*6b6d114aSBen Gras 	.pot_extern	=	_prop_bool_externalize,
57*6b6d114aSBen Gras 	.pot_equals	=	_prop_bool_equals,
58*6b6d114aSBen Gras };
59*6b6d114aSBen Gras 
60*6b6d114aSBen Gras #define	prop_object_is_bool(x)		\
61*6b6d114aSBen Gras 	((x) != NULL && (x)->pb_obj.po_type == &_prop_object_type_bool)
62*6b6d114aSBen Gras 
63*6b6d114aSBen Gras /* ARGSUSED */
64*6b6d114aSBen Gras static _prop_object_free_rv_t
_prop_bool_free(prop_stack_t stack,prop_object_t * obj)65*6b6d114aSBen Gras _prop_bool_free(prop_stack_t stack, prop_object_t *obj)
66*6b6d114aSBen Gras {
67*6b6d114aSBen Gras 	/*
68*6b6d114aSBen Gras 	 * This should never happen as we "leak" our initial reference
69*6b6d114aSBen Gras 	 * count.
70*6b6d114aSBen Gras 	 */
71*6b6d114aSBen Gras 
72*6b6d114aSBen Gras 	/* XXX forced assertion failure? */
73*6b6d114aSBen Gras 	return (_PROP_OBJECT_FREE_DONE);
74*6b6d114aSBen Gras }
75*6b6d114aSBen Gras 
76*6b6d114aSBen Gras static bool
_prop_bool_externalize(struct _prop_object_externalize_context * ctx,void * v)77*6b6d114aSBen Gras _prop_bool_externalize(struct _prop_object_externalize_context *ctx,
78*6b6d114aSBen Gras 		       void *v)
79*6b6d114aSBen Gras {
80*6b6d114aSBen Gras 	prop_bool_t pb = v;
81*6b6d114aSBen Gras 
82*6b6d114aSBen Gras 	return (_prop_object_externalize_empty_tag(ctx,
83*6b6d114aSBen Gras 	    pb->pb_value ? "true" : "false"));
84*6b6d114aSBen Gras }
85*6b6d114aSBen Gras 
86*6b6d114aSBen Gras /* ARGSUSED */
87*6b6d114aSBen Gras static _prop_object_equals_rv_t
_prop_bool_equals(prop_object_t v1,prop_object_t v2,void ** stored_pointer1,void ** stored_pointer2,prop_object_t * next_obj1,prop_object_t * next_obj2)88*6b6d114aSBen Gras _prop_bool_equals(prop_object_t v1, prop_object_t v2,
89*6b6d114aSBen Gras     void **stored_pointer1, void **stored_pointer2,
90*6b6d114aSBen Gras     prop_object_t *next_obj1, prop_object_t *next_obj2)
91*6b6d114aSBen Gras {
92*6b6d114aSBen Gras 	prop_bool_t b1 = v1;
93*6b6d114aSBen Gras 	prop_bool_t b2 = v2;
94*6b6d114aSBen Gras 
95*6b6d114aSBen Gras 	if (! (prop_object_is_bool(b1) &&
96*6b6d114aSBen Gras 	       prop_object_is_bool(b2)))
97*6b6d114aSBen Gras 		return (_PROP_OBJECT_EQUALS_FALSE);
98*6b6d114aSBen Gras 
99*6b6d114aSBen Gras 	/*
100*6b6d114aSBen Gras 	 * Since we only ever allocate one true and one false,
101*6b6d114aSBen Gras 	 * save ourselves a couple of memory operations.
102*6b6d114aSBen Gras 	 */
103*6b6d114aSBen Gras 	if (b1 == b2)
104*6b6d114aSBen Gras 		return (_PROP_OBJECT_EQUALS_TRUE);
105*6b6d114aSBen Gras 	else
106*6b6d114aSBen Gras 		return (_PROP_OBJECT_EQUALS_FALSE);
107*6b6d114aSBen Gras }
108*6b6d114aSBen Gras 
_PROP_ONCE_DECL(_prop_bool_init_once)109*6b6d114aSBen Gras _PROP_ONCE_DECL(_prop_bool_init_once)
110*6b6d114aSBen Gras 
111*6b6d114aSBen Gras static int
112*6b6d114aSBen Gras _prop_bool_init(void)
113*6b6d114aSBen Gras {
114*6b6d114aSBen Gras 
115*6b6d114aSBen Gras 	_prop_object_init(&_prop_bool_true.pb_obj,
116*6b6d114aSBen Gras 	    &_prop_object_type_bool);
117*6b6d114aSBen Gras 	_prop_bool_true.pb_value = true;
118*6b6d114aSBen Gras 
119*6b6d114aSBen Gras 	_prop_object_init(&_prop_bool_false.pb_obj,
120*6b6d114aSBen Gras 	    &_prop_object_type_bool);
121*6b6d114aSBen Gras 	_prop_bool_false.pb_value = false;
122*6b6d114aSBen Gras 
123*6b6d114aSBen Gras 	return 0;
124*6b6d114aSBen Gras }
125*6b6d114aSBen Gras 
126*6b6d114aSBen Gras static prop_bool_t
_prop_bool_alloc(bool val)127*6b6d114aSBen Gras _prop_bool_alloc(bool val)
128*6b6d114aSBen Gras {
129*6b6d114aSBen Gras 	prop_bool_t pb;
130*6b6d114aSBen Gras 
131*6b6d114aSBen Gras 	_PROP_ONCE_RUN(_prop_bool_init_once, _prop_bool_init);
132*6b6d114aSBen Gras 	pb = val ? &_prop_bool_true : &_prop_bool_false;
133*6b6d114aSBen Gras 	prop_object_retain(pb);
134*6b6d114aSBen Gras 
135*6b6d114aSBen Gras 	return (pb);
136*6b6d114aSBen Gras }
137*6b6d114aSBen Gras 
138*6b6d114aSBen Gras /*
139*6b6d114aSBen Gras  * prop_bool_create --
140*6b6d114aSBen Gras  *	Create a prop_bool_t and initialize it with the
141*6b6d114aSBen Gras  *	provided boolean value.
142*6b6d114aSBen Gras  */
143*6b6d114aSBen Gras prop_bool_t
prop_bool_create(bool val)144*6b6d114aSBen Gras prop_bool_create(bool val)
145*6b6d114aSBen Gras {
146*6b6d114aSBen Gras 
147*6b6d114aSBen Gras 	return (_prop_bool_alloc(val));
148*6b6d114aSBen Gras }
149*6b6d114aSBen Gras 
150*6b6d114aSBen Gras /*
151*6b6d114aSBen Gras  * prop_bool_copy --
152*6b6d114aSBen Gras  *	Copy a prop_bool_t.
153*6b6d114aSBen Gras  */
154*6b6d114aSBen Gras prop_bool_t
prop_bool_copy(prop_bool_t opb)155*6b6d114aSBen Gras prop_bool_copy(prop_bool_t opb)
156*6b6d114aSBen Gras {
157*6b6d114aSBen Gras 
158*6b6d114aSBen Gras 	if (! prop_object_is_bool(opb))
159*6b6d114aSBen Gras 		return (NULL);
160*6b6d114aSBen Gras 
161*6b6d114aSBen Gras 	/*
162*6b6d114aSBen Gras 	 * Because we only ever allocate one true and one false, this
163*6b6d114aSBen Gras 	 * can be reduced to a simple retain operation.
164*6b6d114aSBen Gras 	 */
165*6b6d114aSBen Gras 	prop_object_retain(opb);
166*6b6d114aSBen Gras 	return (opb);
167*6b6d114aSBen Gras }
168*6b6d114aSBen Gras 
169*6b6d114aSBen Gras /*
170*6b6d114aSBen Gras  * prop_bool_true --
171*6b6d114aSBen Gras  *	Get the value of a prop_bool_t.
172*6b6d114aSBen Gras  */
173*6b6d114aSBen Gras bool
prop_bool_true(prop_bool_t pb)174*6b6d114aSBen Gras prop_bool_true(prop_bool_t pb)
175*6b6d114aSBen Gras {
176*6b6d114aSBen Gras 
177*6b6d114aSBen Gras 	if (! prop_object_is_bool(pb))
178*6b6d114aSBen Gras 		return (false);
179*6b6d114aSBen Gras 
180*6b6d114aSBen Gras 	return (pb->pb_value);
181*6b6d114aSBen Gras }
182*6b6d114aSBen Gras 
183*6b6d114aSBen Gras /*
184*6b6d114aSBen Gras  * prop_bool_equals --
185*6b6d114aSBen Gras  *	Return true if the boolean values are equivalent.
186*6b6d114aSBen Gras  */
187*6b6d114aSBen Gras bool
prop_bool_equals(prop_bool_t b1,prop_bool_t b2)188*6b6d114aSBen Gras prop_bool_equals(prop_bool_t b1, prop_bool_t b2)
189*6b6d114aSBen Gras {
190*6b6d114aSBen Gras 	if (!prop_object_is_bool(b1) || !prop_object_is_bool(b2))
191*6b6d114aSBen Gras 		return (false);
192*6b6d114aSBen Gras 
193*6b6d114aSBen Gras 	return (prop_object_equals(b1, b2));
194*6b6d114aSBen Gras }
195*6b6d114aSBen Gras 
196*6b6d114aSBen Gras /*
197*6b6d114aSBen Gras  * _prop_bool_internalize --
198*6b6d114aSBen Gras  *	Parse a <true/> or <false/> and return the object created from
199*6b6d114aSBen Gras  *	the external representation.
200*6b6d114aSBen Gras  */
201*6b6d114aSBen Gras 
202*6b6d114aSBen Gras /* ARGSUSED */
203*6b6d114aSBen Gras bool
_prop_bool_internalize(prop_stack_t stack,prop_object_t * obj,struct _prop_object_internalize_context * ctx)204*6b6d114aSBen Gras _prop_bool_internalize(prop_stack_t stack, prop_object_t *obj,
205*6b6d114aSBen Gras     struct _prop_object_internalize_context *ctx)
206*6b6d114aSBen Gras {
207*6b6d114aSBen Gras 	bool val;
208*6b6d114aSBen Gras 
209*6b6d114aSBen Gras 	/* No attributes, and it must be an empty element. */
210*6b6d114aSBen Gras 	if (ctx->poic_tagattr != NULL ||
211*6b6d114aSBen Gras 	    ctx->poic_is_empty_element == false)
212*6b6d114aSBen Gras 	    	return (true);
213*6b6d114aSBen Gras 
214*6b6d114aSBen Gras 	if (_PROP_TAG_MATCH(ctx, "true"))
215*6b6d114aSBen Gras 		val = true;
216*6b6d114aSBen Gras 	else {
217*6b6d114aSBen Gras 		_PROP_ASSERT(_PROP_TAG_MATCH(ctx, "false"));
218*6b6d114aSBen Gras 		val = false;
219*6b6d114aSBen Gras 	}
220*6b6d114aSBen Gras 	*obj = prop_bool_create(val);
221*6b6d114aSBen Gras 	return (true);
222*6b6d114aSBen Gras }
223