root/opal/util/keyval_parse.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. opal_util_keyval_parse_finalize
  2. opal_util_keyval_parse_init
  3. opal_util_keyval_parse
  4. parse_line
  5. parse_error
  6. opal_util_keyval_save_internal_envars
  7. trim_name
  8. save_param_name
  9. add_to_env_str
  10. parse_line_new

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2005 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights
  14  *                         reserved.
  15  * Copyright (c) 2018      Triad National Security, LLC. All rights
  16  *                         reserved.
  17  * $COPYRIGHT$
  18  *
  19  * Additional copyrights may follow
  20  *
  21  * $HEADER$
  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     /* Open the opal */
  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             /* This will also set opal_util_keyval_parse_done to true, so just
  96                break here */
  97             break;
  98 
  99         case OPAL_UTIL_KEYVAL_PARSE_NEWLINE:
 100             /* blank line!  ignore it */
 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             /* anything else is an error */
 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     /* Save the name name */
 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     /* The first thing we have to see is an "=" */
 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     /* Next we get the value */
 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         /* Now we need to see the newline */
 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     /* Did we get an EOL or EOF? */
 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     /* Nope -- we got something unexpected.  Bonk! */
 184     parse_error(3);
 185     return OPAL_ERROR;
 186 }
 187 
 188 
 189 static void parse_error(int num)
 190 {
 191     /* JMS need better error/warning message here */
 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     /* trim spaces at the beginning */
 227     while (isspace (*pchr)) {
 228         pchr++;
 229     }
 230 
 231     /* trim spaces at the end */
 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         /* move the trimmed string to the beginning of the buffer */
 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             /* we got something unexpected.  Bonk! */
 365             parse_error(6);
 366             return OPAL_ERROR;
 367         }
 368 
 369         val = opal_util_keyval_yylex();
 370     }
 371 
 372     return OPAL_SUCCESS;
 373 }

/* [<][>][^][v][top][bottom][index][help] */