Mercurial > bday
comparison bday.c @ 18:c1cd1d444353
removed the type event: bday is only for birthdays and anniversaries
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Mon, 24 Feb 2014 21:32:18 +0100 |
parents | d18a3b2b76bd |
children |
comparison
equal
deleted
inserted
replaced
17:d18a3b2b76bd | 18:c1cd1d444353 |
---|---|
28 | 28 |
29 date flags text | 29 date flags text |
30 | 30 |
31 where: | 31 where: |
32 date is YYYY-MM-DD | 32 date is YYYY-MM-DD |
33 flags is ONE or ZERO of | 33 flags is optionally |
34 #ann for an anniversary | 34 #ann for an anniversary |
35 #ev for an event | 35 and optionally |
36 and zero or more of | |
37 #w<n> to set the warn-in-advance time to n days | 36 #w<n> to set the warn-in-advance time to n days |
38 (don't include the brackets! :) | 37 (don't include the brackets! :) |
39 #to<date> | |
40 #for<days> | |
41 to specify the length of time taken by an | |
42 event, for example a holiday | |
43 separated by spaces. | 38 separated by spaces. |
44 | 39 |
45 Lines preceeded by # are treated as comments. | 40 Lines preceeded by # are treated as comments. |
46 | 41 |
47 Note: If you deviate from this format, I cannot guarantee anything about | 42 Note: If you deviate from this format, I cannot guarantee anything about |
70 | 65 |
71 | 66 |
72 /* -------- modifier flags */ | 67 /* -------- modifier flags */ |
73 #define F_MTYPE 0x07 | 68 #define F_MTYPE 0x07 |
74 #define F_TANNIVERSARY 2 | 69 #define F_TANNIVERSARY 2 |
75 #define F_TEVENT 3 | |
76 | 70 |
77 /* flags processed immediately on encountering */ | 71 /* flags processed immediately on encountering */ |
78 #define F_MIMMEDIATE 0x24 | 72 #define F_MIMMEDIATE 0x24 |
79 #define F_WTIME_P 0x08 | 73 #define F_WTIME_P 0x08 |
80 #define F_FORDAYS 0x16 | |
81 #define F_TODATE 0x24 | |
82 | 74 |
83 struct _ftable { | 75 struct _ftable { |
84 char* txt; | 76 char* txt; |
85 unsigned flag; | 77 unsigned flag; |
86 }; | 78 }; |
93 }; | 85 }; |
94 | 86 |
95 struct event { | 87 struct event { |
96 char* text; | 88 char* text; |
97 struct date date; | 89 struct date date; |
98 struct date enddate; | |
99 int warn; | 90 int warn; |
100 }; | 91 }; |
101 | 92 |
102 /* ========== Global Variables */ | 93 /* ========== Global Variables */ |
103 | 94 |
116 int def_warn = DEF_WARN; | 107 int def_warn = DEF_WARN; |
117 | 108 |
118 | 109 |
119 const struct _ftable FTABLE[] = { | 110 const struct _ftable FTABLE[] = { |
120 {"#ann",F_TANNIVERSARY}, | 111 {"#ann",F_TANNIVERSARY}, |
121 {"#ev", F_TEVENT}, | |
122 {"#w", F_WTIME_P}, | 112 {"#w", F_WTIME_P}, |
123 {"#to", F_TODATE}, | |
124 {"#for", F_FORDAYS}, | |
125 {NULL, 0} | 113 {NULL, 0} |
126 }; | 114 }; |
127 | 115 |
128 | 116 |
129 | 117 |
320 the string to a function. | 308 the string to a function. |
321 */ | 309 */ |
322 void | 310 void |
323 liststrings(struct event *evl) | 311 liststrings(struct event *evl) |
324 { | 312 { |
325 int i,j; | 313 int i; |
326 char *buf, *tmp; | 314 char *buf, *tmp; |
327 int size; | 315 int size; |
328 | 316 |
329 for (i=0; evl[i].text; i++) { | 317 for (i=0; evl[i].text; i++) { |
330 size = 128; | 318 size = 128; |
331 buf = xmalloc(size); | 319 buf = xmalloc(size); |
332 *buf = '\0'; | 320 *buf = '\0'; |
333 | 321 |
334 if (evl[i].warn == -1 && delta(&(evl[i].date))==0) { | 322 if (evl[i].warn == -1 && delta(&(evl[i].date))==0) { |
335 size = append(buf, size, evl[i].text); | 323 size = append(buf, size, evl[i].text); |
336 } else if (evl[i].enddate.day == 0) { | 324 } else if (delta(&(evl[i].date)) <= evl[i].warn) { |
337 | 325 tmp = tdelta(&(evl[i].date)); |
338 if (delta(&(evl[i].date)) <= evl[i].warn) { | 326 size = append(buf, size, tmp); |
339 tmp = tdelta(&(evl[i].date)); | 327 size = append(buf, size, ": "); |
340 size = append(buf, size, tmp); | 328 size = append(buf, size, evl[i].text); |
341 size = append(buf, size, ": "); | 329 free(tmp); |
342 size = append(buf, size, evl[i].text); | |
343 free(tmp); | |
344 } | |
345 } else { | |
346 if (delta(&(evl[i].date)) <= evl[i].warn) { | |
347 size = append(buf, size, evl[i].text); | |
348 size = append(buf, size, " for "); | |
349 /* +1 because, if the difference between | |
350 two dates is one day, then the length of | |
351 an event on those days is two days */ | |
352 j = ddiff(&(evl[i].date),&(evl[i].enddate)) + 1; | |
353 tmp = ttime(0, 0, j/7, j%7); | |
354 size = append(buf, size, tmp); | |
355 free(tmp); | |
356 size = append(buf, size, " "); | |
357 tmp = tdelta(&(evl[i].date)); | |
358 size = append(buf, size, tmp); | |
359 } else if (delta(&(evl[i].enddate)) <= evl[i].warn) { | |
360 size = append(buf, size, evl[i].text); | |
361 size = append(buf, size, " "); | |
362 j = delta(&(evl[i].enddate)); | |
363 if (j) { | |
364 size = append(buf, size, "for "); | |
365 tmp = ttime(0, 0, j/7, j%7); | |
366 size = append(buf, size, tmp); | |
367 free(tmp); | |
368 size = append(buf, size, " longer"); | |
369 } else { | |
370 size = append(buf, size, "finishes today"); | |
371 } | |
372 } | |
373 } | 330 } |
374 if (*buf) { | 331 if (*buf) { |
375 size = append(buf, size, "."); | 332 size = append(buf, size, "."); |
376 puts(buf); | 333 puts(buf); |
377 } | 334 } |
385 | 342 |
386 | 343 |
387 | 344 |
388 | 345 |
389 /* | 346 /* |
390 sort the events by the time before the next time they come up, | 347 sort the events by the time before the next time they come up |
391 putting those where the start has passed but we are still in the | |
392 time-period first | |
393 */ | 348 */ |
394 int | 349 int |
395 evcmp(const void *p1, const void *p2) | 350 evcmp(const void *p1, const void *p2) |
396 { | 351 { |
397 struct event *e1=(struct event *) p1; | 352 struct event *e1=(struct event *) p1; |
398 struct event *e2=(struct event *) p2; | 353 struct event *e2=(struct event *) p2; |
399 unsigned d1, d2; | 354 unsigned d1, d2; |
400 | 355 |
401 /* | |
402 if the delta for the enddate is less than that for the start | |
403 date, then we have passed the start date but not yet the end | |
404 date, and so we should display the enddate; otherwise, we | |
405 should display the start date | |
406 */ | |
407 | |
408 d1=delta(&(e1->date)); | 356 d1=delta(&(e1->date)); |
409 if (e1->enddate.day && delta(&(e1->enddate)) < d1) | |
410 d1=delta(&(e1->enddate)); | |
411 | |
412 d2=delta(&(e2->date)); | 357 d2=delta(&(e2->date)); |
413 if (e2->enddate.day && delta(&(e2->enddate)) < d2) | |
414 d2=delta(&(e2->enddate)); | |
415 | 358 |
416 if (d1 < d2) return -1; | 359 if (d1 < d2) return -1; |
417 if (d1 > d2) return 1; | 360 if (d1 > d2) return 1; |
418 | |
419 return strcmp(e1->text, e2->text); | 361 return strcmp(e1->text, e2->text); |
420 } | 362 } |
421 | 363 |
422 | 364 |
423 | 365 |
543 | 485 |
544 | 486 |
545 struct event * | 487 struct event * |
546 readlist() | 488 readlist() |
547 { | 489 { |
548 int i, j, k, l, d; | 490 int i, j, k; |
549 struct event *evl; | 491 struct event *evl; |
550 char buf[1024], buf2[1024]; | 492 char buf[1024], buf2[1024]; |
551 char *ptr, *cp; | 493 char *ptr, *cp; |
552 unsigned flags; | 494 unsigned flags; |
553 | 495 |
554 /* initialise */ | 496 /* initialise */ |
555 gettoday(); | 497 gettoday(); |
556 | 498 |
557 for (i = 0, evl = NULL; fgets(buf, sizeof(buf), stdin) != NULL; i++) { | 499 for (i=0, evl=NULL; fgets(buf, sizeof(buf), stdin) != NULL; i++) { |
558 evl = (struct event *) xrealloc(evl, sizeof(struct event) * (i + 1)); | 500 evl = (struct event *) xrealloc(evl, sizeof(struct event) * (i + 1)); |
559 | 501 |
560 /* ignore comments and empty lines */ | 502 /* ignore comments and empty lines */ |
561 if (*buf == '#' || *buf == '\n') { | 503 if (*buf == '#' || *buf == '\n') { |
562 i--; | 504 i--; |
587 } | 529 } |
588 | 530 |
589 /* parse flags */ | 531 /* parse flags */ |
590 | 532 |
591 evl[i].warn = def_warn; | 533 evl[i].warn = def_warn; |
592 evl[i].enddate.day = 0; | |
593 evl[i].enddate.month = 0; | |
594 evl[i].enddate.year = 0; | |
595 | |
596 flags = 0; | 534 flags = 0; |
597 j = 0; | 535 j = 0; |
598 cp = skptok(ptr); | 536 cp = skptok(ptr); |
599 for (cp=ptr; *cp && *cp=='#'; cp=skptok(cp)) { | 537 for (cp=ptr; *cp && *cp=='#'; cp=skptok(cp)) { |
600 for (k = 0; FTABLE[k].txt && strncmp(FTABLE[k].txt, cp, strlen(FTABLE[k].txt)); k++) { | 538 for (k = 0; FTABLE[k].txt && strncmp(FTABLE[k].txt, cp, strlen(FTABLE[k].txt)); k++) { |
601 } | 539 } |
602 | 540 |
603 switch (FTABLE[k].flag) { | 541 switch (FTABLE[k].flag) { |
604 case F_WTIME_P: /* #w<n> -- sets warning time */ | 542 case F_WTIME_P: /* #w<n> -- sets warning time */ |
605 sscanf(cp, "#w%u", &(evl[i].warn)); | 543 sscanf(cp, "#w%u", &(evl[i].warn)); |
606 break; | |
607 case F_FORDAYS: /* #for<days> -- sets the duration of the event */ | |
608 sscanf(cp, "#for%u", &d); | |
609 evl[i].enddate=evl[i].date; | |
610 for (l = 1; l < d; l++) { | |
611 evl[i].enddate.day++; | |
612 if (evl[i].enddate.day > mlen(evl[i].enddate.month, evl[i].enddate.year)) { | |
613 evl[i].enddate.month++; | |
614 evl[i].enddate.day = 1; | |
615 } | |
616 if (evl[i].enddate.month > 12) { | |
617 evl[i].enddate.year++; | |
618 evl[i].enddate.month = 1; | |
619 } | |
620 } | |
621 break; | |
622 case F_TODATE: /* #to<date> -- sets the end date of the event */ | |
623 l = sscanf(cp, "#to%u-%u-%u", &(evl[i].enddate.year), &(evl[i].enddate.month), &(evl[i].enddate.day)); | |
624 if (l == 2) { | |
625 evl[i].enddate.year = 0; | |
626 } | |
627 break; | 544 break; |
628 case 0: | 545 case 0: |
629 break; | 546 break; |
630 default: | 547 default: |
631 flags |= FTABLE[k].flag; | 548 flags |= FTABLE[k].flag; |
652 cp, ydelta(evl[i].date, today)); | 569 cp, ydelta(evl[i].date, today)); |
653 } else { | 570 } else { |
654 strcpy(buf2, cp); | 571 strcpy(buf2, cp); |
655 } | 572 } |
656 break; | 573 break; |
657 case F_TEVENT: | |
658 /* if a year was specified, and this | |
659 warning isn't for it, ignore! */ | |
660 if ((evl[i].date.year && ydelta(evl[i].date, today)) | |
661 && (!evl[i].enddate.year || ydelta(evl[i].enddate, today))) { | |
662 i--; | |
663 continue; | |
664 } | |
665 strcpy(buf2, cp); | |
666 break; | |
667 } | 574 } |
668 evl[i].text = strdup(buf2); | 575 evl[i].text = strdup(buf2); |
669 } | 576 } |
670 | 577 |
671 evl = (struct event *) xrealloc(evl, sizeof(struct event) * (i + 1)); | 578 evl = (struct event *) xrealloc(evl, sizeof(struct event) * (i + 1)); |