From 3eacec0e630181c41372b408872ba818dc1adfde Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Fri, 1 Jun 2012 10:33:58 +0100 Subject: [PATCH] Added string processing capability to cron code. --- src/cron.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cron.h | 15 +++++++--- 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/src/cron.c b/src/cron.c index 1bb6e553..dbd55834 100644 --- a/src/cron.c +++ b/src/cron.c @@ -1,5 +1,93 @@ #include "cron.h" #include +#include + +static int _field_to_string + ( char *out, uint64_t field, uint64_t mask, int offset ) +{ + int i, cnt = 0, first = 1, start = -1; + field &= mask; + + /* Star */ + if ( field == mask ) + return sprintf(out, "*"); + + for ( i = 0; i < 64; i++ ) { + int b = (field >> i) & 0x1; + if ( !b & start != -1 ) { + if (!first) + cnt += sprintf(out+cnt, ","); + first = 0; + cnt += sprintf(out+cnt, "%d", start + offset); + if (i != (start+1)) + cnt += sprintf(out+cnt, "-%d", (i - 1) + offset); + start = -1; + } else if ( b & start == -1 ) + start = i; + } + + return cnt; +} + +static int _field_from_string + ( const char *str, uint64_t *field, uint64_t mask, int offset ) +{ + int i = 0, j = 0, sn = -1, en = -1; + *field = 0; + while ( str[i] != '\0' ) { + if ( str[i] == '*' ) *field = mask; + else if ( str[i] == ',' || str[i] == ' ' ) { + sscanf(str+j, "%d", sn == -1 ? &sn : &en); + if (en == -1) en = sn; + while (sn <= en) { + *field |= (0x1LL << (sn - offset)); + sn++; + } + j = i+1; + sn = -1; + en = -1; + if (str[i] == ' ') break; + } else if ( str[i] == '-' ) { + sscanf(str+j, "%d", &sn); + j = i+1; + en = 64; + } + i++; + } + if (str[i] == ' ') i++; + *field &= mask; + return i; +} + +void cron_to_string ( cron_t *cron, char *str ) +{ + int i = 0; + i += _field_to_string(str+i, cron->min, CRON_MIN_MASK, 0); + i += sprintf(str+i, " "); + i += _field_to_string(str+i, cron->hour, CRON_HOUR_MASK, 0); + i += sprintf(str+i, " "); + i += _field_to_string(str+i, cron->dom, CRON_DOM_MASK, 1); + i += sprintf(str+i, " "); + i += _field_to_string(str+i, cron->mon, CRON_MON_MASK, 1); + i += sprintf(str+i, " "); + i += _field_to_string(str+i, cron->dow, CRON_DOW_MASK, 0); +} + +void cron_from_string ( cron_t *cron, const char *str ) +{ + int i = 0; + uint64_t u64; + i += _field_from_string(str+i, &u64, CRON_MIN_MASK, 0); + cron->min = u64; + i += _field_from_string(str+i, &u64, CRON_HOUR_MASK, 0); + cron->hour = (uint32_t)u64; + i += _field_from_string(str+i, &u64, CRON_DOM_MASK, 1); + cron->dom = (uint32_t)u64; + i += _field_from_string(str+i, &u64, CRON_MON_MASK, 1); + cron->mon = (uint16_t)u64; + i += _field_from_string(str+i, &u64, CRON_DOW_MASK, 0); + cron->dow = (uint8_t)u64; +} int cron_is_time ( cron_t *cron ) { diff --git a/src/cron.h b/src/cron.h index 9724c84d..0456b714 100644 --- a/src/cron.h +++ b/src/cron.h @@ -5,6 +5,12 @@ #include #include "htsmsg.h" +#define CRON_MIN_MASK 0x0FFFFFFFFFFFFFFFLL // 60 bits +#define CRON_HOUR_MASK 0x00FFFFFF // 24 bits +#define CRON_DOM_MASK 0x7FFFFFFF // 31 bits +#define CRON_MON_MASK 0x0FFF // 12 bits +#define CRON_DOW_MASK 0xFF // 8 bits (allow 0/7 for sunday) + typedef struct cron { uint64_t min; ///< Minutes @@ -14,9 +20,10 @@ typedef struct cron uint8_t dow; ///< Day of week } cron_t; -void cron_set_string ( cron_t *cron, const char *str ); -int cron_is_time ( cron_t *cron ); -void cron_pack ( cron_t *cron, htsmsg_t *msg ); -void cron_unpack ( cron_t *cron, htsmsg_t *msg ); +void cron_to_string ( cron_t *cron, char *str ); +void cron_from_string ( cron_t *cron, const char *str ); +int cron_is_time ( cron_t *cron ); +void cron_pack ( cron_t *cron, htsmsg_t *msg ); +void cron_unpack ( cron_t *cron, htsmsg_t *msg ); #endif /* __CRON_H__ */