1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/common/byte_buf.h>
#include <aws/common/command_line_parser.h>
#include <ctype.h>
int aws_cli_optind = 1;
int aws_cli_opterr = -1;
int aws_cli_optopt = 0;
bool aws_cli_on_arg = false;
const char *aws_cli_optarg = NULL;
const char *aws_cli_positional_arg = NULL;
static const struct aws_cli_option *s_find_option_from_char(
const struct aws_cli_option *longopts,
char search_for,
int *longindex) {
int index = 0;
const struct aws_cli_option *option = &longopts[index];
while (option->val != 0 || option->name) {
if (option->val == search_for) {
if (longindex) {
*longindex = index;
}
return option;
}
option = &longopts[++index];
}
return NULL;
}
AWS_COMMON_API void aws_cli_reset_state(void) {
aws_cli_optind = 1;
aws_cli_opterr = -1;
aws_cli_optopt = 0;
aws_cli_on_arg = false;
aws_cli_optarg = NULL;
aws_cli_positional_arg = NULL;
}
static const struct aws_cli_option *s_find_option_from_c_str(
const struct aws_cli_option *longopts,
const char *search_for,
int *longindex) {
int index = 0;
const struct aws_cli_option *option = &longopts[index];
while (option->name || option->val != 0) {
if (option->name && !strcmp(search_for, option->name)) {
if (longindex) {
*longindex = index;
}
return option;
}
option = &longopts[++index];
}
return NULL;
}
int aws_cli_getopt_long(
int argc,
char *const argv[],
const char *optstring,
const struct aws_cli_option *longopts,
int *longindex) {
aws_cli_optarg = NULL;
if (aws_cli_optind >= argc) {
return -1;
}
char first_char = argv[aws_cli_optind][0];
char second_char = argv[aws_cli_optind][1];
char *option_start = NULL;
const struct aws_cli_option *option = NULL;
bool positional_arg_encountered = false;
if (first_char == '-' && second_char != '-') {
aws_cli_on_arg = true;
positional_arg_encountered = false;
option_start = &argv[aws_cli_optind][1];
option = s_find_option_from_char(longopts, *option_start, longindex);
} else if (first_char == '-' && second_char == '-') {
aws_cli_on_arg = true;
positional_arg_encountered = false;
option_start = &argv[aws_cli_optind][2];
option = s_find_option_from_c_str(longopts, option_start, longindex);
} else {
if (!aws_cli_on_arg) {
aws_cli_positional_arg = argv[aws_cli_optind];
positional_arg_encountered = true;
} else {
aws_cli_on_arg = false;
aws_cli_positional_arg = NULL;
}
}
aws_cli_optind++;
if (option) {
bool has_arg = false;
aws_cli_on_arg = false;
aws_cli_positional_arg = NULL;
char *opt_value = memchr(optstring, option->val, strlen(optstring) + 1);
if (!opt_value) {
return '?';
}
if (opt_value[1] == ':') {
has_arg = true;
}
if (has_arg) {
if (aws_cli_optind >= argc) {
return '?';
}
aws_cli_optarg = argv[aws_cli_optind++];
}
return option->val;
}
/* start of text to indicate we just have a text argument. */
return positional_arg_encountered ? 0x02 : '?';
}
int aws_cli_dispatch_on_subcommand(
int argc,
char *const argv[],
struct aws_cli_subcommand_dispatch *dispatch_table,
int table_length,
void *user_data) {
if (argc >= 2) {
struct aws_byte_cursor arg_name = aws_byte_cursor_from_c_str(argv[1]);
for (int i = 0; i < table_length; ++i) {
struct aws_byte_cursor cmd_name = aws_byte_cursor_from_c_str(dispatch_table[i].command_name);
if (aws_byte_cursor_eq_ignore_case(&arg_name, &cmd_name)) {
return dispatch_table[i].subcommand_fn(argc - 1, &argv[1], (const char *)arg_name.ptr, user_data);
}
}
return aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
}
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
}
|