make vfs & filesystems use failable copying
[minix3.git] / lib / libsys / env_parse.c
blob2cc0b16d91663d24e4766e44264cd8c20e252d47
1 #include "sysutil.h"
2 #include <stdlib.h>
3 #include <env.h>
4 #include <string.h>
5 #include <minix/param.h>
8 /*=========================================================================*
9 * env_parse *
10 *=========================================================================*/
11 int env_parse(const char *env, const char *fmt,
12 int field, long *param, long min, long max)
14 /* Parse an environment variable setting, something like "DPETH0=300:3".
15 * Panic if the parsing fails. Return EP_UNSET if the environment variable
16 * is not set, EP_OFF if it is set to "off", EP_ON if set to "on" or a
17 * field is left blank, or EP_SET if a field is given (return value through
18 * *param). Punctuation may be used in the environment and format string,
19 * fields in the environment string may be empty, and punctuation may be
20 * missing to skip fields. The format string contains characters 'd', 'o',
21 * 'x' and 'c' to indicate that 10, 8, 16, or 0 is used as the last argument
22 * to strtol(). A '*' means that a field should be skipped. If the format
23 * string contains something like "\4" then the string is repeated 4 characters
24 * to the left.
26 char *val, *end;
27 char value[EP_BUF_SIZE];
28 char PUNCT[] = ":,;.";
29 long newpar;
30 int s, i, radix, r;
32 if ((s=env_get_param(env, value, sizeof(value))) != 0) {
33 if (s == ESRCH) return(EP_UNSET); /* only error allowed */
34 printf("WARNING: env_get_param() failed in env_parse(): %d\n",s);
35 return(EP_EGETKENV);
37 val = value;
38 if (strcmp(val, "off") == 0) return(EP_OFF);
39 if (strcmp(val, "on") == 0) return(EP_ON);
41 i = 0;
42 r = EP_ON;
43 for (;;) {
44 while (*val == ' ') val++; /* skip spaces */
45 if (*val == 0) return(r); /* the proper exit point */
46 if (*fmt == 0) break; /* too many values */
48 if (strchr(PUNCT, *val) != NULL) {
49 /* Time to go to the next field. */
50 if (strchr(PUNCT, *fmt) != NULL) i++;
51 if (*fmt++ == *val) val++;
52 if (*fmt < 32) fmt -= *fmt; /* step back? */
53 } else {
54 /* Environment contains a value, get it. */
55 switch (*fmt) {
56 case '*': radix = -1; break;
57 case 'd': radix = 10; break;
58 case 'o': radix = 010; break;
59 case 'x': radix = 0x10; break;
60 case 'c': radix = 0; break;
61 default: goto badenv;
64 if (radix < 0) {
65 /* Skip. */
66 while (strchr(PUNCT, *val) == NULL) val++;
67 continue;
68 } else {
69 /* A number. */
70 newpar = strtol(val, &end, radix);
72 if (end == val) break; /* not a number */
73 val = end;
76 if (i == field) {
77 /* The field requested. */
78 if (newpar < min || newpar > max) break;
79 *param = newpar;
80 r = EP_SET;
84 badenv:
85 env_panic(env);
86 return -1;