vary.c (7ca215a69037714e5f3cb65c394d3467621daa4c) | vary.c (698f86e401d193b01b09cf1ae7d1a26a5652deac) |
---|---|
1#include <time.h> 2#include <string.h> 3#include <stdlib.h> 4#include "vary.h" 5 6struct trans { 7 int val; 8 char *str; 9}; 10 11static struct trans trans_mon[] = { | 1#include <time.h> 2#include <string.h> 3#include <stdlib.h> 4#include "vary.h" 5 6struct trans { 7 int val; 8 char *str; 9}; 10 11static struct trans trans_mon[] = { |
12 { 1, "jan" }, { 2, "feb" }, { 3, "mar" }, { 4, "apr" }, { 5, "may" }, 13 { 6, "jun" }, { 7, "jul" }, { 8, "aug" }, { 9, "sep" }, { 10, "oct" }, 14 { 11, "nov" }, { 12, "dec" }, | |
15 { 1, "january" }, { 2, "february" }, { 3, "march" }, { 4, "april" }, 16 { 6, "june" }, { 7, "july" }, { 8, "august" }, { 9, "september" }, 17 { 10, "october" }, { 11, "november" }, { 12, "december" }, 18 { -1, NULL } 19}; 20 21static struct trans trans_wday[] = { | 12 { 1, "january" }, { 2, "february" }, { 3, "march" }, { 4, "april" }, 13 { 6, "june" }, { 7, "july" }, { 8, "august" }, { 9, "september" }, 14 { 10, "october" }, { 11, "november" }, { 12, "december" }, 15 { -1, NULL } 16}; 17 18static struct trans trans_wday[] = { |
22 { 0, "sun" }, { 1, "mon" }, { 2, "tue" }, { 3, "wed" }, { 4, "thr" }, 23 { 4, "thu" }, { 5, "fri" }, { 6, "sat" }, | |
24 { 0, "sunday" }, { 1, "monday" }, { 2, "tuesday" }, { 3, "wednesday" }, 25 { 4, "thursday" }, { 5, "friday" }, { 6, "saturday" }, 26 { -1, NULL } 27}; 28 29static char digits[] = "0123456789"; 30 31static int 32trans(const struct trans t[], const char *arg) 33{ 34 int f; 35 | 19 { 0, "sunday" }, { 1, "monday" }, { 2, "tuesday" }, { 3, "wednesday" }, 20 { 4, "thursday" }, { 5, "friday" }, { 6, "saturday" }, 21 { -1, NULL } 22}; 23 24static char digits[] = "0123456789"; 25 26static int 27trans(const struct trans t[], const char *arg) 28{ 29 int f; 30 |
36 if (strspn(arg, digits) == strlen(arg)) 37 return atoi(arg); 38 | |
39 for (f = 0; t[f].val != -1; f++) | 31 for (f = 0; t[f].val != -1; f++) |
40 if (!strcasecmp(t[f].str, arg)) | 32 if (!strncasecmp(t[f].str, arg, 3) || 33 !strncasecmp(t[f].str, arg, strlen(t[f].str))) |
41 return t[f].val; 42 43 return -1; 44} 45 46struct vary * | 34 return t[f].val; 35 36 return -1; 37} 38 39struct vary * |
47vary_append(struct vary *v, char flag, char *arg) | 40vary_append(struct vary *v, char *arg) |
48{ 49 struct vary *result, **nextp; 50 | 41{ 42 struct vary *result, **nextp; 43 |
51 if (!strchr("DWMY", flag)) 52 return 0; 53 | |
54 if (v) { 55 result = v; 56 while (v->next) 57 v = v->next; 58 nextp = &v->next; 59 } else 60 nextp = &result; 61 62 *nextp = (struct vary *)malloc(sizeof(struct vary)); | 44 if (v) { 45 result = v; 46 while (v->next) 47 v = v->next; 48 nextp = &v->next; 49 } else 50 nextp = &result; 51 52 *nextp = (struct vary *)malloc(sizeof(struct vary)); |
63 (*nextp)->flag = flag; | |
64 (*nextp)->arg = arg; 65 (*nextp)->next = NULL; 66 return result; 67} 68 69static int mdays[12] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 70 71static int --- 36 unchanged lines hidden (view full) --- 108 else if (t->tm_year > 1900) 109 t->tm_year -= 1900; /* struct tm holds years since 1900 */ 110 break; 111 } 112 return mktime(t) != -1; 113} 114 115static int | 53 (*nextp)->arg = arg; 54 (*nextp)->next = NULL; 55 return result; 56} 57 58static int mdays[12] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 59 60static int --- 36 unchanged lines hidden (view full) --- 97 else if (t->tm_year > 1900) 98 t->tm_year -= 1900; /* struct tm holds years since 1900 */ 99 break; 100 } 101 return mktime(t) != -1; 102} 103 104static int |
116sadjyear(struct tm *t, char *arg) 117{ 118 switch (*arg) { 119 case '+': 120 case '-': 121 return adjyear(t, *arg, atoi(arg+1)); 122 default: 123 return adjyear(t, '\0', atoi(arg)); 124 } 125} 126 127static int | |
128adjmon(struct tm *t, char type, int val, int istext) 129{ 130 if (val < 0) 131 return 0; 132 133 switch (type) { 134 case '+': 135 if (istext) --- 31 unchanged lines hidden (view full) --- 167 return 0; 168 t->tm_mon = --val; 169 } 170 171 return mktime(t) != -1; 172} 173 174static int | 105adjmon(struct tm *t, char type, int val, int istext) 106{ 107 if (val < 0) 108 return 0; 109 110 switch (type) { 111 case '+': 112 if (istext) --- 31 unchanged lines hidden (view full) --- 144 return 0; 145 t->tm_mon = --val; 146 } 147 148 return mktime(t) != -1; 149} 150 151static int |
175sadjmon(struct tm *t, char *arg) 176{ 177 int istext; 178 int val; 179 180 switch (*arg) { 181 case '+': 182 case '-': 183 istext = strspn(arg+1, digits) != strlen(arg+1); 184 val = trans(trans_mon, arg+1); 185 return adjmon(t, *arg, val, istext); 186 default: 187 istext = strspn(arg, digits) != strlen(arg); 188 val = trans(trans_mon, arg); 189 return adjmon(t, '\0', val, istext); 190 } 191} 192 193static int | |
194adjday(struct tm *t, char type, int val) 195{ 196 int mdays; 197 switch (type) { 198 case '+': 199 while (val) { 200 mdays = daysinmonth(t); 201 if (val > mdays - t->tm_mday) { --- 27 unchanged lines hidden (view full) --- 229 return 0; 230 break; 231 } 232 233 return mktime(t) != -1; 234} 235 236static int | 152adjday(struct tm *t, char type, int val) 153{ 154 int mdays; 155 switch (type) { 156 case '+': 157 while (val) { 158 mdays = daysinmonth(t); 159 if (val > mdays - t->tm_mday) { --- 27 unchanged lines hidden (view full) --- 187 return 0; 188 break; 189 } 190 191 return mktime(t) != -1; 192} 193 194static int |
237sadjwday(struct tm *t, char *arg) | 195adjwday(struct tm *t, char type, int val, int istext) |
238{ | 196{ |
239 int istext; 240 int val; 241 242 switch (*arg) { 243 case '+': 244 case '-': 245 istext = strspn(arg+1, digits) != strlen(arg+1); 246 val = trans(trans_wday, arg+1); 247 break; 248 default: 249 istext = 0; 250 val = trans(trans_wday, arg); 251 break; 252 } 253 | |
254 if (val < 0) 255 return 0; 256 | 197 if (val < 0) 198 return 0; 199 |
257 switch (*arg) { | 200 switch (type) { |
258 case '+': 259 if (istext) 260 if (val < t->tm_wday) 261 val = 7 - t->tm_wday + val; /* early next week */ 262 else 263 val -= t->tm_wday; /* later this week */ 264 else 265 val *= 7; /* "-W +5" == "5 weeks in the future" */ --- 14 unchanged lines hidden (view full) --- 280 return 0; 281 else if (val > t->tm_wday) 282 return adjday(t, '+', val - t->tm_wday); 283 } 284 return 1; 285} 286 287static int | 201 case '+': 202 if (istext) 203 if (val < t->tm_wday) 204 val = 7 - t->tm_wday + val; /* early next week */ 205 else 206 val -= t->tm_wday; /* later this week */ 207 else 208 val *= 7; /* "-W +5" == "5 weeks in the future" */ --- 14 unchanged lines hidden (view full) --- 223 return 0; 224 else if (val > t->tm_wday) 225 return adjday(t, '+', val - t->tm_wday); 226 } 227 return 1; 228} 229 230static int |
288sadjday(struct tm *t, char *arg) | 231adjhour(struct tm *t, char type, int val) |
289{ | 232{ |
290 switch (*arg) { | 233 if (val < 0) 234 return 0; 235 236 switch (type) { |
291 case '+': | 237 case '+': |
238 if (!adjday(t, '+', (t->tm_hour + val) / 24)) 239 return 0; 240 val %= 24; 241 t->tm_hour += val; 242 if (t->tm_hour > 23) 243 t->tm_hour -= 24; 244 break; 245 |
|
292 case '-': | 246 case '-': |
293 return adjday(t, *arg, atoi(arg+1)); | 247 if (!adjday(t, '-', val / 24)) 248 return 0; 249 val %= 24; 250 if (val > t->tm_hour) { 251 if (!adjday(t, '-', 1)) 252 return 0; 253 val -= 24; 254 } 255 t->tm_hour -= val; 256 break; 257 |
294 default: | 258 default: |
295 return adjday(t, '\0', atoi(arg)); | 259 if (val > 23) 260 return 0; 261 t->tm_hour = val; |
296 } | 262 } |
263 264 return mktime(t) != -1; |
|
297} 298 | 265} 266 |
267static int 268adjmin(struct tm *t, char type, int val) 269{ 270 if (val < 0) 271 return 0; 272 273 switch (type) { 274 case '+': 275 if (!adjhour(t, '+', (t->tm_min + val) / 60)) 276 return 0; 277 val %= 60; 278 t->tm_min += val; 279 if (t->tm_min > 59) 280 t->tm_min -= 60; 281 break; 282 283 case '-': 284 if (!adjhour(t, '-', val / 60)) 285 return 0; 286 val %= 60; 287 if (val > t->tm_min) { 288 if (!adjhour(t, '-', 1)) 289 return 0; 290 val -= 60; 291 } 292 t->tm_min -= val; 293 break; 294 295 default: 296 if (val > 59) 297 return 0; 298 t->tm_min = val; 299 } 300 301 return mktime(t) != -1; 302} 303 |
|
299const struct vary * 300vary_apply(const struct vary *v, struct tm *t) 301{ | 304const struct vary * 305vary_apply(const struct vary *v, struct tm *t) 306{ |
307 char type; 308 char which; 309 char *arg; 310 int len; 311 int val; 312 |
|
302 for (; v; v = v->next) { | 313 for (; v; v = v->next) { |
303 switch (v->flag) { 304 case 'D': 305 if (!sadjday(t, v->arg)) | 314 type = *v->arg; 315 arg = v->arg; 316 if (type == '+' || type == '-') 317 arg++; 318 else 319 type = '\0'; 320 len = strlen(arg); 321 if (len < 2) 322 return v; 323 324 if (strspn(arg, digits) != len-1) { 325 val = trans(trans_wday, arg); 326 if (val != -1) { 327 if (!adjwday(t, type, val, 1)) 328 return v; 329 } else { 330 val = trans(trans_mon, arg); 331 if (val != -1) { 332 if (!adjmon(t, type, val, 1)) 333 return v; 334 } else |
306 return v; | 335 return v; |
307 break; 308 case 'W': 309 if (!sadjwday(t, v->arg)) | 336 } 337 } else { 338 val = atoi(arg); 339 which = arg[len-1]; 340 341 switch (which) { 342 case 'M': 343 if (!adjmin(t, type, val)) 344 return v; 345 break; 346 case 'H': 347 if (!adjhour(t, type, val)) 348 return v; 349 break; 350 case 'd': 351 if (!adjday(t, type, val)) 352 return v; 353 break; 354 case 'w': 355 if (!adjwday(t, type, val, 0)) 356 return v; 357 break; 358 case 'm': 359 if (!adjmon(t, type, val, 0)) 360 return v; 361 break; 362 case 'y': 363 if (!adjyear(t, type, val)) 364 return v; 365 break; 366 default: |
310 return v; | 367 return v; |
311 break; 312 case 'M': 313 if (!sadjmon(t, v->arg)) 314 return v; 315 break; 316 case 'Y': 317 if (!sadjyear(t, v->arg)) 318 return v; 319 break; 320 default: 321 return v; | 368 } |
322 } 323 } 324 return 0; 325} 326 327void 328vary_destroy(struct vary *v) 329{ 330 struct vary *n; 331 332 while (v) { 333 n = v->next; 334 free(v); 335 v = n; 336 } 337} | 369 } 370 } 371 return 0; 372} 373 374void 375vary_destroy(struct vary *v) 376{ 377 struct vary *n; 378 379 while (v) { 380 n = v->next; 381 free(v); 382 v = n; 383 } 384} |