/*
* Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Julio M. Merino Vidal.
*
* 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. The name authors may not be used to endorse or promote products
* derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
*/
/* Creates a new, empty block, with the specified type (see BLOCK_* macros).
* Returns a pointer to it. */
struct block *
block_new(int type)
{
struct block *b;
b = (struct block *) calloc(1, sizeof(struct block));
if (b == NULL)
err(EXIT_FAILURE, "calloc");
b->b_type = type;
return b;
}
/* Adds a property to a block. */
void
block_add_prop(struct block *b, struct prop *p)
{
if (p == NULL)
return;
if (b->b_prop_count >= MAX_PROPS)
errx(EXIT_FAILURE, "too many properties for current block");
else {
b->b_prop[b->b_prop_count] = p;
b->b_prop_count++;
}
}
/* Get the value of a property in the specified block (or in its parents).
* If not found, return the value given in def. */
char *
block_get_propval(struct block *b, const char *pname, char *def)
{
int pc;
if (b == NULL)
return def;
while (b != NULL) {
for (pc = 0; pc < b->b_prop_count; pc++)
if (strcmp(b->b_prop[pc]->p_name, pname) == 0)
return b->b_prop[pc]->p_value;
b = b->b_parent;
}
/* Get the value of a property in the specified block converting it to an
* integer, if possible. If the property cannot be found in the given
* block, all its parents are tried. If after all not found (or conversion
* not possible), return the value given in def. */
int
block_get_propval_int(struct block *b, const char *pname, int def)
{
char *ptr;
int pc, ret;
if (b == NULL)
return def;
while (b != NULL) {
for (pc = 0; pc < b->b_prop_count; pc++)
if (strcmp(b->b_prop[pc]->p_name, pname) == 0) {
ret = (int) strtol(b->b_prop[pc]->p_value,
&ptr, 10);
if (b->b_prop[pc]->p_value == ptr) {
warnx("expected integer in `%s' "
"property", pname);
return def;
}
return ret;
}
b = b->b_parent;
}
/* Gets a mode block (childs of the global scope), which matches the
* specified name. */
struct block *
config_get_mode(const char *modename)
{
int bc;
struct block *b;
b = Global;
if (strcmp(modename, "Global") == 0)
return Global;
if (b != NULL)
for (bc = 0; bc < b->b_child_count; bc++)
if (strcmp(b->b_child[bc]->b_name, modename) == 0)
return b->b_child[bc];