Mercurial > bday
comparison bday.c @ 16:79d22407a6be
a lot of refactoring
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Mon, 24 Feb 2014 21:11:38 +0100 |
parents | 032af48d590b |
children | d18a3b2b76bd |
comparison
equal
deleted
inserted
replaced
15:032af48d590b | 16:79d22407a6be |
---|---|
24 ===================================================================== | 24 ===================================================================== |
25 | 25 |
26 Input is read through standard input. For example: bday < ~/.birthdays | 26 Input is read through standard input. For example: bday < ~/.birthdays |
27 The input (file) has to have the following format: | 27 The input (file) has to have the following format: |
28 | 28 |
29 text=date flags | 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 ONE or ZERO of |
34 bd for a birthday (default) | 34 #ann for an anniversary |
35 ann for an anniversary | 35 #ev for an event |
36 ev for an event | |
37 and zero or more of | 36 and zero or more of |
38 w <n> to set the warn-in-advance time to n days | 37 #w<n> to set the warn-in-advance time to n days |
39 (don't include the brackets! :) | 38 (don't include the brackets! :) |
40 to <date> | 39 #to<date> |
41 for <days> | 40 #for<days> |
42 to specify the length of time taken by an | 41 to specify the length of time taken by an |
43 event, for example a holiday. | 42 event, for example a holiday |
43 separated by spaces. | |
44 | 44 |
45 Lines preceeded by # are treated as comments. | 45 Lines preceeded by # are treated as comments. |
46 | 46 |
47 Note: If you deviate from this format, I cannot guarantee anything about | 47 Note: If you deviate from this format, I cannot guarantee anything about |
48 it's behaviour. In most cases, it will just quietly ignore the | 48 it's behaviour. In most cases, it will just quietly ignore the |
67 | 67 |
68 | 68 |
69 /* ========== Global constants and data types */ | 69 /* ========== Global constants and data types */ |
70 | 70 |
71 | 71 |
72 /* month lengths etc */ | |
73 #define isleapyear(y) ((y)%4==0 && ((y)%100 != 0 || (y)%400 == 0)) | |
74 const unsigned MLENDAT[]; | |
75 #define mlen(m,y) (MLENDAT[(m)-1] != -1 ? MLENDAT[(m)-1] : (isleapyear((y)) ? 29 : 28)) | |
76 #define before(a,b) ((a).month < (b).month || ((a).month == (b).month && (a).day < (b).day)) | |
77 #define ydelta(a,b) ((int) (b).year - (a).year + before((a),(b))) | |
78 | |
79 /* -------- modifier flags */ | 72 /* -------- modifier flags */ |
80 #define F_MTYPE 0x07 | 73 #define F_MTYPE 0x07 |
81 #define F_TBIRTHDAY 1 | |
82 #define F_TANNIVERSARY 2 | 74 #define F_TANNIVERSARY 2 |
83 #define F_TEVENT 3 | 75 #define F_TEVENT 3 |
84 | 76 |
85 /* flags processed immediately on encountering */ | 77 /* flags processed immediately on encountering */ |
86 #define F_MIMMEDIATE 0x24 | 78 #define F_MIMMEDIATE 0x24 |
87 #define F_WTIME_P 0x08 | 79 #define F_WTIME_P 0x08 |
88 #define F_FORDAYS 0x16 | 80 #define F_FORDAYS 0x16 |
89 #define F_TODATE 0x24 | 81 #define F_TODATE 0x24 |
90 | 82 |
91 struct _ftable {char* txt; unsigned flag;}; | 83 struct _ftable { |
92 | 84 char* txt; |
85 unsigned flag; | |
86 }; | |
93 const struct _ftable FTABLE[]; | 87 const struct _ftable FTABLE[]; |
94 | 88 |
95 struct date { | 89 struct date { |
96 unsigned day; | 90 unsigned day; |
97 unsigned month; | 91 unsigned month; |
103 struct date date; | 97 struct date date; |
104 struct date enddate; | 98 struct date enddate; |
105 int warn; | 99 int warn; |
106 }; | 100 }; |
107 | 101 |
108 typedef int (*prnfunc)(const char *); | |
109 | |
110 /* ========== Global Variables */ | 102 /* ========== Global Variables */ |
111 | 103 |
112 struct event *readlist(void); | 104 struct event *readlist(void); |
113 void gettoday(void); | 105 void gettoday(void); |
114 unsigned delta(struct date *); | 106 unsigned delta(struct date *); |
115 unsigned ddiff(struct date *D1, struct date *D2); | 107 unsigned ddiff(struct date *D1, struct date *D2); |
116 void liststrings(struct event *evl, prnfunc outf); | 108 void liststrings(struct event *evl); |
117 char *tdelta(struct date *d); | 109 char *tdelta(struct date *d); |
118 char *ttime(int yr, int mn, int wk, int dy); | 110 char *ttime(int yr, int mn, int wk, int dy); |
119 int skptok(int j, char *ptr); | 111 char *skptok(char *ptr); |
120 int evcmp(const void *e1, const void *e2); | 112 int evcmp(const void *e1, const void *e2); |
121 | 113 |
122 | 114 |
123 struct date today; | 115 struct date today; |
124 int iDWarn = DEF_WARN; | 116 int def_warn = DEF_WARN; |
125 | 117 |
126 const unsigned MLENDAT[] = {31,-1,31,30,31,30,31,31,30,31,30,31}; | |
127 | 118 |
128 const struct _ftable FTABLE[] = { | 119 const struct _ftable FTABLE[] = { |
129 {"bd", F_TBIRTHDAY}, | 120 {"#ann",F_TANNIVERSARY}, |
130 {"ann",F_TANNIVERSARY}, | 121 {"#ev", F_TEVENT}, |
131 {"ev", F_TEVENT}, | 122 {"#w", F_WTIME_P}, |
132 {"w", F_WTIME_P}, | 123 {"#to", F_TODATE}, |
133 {"to", F_TODATE}, | 124 {"#for", F_FORDAYS}, |
134 {"for", F_FORDAYS}, | |
135 {NULL, 0} | 125 {NULL, 0} |
136 }; | 126 }; |
137 | 127 |
138 | 128 |
139 | 129 |
172 /* ========== */ | 162 /* ========== */ |
173 | 163 |
174 | 164 |
175 /* | 165 /* |
176 like strcat(), but lets the buffer automagically grow :-) | 166 like strcat(), but lets the buffer automagically grow :-) |
177 (needs local variable "size" with the buffer size) | 167 */ |
178 */ | 168 int |
179 #define append(where, what) do { \ | 169 append(char *where, int size, char *what) |
180 if (strlen(what) > (size - strlen(where))) { \ | 170 { |
181 xrealloc(where, size + 128 + strlen(what)); \ | 171 if (strlen(what) > ((size) - strlen(where))) { |
182 size += 128 + strlen(what); \ | 172 xrealloc(where, (size) + 128 + strlen(what)); |
183 } \ | 173 size += 128 + strlen(what); |
184 strcat(where, what); \ | 174 } |
185 } while(0) | 175 strcat(where, what); |
176 return size; | |
177 } | |
186 | 178 |
187 /* ========== */ | 179 /* ========== */ |
180 | |
181 | |
182 int | |
183 before(struct date a, struct date b) | |
184 { | |
185 if (a.month < b.month) { | |
186 return 1; | |
187 } else if (a.month == b.month && a.day < b.day) { | |
188 return 1; | |
189 } else { | |
190 return 0; | |
191 } | |
192 } | |
193 | |
194 int | |
195 ydelta(struct date a, struct date b) | |
196 { | |
197 return b.year - a.year + before(a, b); | |
198 } | |
199 | |
200 /* | |
201 returns the length of the given month | |
202 */ | |
203 int | |
204 mlen(int month, int year) | |
205 { | |
206 unsigned mlendat[] = {31,0,31,30,31,30,31,31,30,31,30,31}; | |
207 | |
208 if (mlendat[month - 1]) { | |
209 return mlendat[month - 1]; | |
210 } else { | |
211 if (year%4==0 && (year%100!=0 || year%400==0)) { | |
212 return 29; | |
213 } else { | |
214 return 28; | |
215 } | |
216 } | |
217 } | |
218 | |
219 | |
188 | 220 |
189 /* | 221 /* |
190 returns delta(d) in days, weeks, months, etc | 222 returns delta(d) in days, weeks, months, etc |
191 the returned buffer is malloc()ed, do not forget to free() it | 223 the returned buffer is malloc()ed, do not forget to free() it |
192 */ | 224 */ |
199 int size = 128; | 231 int size = 128; |
200 | 232 |
201 *buf = 0; | 233 *buf = 0; |
202 switch (delta(d)) { | 234 switch (delta(d)) { |
203 case 0: | 235 case 0: |
204 append(buf, "today"); | 236 size = append(buf, size, "TODAY"); |
205 return buf; | 237 return buf; |
206 case 1: | 238 case 1: |
207 append(buf, "tomorrow"); | 239 size = append(buf, size, "Tomorrow"); |
208 return buf; | 240 return buf; |
209 default: | 241 default: |
210 /* like delta(), we ignore the year */ | 242 /* like delta(), we ignore the year */ |
211 yr = -before(*d, today); | 243 yr = -before(*d, today); |
212 mn = d->month - today.month; | 244 mn = d->month - today.month; |
222 } | 254 } |
223 | 255 |
224 wk = (dy / 7); | 256 wk = (dy / 7); |
225 dy %= 7; | 257 dy %= 7; |
226 | 258 |
227 append(buf, "in "); | 259 size = append(buf, size, "In "); |
228 tmp = ttime(yr, mn, wk, dy); | 260 tmp = ttime(yr, mn, wk, dy); |
229 append(buf, tmp); | 261 size = append(buf, size, tmp); |
230 free(tmp); | 262 free(tmp); |
231 | 263 |
232 return buf; | 264 return buf; |
233 } | 265 } |
234 } | 266 } |
235 | 267 |
236 | 268 |
237 | 269 |
238 | 270 |
239 | 271 |
240 /* | |
241 void | 272 void |
242 donum(n,txt) | 273 donum(char *buf, int size, int n, char *txt, int *terms) |
243 { | 274 { |
244 if (n > 0) { | 275 char tmp[128]; |
245 snprintf(tmp, sizeof(tmp), "%d", n); | 276 |
246 append(buf, tmp); | 277 if (n <= 0) { |
247 append(buf, " " txt); | 278 return; |
248 if (n != 1) | 279 } |
249 append(buf, "s"); | 280 snprintf(tmp, sizeof(tmp), "%d", n); |
250 terms--; | 281 size = append(buf, size, tmp); |
251 if (orgterms > 1) { | 282 size = append(buf, size, " "); |
252 if (terms == 1) | 283 size = append(buf, size, txt); |
253 append(buf, " and "); | 284 if (n != 1) { |
254 else if (terms > 1) | 285 size = append(buf, size, "s"); |
255 append(buf, ", "); | 286 } |
256 } | 287 if (--*terms == 1) { |
257 } | 288 size = append(buf, size, " and "); |
258 } | 289 } else if (*terms > 1) { |
259 */ | 290 size = append(buf, size, ", "); |
260 | 291 } |
261 | 292 } |
262 #define donum(n,txt) do { \ | |
263 if (n > 0) { \ | |
264 snprintf(tmp, sizeof(tmp), "%d", n); \ | |
265 append(buf, tmp); \ | |
266 append(buf, " " txt); \ | |
267 if (n != 1) \ | |
268 append(buf, "s"); \ | |
269 terms--; \ | |
270 if (orgterms > 1) { \ | |
271 if (terms == 1) \ | |
272 append(buf, " and "); \ | |
273 else if (terms > 1) \ | |
274 append(buf, ", "); \ | |
275 } \ | |
276 } \ | |
277 } while(0) | |
278 | 293 |
279 | 294 |
280 /* returns allocated buffer, don't forget to free() */ | 295 /* returns allocated buffer, don't forget to free() */ |
281 char * | 296 char * |
282 ttime(int yr, int mn, int wk, int dy) | 297 ttime(int yr, int mn, int wk, int dy) |
283 { | 298 { |
284 char *buf = xmalloc(128); | |
285 int size = 128; | 299 int size = 128; |
286 int terms, orgterms; | 300 char *buf = xmalloc(size); |
287 char tmp[128]; | 301 int terms = (yr!=0) + (mn!=0) + (wk!=0) + (dy!=0); |
288 | 302 |
289 *buf = 0; /* Initialize buffer */ | 303 *buf = '\0'; /* Initialize buffer */ |
290 terms = orgterms = (yr!=0) + (mn!=0) + (wk!=0) + (dy!=0); | 304 |
291 | 305 donum(buf, size, yr, "year", &terms); |
292 donum(yr, "year"); | 306 donum(buf, size, mn, "month", &terms); |
293 donum(mn, "month"); | 307 donum(buf, size, wk, "week", &terms); |
294 donum(wk, "week"); | 308 donum(buf, size, dy, "day", &terms); |
295 donum(dy, "day"); | |
296 | 309 |
297 return buf; | 310 return buf; |
298 } | 311 } |
299 #undef donum | |
300 | 312 |
301 | 313 |
302 | 314 |
303 | 315 |
304 | 316 |
306 /* | 318 /* |
307 lists the birthdays in their string format, one by one, and passes | 319 lists the birthdays in their string format, one by one, and passes |
308 the string to a function. | 320 the string to a function. |
309 */ | 321 */ |
310 void | 322 void |
311 liststrings(struct event *evl, prnfunc outf) | 323 liststrings(struct event *evl) |
312 { | 324 { |
313 int i,j; | 325 int i,j; |
314 char *buf, *tmp; | 326 char *buf, *tmp; |
315 int size; | 327 int size; |
316 | 328 |
317 for (i = 0; evl[i].text != NULL; i++) { | 329 for (i=0; evl[i].text; i++) { |
318 buf = xmalloc(128); | 330 size = 128; |
331 buf = xmalloc(size); | |
319 *buf = '\0'; | 332 *buf = '\0'; |
320 size = 128; | |
321 | 333 |
322 if (evl[i].warn == -1 && delta(&(evl[i].date))==0) { | 334 if (evl[i].warn == -1 && delta(&(evl[i].date))==0) { |
323 append(buf, evl[i].text); | 335 size = append(buf, size, evl[i].text); |
324 } else if (evl[i].enddate.day == 0) { | 336 } else if (evl[i].enddate.day == 0) { |
337 | |
325 if (delta(&(evl[i].date)) <= evl[i].warn) { | 338 if (delta(&(evl[i].date)) <= evl[i].warn) { |
326 append(buf, evl[i].text); | |
327 append(buf, " "); | |
328 tmp = tdelta(&(evl[i].date)); | 339 tmp = tdelta(&(evl[i].date)); |
329 append(buf, tmp); | 340 size = append(buf, size, tmp); |
341 size = append(buf, size, ": "); | |
342 size = append(buf, size, evl[i].text); | |
330 free(tmp); | 343 free(tmp); |
331 } | 344 } |
332 } else { | 345 } else { |
333 if (delta(&(evl[i].date)) <= evl[i].warn) { | 346 if (delta(&(evl[i].date)) <= evl[i].warn) { |
334 append(buf, evl[i].text); | 347 size = append(buf, size, evl[i].text); |
335 append(buf, " for "); | 348 size = append(buf, size, " for "); |
336 /* +1 because, if the difference between two dates is one day, | 349 /* +1 because, if the difference between |
337 then the length of an event on those days is two days */ | 350 two dates is one day, then the length of |
351 an event on those days is two days */ | |
338 j = ddiff(&(evl[i].date),&(evl[i].enddate)) + 1; | 352 j = ddiff(&(evl[i].date),&(evl[i].enddate)) + 1; |
339 tmp = ttime(0, 0, j/7, j%7); | 353 tmp = ttime(0, 0, j/7, j%7); |
340 append(buf, tmp); | 354 size = append(buf, size, tmp); |
341 free(tmp); | 355 free(tmp); |
342 append(buf, " "); | 356 size = append(buf, size, " "); |
343 tmp = tdelta(&(evl[i].date)); | 357 tmp = tdelta(&(evl[i].date)); |
344 append(buf, tmp); | 358 size = append(buf, size, tmp); |
345 } else if (delta(&(evl[i].enddate)) <= evl[i].warn) { | 359 } else if (delta(&(evl[i].enddate)) <= evl[i].warn) { |
346 append(buf, evl[i].text); | 360 size = append(buf, size, evl[i].text); |
347 append(buf, " "); | 361 size = append(buf, size, " "); |
348 j = delta(&(evl[i].enddate)); | 362 j = delta(&(evl[i].enddate)); |
349 if (j) { | 363 if (j) { |
350 append(buf, "for "); | 364 size = append(buf, size, "for "); |
351 tmp = ttime(0, 0, j/7, j%7); | 365 tmp = ttime(0, 0, j/7, j%7); |
352 append(buf, tmp); | 366 size = append(buf, size, tmp); |
353 free(tmp); | 367 free(tmp); |
354 append(buf, " longer"); | 368 size = append(buf, size, " longer"); |
355 } else { | 369 } else { |
356 append(buf, "finishes today"); | 370 size = append(buf, size, "finishes today"); |
357 } | 371 } |
358 } | 372 } |
359 } | 373 } |
360 if (*buf) { | 374 if (*buf) { |
361 append(buf, "."); | 375 size = append(buf, size, "."); |
362 outf(buf); | 376 puts(buf); |
363 } | 377 } |
364 free(buf); | 378 free(buf); |
365 } | 379 } |
366 } | 380 } |
367 | 381 |
532 readlist() | 546 readlist() |
533 { | 547 { |
534 int i, j, k, l, d; | 548 int i, j, k, l, d; |
535 struct event *evl; | 549 struct event *evl; |
536 char buf[1024], buf2[1024]; | 550 char buf[1024], buf2[1024]; |
537 char *ptr; | 551 char *ptr, *cp; |
538 unsigned flags; | 552 unsigned flags; |
539 | 553 |
540 /* initialise */ | 554 /* initialise */ |
541 gettoday(); | 555 gettoday(); |
542 | 556 |
548 i--; | 562 i--; |
549 continue; | 563 continue; |
550 } | 564 } |
551 | 565 |
552 /* parse string in buf */ | 566 /* parse string in buf */ |
553 ptr = strrchr(buf, '='); /* allow '=' in text */ | 567 |
568 ptr = strchr(buf, ' '); /* start of text */ | |
554 | 569 |
555 /* not a valid line, so ignore it! Cool, huh? */ | 570 /* not a valid line, so ignore it! Cool, huh? */ |
556 /* Attention: only recognizes lines without '=' */ | 571 /* Attention: only recognizes lines without '=' */ |
557 if (ptr == NULL) { | 572 if (!ptr) { |
558 fprintf(stderr, "WARNING: Invalid line in input:\n%s", buf); | 573 fprintf(stderr, "WARNING: Invalid input line:\n\t%s", buf); |
559 i--; | 574 i--; |
560 continue; | 575 continue; |
561 } | 576 } |
562 | 577 |
563 *(ptr++) = 0; | 578 *(ptr++) = '\0'; |
564 | 579 ptr[strlen(ptr)-1] = '\0'; |
565 j = sscanf(ptr, "%u-%u-%u", &(evl[i].date.year), | 580 |
581 j = sscanf(buf, "%u-%u-%u", &(evl[i].date.year), | |
566 &(evl[i].date.month), &(evl[i].date.day)); | 582 &(evl[i].date.month), &(evl[i].date.day)); |
567 /* ... unless it wasn't read, in which case set it to zero */ | 583 if (j != 3) { |
568 if (j==2) { | 584 fprintf(stderr, "Error: Invalid date:\t%s\n", buf); |
569 evl[i].date.year = 0; | 585 i--; |
570 } | 586 continue; |
571 | 587 } |
572 | 588 |
573 /* parse flags */ | 589 /* parse flags */ |
574 | 590 |
575 evl[i].warn = iDWarn; | 591 evl[i].warn = def_warn; |
576 evl[i].enddate.day = 0; | 592 evl[i].enddate.day = 0; |
577 evl[i].enddate.month = 0; | 593 evl[i].enddate.month = 0; |
578 evl[i].enddate.year = 0; | 594 evl[i].enddate.year = 0; |
579 | 595 |
580 flags = 0; | 596 flags = 0; |
581 j = 0; | 597 j = 0; |
582 | 598 cp = skptok(ptr); |
583 while(j = skptok(j, ptr), ptr[j] != 0) { | 599 for (cp=ptr; *cp && *cp=='#'; cp=skptok(cp)) { |
584 for (k = 0; FTABLE[k].txt != NULL && strncmp(FTABLE[k].txt, ptr + j, strlen(FTABLE[k].txt)); k++) { | 600 for (k = 0; FTABLE[k].txt && strncmp(FTABLE[k].txt, cp, strlen(FTABLE[k].txt)); k++) { |
585 } | 601 } |
586 | 602 |
587 switch (FTABLE[k].flag) { | 603 switch (FTABLE[k].flag) { |
588 case F_WTIME_P: /* w <n> -- sets warning time */ | 604 case F_WTIME_P: /* #w<n> -- sets warning time */ |
589 sscanf(ptr + j, "w %u", &(evl[i].warn)); | 605 sscanf(cp, "#w%u", &(evl[i].warn)); |
590 break; | 606 break; |
591 case F_FORDAYS: /* for <days> -- sets the duration of the event */ | 607 case F_FORDAYS: /* #for<days> -- sets the duration of the event */ |
592 sscanf(ptr + j, "for %u", &d); | 608 sscanf(cp, "#for%u", &d); |
593 evl[i].enddate=evl[i].date; | 609 evl[i].enddate=evl[i].date; |
594 for (l = 1; l < d; l++) { | 610 for (l = 1; l < d; l++) { |
595 evl[i].enddate.day++; | 611 evl[i].enddate.day++; |
596 if (evl[i].enddate.day > mlen(evl[i].enddate.month, evl[i].enddate.year)) { | 612 if (evl[i].enddate.day > mlen(evl[i].enddate.month, evl[i].enddate.year)) { |
597 evl[i].enddate.month++; | 613 evl[i].enddate.month++; |
601 evl[i].enddate.year++; | 617 evl[i].enddate.year++; |
602 evl[i].enddate.month = 1; | 618 evl[i].enddate.month = 1; |
603 } | 619 } |
604 } | 620 } |
605 break; | 621 break; |
606 case F_TODATE: /* to <date> -- sets the end date of the event */ | 622 case F_TODATE: /* #to<date> -- sets the end date of the event */ |
607 l = sscanf(ptr + j, "to %u-%u-%u", &(evl[i].enddate.year), &(evl[i].enddate.month), &(evl[i].enddate.day)); | 623 l = sscanf(cp, "#to%u-%u-%u", &(evl[i].enddate.year), &(evl[i].enddate.month), &(evl[i].enddate.day)); |
608 if (l == 2) { | 624 if (l == 2) { |
609 evl[i].enddate.year = 0; | 625 evl[i].enddate.year = 0; |
610 } | 626 } |
611 break; | 627 break; |
612 case 0: | 628 case 0: |
619 | 635 |
620 | 636 |
621 /* construct event text */ | 637 /* construct event text */ |
622 | 638 |
623 switch(flags & F_MTYPE) { | 639 switch(flags & F_MTYPE) { |
624 case F_TBIRTHDAY: | |
625 default: /* assume it's a birthday */ | 640 default: /* assume it's a birthday */ |
626 if (evl[i].date.year != 0) { | 641 if (!evl[i].date.year) { |
627 int tmp_age = ydelta(evl[i].date, today); | 642 sprintf(buf2, "%s has a birthday", cp); |
628 if (tmp_age != 1) { | 643 break; |
629 sprintf(buf2, "%s is %d years old", buf, tmp_age); | |
630 } else { | |
631 sprintf(buf2, "%s is %d year old", buf, tmp_age); | |
632 } | |
633 } else { | |
634 sprintf(buf2, "%s has a birthday", buf); | |
635 } | 644 } |
645 int tmp_age = ydelta(evl[i].date, today); | |
646 sprintf(buf2, "%s is %d year%s old", | |
647 cp, tmp_age, (tmp_age>1)?"s":""); | |
636 break; | 648 break; |
637 case F_TANNIVERSARY: | 649 case F_TANNIVERSARY: |
638 if (evl[i].date.year != 0) { | 650 if (evl[i].date.year) { |
639 sprintf(buf2, "%s %d years ago", buf, ydelta(evl[i].date, today)); | 651 sprintf(buf2, "%s %d years ago", |
652 cp, ydelta(evl[i].date, today)); | |
640 } else { | 653 } else { |
641 strcpy(buf2, buf); | 654 strcpy(buf2, cp); |
642 } | 655 } |
643 break; | 656 break; |
644 case F_TEVENT: | 657 case F_TEVENT: |
645 /* if a year was specified, and this warning isn't for it, ignore! */ | 658 /* if a year was specified, and this |
646 if ((evl[i].date.year != 0 && ydelta(evl[i].date, today) != 0) | 659 warning isn't for it, ignore! */ |
647 && (evl[i].enddate.year == 0 || ydelta(evl[i].enddate, today) != 0)) { | 660 if ((evl[i].date.year && ydelta(evl[i].date, today)) |
661 && (!evl[i].enddate.year || ydelta(evl[i].enddate, today))) { | |
648 i--; | 662 i--; |
649 continue; | 663 continue; |
650 } | 664 } |
651 strcpy(buf2, buf); | 665 strcpy(buf2, cp); |
652 break; | 666 break; |
653 } | 667 } |
654 evl[i].text = strdup(buf2); | 668 evl[i].text = strdup(buf2); |
655 } | 669 } |
656 | 670 |
669 | 683 |
670 | 684 |
671 | 685 |
672 | 686 |
673 | 687 |
674 int | 688 char * |
675 skptok(int j, char *ptr) | 689 skptok(char *ptr) |
676 { | 690 { |
677 for (; ptr[j] != 0 && ptr[j] != ' ' && ptr[j] != '\t' ; j++); | 691 while (*ptr && (*ptr!=' ' && *ptr!='\t')) { |
678 for (; ptr[j] != 0 && (ptr[j] == ' ' || ptr[j] == '\t'); j++); | 692 ptr++; |
679 | 693 } |
680 return j; | 694 while (*ptr && (*ptr==' ' || *ptr=='\t')) { |
695 ptr++; | |
696 } | |
697 return ptr; | |
681 } | 698 } |
682 | 699 |
683 | 700 |
684 | 701 |
685 | 702 |
686 | 703 |
687 | 704 |
688 int | 705 int |
689 main(int argc, char *argv[]) | 706 main(int argc, char *argv[]) |
690 { | 707 { |
691 while (--argc > 0 && (*++argv)[0] == '-') { | 708 while (--argc > 0 && **++argv == '-') { |
692 if (strcmp(argv[0], "-W") == 0) { | 709 if (strcmp(argv[0], "-W") == 0) { |
693 /* TODO: catch if no value given */ | 710 /* TODO: catch if no value given */ |
694 iDWarn = atoi((++argv)[0]); | 711 def_warn = atoi((++argv)[0]); |
695 argc--; | 712 argc--; |
696 } else { | 713 } else { |
697 fprintf(stderr, "unknown option %s\n", argv[0]); | 714 fprintf(stderr, "unknown option %s\n", argv[0]); |
698 exit(1); | 715 exit(1); |
699 } | 716 } |
700 } | 717 } |
701 | 718 liststrings(readlist()); |
702 liststrings(readlist(), puts); | |
703 | |
704 return 0; | 719 return 0; |
705 } | 720 } |