@@ -43,8 +43,42 @@ static void fix_filename(const char *prefix, const char **file)
43
43
* file = xstrdup (prefix_filename (prefix , strlen (prefix ), * file ));
44
44
}
45
45
46
+ static int opt_command_mode_error (const struct option * opt ,
47
+ const struct option * all_opts ,
48
+ int flags )
49
+ {
50
+ const struct option * that ;
51
+ struct strbuf message = STRBUF_INIT ;
52
+ struct strbuf that_name = STRBUF_INIT ;
53
+
54
+ /*
55
+ * Find the other option that was used to set the variable
56
+ * already, and report that this is not compatible with it.
57
+ */
58
+ for (that = all_opts ; that -> type != OPTION_END ; that ++ ) {
59
+ if (that == opt ||
60
+ that -> type != OPTION_CMDMODE ||
61
+ that -> value != opt -> value ||
62
+ that -> defval != * (int * )opt -> value )
63
+ continue ;
64
+
65
+ if (that -> long_name )
66
+ strbuf_addf (& that_name , "--%s" , that -> long_name );
67
+ else
68
+ strbuf_addf (& that_name , "-%c" , that -> short_name );
69
+ strbuf_addf (& message , ": incompatible with %s" , that_name .buf );
70
+ strbuf_release (& that_name );
71
+ opterror (opt , message .buf , flags );
72
+ strbuf_release (& message );
73
+ return -1 ;
74
+ }
75
+ return opterror (opt , ": incompatible with something else" , flags );
76
+ }
77
+
46
78
static int get_value (struct parse_opt_ctx_t * p ,
47
- const struct option * opt , int flags )
79
+ const struct option * opt ,
80
+ const struct option * all_opts ,
81
+ int flags )
48
82
{
49
83
const char * s , * arg ;
50
84
const int unset = flags & OPT_UNSET ;
@@ -83,6 +117,16 @@ static int get_value(struct parse_opt_ctx_t *p,
83
117
* (int * )opt -> value = unset ? 0 : opt -> defval ;
84
118
return 0 ;
85
119
120
+ case OPTION_CMDMODE :
121
+ /*
122
+ * Giving the same mode option twice, although is unnecessary,
123
+ * is not a grave error, so let it pass.
124
+ */
125
+ if (* (int * )opt -> value && * (int * )opt -> value != opt -> defval )
126
+ return opt_command_mode_error (opt , all_opts , flags );
127
+ * (int * )opt -> value = opt -> defval ;
128
+ return 0 ;
129
+
86
130
case OPTION_SET_PTR :
87
131
* (void * * )opt -> value = unset ? NULL : (void * )opt -> defval ;
88
132
return 0 ;
@@ -143,12 +187,13 @@ static int get_value(struct parse_opt_ctx_t *p,
143
187
144
188
static int parse_short_opt (struct parse_opt_ctx_t * p , const struct option * options )
145
189
{
190
+ const struct option * all_opts = options ;
146
191
const struct option * numopt = NULL ;
147
192
148
193
for (; options -> type != OPTION_END ; options ++ ) {
149
194
if (options -> short_name == * p -> opt ) {
150
195
p -> opt = p -> opt [1 ] ? p -> opt + 1 : NULL ;
151
- return get_value (p , options , OPT_SHORT );
196
+ return get_value (p , options , all_opts , OPT_SHORT );
152
197
}
153
198
154
199
/*
@@ -177,6 +222,7 @@ static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *optio
177
222
static int parse_long_opt (struct parse_opt_ctx_t * p , const char * arg ,
178
223
const struct option * options )
179
224
{
225
+ const struct option * all_opts = options ;
180
226
const char * arg_end = strchr (arg , '=' );
181
227
const struct option * abbrev_option = NULL , * ambiguous_option = NULL ;
182
228
int abbrev_flags = 0 , ambiguous_flags = 0 ;
@@ -253,7 +299,7 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
253
299
continue ;
254
300
p -> opt = rest + 1 ;
255
301
}
256
- return get_value (p , options , flags ^ opt_flags );
302
+ return get_value (p , options , all_opts , flags ^ opt_flags );
257
303
}
258
304
259
305
if (ambiguous_option )
@@ -265,18 +311,20 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
265
311
(abbrev_flags & OPT_UNSET ) ? "no-" : "" ,
266
312
abbrev_option -> long_name );
267
313
if (abbrev_option )
268
- return get_value (p , abbrev_option , abbrev_flags );
314
+ return get_value (p , abbrev_option , all_opts , abbrev_flags );
269
315
return -2 ;
270
316
}
271
317
272
318
static int parse_nodash_opt (struct parse_opt_ctx_t * p , const char * arg ,
273
319
const struct option * options )
274
320
{
321
+ const struct option * all_opts = options ;
322
+
275
323
for (; options -> type != OPTION_END ; options ++ ) {
276
324
if (!(options -> flags & PARSE_OPT_NODASH ))
277
325
continue ;
278
326
if (options -> short_name == arg [0 ] && arg [1 ] == '\0' )
279
- return get_value (p , options , OPT_SHORT );
327
+ return get_value (p , options , all_opts , OPT_SHORT );
280
328
}
281
329
return -2 ;
282
330
}
0 commit comments