at_wini also needs a pci_reserve() for the pci compatability device, if
[minix3.git] / lib / sysutil / env_parse.c
blobc20d5126f1175bc7d90867275e4ffb5dd4a2202c
1 #include "sysutil.h"
2 #include <stdlib.h>
3 #include <env.h>
4 #include <string.h>
7 /*=========================================================================*
8 * env_parse *
9 *=========================================================================*/
10 PUBLIC int env_parse(env, fmt, field, param, min, max)
11 char *env; /* environment variable to inspect */
12 char *fmt; /* template to parse it with */
13 int field; /* field number of value to return */
14 long *param; /* address of parameter to get */
15 long min, max; /* minimum and maximum values for the parameter */
17 /* Parse an environment variable setting, something like "DPETH0=300:3".
18 * Panic if the parsing fails. Return EP_UNSET if the environment variable
19 * is not set, EP_OFF if it is set to "off", EP_ON if set to "on" or a
20 * field is left blank, or EP_SET if a field is given (return value through
21 * *param). Punctuation may be used in the environment and format string,
22 * fields in the environment string may be empty, and punctuation may be
23 * missing to skip fields. The format string contains characters 'd', 'o',
24 * 'x' and 'c' to indicate that 10, 8, 16, or 0 is used as the last argument
25 * to strtol(). A '*' means that a field should be skipped. If the format
26 * string contains something like "\4" then the string is repeated 4 characters
27 * to the left.
29 char *val, *end;
30 char value[EP_BUF_SIZE];
31 char PUNCT[] = ":,;.";
32 long newpar;
33 int s, i, radix, r;
35 if ((s=env_get_param(env, value, sizeof(value))) != 0) {
36 if (s == ESRCH) return(EP_UNSET); /* only error allowed */
37 printf("WARNING: get_mon_param() failed in env_parse(): %d\n",s);
38 return(EP_EGETKENV);
40 val = value;
41 if (strcmp(val, "off") == 0) return(EP_OFF);
42 if (strcmp(val, "on") == 0) return(EP_ON);
44 i = 0;
45 r = EP_ON;
46 for (;;) {
47 while (*val == ' ') val++; /* skip spaces */
48 if (*val == 0) return(r); /* the proper exit point */
49 if (*fmt == 0) break; /* too many values */
51 if (strchr(PUNCT, *val) != NULL) {
52 /* Time to go to the next field. */
53 if (strchr(PUNCT, *fmt) != NULL) i++;
54 if (*fmt++ == *val) val++;
55 if (*fmt < 32) fmt -= *fmt; /* step back? */
56 } else {
57 /* Environment contains a value, get it. */
58 switch (*fmt) {
59 case '*': radix = -1; break;
60 case 'd': radix = 10; break;
61 case 'o': radix = 010; break;
62 case 'x': radix = 0x10; break;
63 case 'c': radix = 0; break;
64 default: goto badenv;
67 if (radix < 0) {
68 /* Skip. */
69 while (strchr(PUNCT, *val) == NULL) val++;
70 continue;
71 } else {
72 /* A number. */
73 newpar = strtol(val, &end, radix);
75 if (end == val) break; /* not a number */
76 val = end;
79 if (i == field) {
80 /* The field requested. */
81 if (newpar < min || newpar > max) break;
82 *param = newpar;
83 r = EP_SET;
87 badenv:
88 env_panic(env);
89 return -1;
92 /*=========================================================================*
93 * env_memory_parse *
94 *=========================================================================*/
96 PUBLIC int env_memory_parse(mem_chunks, maxchunks)
97 struct memory *mem_chunks; /* where to store the memory bits */
98 int maxchunks; /* how many were found */
100 int i, done = 0;
101 char *s;
102 struct memory *memp;
103 char memstr[100], *end;
105 /* Initialize everything to zero. */
106 for (i = 0; i < maxchunks; i++) {
107 memp = &mem_chunks[i]; /* next mem chunk is stored here */
108 memp->base = memp->size = 0;
111 /* The available memory is determined by MINIX' boot loader as a list of
112 * (base:size)-pairs in boothead.s. The 'memory' boot variable is set in
113 * in boot.s. The format is "b0:s0,b1:s1,b2:s2", where b0:s0 is low mem,
114 * b1:s1 is mem between 1M and 16M, b2:s2 is mem above 16M. Pairs b1:s1
115 * and b2:s2 are combined if the memory is adjacent.
117 if(env_get_param("memory", memstr, sizeof(memstr)-1) != OK)
118 return -1;
119 s = memstr;
120 for (i = 0; i < maxchunks && !done; i++) {
121 phys_bytes base = 0, size = 0, limit;
122 memp = &mem_chunks[i]; /* next mem chunk is stored here */
123 if (*s != 0) { /* get fresh data, unless at end */
125 /* Read fresh base and expect colon as next char. */
126 base = strtoul(s, &end, 0x10); /* get number */
127 if (end != s && *end == ':') s = ++end; /* skip ':' */
128 else *s=0; /* terminate, should not happen */
130 /* Read fresh size and expect comma or assume end. */
131 size = strtoul(s, &end, 0x10); /* get number */
132 if (end != s && *end == ',') s = ++end; /* skip ',' */
133 else done = 1;
135 if (base + size <= base) continue;
136 memp->base = base;
137 memp->size = size;
140 return OK;