File indexing completed on 2025-02-22 10:47:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #ifndef PMIX_CMD_LINE_H
0027 #define PMIX_CMD_LINE_H
0028
0029 #include "src/include/pmix_config.h"
0030
0031 #ifdef HAVE_UNISTD_H
0032 # include <unistd.h>
0033 #endif
0034 #include <ctype.h>
0035 #include <stdio.h>
0036 #include <string.h>
0037 #include <getopt.h>
0038
0039 #include "src/class/pmix_list.h"
0040 #include "src/class/pmix_object.h"
0041 #include "src/util/pmix_argv.h"
0042
0043 BEGIN_C_DECLS
0044
0045 typedef struct {
0046 pmix_list_item_t super;
0047 char *key;
0048 char **values;
0049 } pmix_cli_item_t;
0050 PMIX_CLASS_DECLARATION(pmix_cli_item_t);
0051
0052 typedef struct {
0053 pmix_object_t super;
0054 pmix_list_t instances;
0055 char **tail;
0056 } pmix_cli_result_t;
0057 PMIX_CLASS_DECLARATION(pmix_cli_result_t);
0058
0059 #define PMIX_CLI_RESULT_STATIC_INIT \
0060 { \
0061 .super = PMIX_OBJ_STATIC_INIT(pmix_object_t), \
0062 .instances = PMIX_LIST_STATIC_INIT, \
0063 .tail = NULL \
0064 }
0065
0066
0067 #define PMIX_ARG_REQD required_argument
0068 #define PMIX_ARG_NONE no_argument
0069 #define PMIX_ARG_OPTIONAL optional_argument
0070
0071
0072
0073 #define PMIX_CLI_SILENT true
0074 #define PMIX_CLI_WARN false
0075
0076
0077
0078
0079
0080
0081 #define PMIX_OPTION_DEFINE(n, a) \
0082 { \
0083 .name = (n), \
0084 .has_arg = (a), \
0085 .flag = NULL, \
0086 .val = 0 \
0087 }
0088
0089
0090
0091
0092
0093
0094 #define PMIX_OPTION_SHORT_DEFINE(n, a, c) \
0095 { \
0096 .name = (n), \
0097 .has_arg = (a), \
0098 .flag = NULL, \
0099 .val = (c) \
0100 }
0101
0102 #define PMIX_OPTION_END {0, 0, 0, 0}
0103
0104
0105
0106
0107 #define PMIX_CLI_HELP "help"
0108 #define PMIX_CLI_VERSION "version"
0109 #define PMIX_CLI_VERBOSE "verbose"
0110 #define PMIX_CLI_PMIXMCA "pmixmca"
0111
0112
0113 #define PMIX_CLI_SYS_SERVER_FIRST "system-server-first"
0114 #define PMIX_CLI_SYSTEM_SERVER "system-server"
0115 #define PMIX_CLI_SYS_SERVER_ONLY "system-server-only"
0116 #define PMIX_CLI_DO_NOT_CONNECT "do-not-connect"
0117 #define PMIX_CLI_WAIT_TO_CONNECT "wait-to-connect"
0118 #define PMIX_CLI_NUM_CONNECT_RETRIES "num-connect-retries"
0119 #define PMIX_CLI_PID "pid"
0120 #define PMIX_CLI_NAMESPACE "namespace"
0121 #define PMIX_CLI_NSPACE "nspace"
0122 #define PMIX_CLI_URI "uri"
0123 #define PMIX_CLI_TIMEOUT "timeout"
0124 #define PMIX_CLI_TMPDIR "tmpdir"
0125 #define PMIX_CLI_CONNECTION_ORDER "connect-order"
0126 #define PMIX_CLI_SYS_CONTROLLER "system-controller"
0127
0128
0129 #define PMIX_CLI_REQ_ID "request-id"
0130 #define PMIX_CLI_QUEUE "queue"
0131 #define PMIX_CLI_RESOURCES "resources"
0132 #define PMIX_CLI_NODES "nodes"
0133 #define PMIX_CLI_IMAGE "image"
0134 #define PMIX_CLI_EXCLUDE "exclude"
0135 #define PMIX_CLI_WAIT_ALL_NODES "wait-all-nodes"
0136 #define PMIX_CLI_NODELIST "nodelist"
0137 #define PMIX_CLI_UID "uid"
0138 #define PMIX_CLI_GID "gid"
0139 #define PMIX_CLI_TIME "time"
0140 #define PMIX_CLI_SIGNAL "signal"
0141 #define PMIX_CLI_SHARE "share"
0142 #define PMIX_CLI_EXTEND "extend"
0143 #define PMIX_CLI_SHRINK "shrink"
0144 #define PMIX_CLI_NO_SHELL "no-shell"
0145 #define PMIX_CLI_BEGIN "begin"
0146 #define PMIX_CLI_IMMEDIATE "immediate"
0147 #define PMIX_CLI_DEPENDENCY "dependency"
0148 #define PMIX_CLI_DO_NOT_WAIT "do-not-wait"
0149
0150
0151 #define PMIX_CLI_PAUSE "pause"
0152 #define PMIX_CLI_RESUME "resume"
0153 #define PMIX_CLI_CANCEL "cancel"
0154 #define PMIX_CLI_KILL "kill"
0155 #define PMIX_CLI_RESTART "restart"
0156 #define PMIX_CLI_CHKPT "checkpoint"
0157 #define PMIX_CLI_TARGETS "targets"
0158 #define PMIX_CLI_TERMINATE "terminate"
0159 #define PMIX_CLI_PSET_NAME "pset"
0160
0161 typedef void (*pmix_cmd_line_store_fn_t)(const char *name, const char *option,
0162 pmix_cli_result_t *results);
0163
0164 PMIX_EXPORT int pmix_cmd_line_parse(char **argv, char *shorts,
0165 struct option myoptions[],
0166 pmix_cmd_line_store_fn_t storefn,
0167 pmix_cli_result_t *results,
0168 char *helpfile);
0169
0170 static inline pmix_cli_item_t* pmix_cmd_line_get_param(pmix_cli_result_t *results,
0171 const char *key)
0172 {
0173 pmix_cli_item_t *opt;
0174
0175 PMIX_LIST_FOREACH(opt, &results->instances, pmix_cli_item_t) {
0176 if (0 == strcmp(opt->key, key)) {
0177 return opt;
0178 }
0179 }
0180 return NULL;
0181 }
0182
0183 static inline bool pmix_cmd_line_is_taken(pmix_cli_result_t *results,
0184 const char *key)
0185 {
0186 if (NULL == pmix_cmd_line_get_param(results, key)) {
0187 return false;
0188 }
0189 return true;
0190 }
0191
0192 static inline int pmix_cmd_line_get_ninsts(pmix_cli_result_t *results,
0193 const char *key)
0194 {
0195 pmix_cli_item_t *opt;
0196
0197 opt = pmix_cmd_line_get_param(results, key);
0198 if (NULL == opt) {
0199 return 0;
0200 }
0201 return PMIx_Argv_count(opt->values);
0202 }
0203
0204 static inline char* pmix_cmd_line_get_nth_instance(pmix_cli_result_t *results,
0205 const char *key, int idx)
0206 {
0207 pmix_cli_item_t *opt;
0208 int ninst;
0209
0210 opt = pmix_cmd_line_get_param(results, key);
0211 if (NULL == opt) {
0212 return NULL;
0213 }
0214 ninst = PMIx_Argv_count(opt->values);
0215 if (ninst < idx) {
0216 return NULL;
0217 }
0218 return opt->values[idx];
0219 }
0220
0221
0222
0223
0224
0225 static inline bool pmix_check_cli_option(char *a, char *b)
0226 {
0227 size_t len1, len2, len, n;
0228 char **asplit, **bsplit;
0229 int match;
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239 if (NULL != strchr(b, '-') ||
0240 NULL != strchr(a, '-')) {
0241 asplit = PMIx_Argv_split(a, '-');
0242 bsplit = PMIx_Argv_split(b, '-');
0243 if (PMIx_Argv_count(asplit) > PMIx_Argv_count(bsplit)) {
0244 PMIx_Argv_free(asplit);
0245 PMIx_Argv_free(bsplit);
0246 return false;
0247 }
0248 match = 0;
0249 for (n=0; NULL != asplit[n] && NULL != bsplit[n]; n++) {
0250 len1 = strlen(asplit[n]);
0251 len2 = strlen(bsplit[n]);
0252 len = len1 < len2 ? len1 : len2;
0253 if (0 == strncasecmp(asplit[n], bsplit[n], len)) {
0254 ++match;
0255 } else {
0256 PMIx_Argv_free(asplit);
0257 PMIx_Argv_free(bsplit);
0258 return false;
0259 }
0260 }
0261 PMIx_Argv_free(asplit);
0262 PMIx_Argv_free(bsplit);
0263 if (match == PMIx_Argv_count(asplit)) {
0264
0265 return true;
0266 }
0267 return false;
0268 }
0269
0270
0271
0272 len1 = strlen(a);
0273 len2 = strlen(b);
0274 len = (len1 < len2) ? len1 : len2;
0275 if (0 == strncasecmp(a, b, len)) {
0276 return true;
0277 }
0278
0279 return false;
0280 }
0281
0282 #define PMIX_CHECK_CLI_OPTION(a, b) \
0283 pmix_check_cli_option(a, b)
0284
0285 static inline unsigned int pmix_convert_string_to_time(const char *t)
0286 {
0287 char **tmp = PMIx_Argv_split(t, ':');
0288 int sz = PMIx_Argv_count(tmp);
0289 unsigned int tm;
0290
0291
0292
0293
0294 tm = strtoul(tmp[sz-1], NULL, 10);
0295 if (0 <= (sz-2) && NULL != tmp[sz-2]) {
0296 tm += 60 * strtoul(tmp[sz-2], NULL, 10);
0297 }
0298 if (0 <= (sz-3) && NULL != tmp[sz-3]) {
0299 tm += 60 * 60 * strtoul(tmp[sz-3], NULL, 10);
0300 }
0301 if (0 <= (sz-4) && NULL != tmp[sz-4]) {
0302 tm += 24 * 60 * 60 * strtoul(tmp[sz-4], NULL, 10);
0303 }
0304 PMIx_Argv_free(tmp);
0305 return tm;
0306 }
0307
0308 #define PMIX_CONVERT_TIME(s) \
0309 pmix_convert_string_to_time(s)
0310
0311
0312 #define PMIX_CLI_DEBUG_LIST(r) \
0313 do { \
0314 pmix_cli_item_t *_c; \
0315 char *_tail; \
0316 pmix_output(0, "\n[%s:%s:%d]", __FILE__, __func__, __LINE__); \
0317 PMIX_LIST_FOREACH(_c, &(r)->instances, pmix_cli_item_t) { \
0318 pmix_output(0, "KEY: %s", _c->key); \
0319 if (NULL != _c->values) { \
0320 for (int _n=0; NULL != _c->values[_n]; _n++) { \
0321 pmix_output(0, " VAL[%d]: %s", _n, _c->values[_n]); \
0322 } \
0323 } \
0324 } \
0325 _tail = PMIx_Argv_join((r)->tail, ' '); \
0326 pmix_output(0, "TAIL: %s", _tail); \
0327 free(_tail); \
0328 pmix_output(0, "\n"); \
0329 } while(0)
0330
0331 #define PMIX_CLI_REMOVE_DEPRECATED(r, o) \
0332 do { \
0333 pmix_list_remove_item(&(r)->instances, &(o)->super); \
0334 PMIX_RELEASE(o); \
0335 } while(0)
0336 END_C_DECLS
0337
0338 #endif