panic() cleanup.
[minix.git] / drivers / filter / optset.c
bloba338a47171c8bbceb34ed11a04f3ae361e1f49bd
1 /* This file provides functionality to parse strings of comma-separated
2 * options, each being either a single key name or a key=value pair, where the
3 * value may be enclosed in quotes. A table of optset entries is provided to
4 * determine which options are recognized, how to parse their values, and where
5 * to store those. Unrecognized options are silently ignored; improperly
6 * formatted options are silently set to reasonably acceptable values.
8 * The entry points into this file are:
9 * optset_parse parse the given options string using the given table
11 * Created:
12 * May 2009 (D.C. van Moolenbroek)
15 #define _MINIX 1
16 #include <stdlib.h>
17 #include <string.h>
18 #include <minix/config.h>
19 #include <minix/const.h>
21 #include "optset.h"
23 FORWARD _PROTOTYPE( void optset_parse_entry, (struct optset *entry,
24 char *ptr, int len) );
26 /*===========================================================================*
27 * optset_parse_entry *
28 *===========================================================================*/
29 PRIVATE void optset_parse_entry(entry, ptr, len)
30 struct optset *entry;
31 char *ptr;
32 int len;
34 /* Parse and store the value of a single option.
36 char *dst;
37 int val;
39 switch (entry->os_type) {
40 case OPT_BOOL:
41 *((int *) entry->os_ptr) = entry->os_val;
43 break;
45 case OPT_STRING:
46 if (len >= entry->os_val)
47 len = entry->os_val - 1;
49 dst = (char *) entry->os_ptr;
51 if (len > 0)
52 memcpy(dst, ptr, len);
53 dst[len] = 0;
55 break;
57 case OPT_INT:
58 if (len > 0)
59 val = strtol(ptr, NULL, entry->os_val);
60 else
61 val = 0;
63 *((int *) entry->os_ptr) = val;
65 break;
69 /*===========================================================================*
70 * optset_parse *
71 *===========================================================================*/
72 PUBLIC void optset_parse(table, string)
73 struct optset *table;
74 char *string;
76 /* Parse a string of options, using the provided table of optset entries.
78 char *p, *kptr, *vptr;
79 int i, klen, vlen;
81 for (p = string; *p; ) {
82 /* Get the key name for the field. */
83 for (kptr = p, klen = 0; *p && *p != '=' && *p != ','; p++, klen++);
85 if (*p == '=') {
86 /* The field has an associated value. */
87 vptr = ++p;
89 /* If the first character after the '=' is a quote character,
90 * find a matching quote character followed by either a comma
91 * or the terminating null character, and use the string in
92 * between. Otherwise, use the string up to the next comma or
93 * the terminating null character.
95 if (*p == '\'' || *p == '"') {
96 p++;
98 for (vlen = 0; *p && (*p != *vptr ||
99 (p[1] && p[1] != ',')); p++, vlen++);
101 if (*p) p++;
102 vptr++;
104 else
105 for (vlen = 0; *p && *p != ','; p++, vlen++);
107 else {
108 vptr = NULL;
109 vlen = 0;
112 if (*p == ',') p++;
114 /* Find a matching entry for this key in the given table. If found,
115 * call optset_parse_entry() on it. Silently ignore the option
116 * otherwise.
118 for (i = 0; table[i].os_name != NULL; i++) {
119 if (strlen(table[i].os_name) == klen &&
120 !strncasecmp(table[i].os_name, kptr, klen)) {
122 optset_parse_entry(&table[i], vptr, vlen);
124 break;