calendarspec: make specifications with ranges reversible
authorDouglas Christman <DouglasChristman@gmail.com>
Thu, 24 Nov 2016 20:41:04 +0000 (15:41 -0500)
committerDouglas Christman <DouglasChristman@gmail.com>
Thu, 24 Nov 2016 23:40:14 +0000 (18:40 -0500)
"*-*-01..03" is now formatted as "*-*-01..03" instead of "*-*-01,02,03"

man/systemd.time.xml
src/basic/calendarspec.c
src/test/test-calendarspec.c

index fb13ea5..c182d4f 100644 (file)
@@ -273,7 +273,7 @@ Wed..Sat,Tue 12-10-15 1:2:3 → Tue..Sat 2012-10-15 01:02:03
         monday *-12-* 17:00 → Mon *-12-* 17:00:00
   Mon,Fri *-*-3,1,2 *:30:45 → Mon,Fri *-*-01,02,03 *:30:45
        12,14,13,12:20,10,30 → *-*-* 12,13,14:10,20,30:00
-            12..14:10,20,30 → *-*-* 12,13,14:10,20,30:00
+            12..14:10,20,30 → *-*-* 12..14:10,20,30:00
   mon,fri *-1/2-1,3 *:30:45 → Mon,Fri *-01/2-01,03 *:30:45
              03-05 08:05:40 → *-03-05 08:05:40
                    08:05:40 → *-*-* 08:05:40
@@ -282,7 +282,7 @@ Wed..Sat,Tue 12-10-15 1:2:3 → Tue..Sat 2012-10-15 01:02:03
            Sat,Sun 08:05:40 → Sat,Sun *-*-* 08:05:40
            2003-03-05 05:40 → 2003-03-05 05:40:00
  05:40:23.4200004/3.1700005 → 05:40:23.420000/3.170001
-             2003-02..04-05 → 2003-02,03,04-05 00:00:00
+             2003-02..04-05 → 2003-02..04-05 00:00:00
        2003-03-05 05:40 UTC → 2003-03-05 05:40:00 UTC
                  2003-03-05 → 2003-03-05 00:00:00
                       03-05 → *-03-05 00:00:00
index 4ef22df..0caa1d4 100644 (file)
@@ -255,6 +255,8 @@ static void format_weekdays(FILE *f, const CalendarSpec *c) {
 }
 
 static void format_chain(FILE *f, int space, const CalendarComponent *c, bool usec) {
+        const CalendarComponent *n, *p;
+
         assert(f);
 
         if (!c) {
@@ -279,7 +281,23 @@ static void format_chain(FILE *f, int space, const CalendarComponent *c, bool us
                         fprintf(f, "/%i.%06i", (int) (c->repeat / USEC_PER_SEC), (int) (c->repeat % USEC_PER_SEC));
         }
 
-        if (c->next) {
+        p = c;
+        for (;;) {
+                n = p->next;
+
+                if (!n || n->repeat || p->repeat)
+                        break;
+
+                if (n->value - p->value != (usec ? (int) USEC_PER_SEC : 1))
+                       break;
+
+                p = n;
+        }
+
+        if (p->value - c->value >= 2 * (usec ? (int) USEC_PER_SEC : 1)) {
+                fputs("..", f);
+                format_chain(f, space, p, usec);
+        } else if (c->next) {
                 fputc(',', f);
                 format_chain(f, space, c->next, usec);
         }
index 0bb29af..b3d1160 100644 (file)
@@ -149,8 +149,8 @@ int main(int argc, char* argv[]) {
         test_one("*-*-7 0:0:0", "*-*-07 00:00:00");
         test_one("10-15", "*-10-15 00:00:00");
         test_one("monday *-12-* 17:00", "Mon *-12-* 17:00:00");
-        test_one("Mon,Fri *-*-3,1,2 *:30:45", "Mon,Fri *-*-01,02,03 *:30:45");
-        test_one("12,14,13,12:20,10,30", "*-*-* 12,13,14:10,20,30:00");
+        test_one("Mon,Fri *-*-3,1,2 *:30:45", "Mon,Fri *-*-01..03 *:30:45");
+        test_one("12,14,13,12:20,10,30", "*-*-* 12..14:10,20,30:00");
         test_one("mon,fri *-1/2-1,3 *:30:45", "Mon,Fri *-01/2-01,03 *:30:45");
         test_one("03-05 08:05:40", "*-03-05 08:05:40");
         test_one("08:05:40", "*-*-* 08:05:40");
@@ -173,11 +173,12 @@ int main(int argc, char* argv[]) {
         test_one("2016-03-27 03:17:00.4200005", "2016-03-27 03:17:00.420001");
         test_one("2016-03-27 03:17:00/0.42", "2016-03-27 03:17:00/0.420000");
         test_one("2016-03-27 03:17:00/0.42", "2016-03-27 03:17:00/0.420000");
-        test_one("9..11,13:00,30", "*-*-* 09,10,11,13:00,30:00");
-        test_one("1..3-1..3 1..3:1..3", "*-01,02,03-01,02,03 01,02,03:01,02,03:00");
+        test_one("9..11,13:00,30", "*-*-* 09..11,13:00,30:00");
+        test_one("1..3-1..3 1..3:1..3", "*-01..03-01..03 01..03:01..03:00");
         test_one("00:00:1.125..2.125", "*-*-* 00:00:01.125000,02.125000");
-        test_one("00:00:1.0..3.8", "*-*-* 00:00:01,02,03");
-        test_one("00:00:01..03", "*-*-* 00:00:01,02,03");
+        test_one("00:00:1.0..3.8", "*-*-* 00:00:01..03");
+        test_one("00:00:01..03", "*-*-* 00:00:01..03");
+        test_one("00:00:01/2,02..03", "*-*-* 00:00:01/2,02,03");
         test_one("*-*~1 Utc", "*-*~01 00:00:00 UTC");
         test_one("*-*~05,3 ", "*-*~03,05 00:00:00");
         test_one("*-*~* 00:00:00", "*-*-* 00:00:00");