1 #include <ctype.h> 2 3 #include "ipf.h" 4 5 typedef struct variable { 6 struct variable *v_next; 7 char *v_name; 8 char *v_value; 9 } variable_t; 10 11 static variable_t *vtop = NULL; 12 13 static variable_t *find_var __P((char *)); 14 static char *expand_string __P((char *, int)); 15 16 17 static variable_t *find_var(name) 18 char *name; 19 { 20 variable_t *v; 21 22 for (v = vtop; v != NULL; v = v->v_next) 23 if (!strcmp(name, v->v_name)) 24 return v; 25 return NULL; 26 } 27 28 29 char *get_variable(string, after, line) 30 char *string, **after; 31 int line; 32 { 33 char c, *s, *t, *value; 34 variable_t *v; 35 36 s = string; 37 38 if (*s == '{') { 39 s++; 40 for (t = s; *t != '\0'; t++) 41 if (*t == '}') 42 break; 43 if (*t == '\0') { 44 fprintf(stderr, "%d: { without }\n", line); 45 return NULL; 46 } 47 } else if (isalpha(*s)) { 48 for (t = s + 1; *t != '\0'; t++) 49 if (!isalpha(*t) && !isdigit(*t)) 50 break; 51 } else { 52 fprintf(stderr, "%d: variables cannot start with '%c'\n", 53 line, *s); 54 return NULL; 55 } 56 57 if (after != NULL) 58 *after = t; 59 c = *t; 60 *t = '\0'; 61 v = find_var(s); 62 *t = c; 63 if (v == NULL) { 64 fprintf(stderr, "%d: unknown variable '%s'\n", line, s); 65 return NULL; 66 } 67 68 s = strdup(v->v_value); 69 value = expand_string(s, line); 70 if (value != s) 71 free(s); 72 return value; 73 } 74 75 76 static char *expand_string(oldstring, line) 77 char *oldstring; 78 int line; 79 { 80 char c, *s, *p1, *p2, *p3, *newstring, *value; 81 int len; 82 83 p3 = NULL; 84 newstring = oldstring; 85 86 for (s = oldstring; *s != '\0'; s++) 87 if (*s == '$') { 88 *s = '\0'; 89 s++; 90 91 switch (*s) 92 { 93 case '$' : 94 bcopy(s, s - 1, strlen(s)); 95 break; 96 default : 97 c = *s; 98 value = get_variable(s, &p3, line); 99 if (value == NULL) 100 return NULL; 101 102 p2 = expand_string(value, line); 103 if (p2 == NULL) 104 return NULL; 105 106 len = strlen(newstring) + strlen(p2); 107 if (p3 != NULL) { 108 if (c == '{' && *p3 == '}') 109 p3++; 110 len += strlen(p3); 111 } 112 p1 = malloc(len + 1); 113 if (p1 == NULL) 114 return NULL; 115 116 *(s - 1) = '\0'; 117 strcpy(p1, newstring); 118 strcat(p1, p2); 119 if (p3 != NULL) 120 strcat(p1, p3); 121 122 s = p1 + len - strlen(p3); 123 if (newstring != oldstring) 124 free(newstring); 125 newstring = p1; 126 break; 127 } 128 } 129 return newstring; 130 } 131 132 133 void set_variable(name, value) 134 char *name; 135 char *value; 136 { 137 variable_t *v; 138 int len; 139 140 if (name == NULL || value == NULL || *name == '\0') 141 return; 142 143 v = find_var(name); 144 if (v != NULL) { 145 free(v->v_value); 146 v->v_value = strdup(value); 147 return; 148 } 149 150 len = strlen(value); 151 152 if ((*value == '"' && value[len - 1] == '"') || 153 (*value == '\'' && value[len - 1] == '\'')) { 154 value[len - 1] = '\0'; 155 value++; 156 len -=2; 157 } 158 159 v = (variable_t *)malloc(sizeof(*v)); 160 if (v == NULL) 161 return; 162 v->v_name = strdup(name); 163 v->v_value = strdup(value); 164 v->v_next = vtop; 165 vtop = v; 166 } 167