Welcome to little lamb

Code » slicd » commit 061d519

parser: Add prefix '!' to invert matching values

author Olivier Brunel
2016-05-16 17:44:36 UTC
committer Olivier Brunel
2016-05-16 17:44:36 UTC
parent 5025762fb2a49e952ae28a9130df55fb580b4066

parser: Add prefix '!' to invert matching values

INSTALL +1 -1
doc/slicd-parser.pod +8 -3
src/include/slicd/job.h +5 -0
src/libslicd/slicd_add_job_from_cronline.c +12 -0
src/libslicd/slicd_job.c +23 -0

diff --git a/INSTALL b/INSTALL
index 0eac6f9..4ea26ff 100644
--- a/INSTALL
+++ b/INSTALL
@@ -6,7 +6,7 @@ Build Instructions
 
   - A POSIX-compliant C development environment
   - GNU make version 4.0 or later
-  - skalibs version 2.3.9.0 or later: http://skarnet.org/software/skalibs/
+  - skalibs version 2.3.11.0 or later: http://skarnet.org/software/skalibs/
 
 
 * Standard usage
diff --git a/doc/slicd-parser.pod b/doc/slicd-parser.pod
index 73eee22..9511ae0 100644
--- a/doc/slicd-parser.pod
+++ b/doc/slicd-parser.pod
@@ -81,9 +81,6 @@ The time-and-date fields are, in order:
     month               1-12 (or names, see below)
     day of the week     0-6 (0=Sunday, 1=Monday, etc; or names, see below)
 
-The hour field can have its value prefixed with a dollar sign ($) to enable the
-special DST mode for the job; See B<slicd-sched>(1) for more.
-
 Range of values are allowed, separating two values with a hyphen (-). The
 specified range is inclusive, and must always have the lower value first.
 
@@ -112,6 +109,14 @@ names can also be used. Names are always the first 3 letters of the month/day
 Names can be used in place of a single value or within ranges. You can for
 example use "jun-aug", "6-Aug" or "6-7,Aug" indifferently for the 'month' field.
 
+Each field can have its value prefixed with an exclamation point (!) in order to
+invert it. For example, using "!15,20" as value for days will mean every day
+but the 15th and 20th; the invertion being applied to the entire list of values.
+
+The hour field can also have its value prefixed with a dollar sign ($) to enable
+the special DST mode for the job; See B<slicd-sched>(1) for more. Note that when
+also using the invertion flag (!), the dollar sign should come first.
+
 System crontabs have an extra field for the username to run under.
 
 The final field, or rest of the line, will be used as command line. See
diff --git a/src/include/slicd/job.h b/src/include/slicd/job.h
index 1984cf4..1d410ce 100644
--- a/src/include/slicd/job.h
+++ b/src/include/slicd/job.h
@@ -66,6 +66,11 @@ extern int slicd_job_clearset       (slicd_job_t    *job,
 #define slicd_job_set(job,field,from,to) \
     slicd_job_clearset (job, field, from, to, 1)
 
+extern int slicd_job_swap           (slicd_job_t    *job,
+                                     slicd_field_t   field,
+                                     int             from,
+                                     int             to);
+
 extern int slicd_job_first          (slicd_job_t    *job,
                                      slicd_field_t   field,
                                      int             from,
diff --git a/src/libslicd/slicd_add_job_from_cronline.c b/src/libslicd/slicd_add_job_from_cronline.c
index d952539..63a3b75 100644
--- a/src/libslicd/slicd_add_job_from_cronline.c
+++ b/src/libslicd/slicd_add_job_from_cronline.c
@@ -85,11 +85,19 @@ parse_interval (slicd_job_t *job, slicd_field_t field, const char **s)
     int min = _slicd_fields[field].adjust;
     int max = min + _slicd_fields[field].max;
     int from, to, step;
+    int swap = 0;
 
     if (field == SLICD_HOURS && **s == '$')
     {
         slicd_job_set_dst_special (job, 1);
         ++*s;
+
+    }
+
+    if (**s == '!')
+    {
+        swap = 1;
+        ++*s;
     }
 
 again:
@@ -165,6 +173,10 @@ again:
     }
     skip_blanks (*s);
 
+    if (swap)
+        slicd_job_swap (job, field, _slicd_fields[field].adjust,
+                _slicd_fields[field].adjust + _slicd_fields[field].max);
+
     return 0;
 }
 
diff --git a/src/libslicd/slicd_job.c b/src/libslicd/slicd_job.c
index 380bd27..f81fe86 100644
--- a/src/libslicd/slicd_job.c
+++ b/src/libslicd/slicd_job.c
@@ -105,6 +105,29 @@ slicd_job_clearset (slicd_job_t    *job,
     return 0;
 }
 
+int
+slicd_job_swap (slicd_job_t    *job,
+                slicd_field_t   field,
+                int             from,
+                int             to)
+{
+    assert (job != NULL);
+    assert (field <= _SLICD_NB_FIELD);
+
+    if (_slicd_fields[field].adjust)
+    {
+        --from;
+        --to;
+    }
+    ensure_in_range (field, from);
+    ensure_in_range (field, to);
+    if (to < from)
+        return -SLICD_ERR_INVALID_RANGE;
+
+    bitarray_not (job->bits, _slicd_fields[field].offset + from, to - from + 1);
+    return 0;
+}
+
 int
 slicd_job_first (slicd_job_t    *job,
                  slicd_field_t   field,