/* * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2008 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2008 Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2008 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2016-2020 Intel, Inc. All rights reserved. * Copyright (c) 2021-2022 Nanook Consulting. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "pmix_config.h" #include "pmix_common.h" #include #include #include #ifdef HAVE_UNISTD_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #include "src/util/pmix_argv.h" #include "src/util/pmix_output.h" #include "src/util/pmix_printf.h" #include "src/util/pmix_parse_options.h" void pmix_util_parse_range_options(char *inp, char ***output) { char **r1 = NULL, **r2 = NULL; int i, vint; int start, end, n; char nstr[32]; char *input, *bang; bool bang_option = false; /* protect against null input */ if (NULL == inp) { return; } /* protect the provided input */ input = strdup(inp); /* check for the special '!' operator */ if (NULL != (bang = strchr(input, '!'))) { bang_option = true; *bang = '\0'; } /* split on commas */ r1 = PMIx_Argv_split(input, ','); /* for each resulting element, check for range */ for (i = 0; i < PMIx_Argv_count(r1); i++) { r2 = PMIx_Argv_split(r1[i], '-'); if (1 < PMIx_Argv_count(r2)) { /* given range - get start and end */ start = strtol(r2[0], NULL, 10); end = strtol(r2[1], NULL, 10); } else { /* check for wildcard - have to do this here because * the -1 would have been caught in the split */ vint = strtol(r1[i], NULL, 10); if (-1 == vint) { PMIx_Argv_free(*output); *output = NULL; PMIx_Argv_append_nosize(output, "-1"); PMIx_Argv_free(r2); goto cleanup; } start = strtol(r2[0], NULL, 10); end = start; } for (n = start; n <= end; n++) { pmix_snprintf(nstr, 32, "%d", n); PMIx_Argv_append_nosize(output, nstr); } PMIx_Argv_free(r2); } cleanup: if (bang_option) { PMIx_Argv_append_nosize(output, "BANG"); } free(input); PMIx_Argv_free(r1); } void pmix_util_get_ranges(char *inp, char ***startpts, char ***endpts) { char **r1 = NULL, **r2 = NULL; int i; char *input; /* protect against null input */ if (NULL == inp) { return; } /* protect the provided input */ input = strdup(inp); /* split on commas */ r1 = PMIx_Argv_split(input, ','); /* for each resulting element, check for range */ for (i = 0; i < PMIx_Argv_count(r1); i++) { r2 = PMIx_Argv_split(r1[i], '-'); if (2 == PMIx_Argv_count(r2)) { /* given range - get start and end */ PMIx_Argv_append_nosize(startpts, r2[0]); PMIx_Argv_append_nosize(endpts, r2[1]); } else if (1 == PMIx_Argv_count(r2)) { /* only one value provided, so it is both the start * and the end */ PMIx_Argv_append_nosize(startpts, r2[0]); PMIx_Argv_append_nosize(endpts, r2[0]); } else { /* no idea how to parse this */ pmix_output(0, "Unknown parse error on string: %s(%s)", inp, r1[i]); } PMIx_Argv_free(r2); } free(input); PMIx_Argv_free(r1); }