* [PATCH 01/13] cal: use control structure for run time configuration
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-11-10 18:23 ` [PATCH 02/13] cal: rename ascii_wnum() to ascii_weeknum() Sami Kerola
` (12 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
Runtime configuration is set at the time of command line option parsing,
and other initialization. Later the configuration is read-only. This
should make code a little bit more understandable.
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
misc-utils/cal.c | 271 ++++++++++++++++++++++++++++---------------------------
1 file changed, 140 insertions(+), 131 deletions(-)
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index c9264ba..f82d02e 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -234,40 +234,50 @@ enum {
/* utf-8 can have up to 6 bytes per char; and an extra byte for ending \0 */
static char day_headings[J_WEEK_LEN * 6 + 1];
-/* weekstart = 1 => " M Tu W Th F S S " */
-static const char *full_month[MONTHS_IN_YEAR];
-/* 0 => sunday, 1 => monday */
-static int weekstart = SUNDAY;
-static int julian;
+struct cal_control {
+ const char *full_month[MONTHS_IN_YEAR]; /* month names */
+ int colormode; /* day and week number highlight */
+ int num_months; /* number of months horizontally in print out */
+ int weekstart; /* day the week starts, often Sun or Mon */
+ int weektype; /* WEEK_TYPE_{NONE,ISO,US} */
+ int weeknum; /* requested --week=<number> */
+ unsigned int julian:1, /* julian output */
+ yflag:1; /* print whole year */
+};
/* function prototypes */
static int leap_year(long year);
-static char * ascii_day(char *, int);
-static char * ascii_wnum(char *, int,int);
+static char *ascii_day(char *, int, const struct cal_control *ctl);
+static char *ascii_wnum(char *p, int wn, const struct cal_control *ctl);
static int center_str(const char* src, char* dest, size_t dest_size, size_t width);
static void center(const char *, size_t, int);
-static void day_array(int, int, long, int *);
+static void day_array(int, int, long, int *, const struct cal_control *ctl);
static int day_in_week(int, int, long);
static int day_in_year(int, int, long);
-static int week_number(int, int, long, int);
-static int week_to_day(int, long, int);
-static void yearly(int, long, int, int);
-static int do_monthly(int, int, long, int, struct fmt_st*, int);
-static void monthly(int, int, long, int);
-static int two_header_lines(int month, long year);
-static void monthly3(int, int, long, int);
+static int week_number(int, int, long, const struct cal_control *ctl);
+static int week_to_day(long, const struct cal_control *ctl);
+static void yearly(int, long, const struct cal_control *ctl);
+static int do_monthly(int day, int month, long year, struct fmt_st *out,
+ int header_hint, const struct cal_control *ctl);
+static void monthly(int, int, long, const struct cal_control *ctl);
+static int two_header_lines(int month, long year, const struct cal_control *ctl);
+static void monthly3(int, int, long, const struct cal_control *ctl);
static void __attribute__ ((__noreturn__)) usage(FILE * out);
-static void headers_init(int);
+static void headers_init(struct cal_control *ctl);
int main(int argc, char **argv)
{
struct tm *local_time;
time_t now;
- int ch, day = 0, month = 0, yflag = 0, wflag = WEEK_NUM_DISABLED;
+ int ch, day = 0, month = 0;
long year;
- int num_months = NUM_MONTHS;
- int colormode = UL_COLORMODE_AUTO, wnum = 0;
+ static struct cal_control ctl = {
+ .weekstart = SUNDAY,
+ .num_months = NUM_MONTHS,
+ .colormode = UL_COLORMODE_AUTO,
+ .weektype = WEEK_NUM_DISABLED
+ };
enum {
OPT_COLOR = CHAR_MAX + 1
@@ -335,42 +345,42 @@ int main(int argc, char **argv)
wfd = val.word;
wfd = day_in_week(wfd % 100, (wfd / 100) % 100, wfd / (100 * 100));
- weekstart = (wfd + *nl_langinfo(_NL_TIME_FIRST_WEEKDAY) - 1) % DAYS_IN_WEEK;
+ ctl.weekstart = (wfd + *nl_langinfo(_NL_TIME_FIRST_WEEKDAY) - 1) % DAYS_IN_WEEK;
}
#endif
while ((ch = getopt_long(argc, argv, "13mjsywVh", longopts, NULL)) != -1)
switch(ch) {
case '1':
- num_months = 1; /* default */
+ ctl.num_months = 1; /* default */
break;
case '3':
- num_months = 3;
+ ctl.num_months = 3;
break;
case 's':
- weekstart = SUNDAY; /* default */
+ ctl.weekstart = SUNDAY; /* default */
break;
case 'm':
- weekstart = MONDAY;
+ ctl.weekstart = MONDAY;
break;
case 'j':
- julian = 1;
+ ctl.julian = 1;
break;
case 'y':
- yflag = 1;
+ ctl.yflag = 1;
break;
case 'w':
if (optarg) {
- wnum = strtos32_or_err(optarg,
+ ctl.weeknum = strtos32_or_err(optarg,
_("invalid week argument"));
- if (wnum < 1 || wnum > 53)
+ if (ctl.weeknum < 1 || 53 < ctl.weeknum)
errx(EXIT_FAILURE,_("illegal week value: use 1-53"));
}
- wflag = WEEK_NUM_US; /* default per weekstart */
+ ctl.weektype = WEEK_NUM_US; /* default per weekstart */
break;
case OPT_COLOR:
if (optarg)
- colormode = colormode_or_err(optarg,
+ ctl.colormode = colormode_or_err(optarg,
_("unsupported color mode"));
break;
case 'V':
@@ -385,9 +395,9 @@ int main(int argc, char **argv)
argc -= optind;
argv += optind;
- if (wflag) {
- wflag = wnum & WEEK_NUM_MASK;
- wflag |= (weekstart == MONDAY ? WEEK_NUM_ISO : WEEK_NUM_US);
+ if (ctl.weektype) {
+ ctl.weektype = ctl.weeknum & WEEK_NUM_MASK;
+ ctl.weektype |= (ctl.weekstart == MONDAY ? WEEK_NUM_ISO : WEEK_NUM_US);
}
time(&now);
@@ -416,8 +426,8 @@ int main(int argc, char **argv)
} else if ((long) (local_time->tm_year + 1900) == year) {
day = local_time->tm_yday + 1;
}
- if (!month && !wnum)
- yflag=1;
+ if (!month && !ctl.weeknum)
+ ctl.yflag = 1;
break;
case 0:
day = local_time->tm_yday + 1;
@@ -428,14 +438,14 @@ int main(int argc, char **argv)
usage(stderr);
}
- if (wnum > 0) {
- int yday = week_to_day(wnum, year, wflag);
+ if (0 < ctl.weeknum) {
+ int yday = week_to_day(year, &ctl);
int leap = leap_year(year);
if (yday < 1)
errx(EXIT_FAILURE, _("illegal week value: year %ld "
"doesn't have week %d"),
- year, wnum);
+ year, ctl.weeknum);
month = 1;
while (month <= 12 && yday > days_in_month[leap][month])
yday -= days_in_month[leap][month++];
@@ -445,29 +455,29 @@ int main(int argc, char **argv)
* the year in question ends during 52, in this case
* we're assuming that early remnant is being referred
* to if 53 is given as argument. */
- if (wnum == week_number(31, 12, year - 1, wflag))
+ if (ctl.weeknum == week_number(31, 12, year - 1, &ctl))
month = 1;
else
errx(EXIT_FAILURE,
_("illegal week value: year %ld "
"doesn't have week %d"),
- year, wnum);
+ year, ctl.weeknum);
}
}
- headers_init(julian);
+ headers_init(&ctl);
- if (!colors_init(colormode)) {
+ if (!colors_init(ctl.colormode)) {
day = 0;
- wflag &= ~WEEK_NUM_MASK;
+ ctl.weektype &= ~WEEK_NUM_MASK;
}
- if (yflag)
- yearly(day, year, julian, wflag);
- else if (num_months == 1)
- monthly(day, month, year, wflag);
- else if (num_months == 3)
- monthly3(day, month, year, wflag);
+ if (ctl.yflag)
+ yearly(day, year, &ctl);
+ else if (ctl.num_months == 1)
+ monthly(day, month, year, &ctl);
+ else if (ctl.num_months == 3)
+ monthly3(day, month, year, &ctl);
return EXIT_SUCCESS;
}
@@ -481,14 +491,14 @@ static int leap_year(long year)
return ( !(year % 4) && (year % 100) ) || !(year % 400);
}
-static void headers_init(int julian)
+static void headers_init(struct cal_control *ctl)
{
- size_t i, wd, spaces = julian ? J_DAY_LEN - 1 : DAY_LEN - 1;
+ size_t i, wd, spaces = ctl->julian ? J_DAY_LEN - 1 : DAY_LEN - 1;
char *cur_dh = day_headings;
for (i = 0; i < DAYS_IN_WEEK; i++) {
size_t space_left;
- wd = (i + weekstart) % DAYS_IN_WEEK;
+ wd = (i + ctl->weekstart) % DAYS_IN_WEEK;
if (i)
strcat(cur_dh++, " ");
@@ -501,24 +511,24 @@ static void headers_init(int julian)
}
for (i = 0; i < MONTHS_IN_YEAR; i++)
- full_month[i] = nl_langinfo(MON_1 + i);
+ ctl->full_month[i] = nl_langinfo(MON_1 + i);
}
-static int do_monthly(int day, int month, long year, int wflag,
- struct fmt_st *out, int header_hint)
+static int do_monthly(int day, int month, long year, struct fmt_st *out,
+ int header_hint, const struct cal_control *ctl)
{
int col, row, days[MAXDAYS];
char *p, lineout[FMT_ST_CHARS];
- size_t width = (julian ? J_WEEK_LEN : WEEK_LEN) - 1
- + (wflag ? WNUM_LEN : 0);
+ size_t width = (ctl->julian ? J_WEEK_LEN : WEEK_LEN) - 1
+ + (ctl->weektype ? WNUM_LEN : 0);
int pos = 0;
- day_array(day, month, year, days);
+ day_array(day, month, year, days, ctl);
if (header_hint < 0)
- header_hint = two_header_lines(month, year);
+ header_hint = two_header_lines(month, year, ctl);
if (header_hint) {
- snprintf(lineout, sizeof(lineout), _("%s"), full_month[month - 1]);
+ snprintf(lineout, sizeof(lineout), _("%s"), ctl->full_month[month - 1]);
center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), width);
pos++;
snprintf(lineout, sizeof(lineout), _("%ld"), year);
@@ -530,26 +540,25 @@ static int do_monthly(int day, int month, long year, int wflag,
* e.g. for Basque the translation should be "%2$ldko %1$s".
*/
snprintf(lineout, sizeof(lineout), _("%s %ld"),
- full_month[month - 1], year);
+ ctl->full_month[month - 1], year);
center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), width);
pos++;
}
snprintf(out->s[pos++], FMT_ST_CHARS, "%s%s",
- (wflag ? " " : ""),
+ (ctl->weektype ? " " : ""),
day_headings);
for (row = 0; row < DAYS_IN_WEEK - 1; row++) {
int has_hl = 0;
p = lineout;
- if (wflag)
+ if (ctl->weektype)
for (col = 0; col < DAYS_IN_WEEK; col++) {
int xd = days[row * DAYS_IN_WEEK + col];
if (xd != SPACE) {
- int wnum = week_number(xd & ~TODAY_FLAG,
- month, year, wflag);
- p = ascii_wnum(p, wnum,
- (wflag & WEEK_NUM_MASK) == wnum);
+ int wn = week_number(xd & ~TODAY_FLAG,
+ month, year, ctl);
+ p = ascii_wnum(p, wn, ctl);
break;
} else if (col+1 == DAYS_IN_WEEK)
p += sprintf(p," ");
@@ -558,7 +567,7 @@ static int do_monthly(int day, int month, long year, int wflag,
int xd = days[row * DAYS_IN_WEEK + col];
if (xd != SPACE && (xd & TODAY_FLAG))
has_hl = 1;
- p = ascii_day(p, xd);
+ p = ascii_day(p, xd, ctl);
}
*p = '\0';
snprintf(out->s[row+pos], FMT_ST_CHARS, "%s", lineout);
@@ -569,32 +578,32 @@ static int do_monthly(int day, int month, long year, int wflag,
return pos;
}
-static void monthly(int day, int month, long year, int wflag)
+static void monthly(int day, int month, long year, const struct cal_control *ctl)
{
int i, rows;
struct fmt_st out;
- rows = do_monthly(day, month, year, wflag, &out, -1);
+ rows = do_monthly(day, month, year, &out, -1, ctl);
for (i = 0; i < rows; i++) {
my_putstring(out.s[i]);
my_putstring("\n");
}
}
-static int two_header_lines(int month, long year)
+static int two_header_lines(int month, long year, const struct cal_control *ctl)
{
char lineout[FMT_ST_CHARS];
- size_t width = (julian ? J_WEEK_LEN : WEEK_LEN) - 1;
+ size_t width = (ctl->julian ? J_WEEK_LEN : WEEK_LEN) - 1;
size_t len;
snprintf(lineout, sizeof(lineout), "%ld", year);
len = strlen(lineout);
- len += strlen(full_month[month - 1]) + 1;
+ len += strlen(ctl->full_month[month - 1]) + 1;
if (width < len)
return 1;
return 0;
}
-static void monthly3(int day, int month, long year, int wflag)
+static void monthly3(int day, int month, long year, const struct cal_control *ctl)
{
char lineout[FMT_ST_CHARS];
int i;
@@ -622,18 +631,18 @@ static void monthly3(int day, int month, long year, int wflag)
next_month = month + 1;
next_year = year;
}
- two_lines = two_header_lines(prev_month, prev_year);
- two_lines += two_header_lines(month, year);
- two_lines += two_header_lines(next_month, next_year);
+ two_lines = two_header_lines(prev_month, prev_year, ctl);
+ two_lines += two_header_lines(month, year, ctl);
+ two_lines += two_header_lines(next_month, next_year, ctl);
if (0 < two_lines)
rows = FMT_ST_LINES;
else
rows = FMT_ST_LINES - 1;
- do_monthly(day, prev_month, prev_year, wflag, &out_prev, two_lines);
- do_monthly(day, month, year, wflag, &out_curm, two_lines);
- do_monthly(day, next_month, next_year, wflag, &out_next, two_lines);
+ do_monthly(day, prev_month, prev_year, &out_prev, two_lines, ctl);
+ do_monthly(day, month, year, &out_curm, two_lines, ctl);
+ do_monthly(day, next_month, next_year, &out_next, two_lines, ctl);
- width = (julian ? J_WEEK_LEN : WEEK_LEN) -1;
+ width = (ctl->julian ? J_WEEK_LEN : WEEK_LEN) -1;
for (i = 0; i < (two_lines ? 3 : 2); i++) {
snprintf(lineout, sizeof(lineout),
"%s %s %s\n", out_prev.s[i], out_curm.s[i], out_next.s[i]);
@@ -658,9 +667,9 @@ static void monthly3(int day, int month, long year, int wflag)
}
}
-static char *append_wnum(char *p, int *dp,
+static char *append_weeknum(char *p, int *dp,
int month, long year, int cal,
- int row, int wflag)
+ int row, const struct cal_control *ctl)
{
int col;
@@ -668,9 +677,9 @@ static char *append_wnum(char *p, int *dp,
int xd = dp[row * DAYS_IN_WEEK + col];
if (xd != SPACE) {
- int wnum = week_number(xd & ~TODAY_FLAG,
- month + cal + 1, year, wflag);
- p = ascii_wnum(p, wnum, (wflag & WEEK_NUM_MASK) == wnum);
+ int weeknum = week_number(xd & ~TODAY_FLAG,
+ month + cal + 1, year, ctl);
+ p = ascii_wnum(p, weeknum, ctl);
break;
} else if (col+1 == DAYS_IN_WEEK)
p += sprintf(p," ");
@@ -678,25 +687,25 @@ static char *append_wnum(char *p, int *dp,
return p;
}
-static void yearly(int day, long year, int julian, int wflag)
+static void yearly(int day, long year, const struct cal_control *ctl)
{
int col, i, month, row, which_cal;
int maxrow, sep_len, week_len;
int days[MONTHS_IN_YEAR][MAXDAYS];
char *p;
/* three weeks + separators + \0 */
- int wnumlen = (wflag ? WNUM_LEN : 0);
- char lineout[ wnumlen + sizeof(day_headings) + 2 +
- wnumlen + sizeof(day_headings) + 2 +
- wnumlen + sizeof(day_headings) + 1 ];
- if (julian) {
+ int weeknumlen = (ctl->weektype ? WNUM_LEN : 0);
+ char lineout[ weeknumlen + sizeof(day_headings) + 2 +
+ weeknumlen + sizeof(day_headings) + 2 +
+ weeknumlen + sizeof(day_headings) + 1 ];
+ if (ctl->julian) {
maxrow = J_MONTH_COLS;
sep_len = J_HEAD_SEP;
- week_len = J_WEEK_LEN + wnumlen;
+ week_len = J_WEEK_LEN + weeknumlen;
} else {
maxrow = MONTH_COLS;
sep_len = HEAD_SEP;
- week_len = WEEK_LEN + wnumlen;
+ week_len = WEEK_LEN + weeknumlen;
}
snprintf(lineout, sizeof(lineout), "%ld", year);
@@ -707,27 +716,27 @@ static void yearly(int day, long year, int julian, int wflag)
my_putstring("\n\n");
for (i = 0; i < MONTHS_IN_YEAR; i++)
- day_array(day, i + 1, year, days[i]);
+ day_array(day, i + 1, year, days[i], ctl);
for (month = 0; month < MONTHS_IN_YEAR; month += maxrow) {
- center(full_month[month], week_len - 1, sep_len + 1);
- if (julian) {
- center(full_month[month + 1], week_len - 1, 0);
+ center(ctl->full_month[month], week_len - 1, sep_len + 1);
+ if (ctl->julian) {
+ center(ctl->full_month[month + 1], week_len - 1, 0);
} else {
- center(full_month[month + 1], week_len - 1, sep_len + 1);
- center(full_month[month + 2], week_len - 1, 0);
+ center(ctl->full_month[month + 1], week_len - 1, sep_len + 1);
+ center(ctl->full_month[month + 2], week_len - 1, 0);
}
- if (julian)
+ if (ctl->julian)
snprintf(lineout, sizeof(lineout),
"\n%*s%s%*s %*s%s\n",
- wnumlen,"", day_headings, sep_len, "",
- wnumlen,"", day_headings);
+ weeknumlen,"", day_headings, sep_len, "",
+ weeknumlen,"", day_headings);
else
snprintf(lineout, sizeof(lineout),
"\n%*s%s%*s %*s%s%*s %*s%s\n",
- wnumlen,"", day_headings, sep_len, "",
- wnumlen,"", day_headings, sep_len, "",
- wnumlen,"", day_headings);
+ weeknumlen,"", day_headings, sep_len, "",
+ weeknumlen,"", day_headings, sep_len, "",
+ weeknumlen,"", day_headings);
my_putstring(lineout);
for (row = 0; row < DAYS_IN_WEEK - 1; row++) {
@@ -735,13 +744,13 @@ static void yearly(int day, long year, int julian, int wflag)
for (which_cal = 0; which_cal < maxrow; which_cal++) {
int *dp = &days[month + which_cal][row * DAYS_IN_WEEK];
- if (wflag)
- p = append_wnum(p, days[month + which_cal],
+ if (ctl->weektype)
+ p = append_weeknum(p, days[month + which_cal],
month, year, which_cal,
- row, wflag);
+ row, ctl);
for (col = 0; col < DAYS_IN_WEEK; col++)
- p = ascii_day(p, *dp++);
+ p = ascii_day(p, *dp++, ctl);
p += sprintf(p, " ");
}
*p = '\0';
@@ -759,25 +768,25 @@ static void yearly(int day, long year, int julian, int wflag)
* out end to end. You would have 42 numbers or spaces. This routine
* builds that array for any month from Jan. 1 through Dec. 9999.
*/
-static void day_array(int day, int month, long year, int *days)
+static void day_array(int day, int month, long year, int *days, const struct cal_control *ctl)
{
int julday, daynum, dw, dm;
const int *sep1752;
memcpy(days, empty, MAXDAYS * sizeof(int));
if (year == REFORMATION_YEAR && month == REFORMATION_MONTH) {
- sep1752 = julian ? j_sep1752 : d_sep1752;
- memcpy(days, sep1752 + weekstart,
- ((MAXDAYS / 2) - weekstart) * sizeof(int));
+ sep1752 = ctl->julian ? j_sep1752 : d_sep1752;
+ memcpy(days, sep1752 + ctl->weekstart,
+ ((MAXDAYS / 2) - ctl->weekstart) * sizeof(int));
for (dm = 0; dm < MAXDAYS / 2; dm++)
if (j_sep1752[dm] == day)
days[dm] |= TODAY_FLAG;
return;
}
dm = days_in_month[leap_year(year)][month];
- dw = (day_in_week(1, month, year) - weekstart + DAYS_IN_WEEK) % DAYS_IN_WEEK;
+ dw = (day_in_week(1, month, year) - ctl->weekstart + DAYS_IN_WEEK) % DAYS_IN_WEEK;
julday = day_in_year(1, month, year);
- daynum = julian ? julday : 1;
+ daynum = ctl->julian ? julday : 1;
while (dm--) {
days[dw] = daynum++;
@@ -841,12 +850,12 @@ static int day_in_week(int d, int m, long y)
* Day may be given as Julian day of the year mode, in which
* case the month is disregarded entirely.
*/
-static int week_number(int day, int month, long year, int wflag)
+static int week_number(int day, int month, long year, const struct cal_control *ctl)
{
int fday = 0, yday;
int wday = day_in_week(1, 1, year);
- if (wflag & WEEK_NUM_ISO)
+ if (ctl->weektype & WEEK_NUM_ISO)
fday = wday + (wday >= FRIDAY ? -2 : 5);
else
/* WEEK_NUM_US
@@ -869,17 +878,17 @@ static int week_number(int day, int month, long year, int wflag)
/* Last year is last year */
if (yday + fday < 7)
- return week_number(31, 12, year - 1, wflag);
+ return week_number(31, 12, year - 1, ctl);
/* Or it could be part of the next year. The reformation year had less
* days than 365 making this check invalid, but reformation year ended
* on Sunday and in week 51, so it's ok here. */
- if (wflag == WEEK_NUM_ISO && yday >= 363
+ if (ctl->weektype == WEEK_NUM_ISO && yday >= 363
&& day_in_week(day, month, year) >= MONDAY
&& day_in_week(day, month, year) <= WEDNESDAY
&& day_in_week(31, 12, year) >= MONDAY
&& day_in_week(31, 12, year) <= WEDNESDAY)
- return week_number(1, 1, year + 1, wflag);
+ return week_number(1, 1, year + 1, ctl);
return (yday + fday) / 7;
}
@@ -891,14 +900,14 @@ static int week_number(int day, int month, long year, int wflag)
* for ISO-8601 modes. For North American numbering this
* always returns a Sunday.
*/
-static int week_to_day(int wnum, long year, int wflag)
+static int week_to_day(long year, const struct cal_control *ctl)
{
int yday, wday;
wday = day_in_week(1, 1, year);
- yday = wnum * 7 - wday;
+ yday = ctl->weeknum * 7 - wday;
- if (wflag & WEEK_NUM_ISO)
+ if (ctl->weektype & WEEK_NUM_ISO)
yday -= (wday >= FRIDAY ? -2 : 5);
else
yday -= (wday == SUNDAY ? 6 : -1); /* WEEK_NUM_US */
@@ -908,7 +917,7 @@ static int week_to_day(int wnum, long year, int wflag)
return yday;
}
-static char *ascii_day(char *p, int day)
+static char *ascii_day(char *p, int day, const struct cal_control *ctl)
{
int display, val;
int highlight = 0;
@@ -922,7 +931,7 @@ static char *ascii_day(char *p, int day)
};
if (day == SPACE) {
- int len = julian ? J_DAY_LEN : DAY_LEN;
+ int len = ctl->julian ? J_DAY_LEN : DAY_LEN;
memset(p, ' ', len);
return p+len;
}
@@ -931,7 +940,7 @@ static char *ascii_day(char *p, int day)
p += sprintf(p, "%s", Senter);
highlight = 1;
}
- if (julian) {
+ if (ctl->julian) {
if ((val = day / 100)) {
day %= 100;
*p++ = val + '0';
@@ -956,12 +965,12 @@ static char *ascii_day(char *p, int day)
return p;
}
-static char * ascii_wnum(char *p, int wnum,int highlight)
+static char *ascii_wnum(char *p, int weeknum, const struct cal_control *ctl)
{
- if (highlight)
+ if ((ctl->weektype & WEEK_NUM_MASK) == weeknum)
p += sprintf(p,"%s",Senter);
- p += sprintf(p,"%2d",wnum);
- if (highlight)
+ p += sprintf(p,"%2d",weeknum);
+ if ((ctl->weektype & WEEK_NUM_MASK) == weeknum)
p += sprintf(p,"%s ",Sexit);
else
p += sprintf(p," ");
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 02/13] cal: rename ascii_wnum() to ascii_weeknum()
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
2013-11-10 18:23 ` [PATCH 01/13] cal: use control structure for run time configuration Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-11-10 18:23 ` [PATCH 03/13] cal: add input variable names to function prototypes Sami Kerola
` (11 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
Week is not long word, so it does not need to be enshorted and made more
difficult to understand.
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
misc-utils/cal.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index f82d02e..bcc1580 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -249,7 +249,7 @@ struct cal_control {
/* function prototypes */
static int leap_year(long year);
static char *ascii_day(char *, int, const struct cal_control *ctl);
-static char *ascii_wnum(char *p, int wn, const struct cal_control *ctl);
+static char *ascii_weeknum(char *p, int wn, const struct cal_control *ctl);
static int center_str(const char* src, char* dest, size_t dest_size, size_t width);
static void center(const char *, size_t, int);
static void day_array(int, int, long, int *, const struct cal_control *ctl);
@@ -558,7 +558,7 @@ static int do_monthly(int day, int month, long year, struct fmt_st *out,
if (xd != SPACE) {
int wn = week_number(xd & ~TODAY_FLAG,
month, year, ctl);
- p = ascii_wnum(p, wn, ctl);
+ p = ascii_weeknum(p, wn, ctl);
break;
} else if (col+1 == DAYS_IN_WEEK)
p += sprintf(p," ");
@@ -679,7 +679,7 @@ static char *append_weeknum(char *p, int *dp,
if (xd != SPACE) {
int weeknum = week_number(xd & ~TODAY_FLAG,
month + cal + 1, year, ctl);
- p = ascii_wnum(p, weeknum, ctl);
+ p = ascii_weeknum(p, weeknum, ctl);
break;
} else if (col+1 == DAYS_IN_WEEK)
p += sprintf(p," ");
@@ -965,7 +965,7 @@ static char *ascii_day(char *p, int day, const struct cal_control *ctl)
return p;
}
-static char *ascii_wnum(char *p, int weeknum, const struct cal_control *ctl)
+static char *ascii_weeknum(char *p, int weeknum, const struct cal_control *ctl)
{
if ((ctl->weektype & WEEK_NUM_MASK) == weeknum)
p += sprintf(p,"%s",Senter);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 03/13] cal: add input variable names to function prototypes
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
2013-11-10 18:23 ` [PATCH 01/13] cal: use control structure for run time configuration Sami Kerola
2013-11-10 18:23 ` [PATCH 02/13] cal: rename ascii_wnum() to ascii_weeknum() Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-11-10 18:23 ` [PATCH 04/13] cal: make day_in_week() use same variable names as other functions Sami Kerola
` (10 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
While prototypes such as 'function(int, int, char, int);' are legal they
do not help when trying to understand how the function is expected to be
used. Adding variable names gives at least a hint when looking the
prototypes.
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
misc-utils/cal.c | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index bcc1580..abb6e0f 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -248,23 +248,25 @@ struct cal_control {
/* function prototypes */
static int leap_year(long year);
-static char *ascii_day(char *, int, const struct cal_control *ctl);
-static char *ascii_weeknum(char *p, int wn, const struct cal_control *ctl);
-static int center_str(const char* src, char* dest, size_t dest_size, size_t width);
-static void center(const char *, size_t, int);
-static void day_array(int, int, long, int *, const struct cal_control *ctl);
-static int day_in_week(int, int, long);
-static int day_in_year(int, int, long);
-static int week_number(int, int, long, const struct cal_control *ctl);
-static int week_to_day(long, const struct cal_control *ctl);
-static void yearly(int, long, const struct cal_control *ctl);
-static int do_monthly(int day, int month, long year, struct fmt_st *out,
- int header_hint, const struct cal_control *ctl);
-static void monthly(int, int, long, const struct cal_control *ctl);
-static int two_header_lines(int month, long year, const struct cal_control *ctl);
-static void monthly3(int, int, long, const struct cal_control *ctl);
-static void __attribute__ ((__noreturn__)) usage(FILE * out);
static void headers_init(struct cal_control *ctl);
+static int do_monthly(int day, int month, long year, struct fmt_st *out, int header_hint,
+ const struct cal_control *ctl);
+static void monthly(int day, int month, long year, const struct cal_control *ctl);
+static int two_header_lines(int month, long year, const struct cal_control *ctl);
+static void monthly3(int day, int month, long year, const struct cal_control *ctl);
+static char *append_weeknum(char *p, int *dp, int month, long year, int cal, int row,
+ const struct cal_control *ctl);
+static void yearly(int day, long year, const struct cal_control *ctl);
+static void day_array(int day, int month, long year, int *days, const struct cal_control *ctl);
+static int day_in_year(int day, int month, long year);
+static int day_in_week(int d, int m, long y);
+static int week_number(int day, int month, long year, const struct cal_control *ctl);
+static int week_to_day(long year, const struct cal_control *ctl);
+static char *ascii_day(char *p, int day, const struct cal_control *ctl);
+static char *ascii_weeknum(char *p, int weeknum, const struct cal_control *ctl);
+static int center_str(const char *src, char *dest, size_t dest_size, size_t width);
+static void center(const char *str, size_t len, int separate);
+static void __attribute__((__noreturn__)) usage(FILE *out);
int main(int argc, char **argv)
{
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 04/13] cal: make day_in_week() use same variable names as other functions
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
` (2 preceding siblings ...)
2013-11-10 18:23 ` [PATCH 03/13] cal: add input variable names to function prototypes Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-11-10 18:23 ` [PATCH 05/13] cal: simplify ascii_weeknum() function Sami Kerola
` (9 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
misc-utils/cal.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index abb6e0f..748288d 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -259,7 +259,7 @@ static char *append_weeknum(char *p, int *dp, int month, long year, int cal, int
static void yearly(int day, long year, const struct cal_control *ctl);
static void day_array(int day, int month, long year, int *days, const struct cal_control *ctl);
static int day_in_year(int day, int month, long year);
-static int day_in_week(int d, int m, long y);
+static int day_in_week(int day, int month, long year);
static int week_number(int day, int month, long year, const struct cal_control *ctl);
static int week_to_day(long year, const struct cal_control *ctl);
static char *ascii_day(char *p, int day, const struct cal_control *ctl);
@@ -819,7 +819,7 @@ static int day_in_year(int day, int month, long year)
* 3 Sep. 1752 through 13 Sep. 1752, and returns invalid weekday
* during the period of 11 days.
*/
-static int day_in_week(int d, int m, long y)
+static int day_in_week(int day, int month, long year)
{
static const int reform[] = {
SUNDAY, WEDNESDAY, TUESDAY, FRIDAY, SUNDAY, WEDNESDAY,
@@ -829,19 +829,19 @@ static int day_in_week(int d, int m, long y)
FRIDAY, MONDAY, SUNDAY, WEDNESDAY, FRIDAY, MONDAY,
WEDNESDAY, SATURDAY, TUESDAY, THURSDAY, SUNDAY, TUESDAY
};
- if (y != 1753)
- y -= m < 3;
+ if (year != 1753)
+ year -= month < 3;
else
- y -= (m < 3) + 14;
- if (REFORMATION_YEAR < y
- || (y == REFORMATION_YEAR && 9 < m)
- || (y == REFORMATION_YEAR && m == 9 && 13 < d))
- return (y + (y / 4) - (y / 100) + (y / 400) + reform[m - 1] +
- d) % 7;
- if (y < REFORMATION_YEAR
- || (y == REFORMATION_YEAR && m < 9)
- || (y == REFORMATION_YEAR && m == 9 && d < 3))
- return (y + y / 4 + old[m - 1] + d) % 7;
+ year -= (month < 3) + 14;
+ if (REFORMATION_YEAR < year
+ || (year == REFORMATION_YEAR && 9 < month)
+ || (year == REFORMATION_YEAR && month == 9 && 13 < day))
+ return (year + (year / 4) - (year / 100) + (year / 400) + reform[month - 1] +
+ day) % 7;
+ if (year < REFORMATION_YEAR
+ || (year == REFORMATION_YEAR && month < 9)
+ || (year == REFORMATION_YEAR && month == 9 && day < 3))
+ return (year + year / 4 + old[month - 1] + day) % 7;
return NONEDAY;
}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 05/13] cal: simplify ascii_weeknum() function
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
` (3 preceding siblings ...)
2013-11-10 18:23 ` [PATCH 04/13] cal: make day_in_week() use same variable names as other functions Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-11-10 18:23 ` [PATCH 06/13] cal: determine output width at beginning of run and reuse result Sami Kerola
` (8 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
Either the week is or isn't highlighted, there is no need to over
complicate printing of that.
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
misc-utils/cal.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index 748288d..c1bbdce 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -970,12 +970,9 @@ static char *ascii_day(char *p, int day, const struct cal_control *ctl)
static char *ascii_weeknum(char *p, int weeknum, const struct cal_control *ctl)
{
if ((ctl->weektype & WEEK_NUM_MASK) == weeknum)
- p += sprintf(p,"%s",Senter);
- p += sprintf(p,"%2d",weeknum);
- if ((ctl->weektype & WEEK_NUM_MASK) == weeknum)
- p += sprintf(p,"%s ",Sexit);
+ p += sprintf(p, "%s%2d%s ", Senter, weeknum, Sexit);
else
- p += sprintf(p," ");
+ p += sprintf(p, "%2d ", weeknum);
return p;
}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 06/13] cal: determine output width at beginning of run and reuse result
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
` (4 preceding siblings ...)
2013-11-10 18:23 ` [PATCH 05/13] cal: simplify ascii_weeknum() function Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-11-10 18:23 ` [PATCH 07/13] tests: cal: take account week numbers when determing month lenght Sami Kerola
` (7 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
misc-utils/cal.c | 85 +++++++++++++++++++++++++-------------------------------
1 file changed, 38 insertions(+), 47 deletions(-)
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index c1bbdce..bc53d4f 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -187,11 +187,6 @@ enum {
#define MONTH_COLS 3 /* month columns in year view */
#define WNUM_LEN 3
-#define J_DAY_LEN 4 /* 4 spaces per day */
-#define J_WEEK_LEN (DAYS_IN_WEEK * J_DAY_LEN)
-#define J_HEAD_SEP 2
-#define J_MONTH_COLS 2
-
#define TODAY_FLAG 0x400 /* flag day for highlighting */
#define FMT_ST_LINES 9
@@ -233,7 +228,7 @@ enum {
};
/* utf-8 can have up to 6 bytes per char; and an extra byte for ending \0 */
-static char day_headings[J_WEEK_LEN * 6 + 1];
+static char day_headings[(WEEK_LEN + 1) * 6 + 1];
struct cal_control {
const char *full_month[MONTHS_IN_YEAR]; /* month names */
@@ -242,6 +237,8 @@ struct cal_control {
int weekstart; /* day the week starts, often Sun or Mon */
int weektype; /* WEEK_TYPE_{NONE,ISO,US} */
int weeknum; /* requested --week=<number> */
+ size_t day_width; /* day width in characters in printout */
+ size_t week_width; /* 7 * day_width + possible week num */
unsigned int julian:1, /* julian output */
yflag:1; /* print whole year */
};
@@ -278,7 +275,8 @@ int main(int argc, char **argv)
.weekstart = SUNDAY,
.num_months = NUM_MONTHS,
.colormode = UL_COLORMODE_AUTO,
- .weektype = WEEK_NUM_DISABLED
+ .weektype = WEEK_NUM_DISABLED,
+ .day_width = DAY_LEN
};
enum {
@@ -367,6 +365,7 @@ int main(int argc, char **argv)
break;
case 'j':
ctl.julian = 1;
+ ctl.day_width = DAY_LEN + 1;
break;
case 'y':
ctl.yflag = 1;
@@ -400,7 +399,9 @@ int main(int argc, char **argv)
if (ctl.weektype) {
ctl.weektype = ctl.weeknum & WEEK_NUM_MASK;
ctl.weektype |= (ctl.weekstart == MONDAY ? WEEK_NUM_ISO : WEEK_NUM_US);
- }
+ ctl.week_width = (ctl.day_width * DAYS_IN_WEEK) + WNUM_LEN;
+ } else
+ ctl.week_width = ctl.day_width * DAYS_IN_WEEK;
time(&now);
local_time = localtime(&now);
@@ -474,9 +475,13 @@ int main(int argc, char **argv)
ctl.weektype &= ~WEEK_NUM_MASK;
}
- if (ctl.yflag)
+ if (ctl.yflag) {
+ if (ctl.julian)
+ ctl.num_months = MONTH_COLS - 1;
+ else
+ ctl.num_months = MONTH_COLS;
yearly(day, year, &ctl);
- else if (ctl.num_months == 1)
+ } else if (ctl.num_months == 1)
monthly(day, month, year, &ctl);
else if (ctl.num_months == 3)
monthly3(day, month, year, &ctl);
@@ -495,7 +500,7 @@ static int leap_year(long year)
static void headers_init(struct cal_control *ctl)
{
- size_t i, wd, spaces = ctl->julian ? J_DAY_LEN - 1 : DAY_LEN - 1;
+ size_t i, wd;
char *cur_dh = day_headings;
for (i = 0; i < DAYS_IN_WEEK; i++) {
@@ -506,10 +511,10 @@ static void headers_init(struct cal_control *ctl)
strcat(cur_dh++, " ");
space_left = sizeof(day_headings) - (cur_dh - day_headings);
- if (space_left <= spaces)
+ if (space_left <= (ctl->day_width - 1))
break;
cur_dh += center_str(nl_langinfo(ABDAY_1 + wd), cur_dh,
- space_left, spaces);
+ space_left, ctl->day_width - 1);
}
for (i = 0; i < MONTHS_IN_YEAR; i++)
@@ -521,8 +526,6 @@ static int do_monthly(int day, int month, long year, struct fmt_st *out,
{
int col, row, days[MAXDAYS];
char *p, lineout[FMT_ST_CHARS];
- size_t width = (ctl->julian ? J_WEEK_LEN : WEEK_LEN) - 1
- + (ctl->weektype ? WNUM_LEN : 0);
int pos = 0;
day_array(day, month, year, days, ctl);
@@ -531,10 +534,10 @@ static int do_monthly(int day, int month, long year, struct fmt_st *out,
header_hint = two_header_lines(month, year, ctl);
if (header_hint) {
snprintf(lineout, sizeof(lineout), _("%s"), ctl->full_month[month - 1]);
- center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), width);
+ center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), ctl->week_width - 1);
pos++;
snprintf(lineout, sizeof(lineout), _("%ld"), year);
- center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), width);
+ center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), ctl->week_width - 1);
pos++;
} else {
/* TRANSLATORS: %s is the month name, %ld the year number.
@@ -543,7 +546,7 @@ static int do_monthly(int day, int month, long year, struct fmt_st *out,
*/
snprintf(lineout, sizeof(lineout), _("%s %ld"),
ctl->full_month[month - 1], year);
- center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), width);
+ center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), ctl->week_width - 1);
pos++;
}
@@ -595,12 +598,11 @@ static void monthly(int day, int month, long year, const struct cal_control *ctl
static int two_header_lines(int month, long year, const struct cal_control *ctl)
{
char lineout[FMT_ST_CHARS];
- size_t width = (ctl->julian ? J_WEEK_LEN : WEEK_LEN) - 1;
size_t len;
snprintf(lineout, sizeof(lineout), "%ld", year);
len = strlen(lineout);
len += strlen(ctl->full_month[month - 1]) + 1;
- if (width < len)
+ if (ctl->week_width - 1 < len)
return 1;
return 0;
}
@@ -609,7 +611,7 @@ static void monthly3(int day, int month, long year, const struct cal_control *ct
{
char lineout[FMT_ST_CHARS];
int i;
- int width, rows, two_lines;
+ int rows, two_lines;
struct fmt_st out_prev;
struct fmt_st out_curm;
struct fmt_st out_next;
@@ -644,7 +646,6 @@ static void monthly3(int day, int month, long year, const struct cal_control *ct
do_monthly(day, month, year, &out_curm, two_lines, ctl);
do_monthly(day, next_month, next_year, &out_next, two_lines, ctl);
- width = (ctl->julian ? J_WEEK_LEN : WEEK_LEN) -1;
for (i = 0; i < (two_lines ? 3 : 2); i++) {
snprintf(lineout, sizeof(lineout),
"%s %s %s\n", out_prev.s[i], out_curm.s[i], out_next.s[i]);
@@ -652,7 +653,7 @@ static void monthly3(int day, int month, long year, const struct cal_control *ct
}
for (i = two_lines ? 3 : 2; i < rows; i++) {
int w1, w2, w3;
- w1 = w2 = w3 = width;
+ w1 = w2 = w3 = ctl->week_width;
#if defined(HAVE_LIBNCURSES) || defined(HAVE_LIBNCURSESW) || defined(HAVE_LIBTERMCAP)
/* adjust width to allow for non printable characters */
@@ -692,7 +693,6 @@ static char *append_weeknum(char *p, int *dp,
static void yearly(int day, long year, const struct cal_control *ctl)
{
int col, i, month, row, which_cal;
- int maxrow, sep_len, week_len;
int days[MONTHS_IN_YEAR][MAXDAYS];
char *p;
/* three weeks + separators + \0 */
@@ -700,50 +700,42 @@ static void yearly(int day, long year, const struct cal_control *ctl)
char lineout[ weeknumlen + sizeof(day_headings) + 2 +
weeknumlen + sizeof(day_headings) + 2 +
weeknumlen + sizeof(day_headings) + 1 ];
- if (ctl->julian) {
- maxrow = J_MONTH_COLS;
- sep_len = J_HEAD_SEP;
- week_len = J_WEEK_LEN + weeknumlen;
- } else {
- maxrow = MONTH_COLS;
- sep_len = HEAD_SEP;
- week_len = WEEK_LEN + weeknumlen;
- }
+
snprintf(lineout, sizeof(lineout), "%ld", year);
- /* 2013-04-28: The -1 near sep_len makes year header to be aligned
+ /* 2013-04-28: The -1 near HEAD_SEP makes year header to be aligned
* exactly how it has been aligned for long time, but it is
* unexplainable. */
- center(lineout, (week_len + sep_len) * maxrow - sep_len - 1, 0);
+ center(lineout, (ctl->week_width + HEAD_SEP) * ctl->num_months - HEAD_SEP - 1, 0);
my_putstring("\n\n");
for (i = 0; i < MONTHS_IN_YEAR; i++)
day_array(day, i + 1, year, days[i], ctl);
- for (month = 0; month < MONTHS_IN_YEAR; month += maxrow) {
- center(ctl->full_month[month], week_len - 1, sep_len + 1);
+ for (month = 0; month < MONTHS_IN_YEAR; month += ctl->num_months) {
+ center(ctl->full_month[month], ctl->week_width - 1, HEAD_SEP + 1);
if (ctl->julian) {
- center(ctl->full_month[month + 1], week_len - 1, 0);
+ center(ctl->full_month[month + 1], ctl->week_width - 1, 0);
} else {
- center(ctl->full_month[month + 1], week_len - 1, sep_len + 1);
- center(ctl->full_month[month + 2], week_len - 1, 0);
+ center(ctl->full_month[month + 1], ctl->week_width - 1, HEAD_SEP + 1);
+ center(ctl->full_month[month + 2], ctl->week_width - 1, 0);
}
if (ctl->julian)
snprintf(lineout, sizeof(lineout),
"\n%*s%s%*s %*s%s\n",
- weeknumlen,"", day_headings, sep_len, "",
+ weeknumlen,"", day_headings, HEAD_SEP, "",
weeknumlen,"", day_headings);
else
snprintf(lineout, sizeof(lineout),
"\n%*s%s%*s %*s%s%*s %*s%s\n",
- weeknumlen,"", day_headings, sep_len, "",
- weeknumlen,"", day_headings, sep_len, "",
+ weeknumlen,"", day_headings, HEAD_SEP, "",
+ weeknumlen,"", day_headings, HEAD_SEP, "",
weeknumlen,"", day_headings);
my_putstring(lineout);
for (row = 0; row < DAYS_IN_WEEK - 1; row++) {
p = lineout;
- for (which_cal = 0; which_cal < maxrow; which_cal++) {
+ for (which_cal = 0; which_cal < ctl->num_months; which_cal++) {
int *dp = &days[month + which_cal][row * DAYS_IN_WEEK];
if (ctl->weektype)
@@ -933,9 +925,8 @@ static char *ascii_day(char *p, int day, const struct cal_control *ctl)
};
if (day == SPACE) {
- int len = ctl->julian ? J_DAY_LEN : DAY_LEN;
- memset(p, ' ', len);
- return p+len;
+ memset(p, ' ', ctl->day_width);
+ return p + ctl->day_width;
}
if (day & TODAY_FLAG) {
day &= ~TODAY_FLAG;
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 07/13] tests: cal: take account week numbers when determing month lenght
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
` (5 preceding siblings ...)
2013-11-10 18:23 ` [PATCH 06/13] cal: determine output width at beginning of run and reuse result Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-11-10 18:23 ` [PATCH 08/13] cal: make user request to be part of read-only control struct Sami Kerola
` (6 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
The month header does not need to wrap if month width with week number
allows printing to single line.
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
tests/expected/cal/bigyearw | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/tests/expected/cal/bigyearw b/tests/expected/cal/bigyearw
index 61bf92f..d7fe0a2 100644
--- a/tests/expected/cal/bigyearw
+++ b/tests/expected/cal/bigyearw
@@ -20,8 +20,7 @@ Gregorian - Sunday-based month with week numbers
52 24 25 26 27 28 29 30
53 31
Julian - Monday-based month with week numbers
- December
- 1234567890123456789
+ December 1234567890123456789
Mon Tue Wed Thu Fri Sat Sun
48 335 336 337
49 338 339 340 341 342 343 344
@@ -30,8 +29,7 @@ Julian - Monday-based month with week numbers
52 359 360 361 362 363 364 365
Julian - Sunday-based month with week numbers
- December
- 1234567890123456789
+ December 1234567890123456789
Sun Mon Tue Wed Thu Fri Sat
48 335 336
49 337 338 339 340 341 342 343
@@ -60,8 +58,7 @@ Gregorian - Sunday-based three months with week numbers
48 26 27 28 29 30 52 24 25 26 27 28 29 30 4 28 29 30 31
53 31
Julian - Monday-based three months with week numbers
- November December January
- 1234567890123456789 1234567890123456789 1234567890123456790
+ November 1234567890123456789 December 1234567890123456789 January 1234567890123456790
Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun
44 305 306 307 308 309 48 335 336 337 1 1 2 3 4 5 6 7
45 310 311 312 313 314 315 316 49 338 339 340 341 342 343 344 2 8 9 10 11 12 13 14
@@ -70,8 +67,7 @@ Julian - Monday-based three months with week numbers
48 331 332 333 334 52 359 360 361 362 363 364 365 5 29 30 31
Julian - Sunday-based three months with week numbers
- November December January
- 1234567890123456789 1234567890123456789 1234567890123456790
+ November 1234567890123456789 December 1234567890123456789 January 1234567890123456790
Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat
44 305 306 307 308 48 335 336 53 1 2 3 4 5 6
45 309 310 311 312 313 314 315 49 337 338 339 340 341 342 343 1 7 8 9 10 11 12 13
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 08/13] cal: make user request to be part of read-only control struct
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
` (6 preceding siblings ...)
2013-11-10 18:23 ` [PATCH 07/13] tests: cal: take account week numbers when determing month lenght Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-11-10 18:23 ` [PATCH 09/13] tests: cal: do not let --week=<num> to adjust requested month Sami Kerola
` (5 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
misc-utils/cal.c | 138 +++++++++++++++++++++++++++++--------------------------
1 file changed, 73 insertions(+), 65 deletions(-)
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index bc53d4f..185b7a9 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -230,15 +230,22 @@ enum {
/* utf-8 can have up to 6 bytes per char; and an extra byte for ending \0 */
static char day_headings[(WEEK_LEN + 1) * 6 + 1];
+struct cal_request {
+ int day;
+ int month;
+ long year;
+ int week;
+};
+
struct cal_control {
const char *full_month[MONTHS_IN_YEAR]; /* month names */
int colormode; /* day and week number highlight */
int num_months; /* number of months horizontally in print out */
int weekstart; /* day the week starts, often Sun or Mon */
int weektype; /* WEEK_TYPE_{NONE,ISO,US} */
- int weeknum; /* requested --week=<number> */
size_t day_width; /* day width in characters in printout */
size_t week_width; /* 7 * day_width + possible week num */
+ struct cal_request req; /* the times user is interested */
unsigned int julian:1, /* julian output */
yflag:1; /* print whole year */
};
@@ -248,17 +255,17 @@ static int leap_year(long year);
static void headers_init(struct cal_control *ctl);
static int do_monthly(int day, int month, long year, struct fmt_st *out, int header_hint,
const struct cal_control *ctl);
-static void monthly(int day, int month, long year, const struct cal_control *ctl);
+static void monthly(const struct cal_control *ctl);
static int two_header_lines(int month, long year, const struct cal_control *ctl);
-static void monthly3(int day, int month, long year, const struct cal_control *ctl);
+static void monthly3(const struct cal_control *ctl);
static char *append_weeknum(char *p, int *dp, int month, long year, int cal, int row,
const struct cal_control *ctl);
-static void yearly(int day, long year, const struct cal_control *ctl);
+static void yearly(const struct cal_control *ctl);
static void day_array(int day, int month, long year, int *days, const struct cal_control *ctl);
static int day_in_year(int day, int month, long year);
static int day_in_week(int day, int month, long year);
static int week_number(int day, int month, long year, const struct cal_control *ctl);
-static int week_to_day(long year, const struct cal_control *ctl);
+static int week_to_day(const struct cal_control *ctl);
static char *ascii_day(char *p, int day, const struct cal_control *ctl);
static char *ascii_weeknum(char *p, int weeknum, const struct cal_control *ctl);
static int center_str(const char *src, char *dest, size_t dest_size, size_t width);
@@ -269,14 +276,15 @@ int main(int argc, char **argv)
{
struct tm *local_time;
time_t now;
- int ch, day = 0, month = 0;
- long year;
+ int ch;
static struct cal_control ctl = {
.weekstart = SUNDAY,
.num_months = NUM_MONTHS,
.colormode = UL_COLORMODE_AUTO,
.weektype = WEEK_NUM_DISABLED,
- .day_width = DAY_LEN
+ .day_width = DAY_LEN,
+ .req.day = 0,
+ .req.month = 0
};
enum {
@@ -372,9 +380,9 @@ int main(int argc, char **argv)
break;
case 'w':
if (optarg) {
- ctl.weeknum = strtos32_or_err(optarg,
+ ctl.req.week = strtos32_or_err(optarg,
_("invalid week argument"));
- if (ctl.weeknum < 1 || 53 < ctl.weeknum)
+ if (ctl.req.week < 1 || 53 < ctl.req.week)
errx(EXIT_FAILURE,_("illegal week value: use 1-53"));
}
ctl.weektype = WEEK_NUM_US; /* default per weekstart */
@@ -397,7 +405,7 @@ int main(int argc, char **argv)
argv += optind;
if (ctl.weektype) {
- ctl.weektype = ctl.weeknum & WEEK_NUM_MASK;
+ ctl.weektype = ctl.req.week & WEEK_NUM_MASK;
ctl.weektype |= (ctl.weekstart == MONDAY ? WEEK_NUM_ISO : WEEK_NUM_US);
ctl.week_width = (ctl.day_width * DAYS_IN_WEEK) + WNUM_LEN;
} else
@@ -408,70 +416,70 @@ int main(int argc, char **argv)
switch(argc) {
case 3:
- day = strtos32_or_err(*argv++, _("illegal day value"));
- if (day < 1 || DAYS_IN_MONTH < day)
+ ctl.req.day = strtos32_or_err(*argv++, _("illegal day value"));
+ if (ctl.req.day < 1 || DAYS_IN_MONTH < ctl.req.day)
errx(EXIT_FAILURE, _("illegal day value: use 1-%d"), DAYS_IN_MONTH);
/* FALLTHROUGH */
case 2:
- month = strtos32_or_err(*argv++, _("illegal month value: use 1-12"));
- if (month < 1 || MONTHS_IN_YEAR < month)
+ ctl.req.month = strtos32_or_err(*argv++, _("illegal month value: use 1-12"));
+ if (ctl.req.month < 1 || MONTHS_IN_YEAR < ctl.req.month)
errx(EXIT_FAILURE, _("illegal month value: use 1-12"));
/* FALLTHROUGH */
case 1:
- year = strtol_or_err(*argv++, _("illegal year value"));
- if (year < SMALLEST_YEAR)
+ ctl.req.year = strtol_or_err(*argv++, _("illegal year value"));
+ if (ctl.req.year < SMALLEST_YEAR)
errx(EXIT_FAILURE, _("illegal year value: use positive integer"));
- if (day) {
- int dm = days_in_month[leap_year(year)][month];
- if (day > dm)
+ if (ctl.req.day) {
+ int dm = days_in_month[leap_year(ctl.req.year)][ctl.req.month];
+ if (ctl.req.day > dm)
errx(EXIT_FAILURE, _("illegal day value: use 1-%d"), dm);
- day = day_in_year(day, month, year);
- } else if ((long) (local_time->tm_year + 1900) == year) {
- day = local_time->tm_yday + 1;
+ ctl.req.day = day_in_year(ctl.req.day, ctl.req.month, ctl.req.year);
+ } else if ((long) (local_time->tm_year + 1900) == ctl.req.year) {
+ ctl.req.day = local_time->tm_yday + 1;
}
- if (!month && !ctl.weeknum)
+ if (!ctl.req.month && !ctl.req.week)
ctl.yflag = 1;
break;
case 0:
- day = local_time->tm_yday + 1;
- year = local_time->tm_year + 1900;
- month = local_time->tm_mon + 1;
+ ctl.req.day = local_time->tm_yday + 1;
+ ctl.req.year = local_time->tm_year + 1900;
+ ctl.req.month = local_time->tm_mon + 1;
break;
default:
usage(stderr);
}
- if (0 < ctl.weeknum) {
- int yday = week_to_day(year, &ctl);
- int leap = leap_year(year);
+ if (0 < ctl.req.week) {
+ int yday = week_to_day(&ctl);
+ int leap = leap_year(ctl.req.year);
+ int m = 1;
if (yday < 1)
errx(EXIT_FAILURE, _("illegal week value: year %ld "
"doesn't have week %d"),
- year, ctl.weeknum);
- month = 1;
- while (month <= 12 && yday > days_in_month[leap][month])
- yday -= days_in_month[leap][month++];
- if (month > 12) {
+ ctl.req.year, ctl.req.week);
+ while (m <= 12 && yday > days_in_month[leap][m])
+ yday -= days_in_month[leap][m++];
+ if (m > 12) {
/* In some years (e.g. 2010 in ISO mode) it's possible
* to have a remnant of week 53 starting the year yet
* the year in question ends during 52, in this case
* we're assuming that early remnant is being referred
* to if 53 is given as argument. */
- if (ctl.weeknum == week_number(31, 12, year - 1, &ctl))
- month = 1;
- else
+ if (ctl.req.week != week_number(31, 12, ctl.req.year - 1, &ctl))
errx(EXIT_FAILURE,
_("illegal week value: year %ld "
"doesn't have week %d"),
- year, ctl.weeknum);
+ ctl.req.year, ctl.req.week);
}
+ if (!ctl.req.month)
+ ctl.req.month = 12 < m ? 1 : m;
}
headers_init(&ctl);
if (!colors_init(ctl.colormode)) {
- day = 0;
+ ctl.req.day = 0;
ctl.weektype &= ~WEEK_NUM_MASK;
}
@@ -480,11 +488,11 @@ int main(int argc, char **argv)
ctl.num_months = MONTH_COLS - 1;
else
ctl.num_months = MONTH_COLS;
- yearly(day, year, &ctl);
+ yearly(&ctl);
} else if (ctl.num_months == 1)
- monthly(day, month, year, &ctl);
+ monthly(&ctl);
else if (ctl.num_months == 3)
- monthly3(day, month, year, &ctl);
+ monthly3(&ctl);
return EXIT_SUCCESS;
}
@@ -583,12 +591,12 @@ static int do_monthly(int day, int month, long year, struct fmt_st *out,
return pos;
}
-static void monthly(int day, int month, long year, const struct cal_control *ctl)
+static void monthly(const struct cal_control *ctl)
{
int i, rows;
struct fmt_st out;
- rows = do_monthly(day, month, year, &out, -1, ctl);
+ rows = do_monthly(ctl->req.day, ctl->req.month, ctl->req.year, &out, -1, ctl);
for (i = 0; i < rows; i++) {
my_putstring(out.s[i]);
my_putstring("\n");
@@ -607,7 +615,7 @@ static int two_header_lines(int month, long year, const struct cal_control *ctl)
return 0;
}
-static void monthly3(int day, int month, long year, const struct cal_control *ctl)
+static void monthly3(const struct cal_control *ctl)
{
char lineout[FMT_ST_CHARS];
int i;
@@ -621,30 +629,30 @@ static void monthly3(int day, int month, long year, const struct cal_control *ct
memset(&out_prev, 0, sizeof(struct fmt_st));
memset(&out_curm, 0, sizeof(struct fmt_st));
memset(&out_next, 0, sizeof(struct fmt_st));
- if (month == 1) {
+ if (ctl->req.month == 1) {
prev_month = MONTHS_IN_YEAR;
- prev_year = year - 1;
+ prev_year = ctl->req.year - 1;
} else {
- prev_month = month - 1;
- prev_year = year;
+ prev_month = ctl->req.month - 1;
+ prev_year = ctl->req.year;
}
- if (month == MONTHS_IN_YEAR) {
+ if (ctl->req.month == MONTHS_IN_YEAR) {
next_month = 1;
- next_year = year + 1;
+ next_year = ctl->req.year + 1;
} else {
- next_month = month + 1;
- next_year = year;
+ next_month = ctl->req.month + 1;
+ next_year = ctl->req.year;
}
two_lines = two_header_lines(prev_month, prev_year, ctl);
- two_lines += two_header_lines(month, year, ctl);
+ two_lines += two_header_lines(ctl->req.month, ctl->req.year, ctl);
two_lines += two_header_lines(next_month, next_year, ctl);
if (0 < two_lines)
rows = FMT_ST_LINES;
else
rows = FMT_ST_LINES - 1;
- do_monthly(day, prev_month, prev_year, &out_prev, two_lines, ctl);
- do_monthly(day, month, year, &out_curm, two_lines, ctl);
- do_monthly(day, next_month, next_year, &out_next, two_lines, ctl);
+ do_monthly(ctl->req.day, prev_month, prev_year, &out_prev, two_lines, ctl);
+ do_monthly(ctl->req.day, ctl->req.month, ctl->req.year, &out_curm, two_lines, ctl);
+ do_monthly(ctl->req.day, next_month, next_year, &out_next, two_lines, ctl);
for (i = 0; i < (two_lines ? 3 : 2); i++) {
snprintf(lineout, sizeof(lineout),
@@ -690,7 +698,7 @@ static char *append_weeknum(char *p, int *dp,
return p;
}
-static void yearly(int day, long year, const struct cal_control *ctl)
+static void yearly(const struct cal_control *ctl)
{
int col, i, month, row, which_cal;
int days[MONTHS_IN_YEAR][MAXDAYS];
@@ -701,7 +709,7 @@ static void yearly(int day, long year, const struct cal_control *ctl)
weeknumlen + sizeof(day_headings) + 2 +
weeknumlen + sizeof(day_headings) + 1 ];
- snprintf(lineout, sizeof(lineout), "%ld", year);
+ snprintf(lineout, sizeof(lineout), "%ld", ctl->req.year);
/* 2013-04-28: The -1 near HEAD_SEP makes year header to be aligned
* exactly how it has been aligned for long time, but it is
@@ -710,7 +718,7 @@ static void yearly(int day, long year, const struct cal_control *ctl)
my_putstring("\n\n");
for (i = 0; i < MONTHS_IN_YEAR; i++)
- day_array(day, i + 1, year, days[i], ctl);
+ day_array(ctl->req.day, i + 1, ctl->req.year, days[i], ctl);
for (month = 0; month < MONTHS_IN_YEAR; month += ctl->num_months) {
center(ctl->full_month[month], ctl->week_width - 1, HEAD_SEP + 1);
@@ -740,7 +748,7 @@ static void yearly(int day, long year, const struct cal_control *ctl)
if (ctl->weektype)
p = append_weeknum(p, days[month + which_cal],
- month, year, which_cal,
+ month, ctl->req.year, which_cal,
row, ctl);
for (col = 0; col < DAYS_IN_WEEK; col++)
@@ -894,12 +902,12 @@ static int week_number(int day, int month, long year, const struct cal_control *
* for ISO-8601 modes. For North American numbering this
* always returns a Sunday.
*/
-static int week_to_day(long year, const struct cal_control *ctl)
+static int week_to_day(const struct cal_control *ctl)
{
int yday, wday;
- wday = day_in_week(1, 1, year);
- yday = ctl->weeknum * 7 - wday;
+ wday = day_in_week(1, 1, ctl->req.year);
+ yday = ctl->req.week * 7 - wday;
if (ctl->weektype & WEEK_NUM_ISO)
yday -= (wday >= FRIDAY ? -2 : 5);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 09/13] tests: cal: do not let --week=<num> to adjust requested month
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
` (7 preceding siblings ...)
2013-11-10 18:23 ` [PATCH 08/13] cal: make user request to be part of read-only control struct Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-11-10 18:23 ` [PATCH 10/13] cal: determine how many header lines are needed at initialization Sami Kerola
` (4 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
The previous commit made --week=<number> to have smaller weight value
than a month supplied by user. The commit started to print the month
that has more days at the week when a week is split to two months, and
only one month output is requested.
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
tests/expected/cal/weekarg | 84 +++++++++++++++++++++++-----------------------
1 file changed, 42 insertions(+), 42 deletions(-)
diff --git a/tests/expected/cal/weekarg b/tests/expected/cal/weekarg
index 639f0f7..75e2efb 100644
--- a/tests/expected/cal/weekarg
+++ b/tests/expected/cal/weekarg
@@ -1,13 +1,13 @@
Gregorian - Monday-based, week 40, 3 month
- August 2013 September 2013 October 2013
+ September 2013 October 2013 November 2013
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
-31 1 2 3 4 35 1 40 1 2 3 4 5 6
-32 5 6 7 8 9 10 11 36 2 3 4 5 6 7 8 41 7 8 9 10 11 12 13
-33 12 13 14 15 16 17 18 37 9 10 11 12 13 14 15 42 14 15 16 17 18 19 20
-34 19 20 21 22 23 24 25 38 16 17 18 19 20 21 22 43 21 22 23 24 25 26 27
-35 26 27 28 29 30 31 39 23 24 25 26 27 28 29 44 28 29 30 31
- 40 30
+35 1 40 1 2 3 4 5 6 44 1 2 3
+36 2 3 4 5 6 7 8 41 7 8 9 10 11 12 13 45 4 5 6 7 8 9 10
+37 9 10 11 12 13 14 15 42 14 15 16 17 18 19 20 46 11 12 13 14 15 16 17
+38 16 17 18 19 20 21 22 43 21 22 23 24 25 26 27 47 18 19 20 21 22 23 24
+39 23 24 25 26 27 28 29 44 28 29 30 31 48 25 26 27 28 29 30
+40 30
Gregorian - Sunday-based, week 40, 3 month
September 2013 October 2013 November 2013
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
@@ -18,14 +18,14 @@ Gregorian - Sunday-based, week 40, 3 month
39 29 30 43 27 28 29 30 31 47 24 25 26 27 28 29 30
Julian - Monday-based, week 40, 3 month
- August 2013 September 2013 October 2013
+ September 2013 October 2013 November 2013
Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun
-31 213 214 215 216 35 244 40 274 275 276 277 278 279
-32 217 218 219 220 221 222 223 36 245 246 247 248 249 250 251 41 280 281 282 283 284 285 286
-33 224 225 226 227 228 229 230 37 252 253 254 255 256 257 258 42 287 288 289 290 291 292 293
-34 231 232 233 234 235 236 237 38 259 260 261 262 263 264 265 43 294 295 296 297 298 299 300
-35 238 239 240 241 242 243 39 266 267 268 269 270 271 272 44 301 302 303 304
- 40 273
+35 244 40 274 275 276 277 278 279 44 305 306 307
+36 245 246 247 248 249 250 251 41 280 281 282 283 284 285 286 45 308 309 310 311 312 313 314
+37 252 253 254 255 256 257 258 42 287 288 289 290 291 292 293 46 315 316 317 318 319 320 321
+38 259 260 261 262 263 264 265 43 294 295 296 297 298 299 300 47 322 323 324 325 326 327 328
+39 266 267 268 269 270 271 272 44 301 302 303 304 48 329 330 331 332 333 334
+40 273
Julian - Sunday-based, week 40, 3 month
September 2013 October 2013 November 2013
Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat
@@ -36,14 +36,14 @@ Julian - Sunday-based, week 40, 3 month
39 272 273 43 300 301 302 303 304 47 328 329 330 331 332 333 334
Gregorian - Monday-based, week 40, 1 month
- September 2013
+ October 2013
Mo Tu We Th Fr Sa Su
-35 1
-36 2 3 4 5 6 7 8
-37 9 10 11 12 13 14 15
-38 16 17 18 19 20 21 22
-39 23 24 25 26 27 28 29
-40 30
+40 1 2 3 4 5 6
+41 7 8 9 10 11 12 13
+42 14 15 16 17 18 19 20
+43 21 22 23 24 25 26 27
+44 28 29 30 31
+
Gregorian - Sunday-based, week 40, 1 month
October 2013
Su Mo Tu We Th Fr Sa
@@ -54,14 +54,14 @@ Gregorian - Sunday-based, week 40, 1 month
43 27 28 29 30 31
Julian - Monday-based, week 40, 1 month
- September 2013
+ October 2013
Mon Tue Wed Thu Fri Sat Sun
-35 244
-36 245 246 247 248 249 250 251
-37 252 253 254 255 256 257 258
-38 259 260 261 262 263 264 265
-39 266 267 268 269 270 271 272
-40 273
+40 274 275 276 277 278 279
+41 280 281 282 283 284 285 286
+42 287 288 289 290 291 292 293
+43 294 295 296 297 298 299 300
+44 301 302 303 304
+
Julian - Sunday-based, week 40, 1 month
October 2013
Sun Mon Tue Wed Thu Fri Sat
@@ -108,20 +108,20 @@ Julian - Monday-based, week 53 with colors, 1 month
4 25 26 27 28 29 30 31
Gregorian - Monday-based, week 40 with colors, 3 month
- August 2013 September 2013 October 2013
+ September 2013 October 2013 November 2013
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
-31 1 2 3 4 35 1 ^[[7m40^[[27m 1 2 3 4 5 6
-32 5 6 7 8 9 10 11 36 2 3 4 5 6 7 8 41 ^[[7m 7^[[27m 8 9 10 11 12 13
-33 12 13 14 15 16 17 18 37 9 10 11 12 13 14 15 42 14 15 16 17 18 19 20
-34 19 20 21 22 23 24 25 38 16 17 18 19 20 21 22 43 21 22 23 24 25 26 27
-35 26 27 28 29 30 31 39 23 24 25 26 27 28 29 44 28 29 30 31
- ^[[7m40^[[27m 30
+35 1 ^[[7m40^[[27m 1 2 3 4 5 6 44 1 2 3
+36 2 3 4 5 6 7 8 41 ^[[7m 7^[[27m 8 9 10 11 12 13 45 4 5 6 7 8 9 10
+37 9 10 11 12 13 14 15 42 14 15 16 17 18 19 20 46 11 12 13 14 15 16 17
+38 16 17 18 19 20 21 22 43 21 22 23 24 25 26 27 47 18 19 20 21 22 23 24
+39 23 24 25 26 27 28 29 44 28 29 30 31 48 25 26 27 28 29 30
+^[[7m40^[[27m 30
Julian - Monday-based, week 40 with colors, 3 month
- August 2013 September 2013 October 2013
+ September 2013 October 2013 November 2013
Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun
-31 213 214 215 216 35 244 ^[[7m40^[[27m 274 275 276 277 278 279
-32 217 218 219 220 221 222 223 36 245 246 247 248 249 250 251 41 ^[[7m280^[[27m 281 282 283 284 285 286
-33 224 225 226 227 228 229 230 37 252 253 254 255 256 257 258 42 287 288 289 290 291 292 293
-34 231 232 233 234 235 236 237 38 259 260 261 262 263 264 265 43 294 295 296 297 298 299 300
-35 238 239 240 241 242 243 39 266 267 268 269 270 271 272 44 301 302 303 304
- ^[[7m40^[[27m 273
+35 244 ^[[7m40^[[27m 274 275 276 277 278 279 44 305 306 307
+36 245 246 247 248 249 250 251 41 ^[[7m280^[[27m 281 282 283 284 285 286 45 308 309 310 311 312 313 314
+37 252 253 254 255 256 257 258 42 287 288 289 290 291 292 293 46 315 316 317 318 319 320 321
+38 259 260 261 262 263 264 265 43 294 295 296 297 298 299 300 47 322 323 324 325 326 327 328
+39 266 267 268 269 270 271 272 44 301 302 303 304 48 329 330 331 332 333 334
+^[[7m40^[[27m 273
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 10/13] cal: determine how many header lines are needed at initialization
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
` (8 preceding siblings ...)
2013-11-10 18:23 ` [PATCH 09/13] tests: cal: do not let --week=<num> to adjust requested month Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-11-10 18:23 ` [PATCH 11/13] cal: add month contents structure Sami Kerola
` (3 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
misc-utils/cal.c | 53 ++++++++++++++++++++++-------------------------------
1 file changed, 22 insertions(+), 31 deletions(-)
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index 185b7a9..0a6cd8d 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -247,16 +247,16 @@ struct cal_control {
size_t week_width; /* 7 * day_width + possible week num */
struct cal_request req; /* the times user is interested */
unsigned int julian:1, /* julian output */
- yflag:1; /* print whole year */
+ yflag:1, /* print whole year */
+ header_hint:1; /* does month name + year need two lines to fit */
};
/* function prototypes */
static int leap_year(long year);
static void headers_init(struct cal_control *ctl);
-static int do_monthly(int day, int month, long year, struct fmt_st *out, int header_hint,
+static int do_monthly(int day, int month, long year, struct fmt_st *out,
const struct cal_control *ctl);
static void monthly(const struct cal_control *ctl);
-static int two_header_lines(int month, long year, const struct cal_control *ctl);
static void monthly3(const struct cal_control *ctl);
static char *append_weeknum(char *p, int *dp, int month, long year, int cal, int row,
const struct cal_control *ctl);
@@ -510,6 +510,10 @@ static void headers_init(struct cal_control *ctl)
{
size_t i, wd;
char *cur_dh = day_headings;
+ char tmp[FMT_ST_CHARS];
+ size_t year_len;
+
+ year_len = snprintf(tmp, sizeof(tmp), "%ld", ctl->req.year);
for (i = 0; i < DAYS_IN_WEEK; i++) {
size_t space_left;
@@ -525,12 +529,16 @@ static void headers_init(struct cal_control *ctl)
space_left, ctl->day_width - 1);
}
- for (i = 0; i < MONTHS_IN_YEAR; i++)
+ for (i = 0; i < MONTHS_IN_YEAR; i++) {
ctl->full_month[i] = nl_langinfo(MON_1 + i);
+ /* The +1 after year_len is space in between month and year. */
+ if (ctl->week_width < strlen(ctl->full_month[i]) + year_len + 1)
+ ctl->header_hint = 1;
+ }
}
static int do_monthly(int day, int month, long year, struct fmt_st *out,
- int header_hint, const struct cal_control *ctl)
+ const struct cal_control *ctl)
{
int col, row, days[MAXDAYS];
char *p, lineout[FMT_ST_CHARS];
@@ -538,9 +546,7 @@ static int do_monthly(int day, int month, long year, struct fmt_st *out,
day_array(day, month, year, days, ctl);
- if (header_hint < 0)
- header_hint = two_header_lines(month, year, ctl);
- if (header_hint) {
+ if (ctl->header_hint) {
snprintf(lineout, sizeof(lineout), _("%s"), ctl->full_month[month - 1]);
center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), ctl->week_width - 1);
pos++;
@@ -596,30 +602,18 @@ static void monthly(const struct cal_control *ctl)
int i, rows;
struct fmt_st out;
- rows = do_monthly(ctl->req.day, ctl->req.month, ctl->req.year, &out, -1, ctl);
+ rows = do_monthly(ctl->req.day, ctl->req.month, ctl->req.year, &out, ctl);
for (i = 0; i < rows; i++) {
my_putstring(out.s[i]);
my_putstring("\n");
}
}
-static int two_header_lines(int month, long year, const struct cal_control *ctl)
-{
- char lineout[FMT_ST_CHARS];
- size_t len;
- snprintf(lineout, sizeof(lineout), "%ld", year);
- len = strlen(lineout);
- len += strlen(ctl->full_month[month - 1]) + 1;
- if (ctl->week_width - 1 < len)
- return 1;
- return 0;
-}
-
static void monthly3(const struct cal_control *ctl)
{
char lineout[FMT_ST_CHARS];
int i;
- int rows, two_lines;
+ int rows;
struct fmt_st out_prev;
struct fmt_st out_curm;
struct fmt_st out_next;
@@ -643,23 +637,20 @@ static void monthly3(const struct cal_control *ctl)
next_month = ctl->req.month + 1;
next_year = ctl->req.year;
}
- two_lines = two_header_lines(prev_month, prev_year, ctl);
- two_lines += two_header_lines(ctl->req.month, ctl->req.year, ctl);
- two_lines += two_header_lines(next_month, next_year, ctl);
- if (0 < two_lines)
+ if (ctl->header_hint)
rows = FMT_ST_LINES;
else
rows = FMT_ST_LINES - 1;
- do_monthly(ctl->req.day, prev_month, prev_year, &out_prev, two_lines, ctl);
- do_monthly(ctl->req.day, ctl->req.month, ctl->req.year, &out_curm, two_lines, ctl);
- do_monthly(ctl->req.day, next_month, next_year, &out_next, two_lines, ctl);
+ do_monthly(ctl->req.day, prev_month, prev_year, &out_prev, ctl);
+ do_monthly(ctl->req.day, ctl->req.month, ctl->req.year, &out_curm, ctl);
+ do_monthly(ctl->req.day, next_month, next_year, &out_next, ctl);
- for (i = 0; i < (two_lines ? 3 : 2); i++) {
+ for (i = 0; i < (ctl->header_hint ? 3 : 2); i++) {
snprintf(lineout, sizeof(lineout),
"%s %s %s\n", out_prev.s[i], out_curm.s[i], out_next.s[i]);
my_putstring(lineout);
}
- for (i = two_lines ? 3 : 2; i < rows; i++) {
+ for (i = ctl->header_hint ? 3 : 2; i < rows; i++) {
int w1, w2, w3;
w1 = w2 = w3 = ctl->week_width;
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 11/13] cal: add month contents structure
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
` (9 preceding siblings ...)
2013-11-10 18:23 ` [PATCH 10/13] cal: determine how many header lines are needed at initialization Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-11-10 18:23 ` [PATCH 12/13] cal: use month contents structure for --three printing Sami Kerola
` (2 subsequent siblings)
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
This changes determination of calendar month content completely, as well
as outputing.
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
misc-utils/cal.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 169 insertions(+), 7 deletions(-)
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index 0a6cd8d..a3eff48 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -251,11 +251,22 @@ struct cal_control {
header_hint:1; /* does month name + year need two lines to fit */
};
+struct cal_month {
+ int days[MAXDAYS]; /* the day numbers, or SPACE */
+ int weeks[MAXDAYS / DAYS_IN_WEEK];
+ int month;
+ long year;
+ struct cal_month *next;
+};
+
/* function prototypes */
static int leap_year(long year);
static void headers_init(struct cal_control *ctl);
static int do_monthly(int day, int month, long year, struct fmt_st *out,
const struct cal_control *ctl);
+static void cal_fill_month(struct cal_month *month, const struct cal_control *ctl);
+static void cal_output_header(struct cal_month *month, const struct cal_control *ctl);
+static void cal_output_months(struct cal_month *month, const struct cal_control *ctl);
static void monthly(const struct cal_control *ctl);
static void monthly3(const struct cal_control *ctl);
static char *append_weeknum(char *p, int *dp, int month, long year, int cal, int row,
@@ -597,18 +608,169 @@ static int do_monthly(int day, int month, long year, struct fmt_st *out,
return pos;
}
-static void monthly(const struct cal_control *ctl)
+static void cal_fill_month(struct cal_month *month, const struct cal_control *ctl)
{
- int i, rows;
- struct fmt_st out;
+ int first_week_day = day_in_week(1, month->month, month->year);
+ int month_days;
+ int i, j, weeklines = 0;
+
+ if (ctl->julian)
+ j = day_in_year(1, month->month, month->year);
+ else
+ j = 1;
+ month_days = j + days_in_month[leap_year(month->year)][month->month];
+
+ /* True when Sunday is not first day in the output week. */
+ if (ctl->weekstart) {
+ first_week_day -= ctl->weekstart;
+ if (first_week_day < 0)
+ first_week_day = DAYS_IN_WEEK - ctl->weekstart;
+ month_days += ctl->weekstart - 1;
+ }
+
+ /* Fill day array. */
+ for (i = 0; i < MAXDAYS; i++) {
+ if (0 < first_week_day) {
+ month->days[i] = SPACE;
+ first_week_day--;
+ continue;
+ }
+ if (j < month_days) {
+ if (month->year == 1752 && month->month == 9 && (j == 3 || j == 247))
+ j += NUMBER_MISSING_DAYS;
+ month->days[i] = j;
+ j++;
+ continue;
+ }
+ month->days[i] = SPACE;
+ weeklines++;
+ }
- rows = do_monthly(ctl->req.day, ctl->req.month, ctl->req.year, &out, ctl);
- for (i = 0; i < rows; i++) {
- my_putstring(out.s[i]);
- my_putstring("\n");
+ /* Add week numbers */
+ if (ctl->weektype) {
+ int weeknum = week_number(1, month->month, month->year, ctl);
+ weeklines = MAXDAYS / DAYS_IN_WEEK - weeklines / DAYS_IN_WEEK;
+ for (i = 0; i < MAXDAYS / DAYS_IN_WEEK; i++) {
+ if (0 < weeklines)
+ month->weeks[i] = weeknum++;
+ else
+ month->weeks[i] = SPACE;
+ weeklines--;
+ if (52 < weeknum && i == 0)
+ weeknum = week_number(month->days[DAYS_IN_WEEK * (i + 1)], 1, month->year, ctl);
+ else if (52 < weeknum)
+ weeknum = week_number(31, 12, month->year, ctl);
+ }
}
}
+static void cal_output_header(struct cal_month *month, const struct cal_control *ctl)
+{
+ char out[FMT_ST_CHARS];
+ struct cal_month *i;
+
+ if (ctl->header_hint) {
+ for (i = month; i; i = i->next) {
+ sprintf(out, _("%s"), ctl->full_month[i->month - 1]);
+ center(out, ctl->week_width - 1, i->next == NULL ? 0 : 2);
+ }
+ fputs("\n", stdout);
+ for (i = month; i; i = i->next) {
+ sprintf(out, _("%ld"), i->year);
+ center(out, ctl->week_width - 1, i->next == NULL ? 0 : 2);
+ }
+ } else {
+ for (i = month; i; i = i->next) {
+ sprintf(out, _("%s %ld"), ctl->full_month[i->month - 1], i->year);
+ center(out, ctl->week_width - 1, i->next == NULL ? 0 : 2);
+ }
+ }
+ puts("");
+ for (i = month; i; i = i->next) {
+ if (ctl->weektype) {
+ if (ctl->julian)
+ printf("%*s%s", (int)ctl->day_width - 1, "", day_headings);
+ else
+ printf("%*s%s", (int)ctl->day_width, "", day_headings);
+ } else
+ fputs(day_headings, stdout);
+ if (i->next != NULL)
+ fputs(" ", stdout);
+ }
+ puts("");
+}
+
+static void cal_output_months(struct cal_month *month, const struct cal_control *ctl)
+{
+ int reqday, week_line, d;
+ int skip;
+ struct cal_month *i;
+
+ for (week_line = 0; week_line < MAXDAYS / DAYS_IN_WEEK; week_line++) {
+ for (i = month; i; i = i->next) {
+ /* Determine the day that should be highlighted. */
+ reqday = 0;
+ if (i->month == ctl->req.month && i->year == ctl->req.year) {
+ if (ctl->julian)
+ reqday = ctl->req.day;
+ else
+ reqday =
+ ctl->req.day + 1 - day_in_year(1, i->month,
+ i->year);
+ }
+
+ if (ctl->weektype) {
+ if (0 < i->weeks[week_line]) {
+ if ((ctl->weektype & WEEK_NUM_MASK) ==
+ i->weeks[week_line])
+ printf("%s%2d%s", Senter, i->weeks[week_line],
+ Sexit);
+ else
+ printf("%2d", i->weeks[week_line]);
+ } else
+ printf("%2s", "");
+ skip = ctl->day_width;
+ } else
+ /* First day of the week is one char narrower than the other days,
+ * unless week number is printed. */
+ skip = ctl->day_width - 1;
+
+ for (d = DAYS_IN_WEEK * week_line;
+ d < DAYS_IN_WEEK * week_line + DAYS_IN_WEEK; d++) {
+ if (0 < i->days[d]) {
+ if (reqday == i->days[d])
+ printf("%*s%s%*d%s", skip - (ctl->julian ? 3 : 2),
+ "", Senter, (ctl->julian ? 3 : 2),
+ i->days[d], Sexit);
+ else
+ printf("%*d", skip, i->days[d]);
+ } else
+ printf("%*s", skip, "");
+ if (skip < (int)ctl->day_width)
+ skip++;
+ }
+ if (i->next != NULL)
+ fputs(" ", stdout);
+ }
+ if (i == NULL)
+ fputs(" \n", stdout);
+ }
+}
+
+static void monthly(const struct cal_control *ctl)
+{
+ struct cal_month month;
+
+ month.month = ctl->req.month;
+ month.year = ctl->req.year;
+ month.next = NULL;
+
+ cal_fill_month(&month, ctl);
+
+ cal_output_header(&month, ctl);
+ cal_output_months(&month, ctl);
+}
+
static void monthly3(const struct cal_control *ctl)
{
char lineout[FMT_ST_CHARS];
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 12/13] cal: use month contents structure for --three printing
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
` (10 preceding siblings ...)
2013-11-10 18:23 ` [PATCH 11/13] cal: add month contents structure Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-12-06 10:07 ` Karel Zak
2013-11-10 18:23 ` [PATCH 13/13] cal: use month contents structure for --year printing Sami Kerola
2013-12-06 10:02 ` [PATCH 00/13] pull: cal: code revisit part I try II Karel Zak
13 siblings, 1 reply; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
misc-utils/cal.c | 136 +++++++++++--------------------------------------------
1 file changed, 26 insertions(+), 110 deletions(-)
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index a3eff48..a3c5c40 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -141,7 +141,6 @@ static int Slen; /* strlen of Senter+Sexit */
#endif
static const char *Senter="", *Sexit="";/* enter and exit standout mode */
-static char *Hrow; /* pointer to highlighted row in month */
#include "widechar.h"
@@ -262,8 +261,7 @@ struct cal_month {
/* function prototypes */
static int leap_year(long year);
static void headers_init(struct cal_control *ctl);
-static int do_monthly(int day, int month, long year, struct fmt_st *out,
- const struct cal_control *ctl);
+static void set_consecutive_months(struct cal_month *month, int m, long y);
static void cal_fill_month(struct cal_month *month, const struct cal_control *ctl);
static void cal_output_header(struct cal_month *month, const struct cal_control *ctl);
static void cal_output_months(struct cal_month *month, const struct cal_control *ctl);
@@ -548,64 +546,17 @@ static void headers_init(struct cal_control *ctl)
}
}
-static int do_monthly(int day, int month, long year, struct fmt_st *out,
- const struct cal_control *ctl)
+static void set_consecutive_months(struct cal_month *month, int m, long y)
{
- int col, row, days[MAXDAYS];
- char *p, lineout[FMT_ST_CHARS];
- int pos = 0;
-
- day_array(day, month, year, days, ctl);
-
- if (ctl->header_hint) {
- snprintf(lineout, sizeof(lineout), _("%s"), ctl->full_month[month - 1]);
- center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), ctl->week_width - 1);
- pos++;
- snprintf(lineout, sizeof(lineout), _("%ld"), year);
- center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), ctl->week_width - 1);
- pos++;
- } else {
- /* TRANSLATORS: %s is the month name, %ld the year number.
- * You can change the order and/or add something here;
- * e.g. for Basque the translation should be "%2$ldko %1$s".
- */
- snprintf(lineout, sizeof(lineout), _("%s %ld"),
- ctl->full_month[month - 1], year);
- center_str(lineout, out->s[pos], ARRAY_SIZE(out->s[pos]), ctl->week_width - 1);
- pos++;
- }
-
- snprintf(out->s[pos++], FMT_ST_CHARS, "%s%s",
- (ctl->weektype ? " " : ""),
- day_headings);
-
- for (row = 0; row < DAYS_IN_WEEK - 1; row++) {
- int has_hl = 0;
- p = lineout;
- if (ctl->weektype)
- for (col = 0; col < DAYS_IN_WEEK; col++) {
- int xd = days[row * DAYS_IN_WEEK + col];
- if (xd != SPACE) {
- int wn = week_number(xd & ~TODAY_FLAG,
- month, year, ctl);
- p = ascii_weeknum(p, wn, ctl);
- break;
- } else if (col+1 == DAYS_IN_WEEK)
- p += sprintf(p," ");
- }
- for (col = 0; col < DAYS_IN_WEEK; col++) {
- int xd = days[row * DAYS_IN_WEEK + col];
- if (xd != SPACE && (xd & TODAY_FLAG))
- has_hl = 1;
- p = ascii_day(p, xd, ctl);
+ struct cal_month *i;
+ for (i = month; i; i = i->next) {
+ i->month = m++;
+ i->year = y;
+ if (MONTHS_IN_YEAR < m) {
+ m = 1;
+ y++;
}
- *p = '\0';
- snprintf(out->s[row+pos], FMT_ST_CHARS, "%s", lineout);
- if (has_hl)
- Hrow = out->s[row+pos];
}
- pos += row;
- return pos;
}
static void cal_fill_month(struct cal_month *month, const struct cal_control *ctl)
@@ -773,62 +724,27 @@ static void monthly(const struct cal_control *ctl)
static void monthly3(const struct cal_control *ctl)
{
- char lineout[FMT_ST_CHARS];
- int i;
- int rows;
- struct fmt_st out_prev;
- struct fmt_st out_curm;
- struct fmt_st out_next;
- int prev_month, next_month;
- long prev_year, next_year;
-
- memset(&out_prev, 0, sizeof(struct fmt_st));
- memset(&out_curm, 0, sizeof(struct fmt_st));
- memset(&out_next, 0, sizeof(struct fmt_st));
+ struct cal_month m1, m2, m3, *i;
+ int first_month;
+ long first_year;
+
+ m1.next = &m2;
+ m2.next = &m3;
+ m3.next = NULL;
+
if (ctl->req.month == 1) {
- prev_month = MONTHS_IN_YEAR;
- prev_year = ctl->req.year - 1;
- } else {
- prev_month = ctl->req.month - 1;
- prev_year = ctl->req.year;
- }
- if (ctl->req.month == MONTHS_IN_YEAR) {
- next_month = 1;
- next_year = ctl->req.year + 1;
+ first_month = MONTHS_IN_YEAR;
+ first_year = ctl->req.year - 1;
} else {
- next_month = ctl->req.month + 1;
- next_year = ctl->req.year;
- }
- if (ctl->header_hint)
- rows = FMT_ST_LINES;
- else
- rows = FMT_ST_LINES - 1;
- do_monthly(ctl->req.day, prev_month, prev_year, &out_prev, ctl);
- do_monthly(ctl->req.day, ctl->req.month, ctl->req.year, &out_curm, ctl);
- do_monthly(ctl->req.day, next_month, next_year, &out_next, ctl);
-
- for (i = 0; i < (ctl->header_hint ? 3 : 2); i++) {
- snprintf(lineout, sizeof(lineout),
- "%s %s %s\n", out_prev.s[i], out_curm.s[i], out_next.s[i]);
- my_putstring(lineout);
+ first_month = ctl->req.month - 1;
+ first_year = ctl->req.year;
}
- for (i = ctl->header_hint ? 3 : 2; i < rows; i++) {
- int w1, w2, w3;
- w1 = w2 = w3 = ctl->week_width;
-#if defined(HAVE_LIBNCURSES) || defined(HAVE_LIBNCURSESW) || defined(HAVE_LIBTERMCAP)
- /* adjust width to allow for non printable characters */
- w1 += (out_prev.s[i] == Hrow ? Slen : 0);
- w2 += (out_curm.s[i] == Hrow ? Slen : 0);
- w3 += (out_next.s[i] == Hrow ? Slen : 0);
-#endif
- snprintf(lineout, sizeof(lineout), "%-*s %-*s %-*s\n",
- w1, out_prev.s[i],
- w2, out_curm.s[i],
- w3, out_next.s[i]);
-
- my_putstring(lineout);
- }
+ set_consecutive_months(&m1, first_month, first_year);
+ for (i = &m1; i; i = i->next)
+ cal_fill_month(i, ctl);
+ cal_output_header(&m1, ctl);
+ cal_output_months(&m1, ctl);
}
static char *append_weeknum(char *p, int *dp,
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 13/13] cal: use month contents structure for --year printing
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
` (11 preceding siblings ...)
2013-11-10 18:23 ` [PATCH 12/13] cal: use month contents structure for --three printing Sami Kerola
@ 2013-11-10 18:23 ` Sami Kerola
2013-12-06 10:02 ` [PATCH 00/13] pull: cal: code revisit part I try II Karel Zak
13 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-10 18:23 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
misc-utils/cal.c | 229 +++++++++++--------------------------------------------
1 file changed, 45 insertions(+), 184 deletions(-)
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index a3c5c40..87e947a 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -244,6 +244,7 @@ struct cal_control {
int weektype; /* WEEK_TYPE_{NONE,ISO,US} */
size_t day_width; /* day width in characters in printout */
size_t week_width; /* 7 * day_width + possible week num */
+ int gutter_width; /* spaces in between horizontal month outputs */
struct cal_request req; /* the times user is interested */
unsigned int julian:1, /* julian output */
yflag:1, /* print whole year */
@@ -267,16 +268,11 @@ static void cal_output_header(struct cal_month *month, const struct cal_control
static void cal_output_months(struct cal_month *month, const struct cal_control *ctl);
static void monthly(const struct cal_control *ctl);
static void monthly3(const struct cal_control *ctl);
-static char *append_weeknum(char *p, int *dp, int month, long year, int cal, int row,
- const struct cal_control *ctl);
static void yearly(const struct cal_control *ctl);
-static void day_array(int day, int month, long year, int *days, const struct cal_control *ctl);
static int day_in_year(int day, int month, long year);
static int day_in_week(int day, int month, long year);
static int week_number(int day, int month, long year, const struct cal_control *ctl);
static int week_to_day(const struct cal_control *ctl);
-static char *ascii_day(char *p, int day, const struct cal_control *ctl);
-static char *ascii_weeknum(char *p, int weeknum, const struct cal_control *ctl);
static int center_str(const char *src, char *dest, size_t dest_size, size_t width);
static void center(const char *str, size_t len, int separate);
static void __attribute__((__noreturn__)) usage(FILE *out);
@@ -292,6 +288,7 @@ int main(int argc, char **argv)
.colormode = UL_COLORMODE_AUTO,
.weektype = WEEK_NUM_DISABLED,
.day_width = DAY_LEN,
+ .gutter_width = 2,
.req.day = 0,
.req.month = 0
};
@@ -446,8 +443,10 @@ int main(int argc, char **argv)
} else if ((long) (local_time->tm_year + 1900) == ctl.req.year) {
ctl.req.day = local_time->tm_yday + 1;
}
- if (!ctl.req.month && !ctl.req.week)
+ if (!ctl.req.month && !ctl.req.week) {
+ ctl.req.month = local_time->tm_mon + 1;
ctl.yflag = 1;
+ }
break;
case 0:
ctl.req.day = local_time->tm_yday + 1;
@@ -497,6 +496,7 @@ int main(int argc, char **argv)
ctl.num_months = MONTH_COLS - 1;
else
ctl.num_months = MONTH_COLS;
+ ctl.gutter_width = 3;
yearly(&ctl);
} else if (ctl.num_months == 1)
monthly(&ctl);
@@ -620,20 +620,22 @@ static void cal_output_header(struct cal_month *month, const struct cal_control
char out[FMT_ST_CHARS];
struct cal_month *i;
- if (ctl->header_hint) {
+ if (ctl->header_hint || ctl->yflag) {
for (i = month; i; i = i->next) {
sprintf(out, _("%s"), ctl->full_month[i->month - 1]);
- center(out, ctl->week_width - 1, i->next == NULL ? 0 : 2);
+ center(out, ctl->week_width - 1, i->next == NULL ? 0 : ctl->gutter_width);
}
- fputs("\n", stdout);
- for (i = month; i; i = i->next) {
- sprintf(out, _("%ld"), i->year);
- center(out, ctl->week_width - 1, i->next == NULL ? 0 : 2);
+ if (!ctl->yflag) {
+ fputs("\n", stdout);
+ for (i = month; i; i = i->next) {
+ sprintf(out, _("%ld"), i->year);
+ center(out, ctl->week_width - 1, i->next == NULL ? 0 : ctl->gutter_width);
+ }
}
} else {
for (i = month; i; i = i->next) {
sprintf(out, _("%s %ld"), ctl->full_month[i->month - 1], i->year);
- center(out, ctl->week_width - 1, i->next == NULL ? 0 : 2);
+ center(out, ctl->week_width - 1, i->next == NULL ? 0 : ctl->gutter_width);
}
}
puts("");
@@ -646,7 +648,7 @@ static void cal_output_header(struct cal_month *month, const struct cal_control
} else
fputs(day_headings, stdout);
if (i->next != NULL)
- fputs(" ", stdout);
+ printf("%*s", ctl->gutter_width, "");
}
puts("");
}
@@ -701,10 +703,10 @@ static void cal_output_months(struct cal_month *month, const struct cal_control
skip++;
}
if (i->next != NULL)
- fputs(" ", stdout);
+ printf("%*s", ctl->gutter_width, "");
}
if (i == NULL)
- fputs(" \n", stdout);
+ printf("%*s\n", ctl->gutter_width - (ctl->yflag ? 0 : 1), "");
}
}
@@ -747,124 +749,39 @@ static void monthly3(const struct cal_control *ctl)
cal_output_months(&m1, ctl);
}
-static char *append_weeknum(char *p, int *dp,
- int month, long year, int cal,
- int row, const struct cal_control *ctl)
-{
- int col;
-
- for (col = 0; col < DAYS_IN_WEEK; col++) {
- int xd = dp[row * DAYS_IN_WEEK + col];
-
- if (xd != SPACE) {
- int weeknum = week_number(xd & ~TODAY_FLAG,
- month + cal + 1, year, ctl);
- p = ascii_weeknum(p, weeknum, ctl);
- break;
- } else if (col+1 == DAYS_IN_WEEK)
- p += sprintf(p," ");
- }
- return p;
-}
-
static void yearly(const struct cal_control *ctl)
{
- int col, i, month, row, which_cal;
- int days[MONTHS_IN_YEAR][MAXDAYS];
- char *p;
- /* three weeks + separators + \0 */
- int weeknumlen = (ctl->weektype ? WNUM_LEN : 0);
- char lineout[ weeknumlen + sizeof(day_headings) + 2 +
- weeknumlen + sizeof(day_headings) + 2 +
- weeknumlen + sizeof(day_headings) + 1 ];
-
- snprintf(lineout, sizeof(lineout), "%ld", ctl->req.year);
-
- /* 2013-04-28: The -1 near HEAD_SEP makes year header to be aligned
- * exactly how it has been aligned for long time, but it is
- * unexplainable. */
- center(lineout, (ctl->week_width + HEAD_SEP) * ctl->num_months - HEAD_SEP - 1, 0);
- my_putstring("\n\n");
-
- for (i = 0; i < MONTHS_IN_YEAR; i++)
- day_array(ctl->req.day, i + 1, ctl->req.year, days[i], ctl);
-
- for (month = 0; month < MONTHS_IN_YEAR; month += ctl->num_months) {
- center(ctl->full_month[month], ctl->week_width - 1, HEAD_SEP + 1);
- if (ctl->julian) {
- center(ctl->full_month[month + 1], ctl->week_width - 1, 0);
- } else {
- center(ctl->full_month[month + 1], ctl->week_width - 1, HEAD_SEP + 1);
- center(ctl->full_month[month + 2], ctl->week_width - 1, 0);
- }
- if (ctl->julian)
- snprintf(lineout, sizeof(lineout),
- "\n%*s%s%*s %*s%s\n",
- weeknumlen,"", day_headings, HEAD_SEP, "",
- weeknumlen,"", day_headings);
- else
- snprintf(lineout, sizeof(lineout),
- "\n%*s%s%*s %*s%s%*s %*s%s\n",
- weeknumlen,"", day_headings, HEAD_SEP, "",
- weeknumlen,"", day_headings, HEAD_SEP, "",
- weeknumlen,"", day_headings);
+ struct cal_month m1, m2, m3, *i;
+ int month;
+ char out[FMT_ST_CHARS];
+ int year_width = 0;
- my_putstring(lineout);
- for (row = 0; row < DAYS_IN_WEEK - 1; row++) {
- p = lineout;
- for (which_cal = 0; which_cal < ctl->num_months; which_cal++) {
- int *dp = &days[month + which_cal][row * DAYS_IN_WEEK];
-
- if (ctl->weektype)
- p = append_weeknum(p, days[month + which_cal],
- month, ctl->req.year, which_cal,
- row, ctl);
-
- for (col = 0; col < DAYS_IN_WEEK; col++)
- p = ascii_day(p, *dp++, ctl);
- p += sprintf(p, " ");
- }
- *p = '\0';
- my_putstring(lineout);
- my_putstring("\n");
- }
+ m1.next = &m2;
+ if (ctl->julian)
+ m2.next = NULL;
+ else {
+ m2.next = &m3;
+ m3.next = NULL;
}
- my_putstring("\n");
-}
-/*
- * day_array --
- * Fill in an array of 42 integers with a calendar. Assume for a moment
- * that you took the (maximum) 6 rows in a calendar and stretched them
- * out end to end. You would have 42 numbers or spaces. This routine
- * builds that array for any month from Jan. 1 through Dec. 9999.
- */
-static void day_array(int day, int month, long year, int *days, const struct cal_control *ctl)
-{
- int julday, daynum, dw, dm;
- const int *sep1752;
-
- memcpy(days, empty, MAXDAYS * sizeof(int));
- if (year == REFORMATION_YEAR && month == REFORMATION_MONTH) {
- sep1752 = ctl->julian ? j_sep1752 : d_sep1752;
- memcpy(days, sep1752 + ctl->weekstart,
- ((MAXDAYS / 2) - ctl->weekstart) * sizeof(int));
- for (dm = 0; dm < MAXDAYS / 2; dm++)
- if (j_sep1752[dm] == day)
- days[dm] |= TODAY_FLAG;
- return;
- }
- dm = days_in_month[leap_year(year)][month];
- dw = (day_in_week(1, month, year) - ctl->weekstart + DAYS_IN_WEEK) % DAYS_IN_WEEK;
- julday = day_in_year(1, month, year);
- daynum = ctl->julian ? julday : 1;
-
- while (dm--) {
- days[dw] = daynum++;
- if (julday++ == day)
- days[dw] |= TODAY_FLAG;
- dw++;
+ /* year header */
+ for (i = &m1; i; i = i->next)
+ year_width += ctl->week_width + 1;
+ if (ctl->julian)
+ year_width--;
+ sprintf(out, "%ld", ctl->req.year);
+ center(out, year_width, 0);
+ fputs("\n\n", stdout);
+
+ for (month = 1; month < MONTHS_IN_YEAR; month += ctl->julian ? 2 : 3) {
+ set_consecutive_months(&m1, month, ctl->req.year);
+ for (i = &m1; i; i = i->next)
+ cal_fill_month(i, ctl);
+ cal_output_header(&m1, ctl);
+ cal_output_months(&m1, ctl);
}
+ /* Is empty line at the end year output really needed? */
+ puts("");
}
/*
@@ -988,62 +905,6 @@ static int week_to_day(const struct cal_control *ctl)
return yday;
}
-static char *ascii_day(char *p, int day, const struct cal_control *ctl)
-{
- int display, val;
- int highlight = 0;
- static char *aday[] = {
- "",
- " 1", " 2", " 3", " 4", " 5", " 6", " 7",
- " 8", " 9", "10", "11", "12", "13", "14",
- "15", "16", "17", "18", "19", "20", "21",
- "22", "23", "24", "25", "26", "27", "28",
- "29", "30", "31",
- };
-
- if (day == SPACE) {
- memset(p, ' ', ctl->day_width);
- return p + ctl->day_width;
- }
- if (day & TODAY_FLAG) {
- day &= ~TODAY_FLAG;
- p += sprintf(p, "%s", Senter);
- highlight = 1;
- }
- if (ctl->julian) {
- if ((val = day / 100)) {
- day %= 100;
- *p++ = val + '0';
- display = 1;
- } else {
- *p++ = ' ';
- display = 0;
- }
- val = day / 10;
- if (val || display)
- *p++ = val + '0';
- else
- *p++ = ' ';
- *p++ = day % 10 + '0';
- } else {
- *p++ = aday[day][0];
- *p++ = aday[day][1];
- }
- if (highlight)
- p += sprintf(p, "%s", Sexit);
- *p++ = ' ';
- return p;
-}
-
-static char *ascii_weeknum(char *p, int weeknum, const struct cal_control *ctl)
-{
- if ((ctl->weektype & WEEK_NUM_MASK) == weeknum)
- p += sprintf(p, "%s%2d%s ", Senter, weeknum, Sexit);
- else
- p += sprintf(p, "%2d ", weeknum);
- return p;
-}
-
/*
* Center string, handling multibyte characters appropriately.
* In addition if the string is too large for the width it's truncated.
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH 00/13] pull: cal: code revisit part I try II
2013-11-10 18:23 [PATCH 00/13] pull: cal: code revisit part I try II Sami Kerola
` (12 preceding siblings ...)
2013-11-10 18:23 ` [PATCH 13/13] cal: use month contents structure for --year printing Sami Kerola
@ 2013-12-06 10:02 ` Karel Zak
13 siblings, 0 replies; 16+ messages in thread
From: Karel Zak @ 2013-12-06 10:02 UTC (permalink / raw)
To: Sami Kerola; +Cc: util-linux
On Sun, Nov 10, 2013 at 06:23:27PM +0000, Sami Kerola wrote:
> I'll have a look of that about in December.
look forward to see the patches :-)
> misc-utils/cal.c | 781 ++++++++++++++++++++------------------------
> tests/expected/cal/bigyearw | 12 +-
> tests/expected/cal/weekarg | 84 ++---
> 3 files changed, 405 insertions(+), 472 deletions(-)
Applied, thanks.
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply [flat|nested] 16+ messages in thread