diff options
Diffstat (limited to 'coreutils/cal.c')
-rw-r--r-- | coreutils/cal.c | 484 |
1 files changed, 226 insertions, 258 deletions
diff --git a/coreutils/cal.c b/coreutils/cal.c index ab631576a..ed480dd78 100644 --- a/coreutils/cal.c +++ b/coreutils/cal.c | |||
@@ -1,3 +1,14 @@ | |||
1 | /* NOTE: | ||
2 | * | ||
3 | * Apparently, all "Steven J. Merrifield" did was grab the util-linux cal applet, | ||
4 | * spend maybe 5 minutes integrating it into busybox, slapped a copyright on it, | ||
5 | * and submitted it. I certainly saw no evidence of any attempt at size reduction. | ||
6 | * Not only do I consider his copyright below meaningless, I also consider his | ||
7 | * actions shameful. | ||
8 | * | ||
9 | * Manuel Novoa III (mjn3@codepoet.org) | ||
10 | */ | ||
11 | |||
1 | /* | 12 | /* |
2 | * Calendar implementation for busybox | 13 | * Calendar implementation for busybox |
3 | * | 14 | * |
@@ -20,7 +31,16 @@ | |||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | * | 32 | * |
22 | */ | 33 | */ |
23 | 34 | ||
35 | /* BB_AUDIT SUSv3 compliant with -j and -y extensions (from util-linux). */ | ||
36 | /* BB_AUDIT BUG: The output of 'cal -j 1752' is incorrect. The upstream | ||
37 | * BB_AUDIT BUG: version in util-linux seems to be broken as well. */ | ||
38 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cal.html */ | ||
39 | |||
40 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) | ||
41 | * | ||
42 | * Major size reduction... over 50% (>1.5k) on i386. | ||
43 | */ | ||
24 | 44 | ||
25 | #include <sys/types.h> | 45 | #include <sys/types.h> |
26 | #include <ctype.h> | 46 | #include <ctype.h> |
@@ -46,44 +66,30 @@ | |||
46 | #define MAXDAYS 42 /* max slots in a month array */ | 66 | #define MAXDAYS 42 /* max slots in a month array */ |
47 | #define SPACE -1 /* used in day array */ | 67 | #define SPACE -1 /* used in day array */ |
48 | 68 | ||
49 | static int days_in_month[2][13] = { | 69 | static const char days_in_month[] = { |
50 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, | 70 | 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 |
51 | {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, | ||
52 | }; | 71 | }; |
53 | 72 | ||
54 | int sep1752[MAXDAYS] = { | 73 | static const char sep1752[] = { |
55 | SPACE, SPACE, 1, 2, 14, 15, 16, | 74 | 1, 2, 14, 15, 16, |
56 | 17, 18, 19, 20, 21, 22, 23, | 75 | 17, 18, 19, 20, 21, 22, 23, |
57 | 24, 25, 26, 27, 28, 29, 30, | 76 | 24, 25, 26, 27, 28, 29, 30 |
58 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
59 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
60 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
61 | }, j_sep1752[MAXDAYS] = { | ||
62 | SPACE, SPACE, 245, 246, 258, 259, 260, | ||
63 | 261, 262, 263, 264, 265, 266, 267, | ||
64 | 268, 269, 270, 271, 272, 273, 274, | ||
65 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
66 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
67 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
68 | }, empty[MAXDAYS] = { | ||
69 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
70 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
71 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
72 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
73 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
74 | SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, SPACE, | ||
75 | }; | 77 | }; |
76 | 78 | ||
77 | char *month_names[12]; | 79 | static int julian; |
78 | |||
79 | char day_headings[] = " "; | ||
80 | char j_day_headings[] = " "; | ||
81 | 80 | ||
82 | /* leap year -- account for gregorian reformation in 1752 */ | 81 | /* leap year -- account for gregorian reformation in 1752 */ |
83 | #define leap_year(yr) \ | 82 | #define leap_year(yr) \ |
84 | ((yr) <= 1752 ? !((yr) % 4) : \ | 83 | ((yr) <= 1752 ? !((yr) % 4) : \ |
85 | (!((yr) % 4) && ((yr) % 100)) || !((yr) % 400)) | 84 | (!((yr) % 4) && ((yr) % 100)) || !((yr) % 400)) |
86 | 85 | ||
86 | static int is_leap_year(int year) | ||
87 | { | ||
88 | return leap_year(year); | ||
89 | } | ||
90 | #undef leap_year | ||
91 | #define leap_year(yr) is_leap_year(yr) | ||
92 | |||
87 | /* number of centuries since 1700, not inclusive */ | 93 | /* number of centuries since 1700, not inclusive */ |
88 | #define centuries_since_1700(yr) \ | 94 | #define centuries_since_1700(yr) \ |
89 | ((yr) > 1700 ? (yr) / 100 - 17 : 0) | 95 | ((yr) > 1700 ? (yr) / 100 - 17 : 0) |
@@ -96,178 +102,129 @@ char j_day_headings[] = " "; | |||
96 | #define leap_years_since_year_1(yr) \ | 102 | #define leap_years_since_year_1(yr) \ |
97 | ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr)) | 103 | ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr)) |
98 | 104 | ||
99 | int julian; | 105 | static void center __P((char *, int, int)); |
100 | void ascii_day __P((char *, int)); | 106 | static void day_array __P((int, int, int *)); |
101 | void center __P((char *, int, int)); | 107 | static void trim_trailing_spaces_and_print __P((char *)); |
102 | void day_array __P((int, int, int *)); | 108 | |
103 | int day_in_week __P((int, int, int)); | 109 | static void blank_string(char *buf, size_t buflen); |
104 | int day_in_year __P((int, int, int)); | 110 | static char *build_row(char *p, int *dp); |
105 | void j_yearly __P((int)); | 111 | |
106 | void monthly __P((int, int)); | 112 | #define DAY_LEN 3 /* 3 spaces per day */ |
107 | void trim_trailing_spaces __P((char *)); | 113 | #define J_DAY_LEN (DAY_LEN + 1) |
108 | void yearly __P((int)); | 114 | #define WEEK_LEN 20 /* 7 * 3 - one space at the end */ |
115 | #define J_WEEK_LEN (WEEK_LEN + 7) | ||
116 | #define HEAD_SEP 2 /* spaces between day headings */ | ||
109 | 117 | ||
110 | int cal_main(int argc, char **argv) | 118 | int cal_main(int argc, char **argv) |
111 | { | 119 | { |
112 | struct tm *local_time; | 120 | struct tm *local_time; |
113 | static struct tm zero_tm; | 121 | struct tm zero_tm; |
114 | time_t now; | 122 | time_t now; |
115 | int ch, month, year, yflag, i; | 123 | int month, year, flags, i; |
124 | char *month_names[12]; | ||
125 | char day_headings[28]; /* 28 for julian, 21 for nonjulian */ | ||
116 | char buf[40]; | 126 | char buf[40]; |
117 | 127 | ||
118 | #ifdef CONFIG_LOCALE_SUPPORT | 128 | #ifdef CONFIG_LOCALE_SUPPORT |
119 | setlocale(LC_TIME, ""); | 129 | setlocale(LC_TIME, ""); |
120 | #endif | 130 | #endif |
121 | 131 | ||
122 | yflag = 0; | 132 | flags = bb_getopt_ulflags(argc, argv, "jy"); |
123 | while ((ch = getopt(argc, argv, "jy")) != -1) | 133 | |
124 | switch(ch) { | 134 | julian = flags & 1; |
125 | case 'j': | 135 | |
126 | julian = 1; | ||
127 | break; | ||
128 | case 'y': | ||
129 | yflag = 1; | ||
130 | break; | ||
131 | default: | ||
132 | show_usage(); | ||
133 | } | ||
134 | argc -= optind; | ||
135 | argv += optind; | 136 | argv += optind; |
136 | 137 | ||
137 | month = 0; | 138 | month = 0; |
138 | switch(argc) { | 139 | |
139 | case 2: | 140 | if ((argc -= optind) > 2) { |
140 | if ((month = atoi(*argv++)) < 1 || month > 12) | 141 | bb_show_usage(); |
141 | error_msg_and_die("Illegal month value: use 1-12"); | 142 | } |
142 | /* FALLTHROUGH */ | 143 | |
143 | case 1: | 144 | if (!argc) { |
144 | if ((year = atoi(*argv)) < 1 || year > 9999) | ||
145 | error_msg_and_die("Illegal year value: use 1-9999"); | ||
146 | break; | ||
147 | case 0: | ||
148 | time(&now); | 145 | time(&now); |
149 | local_time = localtime(&now); | 146 | local_time = localtime(&now); |
150 | year = local_time->tm_year + 1900; | 147 | year = local_time->tm_year + 1900; |
151 | if (!yflag) | 148 | if (!(flags & 2)) { |
152 | month = local_time->tm_mon + 1; | 149 | month = local_time->tm_mon + 1; |
153 | break; | 150 | } |
154 | default: | 151 | } else { |
155 | show_usage(); | 152 | if (argc == 2) { |
153 | month = bb_xgetularg10_bnd(*argv++, 1, 12); | ||
154 | } | ||
155 | year = bb_xgetularg10_bnd(*argv, 1, 9999); | ||
156 | } | 156 | } |
157 | 157 | ||
158 | for (i = 0; i < 12; i++) { | 158 | blank_string(day_headings, sizeof(day_headings) - 7 + 7*julian); |
159 | |||
160 | i = 0; | ||
161 | do { | ||
159 | zero_tm.tm_mon = i; | 162 | zero_tm.tm_mon = i; |
160 | strftime(buf, sizeof(buf), "%B", &zero_tm); | 163 | strftime(buf, sizeof(buf), "%B", &zero_tm); |
161 | month_names[i] = xstrdup(buf); | 164 | month_names[i] = bb_xstrdup(buf); |
162 | } | ||
163 | for (i = 0; i < 7; i++) { | ||
164 | zero_tm.tm_wday = i; | ||
165 | strftime(buf, sizeof(buf), "%a", &zero_tm); | ||
166 | strncpy(day_headings + i * 3, buf, 2); | ||
167 | strncpy(j_day_headings + i * 4 + 1, buf, 2); | ||
168 | } | ||
169 | |||
170 | if (month) | ||
171 | monthly(month, year); | ||
172 | else if (julian) | ||
173 | j_yearly(year); | ||
174 | else | ||
175 | yearly(year); | ||
176 | exit(0); | ||
177 | } | ||
178 | 165 | ||
179 | #define DAY_LEN 3 /* 3 spaces per day */ | 166 | if (i < 7) { |
180 | #define J_DAY_LEN 4 /* 4 spaces per day */ | 167 | zero_tm.tm_wday = i; |
181 | #define WEEK_LEN 20 /* 7 * 3 - one space at the end */ | 168 | strftime(buf, sizeof(buf), "%a", &zero_tm); |
182 | #define J_WEEK_LEN 27 /* 7 * 4 - one space at the end */ | 169 | strncpy(day_headings + i * (3+julian) + julian, buf, 2); |
183 | #define HEAD_SEP 2 /* spaces between day headings */ | ||
184 | #define J_HEAD_SEP 2 | ||
185 | |||
186 | void monthly(int month, int year) | ||
187 | { | ||
188 | int col, row, len, days[MAXDAYS]; | ||
189 | char *p, lineout[30]; | ||
190 | |||
191 | day_array(month, year, days); | ||
192 | len = sprintf(lineout, "%s %d", month_names[month - 1], year); | ||
193 | printf("%*s%s\n%s\n", | ||
194 | ((julian ? J_WEEK_LEN : WEEK_LEN) - len) / 2, "", | ||
195 | lineout, julian ? j_day_headings : day_headings); | ||
196 | for (row = 0; row < 6; row++) { | ||
197 | for (col = 0, p = lineout; col < 7; col++, | ||
198 | p += julian ? J_DAY_LEN : DAY_LEN) | ||
199 | ascii_day(p, days[row * 7 + col]); | ||
200 | *p = '\0'; | ||
201 | trim_trailing_spaces(lineout); | ||
202 | printf("%s\n", lineout); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | void j_yearly(int year) | ||
207 | { | ||
208 | int col, *dp, i, month, row, which_cal; | ||
209 | int days[12][MAXDAYS]; | ||
210 | char *p, lineout[80]; | ||
211 | |||
212 | sprintf(lineout, "%d", year); | ||
213 | center(lineout, J_WEEK_LEN * 2 + J_HEAD_SEP, 0); | ||
214 | printf("\n\n"); | ||
215 | for (i = 0; i < 12; i++) | ||
216 | day_array(i + 1, year, days[i]); | ||
217 | memset(lineout, ' ', sizeof(lineout) - 1); | ||
218 | lineout[sizeof(lineout) - 1] = '\0'; | ||
219 | for (month = 0; month < 12; month += 2) { | ||
220 | center(month_names[month], J_WEEK_LEN, J_HEAD_SEP); | ||
221 | center(month_names[month + 1], J_WEEK_LEN, 0); | ||
222 | printf("\n%s%*s%s\n", j_day_headings, J_HEAD_SEP, "", | ||
223 | j_day_headings); | ||
224 | for (row = 0; row < 6; row++) { | ||
225 | for (which_cal = 0; which_cal < 2; which_cal++) { | ||
226 | p = lineout + which_cal * (J_WEEK_LEN + 2); | ||
227 | dp = &days[month + which_cal][row * 7]; | ||
228 | for (col = 0; col < 7; col++, p += J_DAY_LEN) | ||
229 | ascii_day(p, *dp++); | ||
230 | } | ||
231 | *p = '\0'; | ||
232 | trim_trailing_spaces(lineout); | ||
233 | printf("%s\n", lineout); | ||
234 | } | 170 | } |
235 | } | 171 | } while (++i < 12); |
236 | printf("\n"); | 172 | |
237 | } | 173 | if (month) { |
238 | 174 | int row, len, days[MAXDAYS]; | |
239 | void yearly(int year) | 175 | int *dp = days; |
240 | { | 176 | char lineout[30]; |
241 | int col, *dp, i, month, row, which_cal; | 177 | |
242 | int days[12][MAXDAYS]; | 178 | day_array(month, year, dp); |
243 | char *p, lineout[80]; | 179 | len = sprintf(lineout, "%s %d", month_names[month - 1], year); |
244 | 180 | bb_printf("%*s%s\n%s\n", | |
245 | sprintf(lineout, "%d", year); | 181 | ((7*julian + WEEK_LEN) - len) / 2, "", |
246 | center(lineout, WEEK_LEN * 3 + HEAD_SEP * 2, 0); | 182 | lineout, day_headings); |
247 | printf("\n\n"); | ||
248 | for (i = 0; i < 12; i++) | ||
249 | day_array(i + 1, year, days[i]); | ||
250 | memset(lineout, ' ', sizeof(lineout) - 1); | ||
251 | lineout[sizeof(lineout) - 1] = '\0'; | ||
252 | for (month = 0; month < 12; month += 3) { | ||
253 | center(month_names[month], WEEK_LEN, HEAD_SEP); | ||
254 | center(month_names[month + 1], WEEK_LEN, HEAD_SEP); | ||
255 | center(month_names[month + 2], WEEK_LEN, 0); | ||
256 | printf("\n%s%*s%s%*s%s\n", day_headings, HEAD_SEP, | ||
257 | "", day_headings, HEAD_SEP, "", day_headings); | ||
258 | for (row = 0; row < 6; row++) { | 183 | for (row = 0; row < 6; row++) { |
259 | for (which_cal = 0; which_cal < 3; which_cal++) { | 184 | build_row(lineout, dp)[0] = '\0'; |
260 | p = lineout + which_cal * (WEEK_LEN + 2); | 185 | dp += 7; |
261 | dp = &days[month + which_cal][row * 7]; | 186 | trim_trailing_spaces_and_print(lineout); |
262 | for (col = 0; col < 7; col++, p += DAY_LEN) | 187 | } |
263 | ascii_day(p, *dp++); | 188 | } else { |
189 | int row, which_cal, week_len, days[12][MAXDAYS]; | ||
190 | int *dp; | ||
191 | char lineout[80]; | ||
192 | |||
193 | sprintf(lineout, "%d", year); | ||
194 | center(lineout, | ||
195 | (WEEK_LEN * 3 + HEAD_SEP * 2) | ||
196 | + julian * (J_WEEK_LEN * 2 + HEAD_SEP | ||
197 | - (WEEK_LEN * 3 + HEAD_SEP * 2)), | ||
198 | 0); | ||
199 | puts("\n"); /* two \n's */ | ||
200 | for (i = 0; i < 12; i++) { | ||
201 | day_array(i + 1, year, days[i]); | ||
202 | } | ||
203 | blank_string(lineout, sizeof(lineout)); | ||
204 | week_len = WEEK_LEN + julian * (J_WEEK_LEN - WEEK_LEN); | ||
205 | for (month = 0; month < 12; month += 3-julian) { | ||
206 | center(month_names[month], week_len, HEAD_SEP); | ||
207 | if (!julian) { | ||
208 | center(month_names[month + 1], week_len, HEAD_SEP); | ||
209 | } | ||
210 | center(month_names[month + 2 - julian], week_len, 0); | ||
211 | bb_printf("\n%s%*s%s", day_headings, HEAD_SEP, "", day_headings); | ||
212 | if (!julian) { | ||
213 | bb_printf("%*s%s", HEAD_SEP, "", day_headings); | ||
214 | } | ||
215 | putchar('\n'); | ||
216 | for (row = 0; row < (6*7); row += 7) { | ||
217 | for (which_cal = 0; which_cal < 3-julian; which_cal++) { | ||
218 | dp = days[month + which_cal] + row; | ||
219 | build_row(lineout + which_cal * (week_len + 2), dp); | ||
220 | } | ||
221 | /* blank_string took care of nul termination. */ | ||
222 | trim_trailing_spaces_and_print(lineout); | ||
264 | } | 223 | } |
265 | *p = '\0'; | ||
266 | trim_trailing_spaces(lineout); | ||
267 | printf("%s\n", lineout); | ||
268 | } | 224 | } |
269 | } | 225 | } |
270 | printf("\n"); | 226 | |
227 | bb_fflush_stdout_and_exit(0); | ||
271 | } | 228 | } |
272 | 229 | ||
273 | /* | 230 | /* |
@@ -277,118 +234,129 @@ void yearly(int year) | |||
277 | * out end to end. You would have 42 numbers or spaces. This routine | 234 | * out end to end. You would have 42 numbers or spaces. This routine |
278 | * builds that array for any month from Jan. 1 through Dec. 9999. | 235 | * builds that array for any month from Jan. 1 through Dec. 9999. |
279 | */ | 236 | */ |
280 | void day_array(int month, int year, int *days) | 237 | static void day_array(int month, int year, int *days) |
281 | { | 238 | { |
239 | long temp; | ||
240 | int i; | ||
241 | int j_offset; | ||
282 | int day, dw, dm; | 242 | int day, dw, dm; |
283 | 243 | ||
244 | memset(days, SPACE, MAXDAYS * sizeof(int)); | ||
245 | |||
284 | if ((month == 9) && (year == 1752)) { | 246 | if ((month == 9) && (year == 1752)) { |
285 | memmove(days, | 247 | j_offset = julian * 244; |
286 | julian ? j_sep1752 : sep1752, MAXDAYS * sizeof(int)); | 248 | i = 0; |
249 | do { | ||
250 | days[i+2] = sep1752[i] + j_offset; | ||
251 | } while (++i < sizeof(sep1752)); | ||
252 | |||
287 | return; | 253 | return; |
288 | } | 254 | } |
289 | memmove(days, empty, MAXDAYS * sizeof(int)); | ||
290 | dm = days_in_month[leap_year(year)][month]; | ||
291 | dw = day_in_week(1, month, year); | ||
292 | day = julian ? day_in_year(1, month, year) : 1; | ||
293 | while (dm--) | ||
294 | days[dw++] = day++; | ||
295 | } | ||
296 | 255 | ||
297 | /* | 256 | /* day_in_year |
298 | * day_in_year -- | 257 | * return the 1 based day number within the year |
299 | * return the 1 based day number within the year | 258 | */ |
300 | */ | 259 | day = 1; |
301 | int day_in_year(int day, int month, int year) | 260 | if ((month > 2) && leap_year(year)) { |
302 | { | 261 | ++day; |
303 | int i, leap; | 262 | } |
304 | |||
305 | leap = leap_year(year); | ||
306 | for (i = 1; i < month; i++) | ||
307 | day += days_in_month[leap][i]; | ||
308 | return (day); | ||
309 | } | ||
310 | 263 | ||
311 | /* | 264 | i = month; |
312 | * day_in_week | 265 | while (i) { |
313 | * return the 0 based day number for any date from 1 Jan. 1 to | 266 | day += days_in_month[--i]; |
314 | * 31 Dec. 9999. Assumes the Gregorian reformation eliminates | 267 | } |
315 | * 3 Sep. 1752 through 13 Sep. 1752. Returns Thursday for all | ||
316 | * missing days. | ||
317 | */ | ||
318 | int day_in_week(int day, int month, int year) | ||
319 | { | ||
320 | long temp; | ||
321 | 268 | ||
269 | /* day_in_week | ||
270 | * return the 0 based day number for any date from 1 Jan. 1 to | ||
271 | * 31 Dec. 9999. Assumes the Gregorian reformation eliminates | ||
272 | * 3 Sep. 1752 through 13 Sep. 1752. Returns Thursday for all | ||
273 | * missing days. | ||
274 | */ | ||
275 | dw = THURSDAY; | ||
322 | temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1) | 276 | temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1) |
323 | + day_in_year(day, month, year); | 277 | + day; |
324 | if (temp < FIRST_MISSING_DAY) | 278 | if (temp < FIRST_MISSING_DAY) { |
325 | return ((temp - 1 + SATURDAY) % 7); | 279 | dw = ((temp - 1 + SATURDAY) % 7); |
326 | if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS)) | 280 | } else if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS)) { |
327 | return (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7); | 281 | dw = (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7); |
328 | return (THURSDAY); | 282 | } |
283 | |||
284 | if (!julian) { | ||
285 | day = 1; | ||
286 | } | ||
287 | |||
288 | dm = days_in_month[month]; | ||
289 | if ((month == 2) && leap_year(year)) { | ||
290 | ++dm; | ||
291 | } | ||
292 | |||
293 | while (dm) { | ||
294 | days[dw++] = day++; | ||
295 | --dm; | ||
296 | } | ||
329 | } | 297 | } |
330 | 298 | ||
331 | void ascii_day(char *p, int day) | 299 | static void trim_trailing_spaces_and_print(char *s) |
332 | { | 300 | { |
333 | int display, val; | 301 | char *p = s; |
334 | static char *aday[] = { | 302 | |
335 | "", | 303 | while (*p) { |
336 | " 1", " 2", " 3", " 4", " 5", " 6", " 7", | 304 | ++p; |
337 | " 8", " 9", "10", "11", "12", "13", "14", | ||
338 | "15", "16", "17", "18", "19", "20", "21", | ||
339 | "22", "23", "24", "25", "26", "27", "28", | ||
340 | "29", "30", "31", | ||
341 | }; | ||
342 | |||
343 | if (day == SPACE) { | ||
344 | memset(p, ' ', julian ? J_DAY_LEN : DAY_LEN); | ||
345 | return; | ||
346 | } | 305 | } |
347 | if (julian) { | 306 | while (p > s) { |
348 | if ((val = day / 100) != 0) { | 307 | --p; |
349 | day %= 100; | 308 | if (!(isspace)(*p)) { /* We want the function... not the inline. */ |
350 | *p++ = val + '0'; | 309 | p[1] = '\0'; |
351 | display = 1; | 310 | break; |
352 | } else { | ||
353 | *p++ = ' '; | ||
354 | display = 0; | ||
355 | } | 311 | } |
356 | val = day / 10; | ||
357 | if (val || display) | ||
358 | *p++ = val + '0'; | ||
359 | else | ||
360 | *p++ = ' '; | ||
361 | *p++ = day % 10 + '0'; | ||
362 | } else { | ||
363 | *p++ = aday[day][0]; | ||
364 | *p++ = aday[day][1]; | ||
365 | } | 312 | } |
366 | *p = ' '; | 313 | |
314 | puts(s); | ||
367 | } | 315 | } |
368 | 316 | ||
369 | void trim_trailing_spaces(char *s) | 317 | static void center(char *str, int len, int separate) |
370 | { | 318 | { |
371 | char *p; | 319 | int n = strlen(str); |
320 | len -= n; | ||
321 | bb_printf("%*s%*s", (len/2) + n, str, (len/2) + (len % 2) + separate, ""); | ||
322 | } | ||
372 | 323 | ||
373 | for (p = s; *p; ++p) | 324 | static void blank_string(char *buf, size_t buflen) |
374 | continue; | 325 | { |
375 | while (p > s && (--p, isspace(*p))) | 326 | memset(buf, ' ', buflen); |
376 | continue; | 327 | buf[buflen-1] = '\0'; |
377 | if (p > s) | ||
378 | ++p; | ||
379 | *p = '\0'; | ||
380 | } | 328 | } |
381 | 329 | ||
382 | void center(char *str, int len, int separate) | 330 | static char *build_row(char *p, int *dp) |
383 | { | 331 | { |
332 | int col, val, day; | ||
333 | |||
334 | memset(p, ' ', (julian + DAY_LEN) * 7); | ||
335 | |||
336 | col = 0; | ||
337 | do { | ||
338 | if ((day = *dp++) != SPACE) { | ||
339 | if (julian) { | ||
340 | *++p; | ||
341 | if (day >= 100) { | ||
342 | *p = '0'; | ||
343 | p[-1] = (day / 100) + '0'; | ||
344 | day %= 100; | ||
345 | } | ||
346 | } | ||
347 | if ((val = day / 10) > 0) { | ||
348 | *p = val + '0'; | ||
349 | } | ||
350 | *++p = day % 10 + '0'; | ||
351 | p += 2; | ||
352 | } else { | ||
353 | p += DAY_LEN + julian; | ||
354 | } | ||
355 | } while (++col < 7); | ||
384 | 356 | ||
385 | len -= strlen(str); | 357 | return p; |
386 | printf("%*s%s%*s", len / 2, "", str, len / 2 + len % 2, ""); | ||
387 | if (separate) | ||
388 | printf("%*s", separate, ""); | ||
389 | } | 358 | } |
390 | 359 | ||
391 | |||
392 | /* | 360 | /* |
393 | * Copyright (c) 1989, 1993, 1994 | 361 | * Copyright (c) 1989, 1993, 1994 |
394 | * The Regents of the University of California. All rights reserved. | 362 | * The Regents of the University of California. All rights reserved. |