root/opal/mca/base/mca_base_var_enum.c

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

DEFINITIONS

This source file includes following definitions.
  1. mca_base_var_enum_bool_get_count
  2. mca_base_var_enum_bool_get_value
  3. mca_base_var_enum_bool_vfs
  4. mca_base_var_enum_bool_sfv
  5. mca_base_var_enum_bool_dump
  6. mca_base_var_enum_auto_bool_get_count
  7. mca_base_var_enum_auto_bool_get_value
  8. mca_base_var_enum_auto_bool_vfs
  9. mca_base_var_enum_auto_bool_sfv
  10. mca_base_var_enum_auto_bool_dump
  11. mca_base_var_enum_verbose_vfs
  12. mca_base_var_enum_verbose_sfv
  13. mca_base_var_enum_verbose_dump
  14. mca_base_var_enum_create
  15. mca_base_var_enum_create_flag
  16. enum_dump
  17. enum_get_count
  18. enum_get_value
  19. enum_value_from_string
  20. enum_string_from_value
  21. mca_base_var_enum_constructor
  22. mca_base_var_enum_destructor
  23. enum_get_value_flag
  24. enum_value_from_string_flag
  25. enum_string_from_value_flag
  26. enum_dump_flag
  27. mca_base_var_enum_flag_constructor
  28. mca_base_var_enum_flag_destructor
  29. mca_base_var_enum_register

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2008 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2012 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) 2008-2013 Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2012-2017 Los Alamos National Security, LLC. All rights
  15  *                         reserved.
  16  * Copyright (c) 2017      Research Organization for Information Science
  17  *                         and Technology (RIST). All rights reserved.
  18  * Copyright (c) 2017      IBM Corporation. All rights reserved.
  19  * Copyright (c) 2018      Amazon.com, Inc. or its affiliates.  All Rights reserved.
  20  * $COPYRIGHT$
  21  *
  22  * Additional copyrights may follow
  23  *
  24  * $HEADER$
  25  */
  26 
  27 #include "opal_config.h"
  28 
  29 #include "opal/mca/base/mca_base_var_enum.h"
  30 #include "opal/mca/base/mca_base_vari.h"
  31 #include "opal/mca/base/base.h"
  32 #include "opal/util/argv.h"
  33 #include "opal/util/printf.h"
  34 
  35 #include <stdio.h>
  36 #include <string.h>
  37 #include <errno.h>
  38 
  39 static void mca_base_var_enum_constructor (mca_base_var_enum_t *enumerator);
  40 static void mca_base_var_enum_destructor (mca_base_var_enum_t *enumerator);
  41 OBJ_CLASS_INSTANCE(mca_base_var_enum_t, opal_object_t, mca_base_var_enum_constructor,
  42                    mca_base_var_enum_destructor);
  43 
  44 static void mca_base_var_enum_flag_constructor (mca_base_var_enum_flag_t *enumerator);
  45 static void mca_base_var_enum_flag_destructor (mca_base_var_enum_flag_t *enumerator);
  46 static OBJ_CLASS_INSTANCE(mca_base_var_enum_flag_t, opal_object_t, mca_base_var_enum_flag_constructor,
  47                    mca_base_var_enum_flag_destructor);
  48 
  49 static int enum_dump (mca_base_var_enum_t *self, char **out);
  50 static int enum_get_count (mca_base_var_enum_t *self, int *count);
  51 static int enum_get_value (mca_base_var_enum_t *self, int index, int *value, const char **string_value);
  52 
  53 static int mca_base_var_enum_bool_get_count (mca_base_var_enum_t *enumerator, int *count)
  54 {
  55     *count = 2;
  56     return OPAL_SUCCESS;
  57 }
  58 
  59 static int mca_base_var_enum_bool_get_value (mca_base_var_enum_t *self, int index,
  60                                              int *value, const char **string_value)
  61 {
  62     if (1 < index) {
  63         return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
  64     }
  65 
  66     *value = index ? 1 : 0;
  67     *string_value = index ? "true" : "false";
  68 
  69     return OPAL_SUCCESS;
  70 }
  71 
  72 static int mca_base_var_enum_bool_vfs (mca_base_var_enum_t *self, const char *string_value,
  73                                        int *value)
  74 {
  75     char *tmp;
  76     long v;
  77 
  78     /* skip whitespace */
  79     string_value += strspn (string_value, " \t\n\v\f\r");
  80 
  81     v = strtol (string_value, &tmp, 10);
  82     if (*tmp != '\0') {
  83         if (0 == strcmp (string_value, "true") || 0 == strcmp (string_value, "t") ||
  84             0 == strcmp (string_value, "enabled") || 0 == strcmp (string_value, "yes") ||
  85             0 == strcmp (string_value, "y")) {
  86             v = 1;
  87         } else if (0 == strcmp (string_value, "false") || 0 == strcmp (string_value, "f") ||
  88                    0 == strcmp (string_value, "disabled") || 0 == strcmp (string_value, "no") ||
  89                    0 == strcmp (string_value, "n")) {
  90             v = 0;
  91         } else {
  92             return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
  93         }
  94     }
  95 
  96     *value = !!v;
  97 
  98     return OPAL_SUCCESS;
  99 }
 100 
 101 static int mca_base_var_enum_bool_sfv (mca_base_var_enum_t *self, const int value,
 102                                        char **string_value)
 103 {
 104     if (string_value) {
 105         *string_value = strdup (value ? "true" : "false");
 106     }
 107 
 108     return OPAL_SUCCESS;
 109 }
 110 
 111 static int mca_base_var_enum_bool_dump (mca_base_var_enum_t *self, char **out)
 112 {
 113     *out = strdup ("0: f|false|disabled|no|n, 1: t|true|enabled|yes|y");
 114     return *out ? OPAL_SUCCESS : OPAL_ERR_OUT_OF_RESOURCE;
 115 }
 116 
 117 mca_base_var_enum_t mca_base_var_enum_bool = {
 118     .super     = OPAL_OBJ_STATIC_INIT(opal_object_t),
 119     .enum_is_static = true,
 120     .enum_name = "boolean",
 121     .get_count = mca_base_var_enum_bool_get_count,
 122     .get_value = mca_base_var_enum_bool_get_value,
 123     .value_from_string = mca_base_var_enum_bool_vfs,
 124     .string_from_value = mca_base_var_enum_bool_sfv,
 125     .dump      = mca_base_var_enum_bool_dump
 126 };
 127 
 128 static int mca_base_var_enum_auto_bool_get_count (mca_base_var_enum_t *enumerator, int *count)
 129 {
 130     *count = 3;
 131     return OPAL_SUCCESS;
 132 }
 133 
 134 static int mca_base_var_enum_auto_bool_get_value (mca_base_var_enum_t *self, int index,
 135                                                   int *value, const char **string_value)
 136 {
 137     const int values[3] = {0, 1, -1};
 138     const char *strings[3] = {"false", "true", "auto"};
 139 
 140     if (2 < index) {
 141         return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
 142     }
 143 
 144     *value = values[index];
 145     *string_value = strings[index];
 146 
 147     return OPAL_SUCCESS;
 148 }
 149 
 150 static int mca_base_var_enum_auto_bool_vfs (mca_base_var_enum_t *self, const char *string_value,
 151                                             int *value)
 152 {
 153     char *tmp;
 154     long v;
 155 
 156     /* skip whitespace */
 157     string_value += strspn (string_value, " \t\n\v\f\r");
 158 
 159     v = strtol (string_value, &tmp, 10);
 160     if (*tmp != '\0') {
 161         if (0 == strcasecmp (string_value, "true") || 0 == strcasecmp (string_value, "t") ||
 162             0 == strcasecmp (string_value, "enabled") || 0 == strcasecmp (string_value, "yes") ||
 163             0 == strcasecmp (string_value, "y")) {
 164             v = 1;
 165         } else if (0 == strcasecmp (string_value, "false") || 0 == strcasecmp (string_value, "f") ||
 166                    0 == strcasecmp (string_value, "disabled") || 0 == strcasecmp (string_value, "no") ||
 167                    0 == strcasecmp (string_value, "n")) {
 168             v = 0;
 169         } else if (0 == strcasecmp (string_value, "auto")) {
 170             v = -1;
 171         } else {
 172             return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
 173         }
 174     }
 175 
 176     if (v > 1) {
 177         *value = 1;
 178     } else if (v < -1) {
 179         *value = -1;
 180     } else {
 181         *value = (int) v;
 182     }
 183 
 184     return OPAL_SUCCESS;
 185 }
 186 
 187 static int mca_base_var_enum_auto_bool_sfv (mca_base_var_enum_t *self, const int value,
 188                                             char **string_value)
 189 {
 190     if (string_value) {
 191         if (value < 0) {
 192             *string_value = strdup ("auto");
 193         } else if (value > 0) {
 194             *string_value = strdup ("true");
 195         } else {
 196             *string_value = strdup ("false");
 197         }
 198     }
 199 
 200     return OPAL_SUCCESS;
 201 }
 202 
 203 static int mca_base_var_enum_auto_bool_dump (mca_base_var_enum_t *self, char **out)
 204 {
 205     *out = strdup ("-1: auto, 0: f|false|disabled|no|n, 1: t|true|enabled|yes|y");
 206     return *out ? OPAL_SUCCESS : OPAL_ERR_OUT_OF_RESOURCE;
 207 }
 208 
 209 mca_base_var_enum_t mca_base_var_enum_auto_bool = {
 210     .super     = OPAL_OBJ_STATIC_INIT(opal_object_t),
 211     .enum_is_static = true,
 212     .enum_name = "auto_boolean",
 213     .get_count = mca_base_var_enum_auto_bool_get_count,
 214     .get_value = mca_base_var_enum_auto_bool_get_value,
 215     .value_from_string = mca_base_var_enum_auto_bool_vfs,
 216     .string_from_value = mca_base_var_enum_auto_bool_sfv,
 217     .dump      = mca_base_var_enum_auto_bool_dump
 218 };
 219 
 220 /* verbosity enumerator */
 221 static mca_base_var_enum_value_t verbose_values[] = {
 222     {MCA_BASE_VERBOSE_NONE,      "none"},
 223     {MCA_BASE_VERBOSE_ERROR,     "error"},
 224     {MCA_BASE_VERBOSE_COMPONENT, "component"},
 225     {MCA_BASE_VERBOSE_WARN,      "warn"},
 226     {MCA_BASE_VERBOSE_INFO,      "info"},
 227     {MCA_BASE_VERBOSE_TRACE,     "trace"},
 228     {MCA_BASE_VERBOSE_DEBUG,     "debug"},
 229     {MCA_BASE_VERBOSE_MAX,       "max"},
 230     {-1, NULL}
 231 };
 232 
 233 static int mca_base_var_enum_verbose_vfs (mca_base_var_enum_t *self, const char *string_value,
 234                                           int *value)
 235 {
 236     char *tmp;
 237     int v;
 238 
 239     /* skip whitespace */
 240     string_value += strspn (string_value, " \t\n\v\f\r");
 241 
 242     v = strtol (string_value, &tmp, 10);
 243     if (*tmp != '\0') {
 244         for (int i = 0 ; verbose_values[i].string ; ++i) {
 245             if (0 == strcmp (verbose_values[i].string, string_value)) {
 246                 *value = verbose_values[i].value;
 247                 return OPAL_SUCCESS;
 248             }
 249         }
 250 
 251         return OPAL_ERR_NOT_FOUND;
 252     } else if (v < MCA_BASE_VERBOSE_NONE) {
 253         v = MCA_BASE_VERBOSE_NONE;
 254     } else if (v > MCA_BASE_VERBOSE_MAX) {
 255         v = MCA_BASE_VERBOSE_MAX;
 256     }
 257 
 258     *value = v;
 259 
 260     return OPAL_SUCCESS;
 261 }
 262 
 263 static int mca_base_var_enum_verbose_sfv (mca_base_var_enum_t *self, const int value,
 264                                           char **string_value)
 265 {
 266     int ret;
 267 
 268     if (value < 0 || value > 100) {
 269         return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
 270     }
 271 
 272     for (int i = 0 ; verbose_values[i].string ; ++i) {
 273         if (verbose_values[i].value == value) {
 274             if (string_value) {
 275                 *string_value = strdup (verbose_values[i].string);
 276             }
 277             return OPAL_SUCCESS;
 278         }
 279     }
 280 
 281     if (string_value) {
 282         ret = opal_asprintf (string_value, "%d", value);
 283         if (0 > ret) {
 284             return OPAL_ERR_OUT_OF_RESOURCE;
 285         }
 286     }
 287 
 288     return OPAL_SUCCESS;
 289 }
 290 
 291 static int mca_base_var_enum_verbose_dump (mca_base_var_enum_t *self, char **out)
 292 {
 293     char *tmp;
 294     int ret;
 295 
 296     ret = enum_dump (self, out);
 297     if (OPAL_SUCCESS != ret) {
 298         return ret;
 299     }
 300 
 301     ret = opal_asprintf (&tmp, "%s, 0 - 100", *out);
 302     free (*out);
 303     if (0 > ret) {
 304         *out = NULL;
 305         return OPAL_ERR_OUT_OF_RESOURCE;
 306     }
 307 
 308     *out = tmp;
 309 
 310     return OPAL_SUCCESS;
 311 }
 312 
 313 mca_base_var_enum_t mca_base_var_enum_verbose = {
 314     .super     = OPAL_OBJ_STATIC_INIT(opal_object_t),
 315     .enum_is_static = true,
 316     .enum_name = "verbosity",
 317     .get_count = enum_get_count,
 318     .get_value = enum_get_value,
 319     .value_from_string = mca_base_var_enum_verbose_vfs,
 320     .string_from_value = mca_base_var_enum_verbose_sfv,
 321     .dump      = mca_base_var_enum_verbose_dump,
 322     .enum_value_count = 8,
 323     .enum_values = verbose_values,
 324 };
 325 
 326 
 327 int mca_base_var_enum_create (const char *name, const mca_base_var_enum_value_t *values, mca_base_var_enum_t **enumerator)
 328 {
 329     mca_base_var_enum_t *new_enum;
 330     int i;
 331 
 332     *enumerator = NULL;
 333 
 334     new_enum = OBJ_NEW(mca_base_var_enum_t);
 335     if (NULL == new_enum) {
 336         return OPAL_ERR_OUT_OF_RESOURCE;
 337     }
 338 
 339     new_enum->enum_name = strdup (name);
 340     if (NULL == new_enum->enum_name) {
 341         return OPAL_ERR_OUT_OF_RESOURCE;
 342     }
 343 
 344     for (i = 0 ; values[i].string ; ++i);
 345     new_enum->enum_value_count = i;
 346 
 347     /* make a copy of the values */
 348     new_enum->enum_values = calloc (new_enum->enum_value_count + 1, sizeof (*new_enum->enum_values));
 349     if (NULL == new_enum->enum_values) {
 350         OBJ_RELEASE(new_enum);
 351         return OPAL_ERR_OUT_OF_RESOURCE;
 352     }
 353 
 354     for (i = 0 ; i < new_enum->enum_value_count ; ++i) {
 355         new_enum->enum_values[i].value = values[i].value;
 356         new_enum->enum_values[i].string = strdup (values[i].string);
 357     }
 358 
 359     *enumerator = new_enum;
 360 
 361     return OPAL_SUCCESS;
 362 }
 363 
 364 int mca_base_var_enum_create_flag (const char *name, const mca_base_var_enum_value_flag_t *flags, mca_base_var_enum_flag_t **enumerator)
 365 {
 366     mca_base_var_enum_flag_t *new_enum;
 367     int i;
 368 
 369     *enumerator = NULL;
 370 
 371     new_enum = OBJ_NEW(mca_base_var_enum_flag_t);
 372     if (NULL == new_enum) {
 373         return OPAL_ERR_OUT_OF_RESOURCE;
 374     }
 375 
 376     new_enum->super.enum_name = strdup (name);
 377     if (NULL == new_enum->super.enum_name) {
 378         return OPAL_ERR_OUT_OF_RESOURCE;
 379     }
 380 
 381     for (i = 0 ; flags[i].string ; ++i);
 382     new_enum->super.enum_value_count = i;
 383 
 384     /* make a copy of the values */
 385     new_enum->enum_flags = calloc (new_enum->super.enum_value_count + 1, sizeof (*new_enum->enum_flags));
 386     if (NULL == new_enum->enum_flags) {
 387         OBJ_RELEASE(new_enum);
 388         return OPAL_ERR_OUT_OF_RESOURCE;
 389     }
 390 
 391     int all_flags = 0;
 392     for (i = 0 ; i < new_enum->super.enum_value_count ; ++i) {
 393         new_enum->enum_flags[i].flag = flags[i].flag;
 394         new_enum->enum_flags[i].string = strdup (flags[i].string);
 395         new_enum->enum_flags[i].conflicting_flag = flags[i].conflicting_flag;
 396         /* ensure flags are only set a single bit, doesn't conflict with itself, and
 397          * hasn't already been specified. */
 398         assert (!(flags[i].flag & (flags[i].flag - 1)));
 399         assert (!(flags[i].flag & flags[i].conflicting_flag));
 400         assert (!(all_flags & flags[i].flag));
 401         assert (flags[i].flag);
 402         all_flags |= flags[i].flag;
 403     }
 404 
 405     *enumerator = new_enum;
 406 
 407     return OPAL_SUCCESS;
 408 }
 409 
 410 static int enum_dump (mca_base_var_enum_t *self, char **out)
 411 {
 412     int i;
 413     char *tmp;
 414     int ret;
 415 
 416     *out = NULL;
 417 
 418     if (NULL == self) {
 419         return OPAL_ERROR;
 420     }
 421 
 422     tmp = NULL;
 423     for (i = 0; i < self->enum_value_count && self->enum_values[i].string ; ++i) {
 424         ret = opal_asprintf (out, "%s%s%d:\"%s\"", tmp ? tmp : "", tmp ? ", " : "", self->enum_values[i].value,
 425                         self->enum_values[i].string);
 426         if (tmp) free (tmp);
 427         if (0 > ret) {
 428             return OPAL_ERR_OUT_OF_RESOURCE;
 429         }
 430         tmp = *out;
 431     }
 432 
 433     return OPAL_SUCCESS;
 434 }
 435 
 436 static int enum_get_count (mca_base_var_enum_t *self, int *count)
 437 {
 438     *count = self->enum_value_count;
 439     return OPAL_SUCCESS;
 440 }
 441 
 442 static int enum_get_value (mca_base_var_enum_t *self, int index, int *value, const char **string_value)
 443 {
 444     int count, ret;
 445 
 446     ret = self->get_count(self, &count);
 447     if (OPAL_SUCCESS != ret) {
 448         return ret;
 449     }
 450 
 451     if (index >= count) {
 452         return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
 453     }
 454 
 455     if (value) {
 456         *value = self->enum_values[index].value;
 457     }
 458 
 459     if (string_value) {
 460         *string_value = strdup (self->enum_values[index].string);
 461     }
 462 
 463     return OPAL_SUCCESS;
 464 }
 465 
 466 static int enum_value_from_string(mca_base_var_enum_t *self, const char *string_value, int *value_out) {
 467     int value, count, ret, i;
 468     bool is_int;
 469     char *tmp;
 470 
 471     ret = self->get_count(self, &count);
 472     if (OPAL_SUCCESS != ret) {
 473         return ret;
 474     }
 475 
 476     value = strtol(string_value, &tmp, 0);
 477 
 478     /* Check if the string is an integer */
 479     is_int = tmp[0] == '\0';
 480 
 481     for (i = 0 ; i < count ; ++i) {
 482         if ((is_int && value == self->enum_values[i].value) ||
 483             0 == strcasecmp (string_value, self->enum_values[i].string)) {
 484             break;
 485         }
 486     }
 487 
 488     if (i == count) {
 489         return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
 490     }
 491 
 492     *value_out = self->enum_values[i].value;
 493 
 494     return OPAL_SUCCESS;
 495 }
 496 
 497 static int enum_string_from_value(mca_base_var_enum_t *self, const int value, char **string_value) {
 498     int count, ret, i;
 499 
 500     ret = self->get_count(self, &count);
 501     if (OPAL_SUCCESS != ret) {
 502         return ret;
 503     }
 504 
 505     for (i = 0 ; i < count ; ++i) {
 506         if (value == self->enum_values[i].value) {
 507             break;
 508         }
 509     }
 510 
 511     if (i == count) {
 512         return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
 513     }
 514 
 515     if (string_value) {
 516         *string_value = strdup (self->enum_values[i].string);
 517     }
 518 
 519     return OPAL_SUCCESS;
 520 }
 521 
 522 static void mca_base_var_enum_constructor (mca_base_var_enum_t *enumerator)
 523 {
 524     memset ((char *) enumerator + sizeof (enumerator->super), 0 , sizeof(*enumerator) - sizeof(enumerator->super));
 525 
 526     enumerator->get_value = enum_get_value;
 527     enumerator->get_count = enum_get_count;
 528     enumerator->value_from_string = enum_value_from_string;
 529     enumerator->string_from_value = enum_string_from_value;
 530     enumerator->dump      = enum_dump;
 531     enumerator->enum_is_static = false;
 532 }
 533 
 534 static void mca_base_var_enum_destructor (mca_base_var_enum_t *enumerator)
 535 {
 536     if (enumerator->enum_name) {
 537         free (enumerator->enum_name);
 538     }
 539 
 540     /* release the copy of the values */
 541     if (enumerator->enum_values) {
 542         for (int i = 0 ; i < enumerator->enum_value_count ; ++i) {
 543             free ((void *) enumerator->enum_values[i].string);
 544         }
 545         free (enumerator->enum_values);
 546     }
 547 }
 548 
 549 static int enum_get_value_flag (mca_base_var_enum_t *self, int index, int *value, const char **string_value)
 550 {
 551     mca_base_var_enum_flag_t *flag_enum = (mca_base_var_enum_flag_t *) self;
 552     int count, ret;
 553 
 554     ret = self->get_count(self, &count);
 555     if (OPAL_SUCCESS != ret) {
 556         return ret;
 557     }
 558 
 559     if (index >= count) {
 560         return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
 561     }
 562 
 563     if (value) {
 564         *value = flag_enum->enum_flags[index].flag;
 565     }
 566 
 567     if (string_value) {
 568         *string_value = strdup (flag_enum->enum_flags[index].string);
 569     }
 570 
 571     return OPAL_SUCCESS;
 572 }
 573 
 574 static int enum_value_from_string_flag (mca_base_var_enum_t *self, const char *string_value, int *value_out) {
 575     mca_base_var_enum_flag_t *flag_enum = (mca_base_var_enum_flag_t *) self;
 576     int value, count, ret, flag;
 577     char **flags;
 578     bool is_int;
 579     char *tmp;
 580 
 581     ret = self->get_count(self, &count);
 582     if (OPAL_SUCCESS != ret) {
 583         return ret;
 584     }
 585 
 586     flags = opal_argv_split (string_value, ',');
 587     if (NULL == flags) {
 588         return OPAL_ERR_BAD_PARAM;
 589     }
 590 
 591     flag = 0;
 592 
 593     for (int i = 0 ; flags[i] ; ++i) {
 594         value = strtol (flags[i], &tmp, 0);
 595         is_int = tmp[0] == '\0';
 596 
 597         bool found = false, conflict = false;
 598         for (int j = 0 ; j < count ; ++j) {
 599             if ((is_int && (value & flag_enum->enum_flags[j].flag)) ||
 600                 0 == strcasecmp (flags[i], flag_enum->enum_flags[j].string)) {
 601                 found = true;
 602 
 603                 if (flag & flag_enum->enum_flags[j].conflicting_flag) {
 604                     conflict = true;
 605                 } else {
 606                     flag |= flag_enum->enum_flags[j].flag;
 607                 }
 608 
 609                 if (is_int) {
 610                     value &= ~flag_enum->enum_flags[j].flag;
 611                     if (0 == value) {
 612                         break;
 613                     }
 614                 } else {
 615                     break;
 616                 }
 617             }
 618         }
 619 
 620         if (!found || conflict || (is_int && value)) {
 621             opal_argv_free (flags);
 622             return !found ? OPAL_ERR_VALUE_OUT_OF_BOUNDS : OPAL_ERR_BAD_PARAM;
 623         }
 624     }
 625 
 626     opal_argv_free (flags);
 627 
 628     *value_out = flag;
 629 
 630     return OPAL_SUCCESS;
 631 }
 632 
 633 static int enum_string_from_value_flag (mca_base_var_enum_t *self, const int value, char **string_value) {
 634     mca_base_var_enum_flag_t *flag_enum = (mca_base_var_enum_flag_t *) self;
 635     int count, ret, current;
 636     char *out = NULL, *tmp;
 637 
 638     ret = self->get_count(self, &count);
 639     if (OPAL_SUCCESS != ret) {
 640         return ret;
 641     }
 642 
 643     current = value;
 644     for (int i = 0 ; i < count ; ++i) {
 645         if (!(flag_enum->enum_flags[i].flag & current)) {
 646             continue;
 647         }
 648 
 649         tmp = out;
 650 
 651         ret = opal_asprintf (&out, "%s%s%s", tmp ? tmp : "", tmp ? "," : "", flag_enum->enum_flags[i].string);
 652         free (tmp);
 653 
 654         if (0 > ret) {
 655             return OPAL_ERR_OUT_OF_RESOURCE;
 656         }
 657 
 658         if (value & flag_enum->enum_flags[i].conflicting_flag) {
 659             free (out);
 660             return OPAL_ERR_BAD_PARAM;
 661         }
 662 
 663         current &= ~flag_enum->enum_flags[i].flag;
 664     }
 665 
 666     if (current) {
 667         free (out);
 668         return OPAL_ERR_VALUE_OUT_OF_BOUNDS;
 669     }
 670 
 671     if (string_value) {
 672         *string_value = out ? out : strdup ("");
 673     } else {
 674         free (out);
 675     }
 676 
 677     return OPAL_SUCCESS;
 678 }
 679 
 680 static int enum_dump_flag (mca_base_var_enum_t *self, char **out)
 681 {
 682     mca_base_var_enum_flag_t *flag_enum = (mca_base_var_enum_flag_t *) self;
 683     char *tmp;
 684     int ret;
 685 
 686     *out = NULL;
 687 
 688     if (NULL == self) {
 689         return OPAL_ERROR;
 690     }
 691 
 692     *out = strdup ("Comma-delimited list of: ");
 693     if (NULL == *out) {
 694         return OPAL_ERR_OUT_OF_RESOURCE;
 695     }
 696 
 697     for (int i = 0; i < self->enum_value_count ; ++i) {
 698         tmp = *out;
 699 
 700         ret = opal_asprintf (out, "%s%s0x%x:\"%s\"", tmp, i ? ", " : " ", flag_enum->enum_flags[i].flag,
 701                         flag_enum->enum_flags[i].string);
 702         free (tmp);
 703         if (0 > ret) {
 704             return OPAL_ERR_OUT_OF_RESOURCE;
 705         }
 706     }
 707 
 708     return OPAL_SUCCESS;
 709 }
 710 
 711 static void mca_base_var_enum_flag_constructor (mca_base_var_enum_flag_t *enumerator)
 712 {
 713     enumerator->enum_flags = NULL;
 714     enumerator->super.get_value = enum_get_value_flag;
 715     enumerator->super.get_count = enum_get_count;
 716     enumerator->super.value_from_string = enum_value_from_string_flag;
 717     enumerator->super.string_from_value = enum_string_from_value_flag;
 718     enumerator->super.dump = enum_dump_flag;
 719     enumerator->super.enum_is_static = false;
 720     enumerator->super.enum_name = NULL;
 721 }
 722 
 723 static void mca_base_var_enum_flag_destructor (mca_base_var_enum_flag_t *enumerator)
 724 {
 725     /* release the copy of the values */
 726     if (enumerator->enum_flags) {
 727         for (int i = 0 ; i < enumerator->super.enum_value_count ; ++i) {
 728             free ((void *) enumerator->enum_flags[i].string);
 729         }
 730         free (enumerator->enum_flags);
 731     }
 732     if (NULL != enumerator->super.enum_name) {
 733         free (enumerator->super.enum_name);
 734     }
 735 }
 736 
 737 int mca_base_var_enum_register(const char *project_name, const char *framework_name,
 738                                const char *component_name, const char *enum_name,
 739                                void *storage)
 740 {
 741     int group_index;
 742 
 743     /* Developer error. Storage can not be NULL */
 744     assert (NULL != storage);
 745 
 746     /* Create a new parameter entry */
 747     group_index = mca_base_var_group_register (project_name, framework_name, component_name,
 748                                                NULL);
 749     if (-1 > group_index) {
 750         return group_index;
 751     }
 752 
 753     if (0 <= group_index) {
 754         mca_base_var_group_add_enum (group_index, storage);
 755     }
 756 
 757     return OPAL_SUCCESS;
 758 
 759     /* All done */
 760 }

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