|
Lines 68-74
Link Here
|
| 68 |
} |
68 |
} |
| 69 |
|
69 |
|
| 70 |
struct vary * |
70 |
struct vary * |
| 71 |
vary_append(struct vary *v, char *arg) |
71 |
vary_append(struct vary *v, char *arg, char vary_logical) |
| 72 |
{ |
72 |
{ |
| 73 |
struct vary *result, **nextp; |
73 |
struct vary *result, **nextp; |
| 74 |
|
74 |
|
|
Lines 82-87
Link Here
|
| 82 |
|
82 |
|
| 83 |
*nextp = (struct vary *)malloc(sizeof(struct vary)); |
83 |
*nextp = (struct vary *)malloc(sizeof(struct vary)); |
| 84 |
(*nextp)->arg = arg; |
84 |
(*nextp)->arg = arg; |
|
|
85 |
(*nextp)->vary_logical = vary_logical; |
| 85 |
(*nextp)->next = NULL; |
86 |
(*nextp)->next = NULL; |
| 86 |
return result; |
87 |
return result; |
| 87 |
} |
88 |
} |
|
Lines 132-139
Link Here
|
| 132 |
return mktime(t) != -1; |
133 |
return mktime(t) != -1; |
| 133 |
} |
134 |
} |
| 134 |
|
135 |
|
|
|
136 |
#define is_leap(year) (!((year) % 4) && (! ((year) % 400) || (year) % 100)) |
| 135 |
static int |
137 |
static int |
| 136 |
adjmon(struct tm *t, char type, int val, int istext) |
138 |
adjmon(struct tm *t, char type, int val, int istext, char vary_logical) |
| 137 |
{ |
139 |
{ |
| 138 |
if (val < 0) |
140 |
if (val < 0) |
| 139 |
return 0; |
141 |
return 0; |
|
Lines 167-175
Link Here
|
| 167 |
if (val > t->tm_mon) { |
169 |
if (val > t->tm_mon) { |
| 168 |
if (!adjyear(t, '-', 1)) |
170 |
if (!adjyear(t, '-', 1)) |
| 169 |
return 0; |
171 |
return 0; |
| 170 |
val -= 12; |
|
|
| 171 |
} |
172 |
} |
| 172 |
t->tm_mon -= val; |
173 |
if (vary_logical) { |
|
|
174 |
for (; val > 0; val--) { |
| 175 |
t->tm_mday -= ((mdays[t->tm_mon] == 0) ? 28 + is_leap(t->tm_year + 1900) : mdays[t->tm_mon]) - ((mdays[(t->tm_mon == 0) ? 13 : t->tm_mon - 1] == 0) ? 28 + is_leap(t->tm_year + 1900) : mdays[t->tm_mon + (t->tm_mon == 0) ? 11 : -1]); |
| 176 |
t->tm_mon -= 1; |
| 177 |
} |
| 178 |
} else |
| 179 |
t->tm_mon -= val; |
| 180 |
if (t->tm_mon < 0) |
| 181 |
t->tm_mon += 12; |
| 173 |
break; |
182 |
break; |
| 174 |
|
183 |
|
| 175 |
default: |
184 |
default: |
|
Lines 192-198
Link Here
|
| 192 |
if (val > mdays - t->tm_mday) { |
200 |
if (val > mdays - t->tm_mday) { |
| 193 |
val -= mdays - t->tm_mday + 1; |
201 |
val -= mdays - t->tm_mday + 1; |
| 194 |
t->tm_mday = 1; |
202 |
t->tm_mday = 1; |
| 195 |
if (!adjmon(t, '+', 1, 0)) |
203 |
if (!adjmon(t, '+', 1, 0, 0)) |
| 196 |
return 0; |
204 |
return 0; |
| 197 |
} else { |
205 |
} else { |
| 198 |
t->tm_mday += val; |
206 |
t->tm_mday += val; |
|
Lines 205-211
Link Here
|
| 205 |
if (val >= t->tm_mday) { |
213 |
if (val >= t->tm_mday) { |
| 206 |
val -= t->tm_mday; |
214 |
val -= t->tm_mday; |
| 207 |
t->tm_mday = 1; |
215 |
t->tm_mday = 1; |
| 208 |
if (!adjmon(t, '-', 1, 0)) |
216 |
if (!adjmon(t, '-', 1, 0, 0)) |
| 209 |
return 0; |
217 |
return 0; |
| 210 |
t->tm_mday = daysinmonth(t); |
218 |
t->tm_mday = daysinmonth(t); |
| 211 |
} else { |
219 |
} else { |
|
Lines 379-388
Link Here
|
| 379 |
char *arg; |
387 |
char *arg; |
| 380 |
int len; |
388 |
int len; |
| 381 |
int val; |
389 |
int val; |
|
|
390 |
char vary_logical; |
| 382 |
|
391 |
|
| 383 |
for (; v; v = v->next) { |
392 |
for (; v; v = v->next) { |
| 384 |
type = *v->arg; |
393 |
type = *v->arg; |
| 385 |
arg = v->arg; |
394 |
arg = v->arg; |
|
|
395 |
vary_logical = v->vary_logical; |
| 386 |
if (type == '+' || type == '-') |
396 |
if (type == '+' || type == '-') |
| 387 |
arg++; |
397 |
arg++; |
| 388 |
else |
398 |
else |
|
Lines 399-405
Link Here
|
| 399 |
} else { |
409 |
} else { |
| 400 |
val = trans(trans_mon, arg); |
410 |
val = trans(trans_mon, arg); |
| 401 |
if (val != -1) { |
411 |
if (val != -1) { |
| 402 |
if (!adjmon(t, type, val, 1)) |
412 |
if (!adjmon(t, type, val, 1, vary_logical)) |
| 403 |
return v; |
413 |
return v; |
| 404 |
} else |
414 |
} else |
| 405 |
return v; |
415 |
return v; |
|
Lines 430-437
Link Here
|
| 430 |
return v; |
440 |
return v; |
| 431 |
break; |
441 |
break; |
| 432 |
case 'm': |
442 |
case 'm': |
| 433 |
if (!adjmon(t, type, val, 0)) |
443 |
if (!adjmon(t, type, val, 0, vary_logical)) |
| 434 |
return v; |
444 |
return v; |
| 435 |
break; |
445 |
break; |
| 436 |
case 'y': |
446 |
case 'y': |
| 437 |
if (!adjyear(t, type, val)) |
447 |
if (!adjyear(t, type, val)) |