arm: protect state after signal handler
[minix.git] / lib / libsys / optset.c
blobf3ef2a0067649885ca994d6ccec70147a64dc144
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>
20 #include <minix/optset.h>
22 static void optset_parse_entry(struct optset *entry, char *ptr, int
23 len);
25 /*===========================================================================*
26 * optset_parse_entry *
27 *===========================================================================*/
28 static void optset_parse_entry(entry, ptr, len)
29 struct optset *entry;
30 char *ptr;
31 int len;
33 /* Parse and store the value of a single option.
35 char *dst;
36 int val;
38 switch (entry->os_type) {
39 case OPT_BOOL:
40 *((int *) entry->os_ptr) = entry->os_val;
42 break;
44 case OPT_STRING:
45 if (len >= entry->os_val)
46 len = entry->os_val - 1;
48 dst = (char *) entry->os_ptr;
50 if (len > 0)
51 memcpy(dst, ptr, len);
52 dst[len] = 0;
54 break;
56 case OPT_INT:
57 if (len > 0)
58 val = (int) strtoul(ptr, NULL, entry->os_val);
59 else
60 val = 0;
62 *((int *) entry->os_ptr) = val;
64 break;
68 /*===========================================================================*
69 * optset_parse *
70 *===========================================================================*/
71 void optset_parse(table, string)
72 struct optset *table;
73 char *string;
75 /* Parse a string of options, using the provided table of optset entries.
77 char *p, *kptr, *vptr;
78 int i, klen, vlen;
80 for (p = string; *p; ) {
81 /* Get the key name for the field. */
82 for (kptr = p, klen = 0; *p && *p != '=' && *p != ','; p++, klen++);
84 if (*p == '=') {
85 /* The field has an associated value. */
86 vptr = ++p;
88 /* If the first character after the '=' is a quote character,
89 * find a matching quote character followed by either a comma
90 * or the terminating null character, and use the string in
91 * between. Otherwise, use the string up to the next comma or
92 * the terminating null character.
94 if (*p == '\'' || *p == '"') {
95 p++;
97 for (vlen = 0; *p && (*p != *vptr ||
98 (p[1] && p[1] != ',')); p++, vlen++);
100 if (*p) p++;
101 vptr++;
103 else
104 for (vlen = 0; *p && *p != ','; p++, vlen++);
106 else {
107 vptr = NULL;
108 vlen = 0;
111 if (*p == ',') p++;
113 /* Find a matching entry for this key in the given table. If found,
114 * call optset_parse_entry() on it. Silently ignore the option
115 * otherwise.
117 for (i = 0; table[i].os_name != NULL; i++) {
118 if ((int) strlen(table[i].os_name) == klen &&
119 !strncasecmp(table[i].os_name, kptr, klen)) {
121 optset_parse_entry(&table[i], vptr, vlen);
123 break;