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 |