| OLD | NEW |
| (Empty) |
| 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | |
| 2 * Use of this source code is governed by a BSD-style license that can be | |
| 3 * found in the LICENSE file. | |
| 4 * | |
| 5 * Update GPT attribute bits. | |
| 6 */ | |
| 7 #include <getopt.h> | |
| 8 #include <stdint.h> | |
| 9 #include <stdio.h> | |
| 10 #include <stdlib.h> | |
| 11 #include "cgpt.h" | |
| 12 #include "utility.h" | |
| 13 | |
| 14 /* Special validator. Set 'integer' as 1 to indicate the option is present. */ | |
| 15 int AssignTrue(const char *argument, void *pointer, void *integer) { | |
| 16 *(int*)integer = 1; | |
| 17 return CGPT_OK; | |
| 18 } | |
| 19 | |
| 20 /* Special validator. Copy string to 'parsed' with max 'valid_range' bytes. */ | |
| 21 int CopyString(const char *argument, void *max_len, void *dst) { | |
| 22 Memcpy(dst, argument, (intptr_t)max_len); | |
| 23 return CGPT_OK; | |
| 24 } | |
| 25 | |
| 26 /* Validator function. Returns 1 if 'argument' is between 'max' and 'min' | |
| 27 * in 'valid_range'. */ | |
| 28 int InNumberRange(const char *argument, void *valid_range, void *parsed) { | |
| 29 struct number_range *range = valid_range; | |
| 30 char *endptr; | |
| 31 int number; | |
| 32 | |
| 33 number = strtol(argument, &endptr, 10); | |
| 34 if (*endptr) { | |
| 35 printf("[ERROR] argument '%s' is not a number.\n", argument); | |
| 36 return CGPT_FAILED; | |
| 37 } | |
| 38 | |
| 39 if (range) { | |
| 40 if (number < range->min) { | |
| 41 printf("[ERROR] argument is too small (min is %d, but you gave: %d).\n", | |
| 42 range->min, number); | |
| 43 return CGPT_FAILED; | |
| 44 } else if (number > range->max) { | |
| 45 printf("[ERROR] argument is too large (max is %d, but you gave: %d).\n", | |
| 46 range->max, number); | |
| 47 return CGPT_FAILED; | |
| 48 } else { | |
| 49 if (parsed) *(int*)parsed = number; | |
| 50 return CGPT_OK; | |
| 51 } | |
| 52 } else { | |
| 53 /* no range to check, assign integer. */ | |
| 54 if (parsed) *(int*)parsed = number; | |
| 55 return CGPT_OK; | |
| 56 } | |
| 57 } | |
| 58 | |
| 59 void ShowOptions(const struct option *opts, | |
| 60 const struct option_details *details, | |
| 61 const int num) { | |
| 62 int i; | |
| 63 for (i = 0; i < num; ++i) { | |
| 64 char buf[32]; | |
| 65 if (!opts[i].name) break; | |
| 66 snprintf(buf, sizeof(buf), "--%s %s", opts[i].name, | |
| 67 opts[i].has_arg ? "ARG" : ""); | |
| 68 printf(" %-20s (-%c) %s\n", buf, opts[i].val, details[i].comment); | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 int HandleOptions(const int argc, | |
| 73 char *const *argv, | |
| 74 const char *short_options, | |
| 75 const int option_count, | |
| 76 const struct option *options, | |
| 77 const struct option_details *details) { | |
| 78 while (1) { | |
| 79 int index; | |
| 80 int option; | |
| 81 | |
| 82 /* We assume every short option has an entry in long option (for validator). | |
| 83 * So please add corresponding entry in attribute_options if you add short | |
| 84 * option. */ | |
| 85 index = NOT_INITED; | |
| 86 option = getopt_long(argc, argv, short_options, options, &index); | |
| 87 if (option == -1) { | |
| 88 break; | |
| 89 } else if (option == 0) { | |
| 90 /* option 'val' has been saved in 'flag'. We do nothing here. */ | |
| 91 } else if (option == ':') { | |
| 92 printf("[ERROR] Missing parameter for option.\n"); | |
| 93 ShowOptions(options, details, option_count); | |
| 94 return CGPT_FAILED; | |
| 95 } else if (option == '?') { | |
| 96 printf("[ERROR] unknown option name: %s\n", argv[optind - 1]); | |
| 97 ShowOptions(options, details, option_count); | |
| 98 return CGPT_FAILED; | |
| 99 } else { | |
| 100 /* Short option doesn't update 'index'. We search whole array to find out | |
| 101 * the corresponding long option. */ | |
| 102 if (index == NOT_INITED) { | |
| 103 for (index = 0; index < option_count; ++index) | |
| 104 if (option == options[index].val) break; | |
| 105 /* assumes every short option has a corresponding long option. */ | |
| 106 assert(index < option_count); | |
| 107 } | |
| 108 assert(option == options[index].val); | |
| 109 | |
| 110 /* Calls validator if an argument is provided. */ | |
| 111 if (details[index].validator && | |
| 112 CGPT_OK != details[index].validator( | |
| 113 optarg ? argv[optind - 1] : 0, | |
| 114 details[index].valid_range, | |
| 115 details[index].parsed)) { | |
| 116 printf("[ERROR] The argument of '%s' is invalid.\n", | |
| 117 options[index].name); | |
| 118 return CGPT_FAILED; | |
| 119 } | |
| 120 } | |
| 121 } | |
| 122 return CGPT_OK; | |
| 123 } | |
| 124 | |
| 125 int OpenDriveInLastArgument(const int argc, | |
| 126 char *const *argv, | |
| 127 struct drive *drive) { | |
| 128 if (optind != (argc - 1)) { | |
| 129 printf("[ERROR] One (and only one) non-option argument is required.\n"); | |
| 130 return CGPT_FAILED; | |
| 131 } | |
| 132 | |
| 133 return DriveOpen(argv[optind], drive); | |
| 134 } | |
| OLD | NEW |