16 |
* |
* |
17 |
* Major size reduction... over 50% (>1.5k) on i386. |
* Major size reduction... over 50% (>1.5k) on i386. |
18 |
*/ |
*/ |
|
|
|
19 |
#include "libbb.h" |
#include "libbb.h" |
20 |
|
#include "unicode.h" |
21 |
|
|
22 |
/* We often use "unsigned" intead of "int", it's easier to div on most CPUs */ |
/* We often use "unsigned" intead of "int", it's easier to div on most CPUs */ |
23 |
|
|
77 |
#define HEAD_SEP 2 /* spaces between day headings */ |
#define HEAD_SEP 2 /* spaces between day headings */ |
78 |
|
|
79 |
int cal_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
int cal_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
80 |
int cal_main(int argc, char **argv) |
int cal_main(int argc UNUSED_PARAM, char **argv) |
81 |
{ |
{ |
|
struct tm *local_time; |
|
82 |
struct tm zero_tm; |
struct tm zero_tm; |
83 |
time_t now; |
time_t now; |
84 |
unsigned month, year, flags, i; |
unsigned month, year, flags, i; |
85 |
char *month_names[12]; |
char *month_names[12]; |
86 |
char day_headings[28]; /* 28 for julian, 21 for nonjulian */ |
/* normal heading: */ |
87 |
|
/* "Su Mo Tu We Th Fr Sa" */ |
88 |
|
/* -j heading: */ |
89 |
|
/* " Su Mo Tu We Th Fr Sa" */ |
90 |
|
char day_headings[ENABLE_FEATURE_ASSUME_UNICODE ? 28 * 6 : 28]; |
91 |
|
IF_FEATURE_ASSUME_UNICODE(char *hp = day_headings;) |
92 |
char buf[40]; |
char buf[40]; |
93 |
|
|
94 |
|
init_unicode(); |
95 |
|
|
96 |
flags = getopt32(argv, "jy"); |
flags = getopt32(argv, "jy"); |
97 |
/* This sets julian = flags & 1: */ |
/* This sets julian = flags & 1: */ |
98 |
option_mask32 &= 1; |
option_mask32 &= 1; |
99 |
month = 0; |
month = 0; |
100 |
argv += optind; |
argv += optind; |
|
argc -= optind; |
|
101 |
|
|
102 |
if (argc > 2) { |
if (!argv[0]) { |
103 |
bb_show_usage(); |
struct tm *ptm; |
|
} |
|
104 |
|
|
|
if (!argc) { |
|
105 |
time(&now); |
time(&now); |
106 |
local_time = localtime(&now); |
ptm = localtime(&now); |
107 |
year = local_time->tm_year + 1900; |
year = ptm->tm_year + 1900; |
108 |
if (!(flags & 2)) { /* no -y */ |
if (!(flags & 2)) { /* no -y */ |
109 |
month = local_time->tm_mon + 1; |
month = ptm->tm_mon + 1; |
110 |
} |
} |
111 |
} else { |
} else { |
112 |
if (argc == 2) { |
if (argv[1]) { |
113 |
|
if (argv[2]) { |
114 |
|
bb_show_usage(); |
115 |
|
} |
116 |
month = xatou_range(*argv++, 1, 12); |
month = xatou_range(*argv++, 1, 12); |
117 |
} |
} |
118 |
year = xatou_range(*argv, 1, 9999); |
year = xatou_range(*argv, 1, 9999); |
123 |
i = 0; |
i = 0; |
124 |
do { |
do { |
125 |
zero_tm.tm_mon = i; |
zero_tm.tm_mon = i; |
126 |
|
/* full month name according to locale */ |
127 |
strftime(buf, sizeof(buf), "%B", &zero_tm); |
strftime(buf, sizeof(buf), "%B", &zero_tm); |
128 |
month_names[i] = xstrdup(buf); |
month_names[i] = xstrdup(buf); |
129 |
|
|
130 |
if (i < 7) { |
if (i < 7) { |
131 |
zero_tm.tm_wday = i; |
zero_tm.tm_wday = i; |
132 |
|
/* abbreviated weekday name according to locale */ |
133 |
strftime(buf, sizeof(buf), "%a", &zero_tm); |
strftime(buf, sizeof(buf), "%a", &zero_tm); |
134 |
|
#if ENABLE_FEATURE_ASSUME_UNICODE |
135 |
|
if (julian) |
136 |
|
*hp++ = ' '; |
137 |
|
{ |
138 |
|
char *two_wchars = unicode_cut_nchars(2, buf); |
139 |
|
strcpy(hp, two_wchars); |
140 |
|
free(two_wchars); |
141 |
|
} |
142 |
|
hp += strlen(hp); |
143 |
|
*hp++ = ' '; |
144 |
|
#else |
145 |
strncpy(day_headings + i * (3+julian) + julian, buf, 2); |
strncpy(day_headings + i * (3+julian) + julian, buf, 2); |
146 |
|
#endif |
147 |
} |
} |
148 |
} while (++i < 12); |
} while (++i < 12); |
149 |
|
IF_FEATURE_ASSUME_UNICODE(hp[-1] = '\0';) |
150 |
|
|
151 |
if (month) { |
if (month) { |
152 |
unsigned row, len, days[MAXDAYS]; |
unsigned row, len, days[MAXDAYS]; |
168 |
unsigned *dp; |
unsigned *dp; |
169 |
char lineout[80]; |
char lineout[80]; |
170 |
|
|
171 |
sprintf(lineout, "%d", year); |
sprintf(lineout, "%u", year); |
172 |
center(lineout, |
center(lineout, |
173 |
(WEEK_LEN * 3 + HEAD_SEP * 2) |
(WEEK_LEN * 3 + HEAD_SEP * 2) |
174 |
+ julian * (J_WEEK_LEN * 2 + HEAD_SEP |
+ julian * (J_WEEK_LEN * 2 + HEAD_SEP |
283 |
} |
} |
284 |
while (p != s) { |
while (p != s) { |
285 |
--p; |
--p; |
286 |
if (!(isspace)(*p)) { /* We want the function... not the inline. */ |
if (!isspace(*p)) { |
287 |
p[1] = '\0'; |
p[1] = '\0'; |
288 |
break; |
break; |
289 |
} |
} |