make vfs & filesystems use failable copying
[minix3.git] / lib / libsys / optset.c
blob9a4ec61e24384435c3bb2f5c11ce79e06ffffdd3
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 #include <stdlib.h>
16 #include <string.h>
17 #include <minix/config.h>
18 #include <minix/const.h>
19 #include <minix/optset.h>
21 static void optset_parse_entry(struct optset *entry, char *ptr, int len);
23 /*===========================================================================*
24 * optset_parse_entry *
25 *===========================================================================*/
26 static void optset_parse_entry(struct optset *entry, char *ptr, int len)
28 /* Parse and store the value of a single option.
30 char *dst;
31 int val;
33 switch (entry->os_type) {
34 case OPT_BOOL:
35 *((int *) entry->os_ptr) = entry->os_val;
37 break;
39 case OPT_STRING:
40 if (len >= entry->os_val)
41 len = entry->os_val - 1;
43 dst = (char *) entry->os_ptr;
45 if (len > 0)
46 memcpy(dst, ptr, len);
47 dst[len] = 0;
49 break;
51 case OPT_INT:
52 if (len > 0)
53 val = (int) strtoul(ptr, NULL, entry->os_val);
54 else
55 val = 0;
57 *((int *) entry->os_ptr) = val;
59 break;
63 /*===========================================================================*
64 * optset_parse *
65 *===========================================================================*/
66 void optset_parse(struct optset *table, char *string)
68 /* Parse a string of options, using the provided table of optset entries.
70 char *p, *kptr, *vptr;
71 int i, klen, vlen;
73 for (p = string; *p; ) {
74 /* Get the key name for the field. */
75 for (kptr = p, klen = 0; *p && *p != '=' && *p != ','; p++, klen++);
77 if (*p == '=') {
78 /* The field has an associated value. */
79 vptr = ++p;
81 /* If the first character after the '=' is a quote character,
82 * find a matching quote character followed by either a comma
83 * or the terminating null character, and use the string in
84 * between. Otherwise, use the string up to the next comma or
85 * the terminating null character.
87 if (*p == '\'' || *p == '"') {
88 p++;
90 for (vlen = 0; *p && (*p != *vptr ||
91 (p[1] && p[1] != ',')); p++, vlen++);
93 if (*p) p++;
94 vptr++;
96 else
97 for (vlen = 0; *p && *p != ','; p++, vlen++);
99 else {
100 vptr = NULL;
101 vlen = 0;
104 if (*p == ',') p++;
106 /* Find a matching entry for this key in the given table. If found,
107 * call optset_parse_entry() on it. Silently ignore the option
108 * otherwise.
110 for (i = 0; table[i].os_name != NULL; i++) {
111 if ((int) strlen(table[i].os_name) == klen &&
112 !strncasecmp(table[i].os_name, kptr, klen)) {
114 optset_parse_entry(&table[i], vptr, vlen);
116 break;