00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include <time.h>
00032
00033 #include "../../mem/mem.h"
00034 #include "cpl_time.h"
00035
00036
00037
00038
00039 static inline int strz2int(char *_bp)
00040 {
00041 int _v;
00042 char *_p;
00043 if(!_bp)
00044 return 0;
00045 _v = 0;
00046 _p = _bp;
00047 while(*_p && *_p>='0' && *_p<='9')
00048 {
00049 _v += *_p - '0';
00050 _p++;
00051 }
00052 return _v;
00053 }
00054
00055
00056 static inline char* trim(char* _s)
00057 {
00058 int len;
00059 char* end;
00060
00061
00062 if (!_s) return _s;
00063
00064
00065 while ((*_s == ' ') || (*_s == '\t')) _s++;
00066
00067 len = strlen(_s);
00068
00069 end = _s + len - 1;
00070
00071
00072 while ((*end == ' ') || (*end == '\t')) end--;
00073 if (end != (_s + len - 1)) {
00074 *(end+1) = '\0';
00075 }
00076
00077 return _s;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #ifndef USE_YWEEK_U
00089 #ifndef USE_YWEEK_V
00090 #ifndef USE_YWEEK_W
00091 #define USE_YWEEK_W .
00092 #endif
00093 #endif
00094 #endif
00095
00096 #ifdef USE_YWEEK_U
00097 #define SUN_WEEK(t) (int)(((t)->tm_yday + 7 - \
00098 ((t)->tm_wday)) / 7)
00099 #else
00100 #define MON_WEEK(t) (int)(((t)->tm_yday + 7 - \
00101 ((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7)
00102 #endif
00103
00104 #define ac_get_wday_yr(t) (int)((t)->tm_yday/7)
00105 #define ac_get_wday_mr(t) (int)(((t)->tm_mday-1)/7)
00106
00107 ac_tm_p ac_tm_new(void)
00108 {
00109 ac_tm_p _atp = NULL;
00110 _atp = (ac_tm_p)pkg_malloc(sizeof(ac_tm_t));
00111 if(!_atp)
00112 return NULL;
00113 memset(_atp, 0, sizeof(ac_tm_t));
00114
00115 return _atp;
00116 }
00117
00118 int ac_tm_fill(ac_tm_p _atp, struct tm* _tm)
00119 {
00120 if(!_atp || !_tm)
00121 return -1;
00122 _atp->t.tm_sec = _tm->tm_sec;
00123 _atp->t.tm_min = _tm->tm_min;
00124 _atp->t.tm_hour = _tm->tm_hour;
00125 _atp->t.tm_mday = _tm->tm_mday;
00126 _atp->t.tm_mon = _tm->tm_mon;
00127 _atp->t.tm_year = _tm->tm_year;
00128 _atp->t.tm_wday = _tm->tm_wday;
00129 _atp->t.tm_yday = _tm->tm_yday;
00130 _atp->t.tm_isdst = _tm->tm_isdst;
00131
00132 _atp->mweek = ac_get_mweek(_tm);
00133 _atp->yweek = ac_get_yweek(_tm);
00134 _atp->ywday = ac_get_wday_yr(_tm);
00135 _atp->mwday = ac_get_wday_mr(_tm);
00136 return 0;
00137 }
00138
00139 int ac_tm_set_time(ac_tm_p _atp, time_t _t)
00140 {
00141 if(!_atp)
00142 return -1;
00143 _atp->time = _t;
00144 return ac_tm_fill(_atp, localtime(&_t));
00145 }
00146
00147 int ac_get_mweek(struct tm* _tm)
00148 {
00149 if(!_tm)
00150 return -1;
00151 #ifdef USE_YWEEK_U
00152 return ((_tm->tm_mday-1)/7 + (7-_tm->tm_wday+(_tm->tm_mday-1)%7)/7);
00153 #else
00154 return ((_tm->tm_mday-1)/7 + (7-(6+_tm->tm_wday)%7+(_tm->tm_mday-1)%7)/7);
00155 #endif
00156 }
00157
00158 int ac_get_yweek(struct tm* _tm)
00159 {
00160 int week = -1;
00161 #ifdef USE_YWEEK_V
00162 int days;
00163 #endif
00164
00165 if(!_tm)
00166 return -1;
00167
00168 #ifdef USE_YWEEK_U
00169 week = SUN_WEEK(_tm);
00170 #else
00171 week = MON_WEEK(_tm);
00172 #endif
00173
00174 #ifdef USE_YWEEK_V
00175 days = ((_tm->tm_yday + 7 - (_tm->tm_wday ? _tm->tm_wday-1 : 6)) % 7);
00176
00177 if(days >= 4)
00178 week++;
00179 else
00180 if(week == 0)
00181 week = 53;
00182 #endif
00183 return week;
00184 }
00185
00186 int ac_get_wkst(void)
00187 {
00188 #ifdef USE_YWEEK_U
00189 return 0;
00190 #else
00191 return 1;
00192 #endif
00193 }
00194
00195 int ac_tm_reset(ac_tm_p _atp)
00196 {
00197 if(!_atp)
00198 return -1;
00199 memset(_atp, 0, sizeof(ac_tm_t));
00200 return 0;
00201 }
00202
00203 int ac_tm_free(ac_tm_p _atp)
00204 {
00205 if(!_atp)
00206 return -1;
00207 if(_atp->mv)
00208 pkg_free(_atp->mv);
00209
00210 return 0;
00211 }
00212
00213 ac_maxval_p ac_get_maxval(ac_tm_p _atp)
00214 {
00215 struct tm _tm;
00216 int _v;
00217 ac_maxval_p _amp = NULL;
00218
00219 if(!_atp)
00220 return NULL;
00221 _amp = (ac_maxval_p)pkg_malloc(sizeof(ac_maxval_t));
00222 if(!_amp)
00223 return NULL;
00224
00225
00226 _amp->yday = 365 + is_leap_year(_atp->t.tm_year+1900);
00227
00228
00229 switch(_atp->t.tm_mon)
00230 {
00231 case 1:
00232 if(_amp->yday == 366)
00233 _amp->mday = 29;
00234 else
00235 _amp->mday = 28;
00236 break;
00237 case 3: case 5: case 8: case 10:
00238 _amp->mday = 30;
00239 break;
00240 default:
00241 _amp->mday = 31;
00242 }
00243
00244
00245 memset(&_tm, 0, sizeof(struct tm));
00246 _tm.tm_year = _atp->t.tm_year;
00247 _tm.tm_mon = 11;
00248 _tm.tm_mday = 31;
00249 mktime(&_tm);
00250 _v = 0;
00251 if(_atp->t.tm_wday > _tm.tm_wday)
00252 _v = _atp->t.tm_wday - _tm.tm_wday + 1;
00253 else
00254 _v = _tm.tm_wday - _atp->t.tm_wday;
00255 _amp->ywday = (int)((_tm.tm_yday-_v)/7) + 1;
00256
00257
00258 _amp->yweek = ac_get_yweek(&_tm) + 1;
00259
00260
00261 _amp->mwday=(int)((_amp->mday-1-(_amp->mday-_atp->t.tm_mday)%7)/7)+1;
00262
00263
00264 _v = (_atp->t.tm_wday + (_amp->mday - _atp->t.tm_mday)%7)%7;
00265 #ifdef USE_YWEEK_U
00266 _amp->mweek = (int)((_amp->mday-1)/7+(7-_v+(_amp->mday-1)%7)/7)+1;
00267 #else
00268 _amp->mweek = (int)((_amp->mday-1)/7+(7-(6+_v)%7+(_amp->mday-1)%7)/7)+1;
00269 #endif
00270
00271 _atp->mv = _amp;
00272 return _amp;
00273 }
00274
00275 int ac_print(ac_tm_p _atp)
00276 {
00277 static char *_wdays[] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
00278 if(!_atp)
00279 {
00280 printf("\n(null)\n");
00281 return -1;
00282 }
00283
00284 printf("\nSys time: %d\nTime: %02d:%02d:%02d\n", (int)_atp->time,
00285 _atp->t.tm_hour, _atp->t.tm_min, _atp->t.tm_sec);
00286 printf("Date: %s, %04d-%02d-%02d\n", _wdays[_atp->t.tm_wday],
00287 _atp->t.tm_year+1900, _atp->t.tm_mon+1, _atp->t.tm_mday);
00288 printf("Year day: %d\nYear week-day: %d\nYear week: %d\n", _atp->t.tm_yday,
00289 _atp->ywday, _atp->yweek);
00290 printf("Month week: %d\nMonth week-day: %d\n", _atp->mweek, _atp->mwday);
00291 if(_atp->mv)
00292 {
00293 printf("Max ydays: %d\nMax yweeks: %d\nMax yweekday: %d\n",
00294 _atp->mv->yday, _atp->mv->yweek, _atp->mv->ywday);;
00295 printf("Max mdays: %d\nMax mweeks: %d\nMax mweekday: %d\n",
00296 _atp->mv->mday, _atp->mv->mweek, _atp->mv->mwday);;
00297 }
00298 return 0;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307 #define _D(c) ((c) -'0')
00308
00309 tr_byxxx_p tr_byxxx_new(void)
00310 {
00311 tr_byxxx_p _bxp = NULL;
00312 _bxp = (tr_byxxx_p)pkg_malloc(sizeof(tr_byxxx_t));
00313 if(!_bxp)
00314 return NULL;
00315 memset(_bxp, 0, sizeof(tr_byxxx_t));
00316 return _bxp;
00317 }
00318
00319 int tr_byxxx_init(tr_byxxx_p _bxp, int _nr)
00320 {
00321 if(!_bxp)
00322 return -1;
00323 _bxp->nr = _nr;
00324 _bxp->xxx = (int*)pkg_malloc(_nr*sizeof(int));
00325 if(!_bxp->xxx)
00326 return -1;
00327 _bxp->req = (int*)pkg_malloc(_nr*sizeof(int));
00328 if(!_bxp->req)
00329 {
00330 pkg_free(_bxp->xxx);
00331 return -1;
00332 }
00333
00334 memset(_bxp->xxx, 0, _nr*sizeof(int));
00335 memset(_bxp->req, 0, _nr*sizeof(int));
00336
00337 return 0;
00338 }
00339
00340
00341 int tr_byxxx_free(tr_byxxx_p _bxp)
00342 {
00343 if(!_bxp)
00344 return -1;
00345 if(_bxp->xxx)
00346 pkg_free(_bxp->xxx);
00347 if(_bxp->req)
00348 pkg_free(_bxp->req);
00349 pkg_free(_bxp);
00350 return 0;
00351 }
00352
00353 tmrec_p tmrec_new(void)
00354 {
00355 tmrec_p _trp = NULL;
00356 _trp = (tmrec_p)pkg_malloc(sizeof(tmrec_t));
00357 if(!_trp)
00358 return NULL;
00359 memset(_trp, 0, sizeof(tmrec_t));
00360 localtime_r(&_trp->dtstart,&(_trp->ts));
00361 return _trp;
00362 }
00363
00364 int tmrec_free(tmrec_p _trp)
00365 {
00366 if(!_trp)
00367 return -1;
00368
00369 tr_byxxx_free(_trp->byday);
00370 tr_byxxx_free(_trp->bymday);
00371 tr_byxxx_free(_trp->byyday);
00372 tr_byxxx_free(_trp->bymonth);
00373 tr_byxxx_free(_trp->byweekno);
00374
00375
00376 return 0;
00377 }
00378
00379 int tr_parse_dtstart(tmrec_p _trp, char *_in)
00380 {
00381 if(!_trp || !_in)
00382 return -1;
00383 _trp->dtstart = ic_parse_datetime(_in, &(_trp->ts));
00384 return (_trp->dtstart==0)?-1:0;
00385 }
00386
00387 int tr_parse_dtend(tmrec_p _trp, char *_in)
00388 {
00389 struct tm _tm;
00390 if(!_trp || !_in)
00391 return -1;
00392 _trp->dtend = ic_parse_datetime(_in,&_tm);
00393 return (_trp->dtend==0)?-1:0;
00394 }
00395
00396 int tr_parse_duration(tmrec_p _trp, char *_in)
00397 {
00398 if(!_trp || !_in)
00399 return -1;
00400 _trp->duration = ic_parse_duration(_in);
00401 return (_trp->duration==0)?-1:0;
00402 }
00403
00404 int tr_parse_until(tmrec_p _trp, char *_in)
00405 {
00406 struct tm _tm;
00407 if(!_trp || !_in)
00408 return -1;
00409 _trp->until = ic_parse_datetime(_in, &_tm);
00410 return (_trp->until==0)?-1:0;
00411 }
00412
00413 int tr_parse_freq(tmrec_p _trp, char *_in)
00414 {
00415 if(!_trp || !_in)
00416 return -1;
00417 if(!strcasecmp(_in, "daily"))
00418 {
00419 _trp->freq = FREQ_DAILY;
00420 return 0;
00421 }
00422 if(!strcasecmp(_in, "weekly"))
00423 {
00424 _trp->freq = FREQ_WEEKLY;
00425 return 0;
00426 }
00427 if(!strcasecmp(_in, "monthly"))
00428 {
00429 _trp->freq = FREQ_MONTHLY;
00430 return 0;
00431 }
00432 if(!strcasecmp(_in, "yearly"))
00433 {
00434 _trp->freq = FREQ_YEARLY;
00435 return 0;
00436 }
00437
00438 _trp->freq = FREQ_NOFREQ;
00439 return 0;
00440 }
00441
00442 int tr_parse_interval(tmrec_p _trp, char *_in)
00443 {
00444 if(!_trp || !_in)
00445 return -1;
00446 _trp->interval = strz2int(_in);
00447 return 0;
00448 }
00449
00450 int tr_parse_byday(tmrec_p _trp, char *_in)
00451 {
00452 if(!_trp || !_in)
00453 return -1;
00454 _trp->byday = ic_parse_byday(_in);
00455 return 0;
00456 }
00457
00458 int tr_parse_bymday(tmrec_p _trp, char *_in)
00459 {
00460 if(!_trp || !_in)
00461 return -1;
00462 _trp->bymday = ic_parse_byxxx(_in);
00463 return 0;
00464 }
00465
00466 int tr_parse_byyday(tmrec_p _trp, char *_in)
00467 {
00468 if(!_trp || !_in)
00469 return -1;
00470 _trp->byyday = ic_parse_byxxx(_in);
00471 return 0;
00472 }
00473
00474 int tr_parse_bymonth(tmrec_p _trp, char *_in)
00475 {
00476 if(!_trp || !_in)
00477 return -1;
00478 _trp->bymonth = ic_parse_byxxx(_in);
00479 return 0;
00480 }
00481
00482 int tr_parse_byweekno(tmrec_p _trp, char *_in)
00483 {
00484 if(!_trp || !_in)
00485 return -1;
00486 _trp->byweekno = ic_parse_byxxx(_in);
00487 return 0;
00488 }
00489
00490 int tr_parse_wkst(tmrec_p _trp, char *_in)
00491 {
00492 if(!_trp || !_in)
00493 return -1;
00494 _trp->wkst = ic_parse_wkst(_in);
00495 return 0;
00496 }
00497
00498 int tr_print(tmrec_p _trp)
00499 {
00500 static char *_wdays[] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
00501 int i;
00502
00503 if(!_trp)
00504 {
00505 printf("\n(null)\n");
00506 return -1;
00507 }
00508 printf("Recurrence definition\n-- start time ---\n");
00509 printf("Sys time: %d\n", (int)_trp->dtstart);
00510 printf("Time: %02d:%02d:%02d\n", _trp->ts.tm_hour,
00511 _trp->ts.tm_min, _trp->ts.tm_sec);
00512 printf("Date: %s, %04d-%02d-%02d\n", _wdays[_trp->ts.tm_wday],
00513 _trp->ts.tm_year+1900, _trp->ts.tm_mon+1, _trp->ts.tm_mday);
00514 printf("---\n");
00515 printf("End time: %d\n", (int)_trp->dtend);
00516 printf("Duration: %d\n", (int)_trp->duration);
00517 printf("Until: %d\n", (int)_trp->until);
00518 printf("Freq: %d\n", (int)_trp->freq);
00519 printf("Interval: %d\n", (int)_trp->interval);
00520 if(_trp->byday)
00521 {
00522 printf("Byday: ");
00523 for(i=0; i<_trp->byday->nr; i++)
00524 printf(" %d%s", _trp->byday->req[i], _wdays[_trp->byday->xxx[i]]);
00525 printf("\n");
00526 }
00527 if(_trp->bymday)
00528 {
00529 printf("Bymday: %d:", _trp->bymday->nr);
00530 for(i=0; i<_trp->bymday->nr; i++)
00531 printf(" %d", _trp->bymday->xxx[i]*_trp->bymday->req[i]);
00532 printf("\n");
00533 }
00534 if(_trp->byyday)
00535 {
00536 printf("Byyday:");
00537 for(i=0; i<_trp->byyday->nr; i++)
00538 printf(" %d", _trp->byyday->xxx[i]*_trp->byyday->req[i]);
00539 printf("\n");
00540 }
00541 if(_trp->bymonth)
00542 {
00543 printf("Bymonth: %d:", _trp->bymonth->nr);
00544 for(i=0; i< _trp->bymonth->nr; i++)
00545 printf(" %d", _trp->bymonth->xxx[i]*_trp->bymonth->req[i]);
00546 printf("\n");
00547 }
00548 if(_trp->byweekno)
00549 {
00550 printf("Byweekno: ");
00551 for(i=0; i<_trp->byweekno->nr; i++)
00552 printf(" %d", _trp->byweekno->xxx[i]*_trp->byweekno->req[i]);
00553 printf("\n");
00554 }
00555 printf("Weekstart: %d\n", _trp->wkst);
00556 return 0;
00557 }
00558
00559 time_t ic_parse_datetime(char *_in, struct tm *_tm)
00560 {
00561 if(!_in || !_tm || strlen(_in)!=15)
00562 return 0;
00563
00564 memset(_tm, 0, sizeof(struct tm));
00565 _tm->tm_year = _D(_in[0])*1000 + _D(_in[1])*100
00566 + _D(_in[2])*10 + _D(_in[3]) - 1900;
00567 _tm->tm_mon = _D(_in[4])*10 + _D(_in[5]) - 1;
00568 _tm->tm_mday = _D(_in[6])*10 + _D(_in[7]);
00569 _tm->tm_hour = _D(_in[9])*10 + _D(_in[10]);
00570 _tm->tm_min = _D(_in[11])*10 + _D(_in[12]);
00571 _tm->tm_sec = _D(_in[13])*10 + _D(_in[14]);
00572 _tm->tm_isdst = -1 ;
00573 return mktime(_tm);
00574 }
00575
00576 time_t ic_parse_duration(char *_in)
00577 {
00578 time_t _t, _ft;
00579 char *_p;
00580 int _fl;
00581
00582 if(!_in || (*_in!='+' && *_in!='-' && *_in!='P' && *_in!='p'))
00583 return 0;
00584
00585 if(*_in == 'P' || *_in=='p')
00586 _p = _in+1;
00587 else
00588 {
00589 if(strlen(_in)<2 || (_in[1]!='P' && _in[1]!='p'))
00590 return 0;
00591 _p = _in+2;
00592 }
00593
00594 _t = _ft = 0;
00595 _fl = 1;
00596
00597 while(*_p)
00598 {
00599 switch(*_p)
00600 {
00601 case '0': case '1': case '2':
00602 case '3': case '4': case '5':
00603 case '6': case '7': case '8':
00604 case '9':
00605 _t = _t*10 + *_p - '0';
00606 break;
00607
00608 case 'w':
00609 case 'W':
00610 if(!_fl)
00611 return 0;
00612 _ft += _t*7*24*3600;
00613 _t = 0;
00614 break;
00615 case 'd':
00616 case 'D':
00617 if(!_fl)
00618 return 0;
00619 _ft += _t*24*3600;
00620 _t = 0;
00621 break;
00622 case 'h':
00623 case 'H':
00624 if(_fl)
00625 return 0;
00626 _ft += _t*3600;
00627 _t = 0;
00628 break;
00629 case 'm':
00630 case 'M':
00631 if(_fl)
00632 return 0;
00633 _ft += _t*60;
00634 _t = 0;
00635 break;
00636 case 's':
00637 case 'S':
00638 if(_fl)
00639 return 0;
00640 _ft += _t;
00641 _t = 0;
00642 break;
00643 case 't':
00644 case 'T':
00645 if(!_fl)
00646 return 0;
00647 _fl = 0;
00648 break;
00649 default:
00650 return 0;
00651 }
00652 _p++;
00653 }
00654
00655 return _ft;
00656 }
00657
00658 tr_byxxx_p ic_parse_byday(char *_in)
00659 {
00660 tr_byxxx_p _bxp = NULL;
00661 int _nr, _s, _v;
00662 char *_p;
00663
00664 if(!_in)
00665 return NULL;
00666 _bxp = tr_byxxx_new();
00667 if(!_bxp)
00668 return NULL;
00669 _p = _in;
00670 _nr = 1;
00671 while(*_p)
00672 {
00673 if(*_p == ',')
00674 _nr++;
00675 _p++;
00676 }
00677 if(tr_byxxx_init(_bxp, _nr) < 0)
00678 {
00679 tr_byxxx_free(_bxp);
00680 return NULL;
00681 }
00682 _p = _in;
00683 _nr = _v = 0;
00684 _s = 1;
00685 while(*_p && _nr < _bxp->nr)
00686 {
00687 switch(*_p)
00688 {
00689 case '0': case '1': case '2':
00690 case '3': case '4': case '5':
00691 case '6': case '7': case '8':
00692 case '9':
00693 _v = _v*10 + *_p - '0';
00694 break;
00695
00696 case 's':
00697 case 'S':
00698 _p++;
00699 switch(*_p)
00700 {
00701 case 'a':
00702 case 'A':
00703 _bxp->xxx[_nr] = WDAY_SA;
00704 _bxp->req[_nr] = _s*_v;
00705 break;
00706 case 'u':
00707 case 'U':
00708 _bxp->xxx[_nr] = WDAY_SU;
00709 _bxp->req[_nr] = _s*_v;
00710 break;
00711 default:
00712 goto error;
00713 }
00714 _s = 1;
00715 _v = 0;
00716 break;
00717 case 'm':
00718 case 'M':
00719 _p++;
00720 if(*_p!='o' && *_p!='O')
00721 goto error;
00722 _bxp->xxx[_nr] = WDAY_MO;
00723 _bxp->req[_nr] = _s*_v;
00724 _s = 1;
00725 _v = 0;
00726 break;
00727 case 't':
00728 case 'T':
00729 _p++;
00730 switch(*_p)
00731 {
00732 case 'h':
00733 case 'H':
00734 _bxp->xxx[_nr] = WDAY_TH;
00735 _bxp->req[_nr] = _s*_v;
00736 break;
00737 case 'u':
00738 case 'U':
00739 _bxp->xxx[_nr] = WDAY_TU;
00740 _bxp->req[_nr] = _s*_v;
00741 break;
00742 default:
00743 goto error;
00744 }
00745 _s = 1;
00746 _v = 0;
00747 break;
00748 case 'w':
00749 case 'W':
00750 _p++;
00751 if(*_p!='e' && *_p!='E')
00752 goto error;
00753 _bxp->xxx[_nr] = WDAY_WE;
00754 _bxp->req[_nr] = _s*_v;
00755 _s = 1;
00756 _v = 0;
00757 break;
00758 case 'f':
00759 case 'F':
00760 _p++;
00761 if(*_p!='r' && *_p!='R')
00762 goto error;
00763 _bxp->xxx[_nr] = WDAY_FR;
00764 _bxp->req[_nr] = _s*_v;
00765 _s = 1;
00766 _v = 0;
00767 break;
00768 case '-':
00769 _s = -1;
00770 break;
00771 case '+':
00772 case ' ':
00773 case '\t':
00774 break;
00775 case ',':
00776 _nr++;
00777 break;
00778 default:
00779 goto error;
00780 }
00781 _p++;
00782 }
00783
00784 return _bxp;
00785
00786 error:
00787 tr_byxxx_free(_bxp);
00788 return NULL;
00789 }
00790
00791 tr_byxxx_p ic_parse_byxxx(char *_in)
00792 {
00793 tr_byxxx_p _bxp = NULL;
00794 int _nr, _s, _v;
00795 char *_p;
00796
00797 if(!_in)
00798 return NULL;
00799 _bxp = tr_byxxx_new();
00800 if(!_bxp)
00801 return NULL;
00802 _p = _in;
00803 _nr = 1;
00804 while(*_p)
00805 {
00806 if(*_p == ',')
00807 _nr++;
00808 _p++;
00809 }
00810 if(tr_byxxx_init(_bxp, _nr) < 0)
00811 {
00812 tr_byxxx_free(_bxp);
00813 return NULL;
00814 }
00815 _p = _in;
00816 _nr = _v = 0;
00817 _s = 1;
00818 while(*_p && _nr < _bxp->nr)
00819 {
00820 switch(*_p)
00821 {
00822 case '0': case '1': case '2':
00823 case '3': case '4': case '5':
00824 case '6': case '7': case '8':
00825 case '9':
00826 _v = _v*10 + *_p - '0';
00827 break;
00828
00829 case '-':
00830 _s = -1;
00831 break;
00832 case '+':
00833 case ' ':
00834 case '\t':
00835 break;
00836 case ',':
00837 _bxp->xxx[_nr] = _v;
00838 _bxp->req[_nr] = _s;
00839 _s = 1;
00840 _v = 0;
00841 _nr++;
00842 break;
00843 default:
00844 goto error;
00845 }
00846 _p++;
00847 }
00848 if(_nr < _bxp->nr)
00849 {
00850 _bxp->xxx[_nr] = _v;
00851 _bxp->req[_nr] = _s;
00852 }
00853 return _bxp;
00854
00855 error:
00856 tr_byxxx_free(_bxp);
00857 return NULL;
00858 }
00859
00860 int ic_parse_wkst(char *_in)
00861 {
00862 if(!_in || strlen(_in)!=2)
00863 goto error;
00864
00865 switch(_in[0])
00866 {
00867 case 's':
00868 case 'S':
00869 switch(_in[1])
00870 {
00871 case 'a':
00872 case 'A':
00873 return WDAY_SA;
00874 case 'u':
00875 case 'U':
00876 return WDAY_SU;
00877 default:
00878 goto error;
00879 }
00880 case 'm':
00881 case 'M':
00882 if(_in[1]!='o' && _in[1]!='O')
00883 goto error;
00884 return WDAY_MO;
00885 case 't':
00886 case 'T':
00887 switch(_in[1])
00888 {
00889 case 'h':
00890 case 'H':
00891 return WDAY_TH;
00892 case 'u':
00893 case 'U':
00894 return WDAY_TU;
00895 default:
00896 goto error;
00897 }
00898 case 'w':
00899 case 'W':
00900 if(_in[1]!='e' && _in[1]!='E')
00901 goto error;
00902 return WDAY_WE;
00903 case 'f':
00904 case 'F':
00905 if(_in[1]!='r' && _in[1]!='R')
00906 goto error;
00907 return WDAY_FR;
00908 break;
00909 default:
00910 goto error;
00911 }
00912
00913 error:
00914 #ifdef USE_YWEEK_U
00915 return WDAY_SU;
00916 #else
00917 return WDAY_MO;
00918 #endif
00919 }
00920
00921
00922
00923
00924
00925
00926
00927
00928 #define REC_ERR -1
00929 #define REC_MATCH 0
00930 #define REC_NOMATCH 1
00931
00932 #define _IS_SET(x) (((x)>0)?1:0)
00933
00934
00935 int get_min_interval(tmrec_p);
00936 int check_min_unit(tmrec_p, ac_tm_p, tr_res_p);
00937 int check_freq_interval(tmrec_p _trp, ac_tm_p _atp);
00938 int check_byxxx(tmrec_p, ac_tm_p);
00939
00940
00941
00942
00943
00944
00945
00946 int check_tmrec(tmrec_p _trp, ac_tm_p _atp, tr_res_p _tsw)
00947 {
00948 if(!_trp || !_atp || (!_IS_SET(_trp->duration) && !_IS_SET(_trp->dtend)))
00949 return REC_ERR;
00950
00951
00952 if(_atp->time < _trp->dtstart)
00953 return REC_NOMATCH;
00954
00955
00956 if(!_IS_SET(_trp->duration))
00957 _trp->duration = _trp->dtend - _trp->dtstart;
00958
00959 if(_atp->time <= _trp->dtstart+_trp->duration)
00960 {
00961 if(_tsw)
00962 {
00963 if(_tsw->flag & TSW_RSET)
00964 {
00965 if(_tsw->rest>_trp->dtstart+_trp->duration-_atp->time)
00966 _tsw->rest = _trp->dtstart+_trp->duration - _atp->time;
00967 }
00968 else
00969 {
00970 _tsw->flag |= TSW_RSET;
00971 _tsw->rest = _trp->dtstart+_trp->duration - _atp->time;
00972 }
00973 }
00974 return REC_MATCH;
00975 }
00976
00977
00978 if(_IS_SET(_trp->until) && _atp->time >= _trp->until + _trp->duration)
00979 return REC_NOMATCH;
00980
00981
00982 if(check_freq_interval(_trp, _atp)!=REC_MATCH)
00983 return REC_NOMATCH;
00984
00985 if(check_min_unit(_trp, _atp, _tsw)!=REC_MATCH)
00986 return REC_NOMATCH;
00987
00988 if(check_byxxx(_trp, _atp)!=REC_MATCH)
00989 return REC_NOMATCH;
00990
00991 return REC_MATCH;
00992 }
00993
00994
00995 int check_freq_interval(tmrec_p _trp, ac_tm_p _atp)
00996 {
00997 int _t0, _t1;
00998 struct tm _tm;
00999 if(!_trp || !_atp)
01000 return REC_ERR;
01001
01002 if(!_IS_SET(_trp->freq))
01003 return REC_NOMATCH;
01004
01005 if(!_IS_SET(_trp->interval) || _trp->interval==1)
01006 return REC_MATCH;
01007
01008 switch(_trp->freq)
01009 {
01010 case FREQ_DAILY:
01011 case FREQ_WEEKLY:
01012 memset(&_tm, 0, sizeof(struct tm));
01013 _tm.tm_year = _trp->ts.tm_year;
01014 _tm.tm_mon = _trp->ts.tm_mon;
01015 _tm.tm_mday = _trp->ts.tm_mday;
01016 _t0 = (int)mktime(&_tm);
01017 memset(&_tm, 0, sizeof(struct tm));
01018 _tm.tm_year = _atp->t.tm_year;
01019 _tm.tm_mon = _atp->t.tm_mon;
01020 _tm.tm_mday = _atp->t.tm_mday;
01021 _t1 = (int)mktime(&_tm);
01022 if(_trp->freq == FREQ_DAILY)
01023 return (((_t1-_t0)/(24*3600))%_trp->interval==0)?
01024 REC_MATCH:REC_NOMATCH;
01025 #ifdef USE_YWEEK_U
01026 _t0 -= _trp->ts.tm_wday*24*3600;
01027 _t1 -= _atp->t.tm_wday*24*3600;
01028 #else
01029 _t0 -= ((_trp->ts.tm_wday+6)%7)*24*3600;
01030 _t1 -= ((_atp->t.tm_wday+6)%7)*24*3600;
01031 #endif
01032 return (((_t1-_t0)/(7*24*3600))%_trp->interval==0)?
01033 REC_MATCH:REC_NOMATCH;
01034 case FREQ_MONTHLY:
01035 _t0 = (_atp->t.tm_year-_trp->ts.tm_year)*12
01036 + _atp->t.tm_mon-_trp->ts.tm_mon;
01037 return (_t0%_trp->interval==0)?REC_MATCH:REC_NOMATCH;
01038 case FREQ_YEARLY:
01039 return ((_atp->t.tm_year-_trp->ts.tm_year)%_trp->interval==0)?
01040 REC_MATCH:REC_NOMATCH;
01041 }
01042
01043 return REC_NOMATCH;
01044 }
01045
01046 int get_min_interval(tmrec_p _trp)
01047 {
01048 if(!_trp)
01049 return FREQ_NOFREQ;
01050
01051 if(_trp->freq == FREQ_DAILY || _trp->byday || _trp->bymday || _trp->byyday)
01052 return FREQ_DAILY;
01053 if(_trp->freq == FREQ_WEEKLY || _trp->byweekno)
01054 return FREQ_WEEKLY;
01055 if(_trp->freq == FREQ_MONTHLY || _trp->bymonth)
01056 return FREQ_MONTHLY;
01057 if(_trp->freq == FREQ_YEARLY)
01058 return FREQ_YEARLY;
01059
01060 return FREQ_NOFREQ;
01061 }
01062
01063 int check_min_unit(tmrec_p _trp, ac_tm_p _atp, tr_res_p _tsw)
01064 {
01065 int _v0, _v1;
01066 if(!_trp || !_atp)
01067 return REC_ERR;
01068 switch(get_min_interval(_trp))
01069 {
01070 case FREQ_DAILY:
01071 break;
01072 case FREQ_WEEKLY:
01073 if(_trp->ts.tm_wday != _atp->t.tm_wday)
01074 return REC_NOMATCH;
01075 break;
01076 case FREQ_MONTHLY:
01077 if(_trp->ts.tm_mday != _atp->t.tm_mday)
01078 return REC_NOMATCH;
01079 break;
01080 case FREQ_YEARLY:
01081 if(_trp->ts.tm_mon != _atp->t.tm_mon
01082 || _trp->ts.tm_mday != _atp->t.tm_mday)
01083 return REC_NOMATCH;
01084 break;
01085 default:
01086 return REC_NOMATCH;
01087 }
01088 _v0 = _trp->ts.tm_hour*3600 + _trp->ts.tm_min*60 + _trp->ts.tm_sec;
01089 _v1 = _atp->t.tm_hour*3600 + _atp->t.tm_min*60 + _atp->t.tm_sec;
01090 if(_v1 >= _v0 && _v1 < _v0 + _trp->duration)
01091 {
01092 if(_tsw)
01093 {
01094 if(_tsw->flag & TSW_RSET)
01095 {
01096 if(_tsw->rest>_v0+_trp->duration-_v1)
01097 _tsw->rest = _v0 + _trp->duration - _v1;
01098 }
01099 else
01100 {
01101 _tsw->flag |= TSW_RSET;
01102 _tsw->rest = _v0 + _trp->duration - _v1;
01103 }
01104 }
01105 return REC_MATCH;
01106 }
01107
01108 return REC_NOMATCH;
01109 }
01110
01111 int check_byxxx(tmrec_p _trp, ac_tm_p _atp)
01112 {
01113 int i;
01114 ac_maxval_p _amp = NULL;
01115 if(!_trp || !_atp)
01116 return REC_ERR;
01117 if(!_trp->byday && !_trp->bymday && !_trp->byyday && !_trp->bymonth
01118 && !_trp->byweekno)
01119 return REC_MATCH;
01120
01121 _amp = ac_get_maxval(_atp);
01122 if(!_amp)
01123 return REC_NOMATCH;
01124
01125 if(_trp->bymonth)
01126 {
01127 for(i=0; i<_trp->bymonth->nr; i++)
01128 {
01129 if(_atp->t.tm_mon ==
01130 (_trp->bymonth->xxx[i]*_trp->bymonth->req[i]+12)%12)
01131 break;
01132 }
01133 if(i>=_trp->bymonth->nr)
01134 return REC_NOMATCH;
01135 }
01136 if(_trp->freq==FREQ_YEARLY && _trp->byweekno)
01137 {
01138 for(i=0; i<_trp->byweekno->nr; i++)
01139 {
01140 if(_atp->yweek == (_trp->byweekno->xxx[i]*_trp->byweekno->req[i]+
01141 _amp->yweek)%_amp->yweek)
01142 break;
01143 }
01144 if(i>=_trp->byweekno->nr)
01145 return REC_NOMATCH;
01146 }
01147 if(_trp->byyday)
01148 {
01149 for(i=0; i<_trp->byyday->nr; i++)
01150 {
01151 if(_atp->t.tm_yday == (_trp->byyday->xxx[i]*_trp->byyday->req[i]+
01152 _amp->yday)%_amp->yday)
01153 break;
01154 }
01155 if(i>=_trp->byyday->nr)
01156 return REC_NOMATCH;
01157 }
01158 if(_trp->bymday)
01159 {
01160 for(i=0; i<_trp->bymday->nr; i++)
01161 {
01162 #ifdef EXTRA_DEBUG
01163 DBG("Req:bymday: %d == %d\n", _atp->t.tm_mday,
01164 (_trp->bymday->xxx[i]*_trp->bymday->req[i]+
01165 _amp->mday)%_amp->mday + ((_trp->bymday->req[i]<0)?1:0));
01166 #endif
01167 if(_atp->t.tm_mday == (_trp->bymday->xxx[i]*_trp->bymday->req[i]+
01168 _amp->mday)%_amp->mday + (_trp->bymday->req[i]<0)?1:0)
01169 break;
01170 }
01171 if(i>=_trp->bymday->nr)
01172 return REC_NOMATCH;
01173 }
01174 if(_trp->byday)
01175 {
01176 for(i=0; i<_trp->byday->nr; i++)
01177 {
01178 if(_trp->freq==FREQ_YEARLY)
01179 {
01180 #ifdef EXTRA_DEBUG
01181 DBG("Req:byday:y: %d==%d && %d==%d\n", _atp->t.tm_wday,
01182 _trp->byday->xxx[i], _atp->ywday+1,
01183 (_trp->byday->req[i]+_amp->ywday)%_amp->ywday);
01184 #endif
01185 if(_atp->t.tm_wday == _trp->byday->xxx[i] &&
01186 _atp->ywday+1 == (_trp->byday->req[i]+_amp->ywday)%
01187 _amp->ywday)
01188 break;
01189 }
01190 else
01191 {
01192 if(_trp->freq==FREQ_MONTHLY)
01193 {
01194 #ifdef EXTRA_DEBUG
01195 DBG("Req:byday:m: %d==%d && %d==%d\n", _atp->t.tm_wday,
01196 _trp->byday->xxx[i], _atp->mwday+1,
01197 (_trp->byday->req[i]+_amp->mwday)%_amp->mwday);
01198 #endif
01199 if(_atp->t.tm_wday == _trp->byday->xxx[i] &&
01200 _atp->mwday+1==(_trp->byday->req[i]+
01201 _amp->mwday)%_amp->mwday)
01202 break;
01203 }
01204 else
01205 {
01206 if(_atp->t.tm_wday == _trp->byday->xxx[i])
01207 break;
01208 }
01209 }
01210 }
01211 if(i>=_trp->byday->nr)
01212 return REC_NOMATCH;
01213 }
01214
01215 return REC_MATCH;
01216 }
01217
01218