commit e70a20477cde4b6ef4fd6608b5197a66d8891a69
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Tue Dec 28 12:55:19 2021 +0100

    complain about --noop/--no-* conflicts
    
    REFMAIL: 20211130124527.t3u7s4fyy57gm...@fastmail.com

 src/config.c | 26 ++++++++++++++++++++------
 src/main.c   | 13 +++++++------
 src/mbsync.1 |  2 ++
 src/sync.h   |  6 ++++++
 4 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/src/config.c b/src/config.c
index 71b0b798..8aa9f2e7 100644
--- a/src/config.c
+++ b/src/config.c
@@ -213,7 +213,9 @@ getopt_helper( conffile_t *cfile, int *cops, channel_conf_t 
*conf )
                                conf->ops[F] |= OP_FLAGS;
                        } else if (!strcasecmp( "All", arg ) || !strcasecmp( 
"Full", arg )) {
                                *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",
                                       cfile->file, cfile->line, arg );
                                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
                                                conf->ops[N] |= op;
                                                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",
                                                       cfile->file, 
cfile->line, boxOps[i].name, arg );
                                                cfile->err = 1;
@@ -300,7 +304,6 @@ channel_str( const char *chan_name )
        return buf;
 }
 
-/* XXX - this does not detect None conflicts ... */
 int
 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];
        if (ops[F] & XOP_HAVE_TYPE) {
                if (aops & OP_MASK_TYPE) {  // PullNew, etc.
-                       if (aops & cops & OP_MASK_TYPE) {  // Overlapping New, 
etc.
+                       if (ops[F] & XOP_TYPE_NOOP) {
                          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 ) );
                                return 1;
                        }
@@ -321,15 +329,17 @@ merge_ops( int cops, int ops[], const char *chan_name )
                        ops[N] |= cops & OP_MASK_TYPE;
                        if (cops & XOP_PULL) {
                                if (ops[N] & OP_MASK_TYPE)
-                                       goto cfl;
+                                       goto ovl;
                                ops[N] |= OP_MASK_TYPE;
                        }
                        if (cops & XOP_PUSH) {
                                if (ops[F] & OP_MASK_TYPE)
-                                       goto cfl;
+                                       goto ovl;
                                ops[F] |= OP_MASK_TYPE;
                        }
                } 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))
                                cops |= OP_MASK_TYPE;
                        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++) {
                op = boxOps[i].op;
                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) {
                                error( "Redundant %s options specified %s.\n", 
boxOps[i].name, channel_str( chan_name ) );
                                return 1;
diff --git a/src/main.c b/src/main.c
index ffcae888..1c3524d6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -238,15 +238,15 @@ main( int argc, char **argv )
                                        op = OP_EXPUNGE|XOP_HAVE_EXPUNGE;
                                        goto lcop;
                                } 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" )) {
-                                       mvars->ops[F] |= XOP_HAVE_CREATE;
+                                       mvars->ops[F] |= XOP_CREATE_NOOP | 
XOP_HAVE_CREATE;
                                } 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" )) {
                                        mvars->ops[F] |= XOP_HAVE_TYPE | 
XOP_PULL | XOP_PUSH;
                                } 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 )) {
                                        op = XOP_PULL;
                                  lcac:
@@ -335,10 +335,11 @@ main( int argc, char **argv )
                        goto cop;
                case 'F':
                        cops |= XOP_PULL|XOP_PUSH;
-                       FALLTHROUGH
-               case '0':
                        mvars->ops[F] |= XOP_HAVE_TYPE;
                        break;
+               case '0':
+                       mvars->ops[F] |= XOP_TYPE_NOOP | XOP_HAVE_TYPE;
+                       break;
                case 'n':
                case 'd':
                case 'f':
diff --git a/src/mbsync.1 b/src/mbsync.1
index ee54129a..242a9018 100644
--- a/src/mbsync.1
+++ b/src/mbsync.1
@@ -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.
 "\fBSync\fR\ \fBPullNew\fR\ \fBPull\fR" and
 "\fBSync\fR\ \fBPullNew\fR\ \fBDelete\fR\ \fBPush\fR" induce error messages.
+.br
+\fBNone\fR may not be combined with any other operation.
 .
 .TP
 \fBCreate\fR {\fBNone\fR|\fBFar\fR|\fBNear\fR|\fBBoth\fR}
diff --git a/src/sync.h b/src/sync.h
index af31ad3b..f69f172b 100644
--- a/src/sync.h
+++ b/src/sync.h
@@ -30,6 +30,12 @@ BIT_ENUM(
        XOP_HAVE_EXPUNGE,
        XOP_HAVE_CREATE,
        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


_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to