xref: /minix/minix/lib/libsys/env_parse.c (revision 433d6423)
1 #include "sysutil.h"
2 #include <stdlib.h>
3 #include <env.h>
4 #include <string.h>
5 #include <minix/param.h>
6 
7 
8 /*=========================================================================*
9  *				env_parse				   *
10  *=========================================================================*/
11 int env_parse(const char *env, const char *fmt,
12 	int field, long *param, long min, long max)
13 {
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.
25  */
26   char *val, *end;
27   char value[EP_BUF_SIZE];
28   char PUNCT[] = ":,;.";
29   long newpar;
30   int s, i, radix, r;
31 
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);
36   }
37   val = value;
38   if (strcmp(val, "off") == 0) return(EP_OFF);
39   if (strcmp(val, "on") == 0) return(EP_ON);
40 
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 */
47 
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;
62 		}
63 
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);
71 
72 			if (end == val) break;	/* not a number */
73 			val = end;
74 		}
75 
76 		if (i == field) {
77 			/* The field requested. */
78 			if (newpar < min || newpar > max) break;
79 			*param = newpar;
80 			r = EP_SET;
81 		}
82 	}
83   }
84 badenv:
85   env_panic(env);
86   return -1;
87 }
88