1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 #include "hydra_arg.h"
7 #include "hydra_err.h"
8 
match_arg(char *** argv_p,struct HYD_arg_match_table * match_table)9 static HYD_status match_arg(char ***argv_p, struct HYD_arg_match_table *match_table)
10 {
11     struct HYD_arg_match_table *m;
12     char *arg, *val;
13     HYD_status status = HYD_SUCCESS;
14 
15     arg = **argv_p;
16     while (*arg == '-') /* Remove leading dashes */
17         arg++;
18 
19     /* If arg is of the form foo=bar, we separate it out as two
20      * arguments */
21     for (val = arg; *val && *val != '='; val++);
22     if (*val == '=') {
23         /* Found an '='; use the rest of the argument as a separate
24          * argument */
25         **argv_p = val + 1;
26     } else {
27         /* Move to the next argument */
28         (*argv_p)++;
29     }
30     *val = 0;   /* close out key */
31 
32     m = match_table;
33     while (m->handler_fn) {
34         if (!strcasecmp(arg, m->arg)) {
35             if (**argv_p &&
36                 (!strcmp(**argv_p, "-h") || !strcmp(**argv_p, "-help") ||
37                  !strcmp(**argv_p, "--help"))) {
38                 if (m->help_fn == NULL) {
39                     HYD_ERR_SETANDJUMP(status, HYD_ERR_INTERNAL, "No help message available\n");
40                 } else {
41                     m->help_fn();
42                     exit(0);
43                 }
44             }
45 
46             status = m->handler_fn(arg, argv_p);
47             HYD_ERR_POP(status, "match handler returned error\n");
48             break;
49         }
50         m++;
51     }
52 
53     if (m->handler_fn == NULL)
54         HYD_ERR_SETANDJUMP(status, HYD_ERR_INTERNAL, "unrecognized argument %s\n", arg);
55 
56   fn_exit:
57     return status;
58 
59   fn_fail:
60     goto fn_exit;
61 }
62 
HYD_arg_parse_array(char *** argv,struct HYD_arg_match_table * match_table)63 HYD_status HYD_arg_parse_array(char ***argv, struct HYD_arg_match_table *match_table)
64 {
65     HYD_status status = HYD_SUCCESS;
66 
67     while (**argv && ***argv == '-') {
68         status = match_arg(argv, match_table);
69         HYD_ERR_POP(status, "argument matching returned error\n");
70     }
71 
72     HYD_FUNC_ENTER();
73 
74   fn_exit:
75     HYD_FUNC_EXIT();
76     return status;
77 
78   fn_fail:
79     goto fn_exit;
80 }
81 
HYD_arg_set_str(char * arg,char ** var,const char * val)82 HYD_status HYD_arg_set_str(char *arg, char **var, const char *val)
83 {
84     HYD_status status = HYD_SUCCESS;
85 
86     HYD_ERR_CHKANDJUMP(status, *var, HYD_ERR_INTERNAL, "duplicate setting: %s\n", arg);
87 
88     if (val == NULL)
89         HYD_ERR_SETANDJUMP(status, HYD_ERR_INTERNAL, "cannot assign NULL object\n");
90 
91     *var = MPL_strdup(val);
92 
93   fn_exit:
94     return status;
95 
96   fn_fail:
97     goto fn_exit;
98 }
99 
HYD_arg_set_int(char * arg,int * var,int val)100 HYD_status HYD_arg_set_int(char *arg, int *var, int val)
101 {
102     HYD_status status = HYD_SUCCESS;
103 
104     HYD_ERR_CHKANDJUMP(status, *var != -1, HYD_ERR_INTERNAL, "duplicate setting: %s\n", arg);
105 
106     *var = val;
107 
108   fn_exit:
109     return status;
110 
111   fn_fail:
112     goto fn_exit;
113 }
114