1/*
2 * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * or in the "license" file accompanying this file. This file is distributed
11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 * express or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15#include <aws/common/command_line_parser.h>
16
17int aws_cli_optind = 1;
18int aws_cli_opterr = -1;
19int aws_cli_optopt = 0;
20
21const char *aws_cli_optarg = NULL;
22
23static const struct aws_cli_option *s_find_option_from_char(
24 const struct aws_cli_option *longopts,
25 char search_for,
26 int *longindex) {
27 int index = 0;
28 const struct aws_cli_option *option = &longopts[index];
29
30 while (option->val != 0 || option->name) {
31 if (option->val == search_for) {
32 if (longindex) {
33 *longindex = index;
34 }
35 return option;
36 }
37
38 option = &longopts[++index];
39 }
40
41 return NULL;
42}
43
44static const struct aws_cli_option *s_find_option_from_c_str(
45 const struct aws_cli_option *longopts,
46 const char *search_for,
47 int *longindex) {
48 int index = 0;
49 const struct aws_cli_option *option = &longopts[index];
50
51 while (option->name || option->val != 0) {
52 if (option->name) {
53 if (option->name && !strcmp(search_for, option->name)) {
54 if (longindex) {
55 *longindex = index;
56 }
57 return option;
58 }
59 }
60
61 option = &longopts[++index];
62 }
63
64 return NULL;
65}
66
67int aws_cli_getopt_long(
68 int argc,
69 char *const argv[],
70 const char *optstring,
71 const struct aws_cli_option *longopts,
72 int *longindex) {
73 aws_cli_optarg = NULL;
74
75 if (aws_cli_optind >= argc) {
76 return -1;
77 }
78
79 char first_char = argv[aws_cli_optind][0];
80 char second_char = argv[aws_cli_optind][1];
81 char *option_start = NULL;
82 const struct aws_cli_option *option = NULL;
83
84 if (first_char == '-' && second_char != '-') {
85 option_start = &argv[aws_cli_optind][1];
86 option = s_find_option_from_char(longopts, *option_start, longindex);
87 } else if (first_char == '-' && second_char == '-') {
88 option_start = &argv[aws_cli_optind][2];
89 option = s_find_option_from_c_str(longopts, option_start, longindex);
90 } else {
91 return -1;
92 }
93
94 aws_cli_optind++;
95 if (option) {
96 bool has_arg = false;
97 if (option) {
98 char *opt_value = memchr(optstring, option->val, strlen(optstring));
99 if (!opt_value) {
100 return '?';
101 }
102
103 if (opt_value[1] == ':') {
104 has_arg = true;
105 }
106 }
107
108 if (has_arg) {
109 if (aws_cli_optind >= argc - 1) {
110 return '?';
111 }
112
113 aws_cli_optarg = argv[aws_cli_optind++];
114 }
115
116 return option->val;
117 }
118
119 return '?';
120}
121