mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-16 06:18:47 +02:00
Implement OMITFUNC clause in REM command.
This commit is contained in:
35
src/dorem.c
35
src/dorem.c
@@ -145,6 +145,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
trig->priority = DefaultPrio;
|
||||
trig->sched[0] = 0;
|
||||
trig->warn[0] = 0;
|
||||
trig->omitfunc[0] = 0;
|
||||
trig->tag[0] = 0;
|
||||
trig->passthru[0] = 0;
|
||||
tim->ttime = NO_TIME;
|
||||
@@ -266,6 +267,13 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
|
||||
return OK;
|
||||
|
||||
case T_OmitFunc:
|
||||
r=ParseToken(s, &buf);
|
||||
if (r) return r;
|
||||
StrnCpy(trig->omitfunc, DBufValue(&buf), VAR_NAME_LEN);
|
||||
DBufFree(&buf);
|
||||
break;
|
||||
|
||||
case T_Warn:
|
||||
r=ParseToken(s, &buf);
|
||||
if(r) return r;
|
||||
@@ -551,7 +559,7 @@ static int ParseScanFrom(ParsePtr s, Trigger *t, int type)
|
||||
int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
|
||||
{
|
||||
int r, y, m, d;
|
||||
char PrioExpr[25];
|
||||
char PrioExpr[VAR_NAME_LEN+25];
|
||||
char tmpBuf[64];
|
||||
DynamicBuffer buf, calRow;
|
||||
DynamicBuffer pre_buf;
|
||||
@@ -795,9 +803,19 @@ int ShouldTriggerReminder(Trigger *t, TimeTrig *tim, int jul)
|
||||
jul = jul + t->delta;
|
||||
else {
|
||||
r = t->delta;
|
||||
while(r && jul > JulianToday) {
|
||||
int iter = 0;
|
||||
int max = MaxSatIter;
|
||||
if (max < r*2) max = r*2;
|
||||
while(iter++ < max) {
|
||||
if (!r || (jul <= JulianToday)) {
|
||||
break;
|
||||
}
|
||||
jul--;
|
||||
if (!IsOmitted(jul, t->localomit)) r--;
|
||||
if (!IsOmitted(jul, t->localomit, t->omitfunc)) r--;
|
||||
}
|
||||
if (iter > max) {
|
||||
/* TODO: Somehow communicate error back to caller!! */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -996,10 +1014,17 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int jul)
|
||||
if (JulianToday + v.v.val == jul) return 1;
|
||||
} else {
|
||||
int j = jul;
|
||||
while (v.v.val) {
|
||||
int iter = 0;
|
||||
int max = MaxSatIter;
|
||||
if (max < v.v.val * 2) max = v.v.val*2;
|
||||
while(iter++ <= max) {
|
||||
j--;
|
||||
if (!IsOmitted(j, t->localomit)) v.v.val++;
|
||||
if (!IsOmitted(j, t->localomit, t->omitfunc)) v.v.val++;
|
||||
if (!v.v.val) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (iter > max) return 0;
|
||||
if (j == JulianToday) return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1302,7 +1302,7 @@ static int FIsomitted(void)
|
||||
{
|
||||
if (!HASDATE(ARG(0))) return E_BAD_TYPE;
|
||||
RetVal.type = INT_TYPE;
|
||||
RetVal.v.val = IsOmitted(DATEPART(ARG(0)), 0);
|
||||
RetVal.v.val = IsOmitted(DATEPART(ARG(0)), 0, NULL);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -2478,7 +2478,7 @@ FNonomitted(void)
|
||||
|
||||
ans = 0;
|
||||
while (d1 < d2) {
|
||||
if (!IsOmitted(d1++, localomit)) {
|
||||
if (!IsOmitted(d1++, localomit, NULL)) {
|
||||
ans++;
|
||||
}
|
||||
}
|
||||
|
||||
20
src/omit.c
20
src/omit.c
@@ -20,6 +20,7 @@
|
||||
#include "protos.h"
|
||||
#include "globals.h"
|
||||
#include "err.h"
|
||||
#include "expr.h"
|
||||
|
||||
static int BexistsIntArray (int array[], int num, int key);
|
||||
static void InsertIntoSortedArray (int *array, int num, int key);
|
||||
@@ -180,7 +181,7 @@ int PopOmitContext(ParsePtr p)
|
||||
/* Return non-zero if date is OMITted, zero if it is not. */
|
||||
/* */
|
||||
/***************************************************************/
|
||||
int IsOmitted(int jul, int localomit)
|
||||
int IsOmitted(int jul, int localomit, char const *omitfunc)
|
||||
{
|
||||
int y, m, d;
|
||||
|
||||
@@ -195,6 +196,23 @@ int IsOmitted(int jul, int localomit)
|
||||
if (BexistsIntArray(PartialOmitArray, NumPartialOmits, (m << 5) + d))
|
||||
return 1;
|
||||
|
||||
/* Is it omitted because of omitfunc? */
|
||||
if (omitfunc && *omitfunc && UserFuncExists(omitfunc)) {
|
||||
char expr[VAR_NAME_LEN + 32];
|
||||
char const *s;
|
||||
int r;
|
||||
Value v;
|
||||
sprintf(expr, "%s('%04d-%02d-%02d')",
|
||||
omitfunc, y, m, d);
|
||||
s = expr;
|
||||
r = EvalExpr(&s, &v);
|
||||
if (!r) {
|
||||
if (v.type == INT_TYPE && v.v.val != 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Not omitted */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ int DoClear (ParsePtr p);
|
||||
int DestroyOmitContexts (void);
|
||||
int PushOmitContext (ParsePtr p);
|
||||
int PopOmitContext (ParsePtr p);
|
||||
int IsOmitted (int jul, int localomit);
|
||||
int IsOmitted (int jul, int localomit, char const *omitfunc);
|
||||
int DoOmit (ParsePtr p);
|
||||
int QueueReminder (ParsePtr p, Trigger *trig, TimeTrig *tim, char const *sched);
|
||||
void HandleQueuedReminders (void);
|
||||
|
||||
@@ -74,6 +74,7 @@ Token TokArray[] = {
|
||||
{ "november", 3, T_Month, 10 },
|
||||
{ "october", 3, T_Month, 9 },
|
||||
{ "omit", 3, T_Omit, 0 },
|
||||
{ "omitfunc", 8, T_OmitFunc, 0 },
|
||||
{ "once", 3, T_Once, 0 },
|
||||
{ "pop-omit-context", 3, T_Pop, 0 },
|
||||
{ "preserve", 8, T_Preserve, 0 },
|
||||
|
||||
@@ -294,8 +294,19 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
|
||||
/* Next: If it's an "AFTER"-type skip, back up
|
||||
until we're at the start of a block of holidays */
|
||||
if (trig->skip == AFTER_SKIP)
|
||||
while (IsOmitted(start-1, trig->localomit)) start--;
|
||||
if (trig->skip == AFTER_SKIP) {
|
||||
int iter = 0;
|
||||
while (iter++ <= MaxSatIter) {
|
||||
if (!IsOmitted(start-1, trig->localomit, trig->omitfunc)) {
|
||||
break;
|
||||
}
|
||||
start--;
|
||||
}
|
||||
if (iter > MaxSatIter) {
|
||||
/* omitfunc must have returned "true" too often */
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the next simple trigger */
|
||||
simple = NextSimpleTrig(start, trig, err);
|
||||
@@ -309,12 +320,23 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
/* If there's a BACK, back up... */
|
||||
if (trig->back != NO_BACK) {
|
||||
mod = trig->back;
|
||||
if (mod < 0) simple += mod;
|
||||
else
|
||||
while(mod) {
|
||||
simple--;
|
||||
if (!IsOmitted(simple, trig->localomit)) mod--;
|
||||
if (mod < 0) {
|
||||
simple += mod;
|
||||
}
|
||||
else {
|
||||
int iter = 0;
|
||||
int max = MaxSatIter;
|
||||
if (max < mod*2) {
|
||||
max = mod*2;
|
||||
}
|
||||
while(iter++ <= max) {
|
||||
if (!mod) {
|
||||
break;
|
||||
}
|
||||
simple--;
|
||||
if (!IsOmitted(simple, trig->localomit, trig->omitfunc)) mod--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's a REP, calculate the next occurrence */
|
||||
@@ -327,12 +349,32 @@ static int GetNextTriggerDate(Trigger *trig, int start, int *err, int *nextstart
|
||||
}
|
||||
|
||||
/* If it's a "BEFORE"-type skip, back up */
|
||||
if (trig->skip == BEFORE_SKIP)
|
||||
while(IsOmitted(simple, trig->localomit)) simple--;
|
||||
if (trig->skip == BEFORE_SKIP) {
|
||||
int iter = 0;
|
||||
while(iter++ <= MaxSatIter) {
|
||||
if (!IsOmitted(simple, trig->localomit, trig->omitfunc)) {
|
||||
break;
|
||||
}
|
||||
simple--;
|
||||
}
|
||||
if (iter > MaxSatIter) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
/* If it's an "AFTER"-type skip, jump ahead */
|
||||
if (trig->skip == AFTER_SKIP)
|
||||
while (IsOmitted(simple, trig->localomit)) simple++;
|
||||
if (trig->skip == AFTER_SKIP) {
|
||||
int iter = 0;
|
||||
while (iter++ <= MaxSatIter) {
|
||||
if (!IsOmitted(simple, trig->localomit, trig->omitfunc)) {
|
||||
break;
|
||||
}
|
||||
simple++;
|
||||
}
|
||||
if (iter > MaxSatIter) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the date */
|
||||
return simple;
|
||||
@@ -373,8 +415,8 @@ int ComputeTrigger(int today, Trigger *trig, int *err)
|
||||
*err = E_REP_FULSPEC;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
while (nattempts++ < TRIG_ATTEMPTS) {
|
||||
result = GetNextTriggerDate(trig, start, err, &nextstart);
|
||||
|
||||
@@ -390,7 +432,7 @@ int ComputeTrigger(int today, Trigger *trig, int *err)
|
||||
|
||||
/* If result is >= today, great! */
|
||||
if (result >= today &&
|
||||
(trig->skip != SKIP_SKIP || !IsOmitted(result, trig->localomit))) {
|
||||
(trig->skip != SKIP_SKIP || !IsOmitted(result, trig->localomit, trig->omitfunc))) {
|
||||
LastTriggerDate = result; /* Save in global var */
|
||||
LastTrigValid = 1;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
@@ -421,7 +463,7 @@ int ComputeTrigger(int today, Trigger *trig, int *err)
|
||||
}
|
||||
|
||||
if (trig->skip == SKIP_SKIP &&
|
||||
IsOmitted(result, trig->localomit) &&
|
||||
IsOmitted(result, trig->localomit, trig->omitfunc) &&
|
||||
nextstart <= start &&
|
||||
result >= start) {
|
||||
nextstart = result + 1;
|
||||
|
||||
@@ -56,6 +56,7 @@ typedef struct {
|
||||
int priority;
|
||||
char sched[VAR_NAME_LEN+1]; /* Scheduling function */
|
||||
char warn[VAR_NAME_LEN+1]; /* Warning function */
|
||||
char omitfunc[VAR_NAME_LEN+1]; /* OMITFUNC function */
|
||||
char tag[TAG_LEN+1];
|
||||
char passthru[PASSTHRU_LEN+1];
|
||||
} Trigger;
|
||||
@@ -148,7 +149,8 @@ enum TokTypes
|
||||
T_Warn,
|
||||
T_Tag,
|
||||
T_Duration,
|
||||
T_LongTime
|
||||
T_LongTime,
|
||||
T_OmitFunc
|
||||
};
|
||||
|
||||
/* The structure of a token */
|
||||
|
||||
@@ -638,7 +638,7 @@ set a057 value("a05"+"6")
|
||||
"a05" + "6" => "a056"
|
||||
value("a056") => "SDFJHSDF KSJDFH KJSDFH KSJDFH"
|
||||
set a058 version()
|
||||
version() => "03.01.06"
|
||||
version() => "03.01.05"
|
||||
set a059 wkday(today())
|
||||
today() => 1991-02-16
|
||||
wkday(1991-02-16) => "Saturday"
|
||||
@@ -779,7 +779,7 @@ dump
|
||||
a048 "foo"
|
||||
a067 "INT"
|
||||
a039 "February"
|
||||
a058 "03.01.06"
|
||||
a058 "03.01.05"
|
||||
a077 "1992 92
|
||||
"
|
||||
a049 21
|
||||
|
||||
Reference in New Issue
Block a user