加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
time_rec.c 22.59 KB
一键复制 编辑 原始数据 按行查看 历史
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mem/mem.h"
#include "mem/shm_mem.h"
#include "time_rec.h"
#ifndef USE_YWEEK_U
#ifndef USE_YWEEK_V
#ifndef USE_YWEEK_W
#define USE_YWEEK_W /* Monday system */
#endif
#endif
#endif
#ifdef USE_YWEEK_U
#define SUN_WEEK(t) (int)(((t)->tm_yday + 7 - \
((t)->tm_wday)) / 7)
#else
#define MON_WEEK(t) (int)(((t)->tm_yday + 7 - \
((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7)
#endif
#define ac_get_wday_yr(t) (int)((t)->tm_yday/7)
#define ac_get_wday_mr(t) (int)(((t)->tm_mday-1)/7)
#define REC_ERR -1
#define REC_MATCH 0
#define REC_NOMATCH 1
#define _IS_SET(x) (((x)>0)?1:0)
#define _D(c) ((c) -'0')
static inline int strz2int(char *_bp)
{
int _v;
char *_p;
if(!_bp)
return 0;
_v = 0;
_p = _bp;
while(*_p && *_p>='0' && *_p<='9')
{
_v += *_p - '0';
_p++;
}
return _v;
}
static inline char* trim(char* _s)
{
int len;
char* end;
/* Null pointer, there is nothing to do */
if (!_s) return _s;
/* Remove spaces and tabs from the beginning of string */
while ((*_s == ' ') || (*_s == '\t')) _s++;
len = strlen(_s);
end = _s + len - 1;
/* Remove trailing spaces and tabs */
while ((*end == ' ') || (*end == '\t')) end--;
if (end != (_s + len - 1)) {
*(end+1) = '\0';
}
return _s;
}
int ac_tm_fill(ac_tm_p _atp, struct tm* _tm)
{
if(!_atp || !_tm)
return -1;
_atp->t.tm_sec = _tm->tm_sec; /* seconds */
_atp->t.tm_min = _tm->tm_min; /* minutes */
_atp->t.tm_hour = _tm->tm_hour; /* hours */
_atp->t.tm_mday = _tm->tm_mday; /* day of the month */
_atp->t.tm_mon = _tm->tm_mon; /* month */
_atp->t.tm_year = _tm->tm_year; /* year */
_atp->t.tm_wday = _tm->tm_wday; /* day of the week */
_atp->t.tm_yday = _tm->tm_yday; /* day in the year */
_atp->t.tm_isdst = _tm->tm_isdst; /* daylight saving time */
_atp->mweek = ac_get_mweek(_tm);
_atp->yweek = ac_get_yweek(_tm);
_atp->ywday = ac_get_wday_yr(_tm);
_atp->mwday = ac_get_wday_mr(_tm);
return 0;
}
int ac_tm_set_time(ac_tm_p _atp, time_t _t)
{
if(!_atp)
return -1;
memset( _atp, 0, sizeof(ac_tm_t));
_atp->time = _t;
return ac_tm_fill(_atp, localtime(&_t));
}
int ac_get_mweek(struct tm* _tm)
{
if(!_tm)
return -1;
#ifdef USE_YWEEK_U
return ((_tm->tm_mday-1)/7 + (7-_tm->tm_wday+(_tm->tm_mday-1)%7)/7);
#else
return ((_tm->tm_mday-1)/7 + (7-(6+_tm->tm_wday)%7+(_tm->tm_mday-1)%7)/7);
#endif
}
int ac_get_yweek(struct tm* _tm)
{
int week = -1;
#ifdef USE_YWEEK_V
int days;
#endif
if(!_tm)
return -1;
#ifdef USE_YWEEK_U
week = SUN_WEEK(_tm);
#else
week = MON_WEEK(_tm);
#endif
#ifdef USE_YWEEK_V
days = ((_tm->tm_yday + 7 - (_tm->tm_wday ? _tm->tm_wday-1 : 6)) % 7);
if(days >= 4)
week++;
else
if(week == 0)
week = 53;
#endif
return week;
}
int ac_get_wkst(void)
{
#ifdef USE_YWEEK_U
return 0;
#else
return 1;
#endif
}
int ac_tm_reset(ac_tm_p _atp)
{
if(!_atp)
return -1;
memset(_atp, 0, sizeof(ac_tm_t));
return 0;
}
static ac_maxval_p ac_get_maxval(ac_tm_p _atp)
{
static ac_maxval_t _amp;
struct tm _tm;
int _v;
/* the number of the days in the year */
_amp.yday = 365 + is_leap_year(_atp->t.tm_year+1900);
/* the number of the days in the month */
switch(_atp->t.tm_mon)
{
case 1:
if(_amp.yday == 366)
_amp.mday = 29;
else
_amp.mday = 28;
break;
case 3: case 5: case 8: case 10:
_amp.mday = 30;
break;
default:
_amp.mday = 31;
}
/* maximum occurrences of a week day in the year */
memset(&_tm, 0, sizeof(struct tm));
_tm.tm_year = _atp->t.tm_year;
_tm.tm_mon = 11;
_tm.tm_mday = 31;
mktime(&_tm);
_v = 0;
if(_atp->t.tm_wday > _tm.tm_wday)
_v = _atp->t.tm_wday - _tm.tm_wday + 1;
else
_v = _tm.tm_wday - _atp->t.tm_wday;
_amp.ywday = (int)((_tm.tm_yday-_v)/7) + 1;
/* maximum number of weeks in the year */
_amp.yweek = ac_get_yweek(&_tm) + 1;
/* maximum number of the week day in the month */
_amp.mwday=(int)((_amp.mday-1-(_amp.mday-_atp->t.tm_mday)%7)/7)+1;
/* maximum number of weeks in the month */
_v = (_atp->t.tm_wday + (_amp.mday - _atp->t.tm_mday)%7)%7;
#ifdef USE_YWEEK_U
_amp.mweek = (int)((_amp.mday-1)/7+(7-_v+(_amp.mday-1)%7)/7)+1;
#else
_amp.mweek = (int)((_amp.mday-1)/7+(7-(6+_v)%7+(_amp.mday-1)%7)/7)+1;
#endif
return &_amp;
}
int ac_print(ac_tm_p _atp)
{
static char *_wdays[] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
if(!_atp)
{
printf("\n(null)\n");
return -1;
}
printf("\nSys time: %d\nTime: %02d:%02d:%02d\n", (int)_atp->time,
_atp->t.tm_hour, _atp->t.tm_min, _atp->t.tm_sec);
printf("Date: %s, %04d-%02d-%02d\n", _wdays[_atp->t.tm_wday],
_atp->t.tm_year+1900, _atp->t.tm_mon+1, _atp->t.tm_mday);
printf("Year day: %d\nYear week-day: %d\nYear week: %d\n", _atp->t.tm_yday,
_atp->ywday, _atp->yweek);
printf("Month week: %d\nMonth week-day: %d\n", _atp->mweek, _atp->mwday);
return 0;
}
tr_byxxx_p tr_byxxx_new(char alloc)
{
tr_byxxx_p _bxp = NULL;
if (alloc & PKG_ALLOC)
_bxp = (tr_byxxx_p)pkg_malloc(sizeof(tr_byxxx_t));
else
_bxp = (tr_byxxx_p)shm_malloc(sizeof(tr_byxxx_t));
if(!_bxp)
return NULL;
memset(_bxp, 0, sizeof(tr_byxxx_t));
_bxp->flags = alloc;
return _bxp;
}
int tr_byxxx_init(tr_byxxx_p _bxp, int _nr)
{
if(!_bxp)
return -1;
_bxp->nr = _nr;
if (_bxp->flags & PKG_ALLOC)
_bxp->xxx = (int*)pkg_malloc(_nr*sizeof(int));
else
_bxp->xxx = (int*)shm_malloc(_nr*sizeof(int));
if(!_bxp->xxx)
return -1;
if (_bxp->flags & PKG_ALLOC)
_bxp->req = (int*)pkg_malloc(_nr*sizeof(int));
else
_bxp->req = (int*)shm_malloc(_nr*sizeof(int));
if(!_bxp->req)
{
if (_bxp->flags & PKG_ALLOC)
pkg_free(_bxp->xxx);
else
shm_free(_bxp->xxx);
return -1;
}
memset(_bxp->xxx, 0, _nr*sizeof(int));
memset(_bxp->req, 0, _nr*sizeof(int));
return 0;
}
int tr_byxxx_free(tr_byxxx_p _bxp)
{
char type;
if(!_bxp)
return -1;
type = _bxp->flags & PKG_ALLOC;
if(_bxp->xxx) {
if (type)
pkg_free(_bxp->xxx);
else
shm_free(_bxp->xxx);
}
if(_bxp->req) {
if (type)
pkg_free(_bxp->req);
else
shm_free(_bxp->req);
}
if (type)
pkg_free(_bxp);
else
shm_free(_bxp);
return 0;
}
tmrec_p tmrec_new(char alloc)
{
tmrec_p _trp = NULL;
if (alloc & PKG_ALLOC)
_trp = (tmrec_p)pkg_malloc(sizeof(tmrec_t));
else
_trp = (tmrec_p)shm_malloc(sizeof(tmrec_t));
if(!_trp)
return NULL;
memset(_trp, 0, sizeof(tmrec_t));
_trp->flags = alloc;
/* localtime_r(&_trp->dtstart,&(_trp->ts)); */
return _trp;
}
int tmrec_free(tmrec_p _trp)
{
if(!_trp)
return -1;
tr_byxxx_free(_trp->byday);
tr_byxxx_free(_trp->bymday);
tr_byxxx_free(_trp->byyday);
tr_byxxx_free(_trp->bymonth);
tr_byxxx_free(_trp->byweekno);
if (_trp->flags & PKG_ALLOC)
pkg_free(_trp);
else
shm_free(_trp);
return 0;
}
int tr_parse_dtstart(tmrec_p _trp, char *_in)
{
if(!_trp || !_in)
return -1;
_trp->dtstart = ic_parse_datetime(_in, &(_trp->ts));
return (_trp->dtstart==0)?-1:0;
}
int tr_parse_dtend(tmrec_p _trp, char *_in)
{
struct tm _tm;
if(!_trp || !_in)
return -1;
_trp->dtend = ic_parse_datetime(_in,&_tm);
return (_trp->dtend==0)?-1:0;
}
int tr_parse_duration(tmrec_p _trp, char *_in)
{
if(!_trp || !_in)
return -1;
_trp->duration = ic_parse_duration(_in);
return 0;
}
int tr_parse_until(tmrec_p _trp, char *_in)
{
struct tm _tm;
if(!_trp || !_in)
return -1;
_trp->until = ic_parse_datetime(_in, &_tm);
return 0;
}
int tr_parse_freq(tmrec_p _trp, char *_in)
{
if(!_trp || !_in)
return -1;
if(strlen(_in)<5)
{
_trp->freq = FREQ_NOFREQ;
return 0;
}
if(!strcasecmp(_in, "daily"))
{
_trp->freq = FREQ_DAILY;
return 0;
}
if(!strcasecmp(_in, "weekly"))
{
_trp->freq = FREQ_WEEKLY;
return 0;
}
if(!strcasecmp(_in, "monthly"))
{
_trp->freq = FREQ_MONTHLY;
return 0;
}
if(!strcasecmp(_in, "yearly"))
{
_trp->freq = FREQ_YEARLY;
return 0;
}
_trp->freq = FREQ_NOFREQ;
return 0;
}
int tr_parse_interval(tmrec_p _trp, char *_in)
{
if(!_trp || !_in)
return -1;
_trp->interval = strz2int(_in);
return 0;
}
int tr_parse_byday(tmrec_p _trp, char *_in)
{
if(!_trp || !_in)
return -1;
_trp->byday = ic_parse_byday(_in, _trp->flags);
return 0;
}
int tr_parse_bymday(tmrec_p _trp, char *_in)
{
if(!_trp || !_in)
return -1;
_trp->bymday = ic_parse_byxxx(_in, _trp->flags);
return 0;
}
int tr_parse_byyday(tmrec_p _trp, char *_in)
{
if(!_trp || !_in)
return -1;
_trp->byyday = ic_parse_byxxx(_in, _trp->flags);
return 0;
}
int tr_parse_bymonth(tmrec_p _trp, char *_in)
{
if(!_trp || !_in)
return -1;
_trp->bymonth = ic_parse_byxxx(_in, _trp->flags);
return 0;
}
int tr_parse_byweekno(tmrec_p _trp, char *_in)
{
if(!_trp || !_in)
return -1;
_trp->byweekno = ic_parse_byxxx(_in, _trp->flags);
return 0;
}
int tr_parse_wkst(tmrec_p _trp, char *_in)
{
if(!_trp || !_in)
return -1;
_trp->wkst = ic_parse_wkst(_in);
return 0;
}
int tr_print(tmrec_p _trp)
{
static char *_wdays[] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
int i;
if(!_trp)
{
printf("\n(null)\n");
return -1;
}
printf("Recurrence definition\n-- start time ---\n");
printf("Sys time: %d\n", (int)_trp->dtstart);
printf("Time: %02d:%02d:%02d\n", _trp->ts.tm_hour,
_trp->ts.tm_min, _trp->ts.tm_sec);
printf("Date: %s, %04d-%02d-%02d\n", _wdays[_trp->ts.tm_wday],
_trp->ts.tm_year+1900, _trp->ts.tm_mon+1, _trp->ts.tm_mday);
printf("---\n");
printf("End time: %d\n", (int)_trp->dtend);
printf("Duration: %d\n", (int)_trp->duration);
printf("Until: %d\n", (int)_trp->until);
printf("Freq: %d\n", (int)_trp->freq);
printf("Interval: %d\n", (int)_trp->interval);
if(_trp->byday)
{
printf("Byday: ");
for(i=0; i<_trp->byday->nr; i++)
printf(" %d%s", _trp->byday->req[i], _wdays[_trp->byday->xxx[i]]);
printf("\n");
}
if(_trp->bymday)
{
printf("Bymday: %d:", _trp->bymday->nr);
for(i=0; i<_trp->bymday->nr; i++)
printf(" %d", _trp->bymday->xxx[i]*_trp->bymday->req[i]);
printf("\n");
}
if(_trp->byyday)
{
printf("Byyday:");
for(i=0; i<_trp->byyday->nr; i++)
printf(" %d", _trp->byyday->xxx[i]*_trp->byyday->req[i]);
printf("\n");
}
if(_trp->bymonth)
{
printf("Bymonth: %d:", _trp->bymonth->nr);
for(i=0; i< _trp->bymonth->nr; i++)
printf(" %d", _trp->bymonth->xxx[i]*_trp->bymonth->req[i]);
printf("\n");
}
if(_trp->byweekno)
{
printf("Byweekno: ");
for(i=0; i<_trp->byweekno->nr; i++)
printf(" %d", _trp->byweekno->xxx[i]*_trp->byweekno->req[i]);
printf("\n");
}
printf("Weekstart: %d\n", _trp->wkst);
return 0;
}
time_t ic_parse_datetime(char *_in, struct tm *_tm)
{
if(!_in || !_tm || strlen(_in)!=15)
return 0;
memset(_tm, 0, sizeof(struct tm));
_tm->tm_year = _D(_in[0])*1000 + _D(_in[1])*100
+ _D(_in[2])*10 + _D(_in[3]) - 1900;
_tm->tm_mon = _D(_in[4])*10 + _D(_in[5]) - 1;
_tm->tm_mday = _D(_in[6])*10 + _D(_in[7]);
_tm->tm_hour = _D(_in[9])*10 + _D(_in[10]);
_tm->tm_min = _D(_in[11])*10 + _D(_in[12]);
_tm->tm_sec = _D(_in[13])*10 + _D(_in[14]);
_tm->tm_isdst = -1 /*daylight*/;
return mktime(_tm);
}
time_t ic_parse_duration(char *_in)
{
time_t _t, _ft;
char *_p;
int _fl;
if(!_in || strlen(_in)<2)
return 0;
if(*_in == 'P' || *_in=='p')
{
_p = _in+1;
_fl = 1;
} else {
_p = _in;
_fl = 0;
}
_t = _ft = 0;
while(*_p)
{
switch(*_p)
{
case '0': case '1': case '2':
case '3': case '4': case '5':
case '6': case '7': case '8':
case '9':
_t = _t*10 + *_p - '0';
break;
case 'w':
case 'W':
if(!_fl)
{
LM_ERR("week duration not allowed"
" here (%d) [%s]\n", (int)(_p-_in), _in);
return 0;
}
_ft += _t*7*24*3600;
_t = 0;
break;
case 'd':
case 'D':
if(!_fl)
{
LM_ERR("day duration not allowed"
" here (%d) [%s]\n", (int)(_p-_in), _in);
return 0;
}
_ft += _t*24*3600;
_t = 0;
break;
case 'h':
case 'H':
if(_fl)
{
LM_ERR("hour duration not allowed"
" here (%d) [%s]\n", (int)(_p-_in), _in);
return 0;
}
_ft += _t*3600;
_t = 0;
break;
case 'm':
case 'M':
if(_fl)
{
LM_ERR("minute duration not allowed"
" here (%d) [%s]\n", (int)(_p-_in), _in);
return 0;
}
_ft += _t*60;
_t = 0;
break;
case 's':
case 'S':
if(_fl)
{
LM_ERR("second duration not allowed"
" here (%d) [%s]\n", (int)(_p-_in), _in);
return 0;
}
_ft += _t;
_t = 0;
break;
case 't':
case 'T':
if(!_fl)
{
LM_ERR("'T' not allowed"
" here (%d) [%s]\n", (int)(_p-_in), _in);
return 0;
}
_fl = 0;
break;
default:
LM_ERR("bad character here (%d) [%s]\n",
(int)(_p-_in), _in);
return 0;
}
_p++;
}
return _ft;
}
tr_byxxx_p ic_parse_byday(char *_in, char type)
{
tr_byxxx_p _bxp = NULL;
int _nr, _s, _v;
char *_p;
if(!_in)
return NULL;
_bxp = tr_byxxx_new(type);
if(!_bxp)
return NULL;
_p = _in;
_nr = 1;
while(*_p)
{
if(*_p == ',')
_nr++;
_p++;
}
if(tr_byxxx_init(_bxp, _nr) < 0)
{
tr_byxxx_free(_bxp);
return NULL;
}
_p = _in;
_nr = _v = 0;
_s = 1;
while(*_p && _nr < _bxp->nr)
{
switch(*_p)
{
case '0': case '1': case '2':
case '3': case '4': case '5':
case '6': case '7': case '8':
case '9':
_v = _v*10 + *_p - '0';
break;
case 's':
case 'S':
_p++;
switch(*_p)
{
case 'a':
case 'A':
_bxp->xxx[_nr] = WDAY_SA;
_bxp->req[_nr] = _s*_v;
break;
case 'u':
case 'U':
_bxp->xxx[_nr] = WDAY_SU;
_bxp->req[_nr] = _s*_v;
break;
default:
goto error;
}
_s = 1;
_v = 0;
break;
case 'm':
case 'M':
_p++;
if(*_p!='o' && *_p!='O')
goto error;
_bxp->xxx[_nr] = WDAY_MO;
_bxp->req[_nr] = _s*_v;
_s = 1;
_v = 0;
break;
case 't':
case 'T':
_p++;
switch(*_p)
{
case 'h':
case 'H':
_bxp->xxx[_nr] = WDAY_TH;
_bxp->req[_nr] = _s*_v;
break;
case 'u':
case 'U':
_bxp->xxx[_nr] = WDAY_TU;
_bxp->req[_nr] = _s*_v;
break;
default:
goto error;
}
_s = 1;
_v = 0;
break;
case 'w':
case 'W':
_p++;
if(*_p!='e' && *_p!='E')
goto error;
_bxp->xxx[_nr] = WDAY_WE;
_bxp->req[_nr] = _s*_v;
_s = 1;
_v = 0;
break;
case 'f':
case 'F':
_p++;
if(*_p!='r' && *_p!='R')
goto error;
_bxp->xxx[_nr] = WDAY_FR;
_bxp->req[_nr] = _s*_v;
_s = 1;
_v = 0;
break;
case '-':
_s = -1;
break;
case '+':
case ' ':
case '\t':
break;
case ',':
_nr++;
break;
default:
goto error;
}
_p++;
}
return _bxp;
error:
tr_byxxx_free(_bxp);
return NULL;
}
tr_byxxx_p ic_parse_byxxx(char *_in, char type)
{
tr_byxxx_p _bxp = NULL;
int _nr, _s, _v;
char *_p;
if(!_in)
return NULL;
_bxp = tr_byxxx_new(type);
if(!_bxp)
return NULL;
_p = _in;
_nr = 1;
while(*_p)
{
if(*_p == ',')
_nr++;
_p++;
}
if(tr_byxxx_init(_bxp, _nr) < 0)
{
tr_byxxx_free(_bxp);
return NULL;
}
_p = _in;
_nr = _v = 0;
_s = 1;
while(*_p && _nr < _bxp->nr)
{
switch(*_p)
{
case '0': case '1': case '2':
case '3': case '4': case '5':
case '6': case '7': case '8':
case '9':
_v = _v*10 + *_p - '0';
break;
case '-':
_s = -1;
break;
case '+':
case ' ':
case '\t':
break;
case ',':
_bxp->xxx[_nr] = _v;
_bxp->req[_nr] = _s;
_s = 1;
_v = 0;
_nr++;
break;
default:
goto error;
}
_p++;
}
if(_nr < _bxp->nr)
{
_bxp->xxx[_nr] = _v;
_bxp->req[_nr] = _s;
}
return _bxp;
error:
tr_byxxx_free(_bxp);
return NULL;
}
int ic_parse_wkst(char *_in)
{
if(!_in || strlen(_in)!=2)
goto error;
switch(_in[0])
{
case 's':
case 'S':
switch(_in[1])
{
case 'a':
case 'A':
return WDAY_SA;
case 'u':
case 'U':
return WDAY_SU;
default:
goto error;
}
case 'm':
case 'M':
if(_in[1]!='o' && _in[1]!='O')
goto error;
return WDAY_MO;
case 't':
case 'T':
switch(_in[1])
{
case 'h':
case 'H':
return WDAY_TH;
case 'u':
case 'U':
return WDAY_TU;
default:
goto error;
}
case 'w':
case 'W':
if(_in[1]!='e' && _in[1]!='E')
goto error;
return WDAY_WE;
case 'f':
case 'F':
if(_in[1]!='r' && _in[1]!='R')
goto error;
return WDAY_FR;
break;
default:
goto error;
}
error:
#ifdef USE_YWEEK_U
return WDAY_SU;
#else
return WDAY_MO;
#endif
}
/*** local headers ***/
int get_min_interval(tmrec_p);
int check_min_unit(tmrec_p, ac_tm_p, tr_res_p);
int check_freq_interval(tmrec_p _trp, ac_tm_p _atp);
int check_byxxx(tmrec_p, ac_tm_p);
/**
*
* return 0/REC_MATCH - the time falls in
* -1/REC_ERR - error
* 1/REC_NOMATCH - the time falls out
*/
int check_tmrec(tmrec_p _trp, ac_tm_p _atp, tr_res_p _tsw)
{
if(!_trp || !_atp)
return REC_ERR;
/* it is before start date */
if(_atp->time < _trp->dtstart)
return REC_NOMATCH;
/* no duration or end -> for ever */
if (!_IS_SET(_trp->duration) && !_IS_SET(_trp->dtend))
return REC_MATCH;
/* compute the duration of the recurrence interval */
if(!_IS_SET(_trp->duration))
_trp->duration = _trp->dtend - _trp->dtstart;
if(_atp->time <= _trp->dtstart+_trp->duration)
{
if(_tsw)
{
if(_tsw->flag & TSW_RSET)
{
if(_tsw->rest>_trp->dtstart+_trp->duration-_atp->time)
_tsw->rest = _trp->dtstart+_trp->duration - _atp->time;
}
else
{
_tsw->flag |= TSW_RSET;
_tsw->rest = _trp->dtstart+_trp->duration - _atp->time;
}
}
return REC_MATCH;
}
/* after the bound of recurrence */
if(_IS_SET(_trp->until) && _atp->time >= _trp->until + _trp->duration)
return REC_NOMATCH;
/* check if the instance of recurrence matches the 'interval' */
if(check_freq_interval(_trp, _atp)!=REC_MATCH)
return REC_NOMATCH;
if(check_min_unit(_trp, _atp, _tsw)!=REC_MATCH)
return REC_NOMATCH;
if(check_byxxx(_trp, _atp)!=REC_MATCH)
return REC_NOMATCH;
return REC_MATCH;
}
int check_freq_interval(tmrec_p _trp, ac_tm_p _atp)
{
int _t0, _t1;
struct tm _tm;
if(!_trp || !_atp)
return REC_ERR;
if(!_IS_SET(_trp->freq))
return REC_NOMATCH;
if(!_IS_SET(_trp->interval) || _trp->interval==1)
return REC_MATCH;
switch(_trp->freq)
{
case FREQ_DAILY:
case FREQ_WEEKLY:
memset(&_tm, 0, sizeof(struct tm));
_tm.tm_year = _trp->ts.tm_year;
_tm.tm_mon = _trp->ts.tm_mon;
_tm.tm_mday = _trp->ts.tm_mday;
_t0 = (int)mktime(&_tm);
memset(&_tm, 0, sizeof(struct tm));
_tm.tm_year = _atp->t.tm_year;
_tm.tm_mon = _atp->t.tm_mon;
_tm.tm_mday = _atp->t.tm_mday;
_t1 = (int)mktime(&_tm);
if(_trp->freq == FREQ_DAILY)
return (((_t1-_t0)/(24*3600))%_trp->interval==0)?
REC_MATCH:REC_NOMATCH;
#ifdef USE_YWEEK_U
_t0 -= _trp->ts.tm_wday*24*3600;
_t1 -= _atp->t.tm_wday*24*3600;
#else
_t0 -= ((_trp->ts.tm_wday+6)%7)*24*3600;
_t1 -= ((_atp->t.tm_wday+6)%7)*24*3600;
#endif
return (((_t1-_t0)/(7*24*3600))%_trp->interval==0)?
REC_MATCH:REC_NOMATCH;
case FREQ_MONTHLY:
_t0 = (_atp->t.tm_year-_trp->ts.tm_year)*12
+ _atp->t.tm_mon-_trp->ts.tm_mon;
return (_t0%_trp->interval==0)?REC_MATCH:REC_NOMATCH;
case FREQ_YEARLY:
return ((_atp->t.tm_year-_trp->ts.tm_year)%_trp->interval==0)?
REC_MATCH:REC_NOMATCH;
}
return REC_NOMATCH;
}
int get_min_interval(tmrec_p _trp)
{
if(!_trp)
return FREQ_NOFREQ;
if(_trp->freq == FREQ_DAILY || _trp->byday || _trp->bymday || _trp->byyday)
return FREQ_DAILY;
if(_trp->freq == FREQ_WEEKLY || _trp->byweekno)
return FREQ_WEEKLY;
if(_trp->freq == FREQ_MONTHLY || _trp->bymonth)
return FREQ_MONTHLY;
if(_trp->freq == FREQ_YEARLY)
return FREQ_YEARLY;
return FREQ_NOFREQ;
}
int check_min_unit(tmrec_p _trp, ac_tm_p _atp, tr_res_p _tsw)
{
int _v0, _v1;
if(!_trp || !_atp)
return REC_ERR;
switch(get_min_interval(_trp))
{
case FREQ_DAILY:
break;
case FREQ_WEEKLY:
if(_trp->ts.tm_wday != _atp->t.tm_wday)
return REC_NOMATCH;
break;
case FREQ_MONTHLY:
if(_trp->ts.tm_mday != _atp->t.tm_mday)
return REC_NOMATCH;
break;
case FREQ_YEARLY:
if(_trp->ts.tm_mon != _atp->t.tm_mon
|| _trp->ts.tm_mday != _atp->t.tm_mday)
return REC_NOMATCH;
break;
default:
return REC_NOMATCH;
}
_v0 = _trp->ts.tm_hour*3600 + _trp->ts.tm_min*60 + _trp->ts.tm_sec;
_v1 = _atp->t.tm_hour*3600 + _atp->t.tm_min*60 + _atp->t.tm_sec;
if(_v1 >= _v0 && _v1 < _v0 + _trp->duration)
{
if(_tsw)
{
if(_tsw->flag & TSW_RSET)
{
if(_tsw->rest>_v0+_trp->duration-_v1)
_tsw->rest = _v0 + _trp->duration - _v1;
}
else
{
_tsw->flag |= TSW_RSET;
_tsw->rest = _v0 + _trp->duration - _v1;
}
}
return REC_MATCH;
}
return REC_NOMATCH;
}
int check_byxxx(tmrec_p _trp, ac_tm_p _atp)
{
int i;
ac_maxval_p _amp = NULL;
if(!_trp || !_atp)
return REC_ERR;
if(!_trp->byday && !_trp->bymday && !_trp->byyday && !_trp->bymonth
&& !_trp->byweekno)
return REC_MATCH;
_amp = ac_get_maxval(_atp);
if(_trp->bymonth)
{
for(i=0; i<_trp->bymonth->nr; i++)
{
if(_atp->t.tm_mon ==
(_trp->bymonth->xxx[i]*_trp->bymonth->req[i]+12)%12)
break;
}
if(i>=_trp->bymonth->nr)
return REC_NOMATCH;
}
if(_trp->freq==FREQ_YEARLY && _trp->byweekno)
{
for(i=0; i<_trp->byweekno->nr; i++)
{
if(_atp->yweek == (_trp->byweekno->xxx[i]*_trp->byweekno->req[i]+
_amp->yweek)%_amp->yweek)
break;
}
if(i>=_trp->byweekno->nr)
return REC_NOMATCH;
}
if(_trp->byyday)
{
for(i=0; i<_trp->byyday->nr; i++)
{
if(_atp->t.tm_yday == (_trp->byyday->xxx[i]*_trp->byyday->req[i]+
_amp->yday)%_amp->yday)
break;
}
if(i>=_trp->byyday->nr)
return REC_NOMATCH;
}
if(_trp->bymday)
{
for(i=0; i<_trp->bymday->nr; i++)
{
#ifdef EXTRA_DEBUG
LM_DBG("%d == %d\n", _atp->t.tm_mday,
(_trp->bymday->xxx[i]*_trp->bymday->req[i]+
_amp->mday)%_amp->mday + ((_trp->bymday->req[i]<0)?1:0));
#endif
if(_atp->t.tm_mday == (_trp->bymday->xxx[i]*_trp->bymday->req[i]+
_amp->mday)%_amp->mday + (_trp->bymday->req[i]<0)?1:0)
break;
}
if(i>=_trp->bymday->nr)
return REC_NOMATCH;
}
if(_trp->byday)
{
for(i=0; i<_trp->byday->nr; i++)
{
if(_trp->freq==FREQ_YEARLY)
{
#ifdef EXTRA_DEBUG
LM_DBG("%d==%d && %d==%d\n", _atp->t.tm_wday,
_trp->byday->xxx[i], _atp->ywday+1,
(_trp->byday->req[i]+_amp->ywday)%_amp->ywday);
#endif
if(_atp->t.tm_wday == _trp->byday->xxx[i] &&
_atp->ywday+1 == (_trp->byday->req[i]+_amp->ywday)%
_amp->ywday)
break;
}
else
{
if(_trp->freq==FREQ_MONTHLY)
{
#ifdef EXTRA_DEBUG
LM_DBG("%d==%d && %d==%d\n", _atp->t.tm_wday,
_trp->byday->xxx[i], _atp->mwday+1,
(_trp->byday->req[i]+_amp->mwday)%_amp->mwday);
#endif
if(_atp->t.tm_wday == _trp->byday->xxx[i] &&
_atp->mwday+1==(_trp->byday->req[i]+
_amp->mwday)%_amp->mwday)
break;
}
else
{
if(_atp->t.tm_wday == _trp->byday->xxx[i])
break;
}
}
}
if(i>=_trp->byday->nr)
return REC_NOMATCH;
}
return REC_MATCH;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化