root/opal/mca/pmix/pmix4x/pmix/src/util/keyval_parse.c

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

DEFINITIONS

This source file includes following definitions.
  1. pmix_util_keyval_parse_init
  2. pmix_util_keyval_parse_finalize
  3. pmix_util_keyval_parse
  4. parse_line
  5. parse_error
  6. pmix_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) 2016-2018 Intel, Inc.  All rights reserved.
  16  * $COPYRIGHT$
  17  *
  18  * Additional copyrights may follow
  19  *
  20  * $HEADER$
  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     /* Open the pmix */
  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             /* This will also set pmix_util_keyval_parse_done to true, so just
  87                break here */
  88             break;
  89 
  90         case PMIX_UTIL_KEYVAL_PARSE_NEWLINE:
  91             /* blank line!  ignore it */
  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             /* anything else is an error */
 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     /* Save the name name */
 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     /* The first thing we have to see is an "=" */
 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     /* Next we get the value */
 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         /* Now we need to see the newline */
 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     /* Did we get an EOL or EOF? */
 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     /* Nope -- we got something unexpected.  Bonk! */
 174     parse_error(3);
 175     return PMIX_ERROR;
 176 }
 177 
 178 
 179 static void parse_error(int num)
 180 {
 181     /* JMS need better error/warning message here */
 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     /* trim spaces at the beginning */
 217     while (isspace (*pchr)) {
 218         pchr++;
 219     }
 220 
 221     /* trim spaces at the end */
 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         /* move the trimmed string to the beginning of the buffer */
 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             /* we got something unexpected.  Bonk! */
 355             parse_error(6);
 356             return PMIX_ERROR;
 357         }
 358 
 359         val = pmix_util_keyval_yylex();
 360     }
 361 
 362     return PMIX_SUCCESS;
 363 }

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