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