Home | History | Annotate | Line # | Download | only in wsmoused
config.c revision 1.1
      1 /* $NetBSD: config.c,v 1.1 2003/03/04 14:33:55 jmmv Exp $ */
      2 
      3 /*
      4  * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Julio Merino.
      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  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. The name authors may not be used to endorse or promote products
     16  *    derived from this software without specific prior written
     17  *    permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
     20  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
     23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     25  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 
     34 #ifndef lint
     35 __RCSID("$NetBSD: config.c,v 1.1 2003/03/04 14:33:55 jmmv Exp $");
     36 #endif /* not lint */
     37 
     38 #include <sys/time.h>
     39 #include <dev/wscons/wsconsio.h>
     40 #include <stdio.h>
     41 #include <stdlib.h>
     42 #include <err.h>
     43 #include <errno.h>
     44 #include <string.h>
     45 
     46 #include "pathnames.h"
     47 #include "wsmoused.h"
     48 
     49 static struct block *Global = NULL;
     50 
     51 /* Prototypes for config_yacc.y (only used here) */
     52 struct block *config_parse(FILE *);
     53 
     54 /*
     55  * Creates a new, empty property.  Returns a pointer to it.
     56  */
     57 struct prop *
     58 prop_new(void)
     59 {
     60 	struct prop *p;
     61 
     62 	p = (struct prop *) calloc(1, sizeof(struct prop));
     63 	if (p == NULL)
     64 		err(EXIT_FAILURE, "calloc");
     65 	return p;
     66 }
     67 
     68 /*
     69  * Frees a property created with prop_new.  All data stored in the property
     70  * is also destroyed.
     71  */
     72 void
     73 prop_free(struct prop *p)
     74 {
     75 	free(p->p_name);
     76 	free(p->p_value);
     77 	free(p);
     78 }
     79 
     80 /*
     81  * Creates a new, empty block, with the specified type (see BLOCK_* macros).
     82  * Returns a pointer to it.
     83  */
     84 struct block *
     85 block_new(int type)
     86 {
     87 	struct block *b;
     88 
     89 	b = (struct block *) calloc(1, sizeof(struct block));
     90 	if (b == NULL)
     91 		err(EXIT_FAILURE, "calloc");
     92 	b->b_type = type;
     93 	return b;
     94 }
     95 
     96 /*
     97  * Frees a block created with block_new.  All data contained inside the block
     98  * is also destroyed.
     99  */
    100 void
    101 block_free(struct block *b)
    102 {
    103 	int i;
    104 
    105 	if (b->b_name != NULL)
    106 		free(b->b_name);
    107 
    108 	for (i = 0; i < b->b_prop_count; i++)
    109 		prop_free(b->b_prop[i]);
    110 	for (i = 0; i < b->b_child_count; i++)
    111 		block_free(b->b_child[i]);
    112 
    113 	free(b);
    114 }
    115 
    116 /*
    117  * Add a property to a block.
    118  */
    119 void
    120 block_add_prop(struct block *b, struct prop *p)
    121 {
    122 	if (p == NULL)
    123 		return;
    124 
    125 	if (b->b_prop_count >= MAX_PROPS)
    126 		errx(EXIT_FAILURE, "too many properties for current block");
    127 	else {
    128 		b->b_prop[b->b_prop_count] = p;
    129 		b->b_prop_count++;
    130 	}
    131 }
    132 
    133 /*
    134  * Add a child (block) to a block.
    135  */
    136 void
    137 block_add_child(struct block *b, struct block *c)
    138 {
    139 	if (c == NULL)
    140 		return;
    141 
    142 	if (b->b_child_count >= MAX_BLOCKS)
    143 		errx(EXIT_FAILURE, "too many childs for current block");
    144 	else {
    145 		c->b_parent = b;
    146 		b->b_child[b->b_child_count] = c;
    147 		b->b_child_count++;
    148 	}
    149 }
    150 
    151 /*
    152  * Get the value of a property in the specified block (or in its parents).
    153  * If not found, return the value given in def.
    154  */
    155 char *
    156 block_get_propval(struct block *b, char *pname, char *def)
    157 {
    158 	int pc;
    159 
    160 	if (b == NULL)
    161 		return def;
    162 
    163 	while (b != NULL) {
    164 		for (pc = 0; pc < b->b_prop_count; pc++)
    165 			if (strcmp(b->b_prop[pc]->p_name, pname) == 0)
    166 				return b->b_prop[pc]->p_value;
    167 		b = b->b_parent;
    168 	}
    169 
    170 	return def;
    171 }
    172 
    173 /*
    174  * Get the value of a property in the specified block converting it to an
    175  * integer, if possible.  If the property cannot be found in the given
    176  * block, all its parents are tried.  If after all not found (or conversion
    177  * not possible), return the value given in def.
    178  */
    179 int
    180 block_get_propval_int(struct block *b, char *pname, int def)
    181 {
    182 	int pc, ret;
    183 	char *ptr;
    184 
    185 	if (b == NULL)
    186 		return def;
    187 
    188 	while (b != NULL) {
    189 		for (pc = 0; pc < b->b_prop_count; pc++)
    190 			if (strcmp(b->b_prop[pc]->p_name, pname) == 0) {
    191 				ret = (int) strtol(b->b_prop[pc]->p_value,
    192 				    &ptr, 10);
    193 				if (b->b_prop[pc]->p_value == ptr) {
    194 					warnx("expected integer in `%s' "
    195 					    "property", pname);
    196 					return def;
    197 				}
    198 				return ret;
    199 			}
    200 		b = b->b_parent;
    201 	}
    202 
    203 	return def;
    204 }
    205 
    206 /*
    207  * Get a mode block (childs of the global scope), which matches the specified
    208  * name.
    209  */
    210 struct block *
    211 config_get_mode(char *modename)
    212 {
    213 	struct block *b = Global;
    214 	int bc;
    215 
    216 	if (b != NULL)
    217 		for (bc = 0; bc < b->b_child_count; bc++)
    218 			if (strcmp(b->b_child[bc]->b_name, modename) == 0)
    219 				return b->b_child[bc];
    220 
    221 	return NULL;
    222 }
    223 
    224 /*
    225  * Read the configuration file.
    226  */
    227 void
    228 config_read(char *conffile, int opt)
    229 {
    230 	FILE *f;
    231 
    232 	errno = 0;
    233 	f = fopen(conffile, "r");
    234 	if (f != NULL) {
    235 		Global = config_parse(f);
    236 		if (Global == NULL)
    237 			errx(EXIT_FAILURE, "%s contains fatal errors",
    238 			     conffile);
    239 	} else if (errno != ENOENT || opt) {
    240 		err(EXIT_FAILURE, "cannot open %s", conffile);
    241 	}
    242 }
    243 
    244 /*
    245  * Destroy all the configuration data.
    246  */
    247 void
    248 config_free(void)
    249 {
    250 	block_free(Global);
    251 }
    252