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