This source file includes following definitions.
- opal_util_keyval_parse_finalize
- opal_util_keyval_parse_init
- opal_util_keyval_parse
- parse_line
- parse_error
- opal_util_keyval_save_internal_envars
- trim_name
- save_param_name
- add_to_env_str
- parse_line_new
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include "opal_config.h"
25
26 #include "opal/constants.h"
27 #include "opal/runtime/opal.h"
28 #include "opal/util/keyval_parse.h"
29 #include "opal/util/keyval/keyval_lex.h"
30 #include "opal/util/output.h"
31 #include "opal/util/string_copy.h"
32 #include "opal/threads/mutex.h"
33 #include <string.h>
34 #include <ctype.h>
35
36 int opal_util_keyval_parse_lineno = 0;
37
38 static const char *keyval_filename;
39 static opal_keyval_parse_fn_t keyval_callback;
40 static char *key_buffer = NULL;
41 static size_t key_buffer_len = 0;
42 static opal_mutex_t keyval_mutex;
43
44 static int parse_line(void);
45 static int parse_line_new(opal_keyval_parse_state_t first_val);
46 static void parse_error(int num);
47
48 static char *env_str = NULL;
49 static int envsize = 1024;
50
51 static void opal_util_keyval_parse_finalize (void)
52 {
53 free(key_buffer);
54 key_buffer = NULL;
55 key_buffer_len = 0;
56
57 OBJ_DESTRUCT(&keyval_mutex);
58 }
59
60 int opal_util_keyval_parse_init(void)
61 {
62 OBJ_CONSTRUCT(&keyval_mutex, opal_mutex_t);
63
64 opal_finalize_register_cleanup (opal_util_keyval_parse_finalize);
65
66 return OPAL_SUCCESS;
67 }
68
69 int
70 opal_util_keyval_parse(const char *filename,
71 opal_keyval_parse_fn_t callback)
72 {
73 int val;
74 int ret = OPAL_SUCCESS;;
75
76 OPAL_THREAD_LOCK(&keyval_mutex);
77
78 keyval_filename = filename;
79 keyval_callback = callback;
80
81
82 opal_util_keyval_yyin = fopen(keyval_filename, "r");
83 if (NULL == opal_util_keyval_yyin) {
84 ret = OPAL_ERR_NOT_FOUND;
85 goto cleanup;
86 }
87
88 opal_util_keyval_parse_done = false;
89 opal_util_keyval_yynewlines = 1;
90 opal_util_keyval_init_buffer(opal_util_keyval_yyin);
91 while (!opal_util_keyval_parse_done) {
92 val = opal_util_keyval_yylex();
93 switch (val) {
94 case OPAL_UTIL_KEYVAL_PARSE_DONE:
95
96
97 break;
98
99 case OPAL_UTIL_KEYVAL_PARSE_NEWLINE:
100
101 break;
102
103 case OPAL_UTIL_KEYVAL_PARSE_SINGLE_WORD:
104 parse_line();
105 break;
106
107 case OPAL_UTIL_KEYVAL_PARSE_MCAVAR:
108 case OPAL_UTIL_KEYVAL_PARSE_ENVVAR:
109 case OPAL_UTIL_KEYVAL_PARSE_ENVEQL:
110 parse_line_new(val);
111 break;
112
113 default:
114
115 parse_error(1);
116 break;
117 }
118 }
119 fclose(opal_util_keyval_yyin);
120 opal_util_keyval_yylex_destroy ();
121
122 cleanup:
123 OPAL_THREAD_UNLOCK(&keyval_mutex);
124 return ret;
125 }
126
127
128
129 static int parse_line(void)
130 {
131 int val;
132
133 opal_util_keyval_parse_lineno = opal_util_keyval_yylineno;
134
135
136 if (key_buffer_len < strlen(opal_util_keyval_yytext) + 1) {
137 char *tmp;
138 key_buffer_len = strlen(opal_util_keyval_yytext) + 1;
139 tmp = (char*)realloc(key_buffer, key_buffer_len);
140 if (NULL == tmp) {
141 free(key_buffer);
142 key_buffer_len = 0;
143 key_buffer = NULL;
144 return OPAL_ERR_TEMP_OUT_OF_RESOURCE;
145 }
146 key_buffer = tmp;
147 }
148
149 opal_string_copy(key_buffer, opal_util_keyval_yytext, key_buffer_len);
150
151
152
153 val = opal_util_keyval_yylex();
154 if (opal_util_keyval_parse_done || OPAL_UTIL_KEYVAL_PARSE_EQUAL != val) {
155 parse_error(2);
156 return OPAL_ERROR;
157 }
158
159
160
161 val = opal_util_keyval_yylex();
162 if (OPAL_UTIL_KEYVAL_PARSE_SINGLE_WORD == val ||
163 OPAL_UTIL_KEYVAL_PARSE_VALUE == val) {
164 keyval_callback(key_buffer, opal_util_keyval_yytext);
165
166
167
168 val = opal_util_keyval_yylex();
169 if (OPAL_UTIL_KEYVAL_PARSE_NEWLINE == val ||
170 OPAL_UTIL_KEYVAL_PARSE_DONE == val) {
171 return OPAL_SUCCESS;
172 }
173 }
174
175
176
177 else if (OPAL_UTIL_KEYVAL_PARSE_DONE == val ||
178 OPAL_UTIL_KEYVAL_PARSE_NEWLINE == val) {
179 keyval_callback(key_buffer, NULL);
180 return OPAL_SUCCESS;
181 }
182
183
184 parse_error(3);
185 return OPAL_ERROR;
186 }
187
188
189 static void parse_error(int num)
190 {
191
192 opal_output(0, "keyval parser: error %d reading file %s at line %d:\n %s\n",
193 num, keyval_filename, opal_util_keyval_yynewlines, opal_util_keyval_yytext);
194 }
195
196 int opal_util_keyval_save_internal_envars(opal_keyval_parse_fn_t callback)
197 {
198 if (NULL != env_str && 0 < strlen(env_str)) {
199 callback("mca_base_env_list_internal", env_str);
200 free(env_str);
201 env_str = NULL;
202 }
203 return OPAL_SUCCESS;
204 }
205
206 static void trim_name(char *buffer, const char* prefix, const char* suffix)
207 {
208 char *pchr, *echr;
209 size_t buffer_len;
210
211 if (NULL == buffer) {
212 return;
213 }
214
215 buffer_len = strlen (buffer);
216
217 pchr = buffer;
218 if (NULL != prefix) {
219 size_t prefix_len = strlen (prefix);
220
221 if (0 == strncmp (buffer, prefix, prefix_len)) {
222 pchr += prefix_len;
223 }
224 }
225
226
227 while (isspace (*pchr)) {
228 pchr++;
229 }
230
231
232 echr = buffer + buffer_len;
233 while (echr > buffer && isspace (*(echr - 1))) {
234 echr--;
235 }
236 echr[0] = '\0';
237
238 if (NULL != suffix && (uintptr_t) (echr - buffer) > strlen (suffix)) {
239 size_t suffix_len = strlen (suffix);
240
241 echr -= suffix_len;
242
243 if (0 == strncmp (echr, suffix, strlen(suffix))) {
244 do {
245 echr--;
246 } while (isspace (*echr));
247 echr[1] = '\0';
248 }
249 }
250
251 if (buffer != pchr) {
252
253 memmove (buffer, pchr, strlen (pchr) + 1);
254 }
255 }
256
257 static int save_param_name (void)
258 {
259 if (key_buffer_len < strlen(opal_util_keyval_yytext) + 1) {
260 char *tmp;
261 key_buffer_len = strlen(opal_util_keyval_yytext) + 1;
262 tmp = (char*)realloc(key_buffer, key_buffer_len);
263 if (NULL == tmp) {
264 free(key_buffer);
265 key_buffer_len = 0;
266 key_buffer = NULL;
267 return OPAL_ERR_TEMP_OUT_OF_RESOURCE;
268 }
269 key_buffer = tmp;
270 }
271
272 opal_string_copy (key_buffer, opal_util_keyval_yytext, key_buffer_len);
273
274 return OPAL_SUCCESS;
275 }
276
277 static int add_to_env_str(char *var, char *val)
278 {
279 int sz, varsz, valsz;
280 void *tmp;
281
282 if (NULL == var) {
283 return OPAL_ERR_BAD_PARAM;
284 }
285
286 if (NULL != env_str) {
287 varsz = strlen(var);
288 valsz = (NULL != val) ? strlen(val) : 0;
289 sz = strlen(env_str)+varsz+valsz+2;
290 if (envsize <= sz) {
291 envsize *=2;
292
293 tmp = realloc(env_str, envsize);
294 if (NULL == tmp) {
295 return OPAL_ERR_OUT_OF_RESOURCE;
296 }
297 env_str = tmp;
298 }
299 strcat(env_str, ";");
300 } else {
301 env_str = calloc(1, envsize);
302 if (NULL == env_str) {
303 return OPAL_ERR_OUT_OF_RESOURCE;
304 }
305 }
306
307 strcat(env_str, var);
308 if (NULL != val) {
309 strcat(env_str, "=");
310 strcat(env_str, val);
311 }
312
313 return OPAL_SUCCESS;
314 }
315
316 static int parse_line_new(opal_keyval_parse_state_t first_val)
317 {
318 opal_keyval_parse_state_t val;
319 char *tmp;
320 int rc;
321
322 val = first_val;
323 while (OPAL_UTIL_KEYVAL_PARSE_NEWLINE != val && OPAL_UTIL_KEYVAL_PARSE_DONE != val) {
324 rc = save_param_name ();
325 if (OPAL_SUCCESS != rc) {
326 return rc;
327 }
328
329 if (OPAL_UTIL_KEYVAL_PARSE_MCAVAR == val) {
330 trim_name (key_buffer, "-mca", NULL);
331 trim_name (key_buffer, "--mca", NULL);
332
333 val = opal_util_keyval_yylex();
334 if (OPAL_UTIL_KEYVAL_PARSE_VALUE == val) {
335 if (NULL != opal_util_keyval_yytext) {
336 tmp = strdup(opal_util_keyval_yytext);
337 if ('\'' == tmp[0] || '\"' == tmp[0]) {
338 trim_name (tmp, "\'", "\'");
339 trim_name (tmp, "\"", "\"");
340 }
341 keyval_callback(key_buffer, tmp);
342 free(tmp);
343 }
344 } else {
345 parse_error(4);
346 return OPAL_ERROR;
347 }
348 } else if (OPAL_UTIL_KEYVAL_PARSE_ENVEQL == val) {
349 trim_name (key_buffer, "-x", "=");
350 trim_name (key_buffer, "--x", NULL);
351
352 val = opal_util_keyval_yylex();
353 if (OPAL_UTIL_KEYVAL_PARSE_VALUE == val) {
354 add_to_env_str(key_buffer, opal_util_keyval_yytext);
355 } else {
356 parse_error(5);
357 return OPAL_ERROR;
358 }
359 } else if (OPAL_UTIL_KEYVAL_PARSE_ENVVAR == val) {
360 trim_name (key_buffer, "-x", "=");
361 trim_name (key_buffer, "--x", NULL);
362 add_to_env_str(key_buffer, NULL);
363 } else {
364
365 parse_error(6);
366 return OPAL_ERROR;
367 }
368
369 val = opal_util_keyval_yylex();
370 }
371
372 return OPAL_SUCCESS;
373 }