diff options
| author | Ron Yorston <rmy@pobox.com> | 2021-09-21 15:19:18 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2021-09-21 15:19:18 +0100 |
| commit | 90b3ba992ecb39e32e5a66b2e37579becc56d286 (patch) | |
| tree | 4c4a2c9e1baeb8230d78efd058bb4bcabc3fd12b /util-linux | |
| parent | df34f5e92b1d10f0bb858d2ea6e8c249e87ac593 (diff) | |
| parent | 56f0e886db0543a27f369d7f95eb9da2fb3d069c (diff) | |
| download | busybox-w32-90b3ba992ecb39e32e5a66b2e37579becc56d286.tar.gz busybox-w32-90b3ba992ecb39e32e5a66b2e37579becc56d286.tar.bz2 busybox-w32-90b3ba992ecb39e32e5a66b2e37579becc56d286.zip | |
Merge branch 'busybox' into merge
Diffstat (limited to 'util-linux')
| -rw-r--r-- | util-linux/cal.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/util-linux/cal.c b/util-linux/cal.c index 006bc817b..6ba6ebf98 100644 --- a/util-linux/cal.c +++ b/util-linux/cal.c | |||
| @@ -27,10 +27,11 @@ | |||
| 27 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cal.html */ | 27 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cal.html */ |
| 28 | 28 | ||
| 29 | //usage:#define cal_trivial_usage | 29 | //usage:#define cal_trivial_usage |
| 30 | //usage: "[-jy] [[MONTH] YEAR]" | 30 | //usage: "[-jmy] [[MONTH] YEAR]" |
| 31 | //usage:#define cal_full_usage "\n\n" | 31 | //usage:#define cal_full_usage "\n\n" |
| 32 | //usage: "Display a calendar\n" | 32 | //usage: "Display a calendar\n" |
| 33 | //usage: "\n -j Use julian dates" | 33 | //usage: "\n -j Use julian dates" |
| 34 | //usage: "\n -m Week starts on Monday" | ||
| 34 | //usage: "\n -y Display the entire year" | 35 | //usage: "\n -y Display the entire year" |
| 35 | 36 | ||
| 36 | #include "libbb.h" | 37 | #include "libbb.h" |
| @@ -38,6 +39,8 @@ | |||
| 38 | 39 | ||
| 39 | /* We often use "unsigned" instead of "int", it's easier to div on most CPUs */ | 40 | /* We often use "unsigned" instead of "int", it's easier to div on most CPUs */ |
| 40 | 41 | ||
| 42 | #define SUNDAY 0 | ||
| 43 | #define MONDAY 1 | ||
| 41 | #define THURSDAY 4 /* for reformation */ | 44 | #define THURSDAY 4 /* for reformation */ |
| 42 | #define SATURDAY 6 /* 1 Jan 1 was a Saturday */ | 45 | #define SATURDAY 6 /* 1 Jan 1 was a Saturday */ |
| 43 | 46 | ||
| @@ -81,7 +84,7 @@ static int leap_year(unsigned yr) | |||
| 81 | ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr)) | 84 | ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr)) |
| 82 | 85 | ||
| 83 | static void center(char *, unsigned, unsigned); | 86 | static void center(char *, unsigned, unsigned); |
| 84 | static void day_array(unsigned, unsigned, unsigned *); | 87 | static void day_array(unsigned, unsigned, unsigned, unsigned *); |
| 85 | static void trim_trailing_spaces_and_print(char *); | 88 | static void trim_trailing_spaces_and_print(char *); |
| 86 | 89 | ||
| 87 | static void blank_string(char *buf, size_t buflen); | 90 | static void blank_string(char *buf, size_t buflen); |
| @@ -93,12 +96,18 @@ static char *build_row(char *p, unsigned *dp); | |||
| 93 | #define J_WEEK_LEN (WEEK_LEN + 7) | 96 | #define J_WEEK_LEN (WEEK_LEN + 7) |
| 94 | #define HEAD_SEP 2 /* spaces between day headings */ | 97 | #define HEAD_SEP 2 /* spaces between day headings */ |
| 95 | 98 | ||
| 99 | enum { | ||
| 100 | OPT_JULIAN = (1 << 0), | ||
| 101 | OPT_MONDAY = (1 << 1), | ||
| 102 | OPT_YEAR = (1 << 2), | ||
| 103 | }; | ||
| 104 | |||
| 96 | int cal_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 105 | int cal_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 97 | int cal_main(int argc UNUSED_PARAM, char **argv) | 106 | int cal_main(int argc UNUSED_PARAM, char **argv) |
| 98 | { | 107 | { |
| 99 | struct tm zero_tm; | 108 | struct tm zero_tm; |
| 100 | time_t now; | 109 | time_t now; |
| 101 | unsigned month, year, flags, i; | 110 | unsigned month, year, flags, i, weekstart; |
| 102 | char *month_names[12]; | 111 | char *month_names[12]; |
| 103 | /* normal heading: */ | 112 | /* normal heading: */ |
| 104 | /* "Su Mo Tu We Th Fr Sa" */ | 113 | /* "Su Mo Tu We Th Fr Sa" */ |
| @@ -110,10 +119,11 @@ int cal_main(int argc UNUSED_PARAM, char **argv) | |||
| 110 | 119 | ||
| 111 | init_unicode(); | 120 | init_unicode(); |
| 112 | 121 | ||
| 113 | flags = getopt32(argv, "jy"); | 122 | flags = getopt32(argv, "jmy"); |
| 114 | /* This sets julian = flags & 1: */ | 123 | /* This sets julian = flags & OPT_JULIAN: */ |
| 115 | option_mask32 &= 1; | 124 | option_mask32 &= OPT_JULIAN; |
| 116 | month = 0; | 125 | month = 0; |
| 126 | weekstart = (flags & OPT_MONDAY) ? MONDAY : SUNDAY; | ||
| 117 | argv += optind; | 127 | argv += optind; |
| 118 | 128 | ||
| 119 | if (!argv[0]) { | 129 | if (!argv[0]) { |
| @@ -122,7 +132,7 @@ int cal_main(int argc UNUSED_PARAM, char **argv) | |||
| 122 | time(&now); | 132 | time(&now); |
| 123 | ptm = localtime(&now); | 133 | ptm = localtime(&now); |
| 124 | year = ptm->tm_year + 1900; | 134 | year = ptm->tm_year + 1900; |
| 125 | if (!(flags & 2)) { /* no -y */ | 135 | if (!(flags & OPT_YEAR)) { /* no -y */ |
| 126 | month = ptm->tm_mon + 1; | 136 | month = ptm->tm_mon + 1; |
| 127 | } | 137 | } |
| 128 | } else { | 138 | } else { |
| @@ -130,7 +140,7 @@ int cal_main(int argc UNUSED_PARAM, char **argv) | |||
| 130 | if (argv[2]) { | 140 | if (argv[2]) { |
| 131 | bb_show_usage(); | 141 | bb_show_usage(); |
| 132 | } | 142 | } |
| 133 | if (!(flags & 2)) { /* no -y */ | 143 | if (!(flags & OPT_YEAR)) { /* no -y */ |
| 134 | month = xatou_range(*argv, 1, 12); | 144 | month = xatou_range(*argv, 1, 12); |
| 135 | } | 145 | } |
| 136 | argv++; | 146 | argv++; |
| @@ -148,7 +158,7 @@ int cal_main(int argc UNUSED_PARAM, char **argv) | |||
| 148 | month_names[i] = xstrdup(buf); | 158 | month_names[i] = xstrdup(buf); |
| 149 | 159 | ||
| 150 | if (i < 7) { | 160 | if (i < 7) { |
| 151 | zero_tm.tm_wday = i; | 161 | zero_tm.tm_wday = (i + weekstart) % 7; |
| 152 | /* abbreviated weekday name according to locale */ | 162 | /* abbreviated weekday name according to locale */ |
| 153 | strftime(buf, sizeof(buf), "%a", &zero_tm); | 163 | strftime(buf, sizeof(buf), "%a", &zero_tm); |
| 154 | #if ENABLE_UNICODE_SUPPORT | 164 | #if ENABLE_UNICODE_SUPPORT |
| @@ -173,7 +183,7 @@ int cal_main(int argc UNUSED_PARAM, char **argv) | |||
| 173 | unsigned *dp = days; | 183 | unsigned *dp = days; |
| 174 | char lineout[30]; | 184 | char lineout[30]; |
| 175 | 185 | ||
| 176 | day_array(month, year, dp); | 186 | day_array(month, year, weekstart, dp); |
| 177 | len = sprintf(lineout, "%s %u", month_names[month - 1], year); | 187 | len = sprintf(lineout, "%s %u", month_names[month - 1], year); |
| 178 | printf("%*s%s\n%s\n", | 188 | printf("%*s%s\n%s\n", |
| 179 | ((7*julian + WEEK_LEN) - len) / 2, "", | 189 | ((7*julian + WEEK_LEN) - len) / 2, "", |
| @@ -197,7 +207,7 @@ int cal_main(int argc UNUSED_PARAM, char **argv) | |||
| 197 | ); | 207 | ); |
| 198 | puts("\n"); /* two \n's */ | 208 | puts("\n"); /* two \n's */ |
| 199 | for (i = 0; i < 12; i++) { | 209 | for (i = 0; i < 12; i++) { |
| 200 | day_array(i + 1, year, days[i]); | 210 | day_array(i + 1, year, weekstart, days[i]); |
| 201 | } | 211 | } |
| 202 | blank_string(lineout, sizeof(lineout)); | 212 | blank_string(lineout, sizeof(lineout)); |
| 203 | week_len = WEEK_LEN + julian * (J_WEEK_LEN - WEEK_LEN); | 213 | week_len = WEEK_LEN + julian * (J_WEEK_LEN - WEEK_LEN); |
| @@ -233,7 +243,8 @@ int cal_main(int argc UNUSED_PARAM, char **argv) | |||
| 233 | * out end to end. You would have 42 numbers or spaces. This routine | 243 | * out end to end. You would have 42 numbers or spaces. This routine |
| 234 | * builds that array for any month from Jan. 1 through Dec. 9999. | 244 | * builds that array for any month from Jan. 1 through Dec. 9999. |
| 235 | */ | 245 | */ |
| 236 | static void day_array(unsigned month, unsigned year, unsigned *days) | 246 | static void day_array(unsigned month, unsigned year, unsigned weekstart, |
| 247 | unsigned *days) | ||
| 237 | { | 248 | { |
| 238 | unsigned long temp; | 249 | unsigned long temp; |
| 239 | unsigned i; | 250 | unsigned i; |
| @@ -249,7 +260,7 @@ static void day_array(unsigned month, unsigned year, unsigned *days) | |||
| 249 | size_t oday = 0; | 260 | size_t oday = 0; |
| 250 | 261 | ||
| 251 | do { | 262 | do { |
| 252 | days[oday+2] = sep1752[oday] + j_offset; | 263 | days[oday+2-weekstart] = sep1752[oday] + j_offset; |
| 253 | } while (++oday < sizeof(sep1752)); | 264 | } while (++oday < sizeof(sep1752)); |
| 254 | 265 | ||
| 255 | return; | 266 | return; |
| @@ -280,6 +291,7 @@ static void day_array(unsigned month, unsigned year, unsigned *days) | |||
| 280 | } else { | 291 | } else { |
| 281 | dw = (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7); | 292 | dw = (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7); |
| 282 | } | 293 | } |
| 294 | dw = (dw - weekstart + 7) % 7; | ||
| 283 | 295 | ||
| 284 | if (!julian) { | 296 | if (!julian) { |
| 285 | day = 1; | 297 | day = 1; |
