replace: use OPT_CMDMODE to handle modes

By using OPT_CMDMODE, the mutual exclusion between modes is taken care of for us. It also makes it easy for us to maintain a single variable with the mode, which makes its intent more clear. We can use a single switch() to make sure we have covered all of the modes. This ends up breaking even in code size, but the win will be much bigger when we start adding more modes. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Apr 26, 2014 at 22:00 UTC 70c7bd6dafc83eee7bf76d33d12027224d80f20d
1 file changed +25 -24
builtin/replace.c
+25 -24
@@ -168,11 +168,17 @@ static int replace_object(const char *object_ref, const char *replace_ref,
168
169 int cmd_replace(int argc, const char **argv, const char *prefix)
170 {
171 - int list = 0, delete = 0, force = 0;
171 + int force = 0;
172 const char *format = NULL;
173 + enum {
174 + MODE_UNSPECIFIED = 0,
175 + MODE_LIST,
176 + MODE_DELETE,
177 + MODE_REPLACE
178 + } cmdmode = MODE_UNSPECIFIED;
179 struct option options[] = {
174 - OPT_BOOL('l', "list", &list, N_("list replace refs")),
175 - OPT_BOOL('d', "delete", &delete, N_("delete replace refs")),
180 + OPT_CMDMODE('l', "list", &cmdmode, N_("list replace refs"), MODE_LIST),
181 + OPT_CMDMODE('d', "delete", &cmdmode, N_("delete replace refs"), MODE_DELETE),
182 OPT_BOOL('f', "force", &force, N_("replace the ref if it exists")),
183 OPT_STRING(0, "format", &format, N_("format"), N_("use this format")),
184 OPT_END()
@@ -182,42 +188,37 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
188
189 argc = parse_options(argc, argv, prefix, options, git_replace_usage, 0);
190
185 - if (!list && !delete)
186 - if (!argc)
187 - list = 1;
191 + if (!cmdmode)
192 + cmdmode = argc ? MODE_REPLACE : MODE_LIST;
193
189 - if (list && delete)
190 - usage_msg_opt("-l and -d cannot be used together",
191 - git_replace_usage, options);
192 -
193 - if (format && !list)
194 + if (format && cmdmode != MODE_LIST)
195 usage_msg_opt("--format cannot be used when not listing",
196 git_replace_usage, options);
197
197 - if (force && (list || delete))
198 - usage_msg_opt("-f cannot be used with -d or -l",
198 + if (force && cmdmode != MODE_REPLACE)
199 + usage_msg_opt("-f only makes sense when writing a replacement",
200 git_replace_usage, options);
201
201 - /* Delete refs */
202 - if (delete) {
202 + switch (cmdmode) {
203 + case MODE_DELETE:
204 if (argc < 1)
205 usage_msg_opt("-d needs at least one argument",
206 git_replace_usage, options);
207 return for_each_replace_name(argv, delete_replace_ref);
207 - }
208
209 - /* Replace object */
210 - if (!list && argc) {
209 + case MODE_REPLACE:
210 if (argc != 2)
211 usage_msg_opt("bad number of arguments",
212 git_replace_usage, options);
213 return replace_object(argv[0], argv[1], force);
215 - }
214
217 - /* List refs, even if "list" is not set */
218 - if (argc > 1)
219 - usage_msg_opt("only one pattern can be given with -l",
220 - git_replace_usage, options);
215 + case MODE_LIST:
216 + if (argc > 1)
217 + usage_msg_opt("only one pattern can be given with -l",
218 + git_replace_usage, options);
219 + return list_replace_refs(argv[0], format);
220
222 - return list_replace_refs(argv[0], format);
221 + default:
222 + die("BUG: invalid cmdmode %d", (int)cmdmode);
223 + }
224 }