complain about --noop/--no-* conflicts

REFMAIL: 20211130124527.t3u7s4fyy57gmfzc@fastmail.com
This commit is contained in:
Oswald Buddenhagen 2021-12-28 12:55:19 +01:00
parent be6e07c5c9
commit e70a20477c
4 changed files with 35 additions and 12 deletions

View File

@ -213,7 +213,9 @@ getopt_helper( conffile_t *cfile, int *cops, channel_conf_t *conf )
conf->ops[F] |= OP_FLAGS; conf->ops[F] |= OP_FLAGS;
} else if (!strcasecmp( "All", arg ) || !strcasecmp( "Full", arg )) { } else if (!strcasecmp( "All", arg ) || !strcasecmp( "Full", arg )) {
*cops |= XOP_PULL|XOP_PUSH; *cops |= XOP_PULL|XOP_PUSH;
} else if (strcasecmp( "None", arg ) && strcasecmp( "Noop", arg )) { } else if (!strcasecmp( "None", arg ) || !strcasecmp( "Noop", arg )) {
conf->ops[F] |= XOP_TYPE_NOOP;
} else {
error( "%s:%d: invalid Sync arg '%s'\n", error( "%s:%d: invalid Sync arg '%s'\n",
cfile->file, cfile->line, arg ); cfile->file, cfile->line, arg );
cfile->err = 1; cfile->err = 1;
@ -246,7 +248,9 @@ getopt_helper( conffile_t *cfile, int *cops, channel_conf_t *conf )
} else if (!strcasecmp( "Slave", arg )) { // Pre-1.4 legacy } else if (!strcasecmp( "Slave", arg )) { // Pre-1.4 legacy
conf->ops[N] |= op; conf->ops[N] |= op;
cfile->ms_warn = 1; cfile->ms_warn = 1;
} else if (strcasecmp( "None", arg )) { } else if (!strcasecmp( "None", arg )) {
conf->ops[F] |= op * (XOP_EXPUNGE_NOOP / OP_EXPUNGE);
} else {
error( "%s:%d: invalid %s arg '%s'\n", error( "%s:%d: invalid %s arg '%s'\n",
cfile->file, cfile->line, boxOps[i].name, arg ); cfile->file, cfile->line, boxOps[i].name, arg );
cfile->err = 1; cfile->err = 1;
@ -300,7 +304,6 @@ channel_str( const char *chan_name )
return buf; return buf;
} }
/* XXX - this does not detect None conflicts ... */
int int
merge_ops( int cops, int ops[], const char *chan_name ) merge_ops( int cops, int ops[], const char *chan_name )
{ {
@ -310,8 +313,13 @@ merge_ops( int cops, int ops[], const char *chan_name )
aops = ops[F] | ops[N]; aops = ops[F] | ops[N];
if (ops[F] & XOP_HAVE_TYPE) { if (ops[F] & XOP_HAVE_TYPE) {
if (aops & OP_MASK_TYPE) { // PullNew, etc. if (aops & OP_MASK_TYPE) { // PullNew, etc.
if (aops & cops & OP_MASK_TYPE) { // Overlapping New, etc. if (ops[F] & XOP_TYPE_NOOP) {
cfl: cfl:
error( "Conflicting Sync options specified %s.\n", channel_str( chan_name ) );
return 1;
}
if (aops & cops & OP_MASK_TYPE) { // Overlapping New, etc.
ovl:
error( "Redundant Sync options specified %s.\n", channel_str( chan_name ) ); error( "Redundant Sync options specified %s.\n", channel_str( chan_name ) );
return 1; return 1;
} }
@ -321,15 +329,17 @@ merge_ops( int cops, int ops[], const char *chan_name )
ops[N] |= cops & OP_MASK_TYPE; ops[N] |= cops & OP_MASK_TYPE;
if (cops & XOP_PULL) { if (cops & XOP_PULL) {
if (ops[N] & OP_MASK_TYPE) if (ops[N] & OP_MASK_TYPE)
goto cfl; goto ovl;
ops[N] |= OP_MASK_TYPE; ops[N] |= OP_MASK_TYPE;
} }
if (cops & XOP_PUSH) { if (cops & XOP_PUSH) {
if (ops[F] & OP_MASK_TYPE) if (ops[F] & OP_MASK_TYPE)
goto cfl; goto ovl;
ops[F] |= OP_MASK_TYPE; ops[F] |= OP_MASK_TYPE;
} }
} else if (cops & (OP_MASK_TYPE | XOP_MASK_DIR)) { // Pull New, etc. } else if (cops & (OP_MASK_TYPE | XOP_MASK_DIR)) { // Pull New, etc.
if (ops[F] & XOP_TYPE_NOOP)
goto cfl;
if (!(cops & OP_MASK_TYPE)) if (!(cops & OP_MASK_TYPE))
cops |= OP_MASK_TYPE; cops |= OP_MASK_TYPE;
else if (!(cops & XOP_MASK_DIR)) else if (!(cops & XOP_MASK_DIR))
@ -343,6 +353,10 @@ merge_ops( int cops, int ops[], const char *chan_name )
for (i = 0; i < as(boxOps); i++) { for (i = 0; i < as(boxOps); i++) {
op = boxOps[i].op; op = boxOps[i].op;
if (ops[F] & (op * (XOP_HAVE_EXPUNGE / OP_EXPUNGE))) { if (ops[F] & (op * (XOP_HAVE_EXPUNGE / OP_EXPUNGE))) {
if (((aops | cops) & op) && (ops[F] & (op * (XOP_EXPUNGE_NOOP / OP_EXPUNGE)))) {
error( "Conflicting %s options specified %s.\n", boxOps[i].name, channel_str( chan_name ) );
return 1;
}
if (aops & cops & op) { if (aops & cops & op) {
error( "Redundant %s options specified %s.\n", boxOps[i].name, channel_str( chan_name ) ); error( "Redundant %s options specified %s.\n", boxOps[i].name, channel_str( chan_name ) );
return 1; return 1;

View File

@ -238,15 +238,15 @@ main( int argc, char **argv )
op = OP_EXPUNGE|XOP_HAVE_EXPUNGE; op = OP_EXPUNGE|XOP_HAVE_EXPUNGE;
goto lcop; goto lcop;
} else if (!strcmp( opt, "no-expunge" )) { } else if (!strcmp( opt, "no-expunge" )) {
mvars->ops[F] |= XOP_HAVE_EXPUNGE; mvars->ops[F] |= XOP_EXPUNGE_NOOP | XOP_HAVE_EXPUNGE;
} else if (!strcmp( opt, "no-create" )) { } else if (!strcmp( opt, "no-create" )) {
mvars->ops[F] |= XOP_HAVE_CREATE; mvars->ops[F] |= XOP_CREATE_NOOP | XOP_HAVE_CREATE;
} else if (!strcmp( opt, "no-remove" )) { } else if (!strcmp( opt, "no-remove" )) {
mvars->ops[F] |= XOP_HAVE_REMOVE; mvars->ops[F] |= XOP_REMOVE_NOOP | XOP_HAVE_REMOVE;
} else if (!strcmp( opt, "full" )) { } else if (!strcmp( opt, "full" )) {
mvars->ops[F] |= XOP_HAVE_TYPE | XOP_PULL | XOP_PUSH; mvars->ops[F] |= XOP_HAVE_TYPE | XOP_PULL | XOP_PUSH;
} else if (!strcmp( opt, "noop" )) { } else if (!strcmp( opt, "noop" )) {
mvars->ops[F] |= XOP_HAVE_TYPE; mvars->ops[F] |= XOP_TYPE_NOOP | XOP_HAVE_TYPE;
} else if (starts_with( opt, -1, "pull", 4 )) { } else if (starts_with( opt, -1, "pull", 4 )) {
op = XOP_PULL; op = XOP_PULL;
lcac: lcac:
@ -335,10 +335,11 @@ main( int argc, char **argv )
goto cop; goto cop;
case 'F': case 'F':
cops |= XOP_PULL|XOP_PUSH; cops |= XOP_PULL|XOP_PUSH;
FALLTHROUGH
case '0':
mvars->ops[F] |= XOP_HAVE_TYPE; mvars->ops[F] |= XOP_HAVE_TYPE;
break; break;
case '0':
mvars->ops[F] |= XOP_TYPE_NOOP | XOP_HAVE_TYPE;
break;
case 'n': case 'n':
case 'd': case 'd':
case 'f': case 'f':

View File

@ -624,6 +624,8 @@ changes from the near side to the far side.
Note that it is not allowed to assert a cell in two ways, e.g. Note that it is not allowed to assert a cell in two ways, e.g.
"\fBSync\fR\ \fBPullNew\fR\ \fBPull\fR" and "\fBSync\fR\ \fBPullNew\fR\ \fBPull\fR" and
"\fBSync\fR\ \fBPullNew\fR\ \fBDelete\fR\ \fBPush\fR" induce error messages. "\fBSync\fR\ \fBPullNew\fR\ \fBDelete\fR\ \fBPush\fR" induce error messages.
.br
\fBNone\fR may not be combined with any other operation.
. .
.TP .TP
\fBCreate\fR {\fBNone\fR|\fBFar\fR|\fBNear\fR|\fBBoth\fR} \fBCreate\fR {\fBNone\fR|\fBFar\fR|\fBNear\fR|\fBBoth\fR}

View File

@ -30,6 +30,12 @@ BIT_ENUM(
XOP_HAVE_EXPUNGE, XOP_HAVE_EXPUNGE,
XOP_HAVE_CREATE, XOP_HAVE_CREATE,
XOP_HAVE_REMOVE, XOP_HAVE_REMOVE,
// ... until here.
XOP_TYPE_NOOP,
// ... and here again from scratch.
XOP_EXPUNGE_NOOP,
XOP_CREATE_NOOP,
XOP_REMOVE_NOOP,
) )
#define OP_MASK_TYPE (OP_NEW | OP_RENEW | OP_DELETE | OP_FLAGS) // Asserted in the target side ops #define OP_MASK_TYPE (OP_NEW | OP_RENEW | OP_DELETE | OP_FLAGS) // Asserted in the target side ops