| 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 | |