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 | |
17 | int aws_cli_optind = 1; |
18 | int aws_cli_opterr = -1; |
19 | int aws_cli_optopt = 0; |
20 | |
21 | const char *aws_cli_optarg = NULL; |
22 | |
23 | static 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 | |
44 | static 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 | |
67 | int 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 | |