All of lore.kernel.org
 help / color / mirror / Atom feed
* [0000/0010] cal: code revisit part I
@ 2013-10-27 20:42 Sami Kerola
  2013-10-27 20:42 ` [PATCH 01/10] cal: use control structure for run time configuration Sami Kerola
                   ` (10 more replies)
  0 siblings, 11 replies; 16+ messages in thread
From: Sami Kerola @ 2013-10-27 20:42 UTC (permalink / raw)
  To: util-linux; +Cc: kerolasa

Hi Karel, and others,

I promised earlier to put some effort in making the cal(1) a little bit
less messy.  The patch set begins by adding a structure that contains
what user wants.  Last two changes are hopefully most interesting.  They
add run time configuration that is filled, and used later.

I got the --one and --three outputs working, but I am not completely
happy about the --three.  Quite frankly better function would take input
how many horizontal calendar outputs are needed, and would do exactly
that.  Such function would be more reusable when considering yearly
output, and the fact it has two column output when in julian mode.

Karel, it is be best not to merge the last patch.  It is more of
work-in-progress, comments would be great.


The following changes since commit 433d05ff9afeb4a374943cb35d1b8b19613c8039:

  libfdisk: (gpt) allow to work with hybrid GPT (2013-10-23 16:59:45 +0200)

are available in the git repository at:

  git://github.com/kerolasa/lelux-utiliteetit.git cal-ng

for you to fetch changes up to 69e4ed597fb54710cdc3337e3af14aedbc2f481c:

  cal: make cal --three to use content structures (2013-10-27 20:27:49 +0000)

----------------------------------------------------------------
Sami Kerola (10):
      cal: use control structure for run time configuration
      cal: add input variable names to function prototypes
      cal: make day_in_week() use same variable names as other functions
      cal: simplify ascii_wnum() function
      cal: determine output width at beginning of run and reuse result
      tests: cal: take account week numbers when determing month lenght
      cal: make user request to be part of read-only control struct
      cal: determine how many header lines are needed at initialization
      cal: add month contents structure
      cal: make cal --three to use content structures

 misc-utils/cal.c            | 637 +++++++++++++++++++++++++++-----------------
 tests/expected/cal/bigyearw |  12 +-
 2 files changed, 391 insertions(+), 258 deletions(-)



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 01/10] cal: use control structure for run time configuration
  2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
@ 2013-10-27 20:42 ` Sami Kerola
  2013-10-31 11:29   ` Karel Zak
  2013-10-27 20:42 ` [PATCH 02/10] cal: add input variable names to function prototypes Sami Kerola
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: Sami Kerola @ 2013-10-27 20:42 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 | 243 ++++++++++++++++++++++++++++---------------------------
 1 file changed, 126 insertions(+), 117 deletions(-)

diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index c9264ba..b4eb1ba 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 wflag;			/* uses WEEK_NUM_ enum */
+	int wnum;			/* 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,
+		.wflag = 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.wnum = strtos32_or_err(optarg,
 						_("invalid week argument"));
-				if (wnum < 1 || wnum > 53)
+				if (ctl.wnum < 1 || 53 < ctl.wnum)
 					errx(EXIT_FAILURE,_("illegal week value: use 1-53"));
 			}
-			wflag = WEEK_NUM_US;	/* default per weekstart */
+			ctl.wflag = 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.wflag) {
+		ctl.wflag = ctl.wnum & WEEK_NUM_MASK;
+		ctl.wflag |= (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.wnum)
+			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.wnum) {
+		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.wnum);
 		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.wnum == 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.wnum);
 		}
 	}
 
-	headers_init(julian);
+	headers_init(&ctl);
 
-	if (!colors_init(colormode)) {
+	if (!colors_init(ctl.colormode)) {
 		day = 0;
-		wflag &= ~WEEK_NUM_MASK;
+		ctl.wflag &= ~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->wflag ? 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->wflag ? "   " : ""),
 				day_headings);
 
 	for (row = 0; row < DAYS_IN_WEEK - 1; row++) {
 		int has_hl = 0;
 		p = lineout;
-		if (wflag)
+		if (ctl->wflag)
 			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]);
@@ -660,7 +669,7 @@ static void monthly3(int day, int month, long year, int wflag)
 
 static char *append_wnum(char *p, int *dp,
 			 int month, long year, int cal,
-			 int row, int wflag)
+			 int row, const struct cal_control *ctl)
 {
 	int col;
 
@@ -669,8 +678,8 @@ static char *append_wnum(char *p, int *dp,
 
 		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);
+					       month + cal + 1, year, ctl);
+			p = ascii_wnum(p, wnum, ctl);
 			break;
 		} else if (col+1 == DAYS_IN_WEEK)
 			p += sprintf(p,"   ");
@@ -678,18 +687,18 @@ 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);
+	int wnumlen = (ctl->wflag ? WNUM_LEN : 0);
 	char lineout[ wnumlen + sizeof(day_headings) + 2 +
 		      wnumlen + sizeof(day_headings) + 2 +
 		      wnumlen + sizeof(day_headings) + 1 ];
-	if (julian) {
+	if (ctl->julian) {
 		maxrow = J_MONTH_COLS;
 		sep_len = J_HEAD_SEP;
 		week_len = J_WEEK_LEN + wnumlen;
@@ -707,17 +716,17 @@ 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, "",
@@ -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)
+				if (ctl->wflag)
 					p = append_wnum(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->wflag & 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->wflag == 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->wnum * 7 - wday;
 
-	if (wflag & WEEK_NUM_ISO)
+	if (ctl->wflag & 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 wnum, const struct cal_control *ctl)
 {
-	if (highlight)
+	if ((ctl->wflag & WEEK_NUM_MASK) == wnum)
 		p += sprintf(p,"%s",Senter);
 	p += sprintf(p,"%2d",wnum);
-	if (highlight)
+	if ((ctl->wflag & WEEK_NUM_MASK) == wnum)
 		p += sprintf(p,"%s ",Sexit);
 	else
 		p += sprintf(p," ");
-- 
1.8.4.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 02/10] cal: add input variable names to function prototypes
  2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
  2013-10-27 20:42 ` [PATCH 01/10] cal: use control structure for run time configuration Sami Kerola
@ 2013-10-27 20:42 ` Sami Kerola
  2013-10-27 20:42 ` [PATCH 03/10] cal: make day_in_week() use same variable names as other functions Sami Kerola
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-10-27 20:42 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 b4eb1ba..720a548 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_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 *, 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_wnum(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_wnum(char *p, int wnum, 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.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 03/10] cal: make day_in_week() use same variable names as other functions
  2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
  2013-10-27 20:42 ` [PATCH 01/10] cal: use control structure for run time configuration Sami Kerola
  2013-10-27 20:42 ` [PATCH 02/10] cal: add input variable names to function prototypes Sami Kerola
@ 2013-10-27 20:42 ` Sami Kerola
  2013-10-27 20:42 ` [PATCH 04/10] cal: simplify ascii_wnum() function Sami Kerola
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-10-27 20:42 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 720a548..f8e3714 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -259,7 +259,7 @@ static char *append_wnum(char *p, int *dp, int month, long year, int cal, int ro
 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.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 04/10] cal: simplify ascii_wnum() function
  2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
                   ` (2 preceding siblings ...)
  2013-10-27 20:42 ` [PATCH 03/10] cal: make day_in_week() use same variable names as other functions Sami Kerola
@ 2013-10-27 20:42 ` Sami Kerola
  2013-10-27 20:42 ` [PATCH 05/10] cal: determine output width at beginning of run and reuse result Sami Kerola
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-10-27 20:42 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 f8e3714..44c1af1 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_wnum(char *p, int wnum, const struct cal_control *ctl)
 {
 	if ((ctl->wflag & WEEK_NUM_MASK) == wnum)
-		p += sprintf(p,"%s",Senter);
-	p += sprintf(p,"%2d",wnum);
-	if ((ctl->wflag & WEEK_NUM_MASK) == wnum)
-		p += sprintf(p,"%s ",Sexit);
+		p += sprintf(p, "%s%2d%s ", Senter, wnum, Sexit);
 	else
-		p += sprintf(p," ");
+		p += sprintf(p, "%2d ", wnum);
 	return p;
 }
 
-- 
1.8.4.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 05/10] cal: determine output width at beginning of run and reuse result
  2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
                   ` (3 preceding siblings ...)
  2013-10-27 20:42 ` [PATCH 04/10] cal: simplify ascii_wnum() function Sami Kerola
@ 2013-10-27 20:42 ` Sami Kerola
  2013-10-31 11:34   ` Karel Zak
  2013-10-27 20:42 ` [PATCH 06/10] tests: cal: take account week numbers when determing month lenght Sami Kerola
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: Sami Kerola @ 2013-10-27 20:42 UTC (permalink / raw)
  To: util-linux; +Cc: kerolasa

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/cal.c | 90 +++++++++++++++++++++++++++-----------------------------
 1 file changed, 43 insertions(+), 47 deletions(-)

diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index 44c1af1..df92cdd 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,12 +228,18 @@ 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_width {
+	size_t dy;			/* day width in characters in printout */
+	size_t wk;			/* week width == (7 * dlen + possible week num) */
+};
 
 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 */
+	struct cal_width width;		/* width of output */
 	int weekstart;			/* day the week starts, often Sun or Mon */
 	int wflag;			/* uses WEEK_NUM_ enum */
 	int wnum;			/* requested --week=number */
@@ -278,7 +279,8 @@ int main(int argc, char **argv)
 		.weekstart = SUNDAY,
 		.num_months = NUM_MONTHS,
 		.colormode = UL_COLORMODE_AUTO,
-		.wflag = WEEK_NUM_DISABLED
+		.wflag = WEEK_NUM_DISABLED,
+		.width.dy = DAY_LEN
 	};
 
 	enum {
@@ -367,6 +369,7 @@ int main(int argc, char **argv)
 			break;
 		case 'j':
 			ctl.julian = 1;
+			ctl.width.dy = DAY_LEN + 1;
 			break;
 		case 'y':
 			ctl.yflag = 1;
@@ -400,7 +403,9 @@ int main(int argc, char **argv)
 	if (ctl.wflag) {
 		ctl.wflag = ctl.wnum & WEEK_NUM_MASK;
 		ctl.wflag |= (ctl.weekstart == MONDAY ? WEEK_NUM_ISO : WEEK_NUM_US);
-	}
+		ctl.width.wk = (ctl.width.dy * DAYS_IN_WEEK) + WNUM_LEN;
+	} else
+		ctl.width.wk = (ctl.width.dy * DAYS_IN_WEEK);
 
 	time(&now);
 	local_time = localtime(&now);
@@ -474,9 +479,13 @@ int main(int argc, char **argv)
 		ctl.wflag &= ~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 +504,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 +515,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->width.dy - 1))
 			break;
 		cur_dh += center_str(nl_langinfo(ABDAY_1 + wd), cur_dh,
-				     space_left, spaces);
+				     space_left, ctl->width.dy - 1);
 	}
 
 	for (i = 0; i < MONTHS_IN_YEAR; i++)
@@ -521,8 +530,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->wflag ? WNUM_LEN : 0);
 	int pos = 0;
 
 	day_array(day, month, year, days, ctl);
@@ -531,10 +538,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->width.wk - 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->width.wk - 1);
 		pos++;
 	} else {
 		/* TRANSLATORS: %s is the month name, %ld the year number.
@@ -543,7 +550,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->width.wk - 1);
 		pos++;
 	}
 
@@ -595,12 +602,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->width.wk - 1 < len)
 		return 1;
 	return 0;
 }
@@ -609,7 +615,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 +650,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 +657,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->width.wk;
 
 #if defined(HAVE_LIBNCURSES) || defined(HAVE_LIBNCURSESW) || defined(HAVE_LIBTERMCAP)
 		/* adjust width to allow for non printable characters */
@@ -692,7 +697,6 @@ static char *append_wnum(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 +704,42 @@ static void yearly(int day, long year, const struct cal_control *ctl)
 	char lineout[ wnumlen + sizeof(day_headings) + 2 +
 		      wnumlen + sizeof(day_headings) + 2 +
 		      wnumlen + sizeof(day_headings) + 1 ];
-	if (ctl->julian) {
-		maxrow = J_MONTH_COLS;
-		sep_len = J_HEAD_SEP;
-		week_len = J_WEEK_LEN + wnumlen;
-	} else {
-		maxrow = MONTH_COLS;
-		sep_len = HEAD_SEP;
-		week_len = WEEK_LEN + wnumlen;
-	}
+
 	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->width.wk + 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->width.wk - 1, HEAD_SEP + 1);
 		if (ctl->julian) {
-			center(ctl->full_month[month + 1], week_len - 1, 0);
+			center(ctl->full_month[month + 1], ctl->width.wk - 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->width.wk - 1, HEAD_SEP + 1);
+			center(ctl->full_month[month + 2], ctl->width.wk - 1, 0);
 		}
 		if (ctl->julian)
 			snprintf(lineout, sizeof(lineout),
 				 "\n%*s%s%*s %*s%s\n",
-				 wnumlen,"", day_headings, sep_len, "",
+				 wnumlen,"", day_headings, HEAD_SEP, "",
 				 wnumlen,"", 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, HEAD_SEP, "",
+				 wnumlen,"", day_headings, HEAD_SEP, "",
 				 wnumlen,"", 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->wflag)
@@ -919,6 +915,7 @@ static int week_to_day(long year, const struct cal_control *ctl)
 	return yday;
 }
 
+
 static char *ascii_day(char *p, int day, const struct cal_control *ctl)
 {
 	int display, val;
@@ -933,9 +930,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->width.dy);
+		return p + ctl->width.dy;
 	}
 	if (day & TODAY_FLAG) {
 		day &= ~TODAY_FLAG;
-- 
1.8.4.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 06/10] tests: cal: take account week numbers when determing month lenght
  2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
                   ` (4 preceding siblings ...)
  2013-10-27 20:42 ` [PATCH 05/10] cal: determine output width at beginning of run and reuse result Sami Kerola
@ 2013-10-27 20:42 ` Sami Kerola
  2013-10-27 20:42 ` [PATCH 07/10] cal: make user request to be part of read-only control struct Sami Kerola
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-10-27 20:42 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.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 07/10] cal: make user request to be part of read-only control struct
  2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
                   ` (5 preceding siblings ...)
  2013-10-27 20:42 ` [PATCH 06/10] tests: cal: take account week numbers when determing month lenght Sami Kerola
@ 2013-10-27 20:42 ` Sami Kerola
  2013-10-31 11:49   ` Karel Zak
  2013-10-27 20:42 ` [PATCH 08/10] cal: determine how many header lines are needed at initialization Sami Kerola
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: Sami Kerola @ 2013-10-27 20:42 UTC (permalink / raw)
  To: util-linux; +Cc: kerolasa

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/cal.c | 136 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 72 insertions(+), 64 deletions(-)

diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index df92cdd..b12a959 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -235,6 +235,13 @@ struct cal_width {
 	size_t wk;			/* week width == (7 * dlen + possible week num) */
 };
 
+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 */
@@ -242,7 +249,7 @@ struct cal_control {
 	struct cal_width width;		/* width of output */
 	int weekstart;			/* day the week starts, often Sun or Mon */
 	int wflag;			/* uses WEEK_NUM_ enum */
-	int wnum;			/* requested --week=number */
+	struct cal_request req;		/* the times user is interested */
 	unsigned int	julian:1,	/* julian output */
 			yflag:1;	/* print whole year */
 };
@@ -252,17 +259,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_wnum(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_wnum(char *p, int wnum, const struct cal_control *ctl);
 static int center_str(const char *src, char *dest, size_t dest_size, size_t width);
@@ -273,14 +280,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,
 		.wflag = WEEK_NUM_DISABLED,
-		.width.dy = DAY_LEN
+		.width.dy = DAY_LEN,
+		.req.day = 0,
+		.req.month = 0
 	};
 
 	enum {
@@ -376,9 +384,9 @@ int main(int argc, char **argv)
 			break;
 		case 'w':
 			if (optarg) {
-				ctl.wnum = strtos32_or_err(optarg,
+				ctl.req.week = strtos32_or_err(optarg,
 						_("invalid week argument"));
-				if (ctl.wnum < 1 || 53 < ctl.wnum)
+				if (ctl.req.week < 1 || 53 < ctl.req.week)
 					errx(EXIT_FAILURE,_("illegal week value: use 1-53"));
 			}
 			ctl.wflag = WEEK_NUM_US;	/* default per weekstart */
@@ -401,7 +409,7 @@ int main(int argc, char **argv)
 	argv += optind;
 
 	if (ctl.wflag) {
-		ctl.wflag = ctl.wnum & WEEK_NUM_MASK;
+		ctl.wflag = ctl.req.week & WEEK_NUM_MASK;
 		ctl.wflag |= (ctl.weekstart == MONDAY ? WEEK_NUM_ISO : WEEK_NUM_US);
 		ctl.width.wk = (ctl.width.dy * DAYS_IN_WEEK) + WNUM_LEN;
 	} else
@@ -412,70 +420,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 (dm < ctl.req.day)
 				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.wnum)
+		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.month = local_time->tm_mon + 1;
+		ctl.req.year = local_time->tm_year + 1900;
 		break;
 	default:
 		usage(stderr);
 	}
 
-	if (0 < ctl.wnum) {
-		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);
 
 		if (yday < 1)
 			errx(EXIT_FAILURE, _("illegal week value: year %ld "
 					     "doesn't have week %d"),
-					year, ctl.wnum);
-		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);
+		ctl.req.month = 1;
+		while (ctl.req.month <= 12 && days_in_month[leap][ctl.req.month] < yday)
+			yday -= days_in_month[leap][ctl.req.month++];
+		if (12 < ctl.req.month) {
 			/* 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.wnum == week_number(31, 12, year - 1, &ctl))
-				month = 1;
+			if (ctl.req.week == week_number(31, 12, ctl.req.year - 1, &ctl))
+				ctl.req.month = 1;
 			else
 				errx(EXIT_FAILURE,
 					_("illegal week value: year %ld "
 					  "doesn't have week %d"),
-					year, ctl.wnum);
+					ctl.req.year, ctl.req.week);
 		}
 	}
 
 	headers_init(&ctl);
 
 	if (!colors_init(ctl.colormode)) {
-		day = 0;
+		ctl.req.day = 0;
 		ctl.wflag &= ~WEEK_NUM_MASK;
 	}
 
@@ -484,11 +492,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;
 }
@@ -587,12 +595,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");
@@ -611,7 +619,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;
@@ -625,30 +633,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),
@@ -694,7 +702,7 @@ static char *append_wnum(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];
@@ -705,7 +713,7 @@ static void yearly(int day, long year, const struct cal_control *ctl)
 		      wnumlen + sizeof(day_headings) + 2 +
 		      wnumlen + 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
@@ -714,7 +722,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->width.wk - 1, HEAD_SEP + 1);
@@ -744,7 +752,7 @@ static void yearly(int day, long year, const struct cal_control *ctl)
 
 				if (ctl->wflag)
 					p = append_wnum(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++)
@@ -898,12 +906,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->wnum * 7 - wday;
+	wday = day_in_week(1, 1, ctl->req.year);
+	yday = ctl->req.week * 7 - wday;
 
 	if (ctl->wflag & WEEK_NUM_ISO)
 		yday -= (wday >= FRIDAY ? -2 : 5);
-- 
1.8.4.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 08/10] cal: determine how many header lines are needed at initialization
  2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
                   ` (6 preceding siblings ...)
  2013-10-27 20:42 ` [PATCH 07/10] cal: make user request to be part of read-only control struct Sami Kerola
@ 2013-10-27 20:42 ` Sami Kerola
  2013-10-27 20:42 ` [PATCH 09/10] cal: add month contents structure Sami Kerola
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-10-27 20:42 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 b12a959..07c613a 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -251,16 +251,16 @@ struct cal_control {
 	int wflag;			/* uses WEEK_NUM_ enum */
 	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 execeed cal_width.wk */
 };
 
 /* 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_wnum(char *p, int *dp, int month, long year, int cal, int row,
 			 const struct cal_control *ctl);
@@ -514,6 +514,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;
@@ -529,12 +533,16 @@ static void headers_init(struct cal_control *ctl)
 				     space_left, ctl->width.dy - 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->width.wk < 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];
@@ -542,9 +550,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->width.wk - 1);
 		pos++;
@@ -600,30 +606,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->width.wk - 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;
@@ -647,23 +641,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->width.wk;
 
-- 
1.8.4.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 09/10] cal: add month contents structure
  2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
                   ` (7 preceding siblings ...)
  2013-10-27 20:42 ` [PATCH 08/10] cal: determine how many header lines are needed at initialization Sami Kerola
@ 2013-10-27 20:42 ` Sami Kerola
  2013-10-27 20:42 ` [PATCH 10/10] cal: make cal --three to use content structures Sami Kerola
  2013-10-31 12:14 ` [0000/0010] cal: code revisit part I Karel Zak
  10 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-10-27 20:42 UTC (permalink / raw)
  To: util-linux; +Cc: kerolasa

This commit changes determination of calendar month content completely,
as well as outputing.  The output is done week by week, which will allow
laying out months horizontally more understandable way.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/cal.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 150 insertions(+), 6 deletions(-)

diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index 07c613a..1e1721e 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -255,11 +255,21 @@ struct cal_control {
 			header_hint:1;	/* does month name + year execeed cal_width.wk */
 };
 
+struct cal_month {
+	int days[MAXDAYS];		/* internally day numbers are julian or SPACE */
+	int dsny;			/* days since new year */
+	int weeks[MAXDAYS / DAYS_IN_WEEK];
+	int month;
+	long year;
+};
+
 /* 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, int mt, long yr,
+			   const struct cal_control *ctl);
 static void monthly(const struct cal_control *ctl);
 static void monthly3(const struct cal_control *ctl);
 static char *append_wnum(char *p, int *dp, int month, long year, int cal, int row,
@@ -601,15 +611,149 @@ static int do_monthly(int day, int month, long year, struct fmt_st *out,
 	return pos;
 }
 
+static void cal_fill_month(struct cal_month *month, int mt, long yr, const struct cal_control *ctl)
+{
+	int first_week_day = day_in_week(1, mt, yr);
+	int month_days;
+	int i, j, weeklines = 0;
+
+	month->year = yr;
+	month->month = mt - 1;
+
+	if (ctl->julian)
+		j = day_in_year(1, mt, yr);
+	else
+		j = 1;
+	month_days = j + days_in_month[leap_year(yr)][mt];
+
+	/* 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 (yr == 1752 && mt == 9 && (j == 3 || j == 247))
+				j += NUMBER_MISSING_DAYS;
+			month->days[i] = j;
+			j++;
+			continue;
+		}
+		month->days[i] = SPACE;
+		weeklines++;
+	}
+
+	/* Add week numbers */
+	if (ctl->wflag) {
+		int weeknum = week_number(1, mt, yr, 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, yr, ctl);
+			else if (52 < weeknum)
+				weeknum = week_number(31, 12, yr, ctl);
+		}
+	}
+}
+
+static void cal_output_month_headers(int line, struct cal_month *month, const struct cal_control *ctl)
+{
+	char out[FMT_ST_CHARS];
+
+	if (!ctl->header_hint) {
+		sprintf(out, _("%s %ld"), ctl->full_month[month->month], month->year);
+		center(out, ctl->width.wk - 1, 0);
+	} else {
+		if (line == 0)
+			sprintf(out, _("%s"), ctl->full_month[month->month]);
+		else
+			sprintf(out, _("%ld"), month->year);
+		center(out, ctl->width.wk - 1, 0);
+	}
+}
+
+static void cal_output_day_header(const struct cal_control *ctl)
+{
+	if (ctl->wflag) {
+		if (ctl->julian)
+			printf("%*s%s", (int)ctl->width.dy - 1, "", day_headings);
+		else
+			printf("%*s%s", (int)ctl->width.dy, "", day_headings);
+	} else
+		fputs(day_headings, stdout);
+}
+
+static void cal_output_week(int week, struct cal_month *month, const struct cal_control *ctl)
+{
+	int i, reqday = 0;
+	int j = 7 * week;
+	int skip = ctl->width.dy - 1;
+
+	if (ctl->wflag) {
+		skip--;
+		if (0 < month->weeks[week]) {
+			if ((ctl->wflag & WEEK_NUM_MASK) == month->weeks[week])
+				printf("%s%2d%s", Senter, month->weeks[week], Sexit);
+			else
+				printf("%2d", month->weeks[week]);
+		} else
+			printf("%2s", "");
+		skip = ctl->width.dy;
+	}
+
+	/* Determine the day that should be highlighted. */
+	if ((month->month + 1) == ctl->req.month && month->year == ctl->req.year) {
+		if (ctl->julian)
+			reqday = ctl->req.day;
+		else
+			reqday = ctl->req.day + 1 - day_in_year(1, month->month + 1, ctl->req.year);
+	}
+
+	for (i = 0; i < DAYS_IN_WEEK; i++) {
+		if (0 < month->days[j])
+			if (reqday == month->days[j])
+				printf("%*s%s%*d%s", skip - (ctl->julian ? 3 : 2), "", Senter, (ctl->julian ? 3 : 2), month->days[j], Sexit);
+			else
+				printf("%*d", skip, month->days[j]);
+		else {
+			printf("%*s", skip, "");
+		}
+		if (skip < (int)ctl->width.dy)
+			skip++;
+		j++;
+	}
+}
+
 static void monthly(const struct cal_control *ctl)
 {
-	int i, rows;
-	struct fmt_st out;
+	struct cal_month month;
+	int i;
+
+	cal_fill_month(&month, ctl->req.month, ctl->req.year, 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");
+	for (i = 0; i <= ctl->header_hint; i++) {
+		cal_output_month_headers(i, &month, ctl);
+		fputs("\n", stdout);
+	}
+	cal_output_day_header(ctl);
+	fputs("\n", stdout);
+	for (i = 0; i < MAXDAYS / DAYS_IN_WEEK; i++) {
+		cal_output_week(i, &month, ctl);
+		fputs(" \n", stdout);
 	}
 }
 
-- 
1.8.4.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 10/10] cal: make cal --three to use content structures
  2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
                   ` (8 preceding siblings ...)
  2013-10-27 20:42 ` [PATCH 09/10] cal: add month contents structure Sami Kerola
@ 2013-10-27 20:42 ` Sami Kerola
  2013-10-31 12:14 ` [0000/0010] cal: code revisit part I Karel Zak
  10 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-10-27 20:42 UTC (permalink / raw)
  To: util-linux; +Cc: kerolasa

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/cal.c | 64 ++++++++++++++++++++++++--------------------------------
 1 file changed, 27 insertions(+), 37 deletions(-)

diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index 1e1721e..5d0a5f5 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -716,7 +716,7 @@ static void cal_output_week(int week, struct cal_month *month, const struct cal_
 	}
 
 	/* Determine the day that should be highlighted. */
-	if ((month->month + 1) == ctl->req.month && month->year == ctl->req.year) {
+	if (((month->month + 1) == ctl->req.month || ctl->req.week) && month->year == ctl->req.year) {
 		if (ctl->julian)
 			reqday = ctl->req.day;
 		else
@@ -759,18 +759,11 @@ 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;
+	struct cal_month month[3];
+	int i, m;
 	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));
 	if (ctl->req.month == 1) {
 		prev_month = MONTHS_IN_YEAR;
 		prev_year  = ctl->req.year - 1;
@@ -785,35 +778,32 @@ static void monthly3(const struct cal_control *ctl)
 		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);
-	}
-	for (i = ctl->header_hint ? 3 : 2; i < rows; i++) {
-		int w1, w2, w3;
-		w1 = w2 = w3 = ctl->width.wk;
 
-#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]);
+	cal_fill_month(&(month[0]), prev_month, prev_year, ctl);
+	cal_fill_month(&(month[1]), ctl->req.month, ctl->req.year, ctl);
+	cal_fill_month(&(month[2]), next_month, next_year, ctl);
 
-		my_putstring(lineout);
+	for (i = 0; i <= ctl->header_hint; i++) {
+		for (m = 0; m < 3; m++) {
+			cal_output_month_headers(i, &month[m], ctl);
+			if (m < 2)
+				fputs("  ", stdout);
+		}
+		fputs("\n", stdout);
+	}
+	for (m = 0; m < 3; m++) {
+		cal_output_day_header(ctl);
+		if (m < 2)
+			fputs("  ", stdout);
+	}
+	fputs("\n", stdout);
+	for (i = 0; i < MAXDAYS / DAYS_IN_WEEK; i++) {
+		for (m = 0; m < 3; m++) {
+			cal_output_week(i, &month[m], ctl);
+			if (m < 2)
+				fputs("  ", stdout);
+		}
+		fputs(" \n", stdout);
 	}
 }
 
-- 
1.8.4.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 01/10] cal: use control structure for run time configuration
  2013-10-27 20:42 ` [PATCH 01/10] cal: use control structure for run time configuration Sami Kerola
@ 2013-10-31 11:29   ` Karel Zak
  0 siblings, 0 replies; 16+ messages in thread
From: Karel Zak @ 2013-10-31 11:29 UTC (permalink / raw)
  To: Sami Kerola; +Cc: util-linux

On Sun, Oct 27, 2013 at 08:42:27PM +0000, Sami Kerola wrote:
> +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 wflag;			/* uses WEEK_NUM_ enum */
> +	int wnum;			/* requested --week=number */

 hmm... you duplicate information the struct
 
    wnum == wflag & WEEK_NUM_MASK 

 Anyway, I think the whole WEEK_NUM_MASK thing is unnecessary if you
 have the control struct, just use:

    struct cal_control {
      ...
      int weekstart;
      int weektype;     /* WEEK_TYPE_{NONE,ISO,US} */
      int weeknum;      /* --week=<num> */
      ...
    }

 Note more readable "week" rather than "w" prefix :-)

> -	if (wflag) {
> -		wflag = wnum & WEEK_NUM_MASK;
> -		wflag |= (weekstart == MONDAY ? WEEK_NUM_ISO : WEEK_NUM_US);
> +	if (ctl.wflag) {
> +		ctl.wflag = ctl.wnum & WEEK_NUM_MASK;
> +		ctl.wflag |= (ctl.weekstart == MONDAY ? WEEK_NUM_ISO : WEEK_NUM_US);
>  	}

 In the original code is wnum main()-only variable.

    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 05/10] cal: determine output width at beginning of run and reuse result
  2013-10-27 20:42 ` [PATCH 05/10] cal: determine output width at beginning of run and reuse result Sami Kerola
@ 2013-10-31 11:34   ` Karel Zak
  0 siblings, 0 replies; 16+ messages in thread
From: Karel Zak @ 2013-10-31 11:34 UTC (permalink / raw)
  To: Sami Kerola; +Cc: util-linux

On Sun, Oct 27, 2013 at 08:42:31PM +0000, Sami Kerola wrote:
> +struct cal_width {
> +	size_t dy;			/* day width in characters in printout */
> +	size_t wk;			/* week width == (7 * dlen + possible week num) */
> +};

 Is it really necessary to have a special struct for this setting? I
 see that everywhere in the code you have

    ctl.width.wk or ctl.width.wk

 what about to add 
 
    int day_width;
    int week_width; 
    
 to the control struct?
 
 BTW, yes, it's C, but ... "dy" and "wk" seems pretty unreadable :-)

    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 07/10] cal: make user request to be part of read-only control struct
  2013-10-27 20:42 ` [PATCH 07/10] cal: make user request to be part of read-only control struct Sami Kerola
@ 2013-10-31 11:49   ` Karel Zak
  2013-11-01  9:29     ` Sami Kerola
  0 siblings, 1 reply; 16+ messages in thread
From: Karel Zak @ 2013-10-31 11:49 UTC (permalink / raw)
  To: Sami Kerola; +Cc: util-linux

On Sun, Oct 27, 2013 at 08:42:33PM +0000, Sami Kerola wrote:
> +struct cal_request {
> +	int day;
> +	int month;
> +	long year;
> +	int week;
> +};

 It makes more sense than cal_width :-)

> +			ctl.req.day = day_in_year(ctl.req.day, ctl.req.month, ctl.req.year);

   req.day = calculate_request_day(&req);

> -static void monthly(int day, int month, long year, const struct cal_control *ctl)
> +static void monthly(const struct cal_control *ctl)
...  
> -	rows = do_monthly(day, month, year, &out, -1, ctl);
> +	rows = do_monthly(ctl->req.day, ctl->req.month, ctl->req.year, &out, -1, ctl);
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 Well, if you have a request struct then use it!

      do_monthly(req, &out, -1, ctl);


 Maybe you can keep request and control structs independent, so then
 one day you can implement something like  
 
    cal --date=Dec-2013 --date=Dec-2014

 to print more independent calendars :-)

 
    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [0000/0010] cal: code revisit part I
  2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
                   ` (9 preceding siblings ...)
  2013-10-27 20:42 ` [PATCH 10/10] cal: make cal --three to use content structures Sami Kerola
@ 2013-10-31 12:14 ` Karel Zak
  10 siblings, 0 replies; 16+ messages in thread
From: Karel Zak @ 2013-10-31 12:14 UTC (permalink / raw)
  To: Sami Kerola; +Cc: util-linux

On Sun, Oct 27, 2013 at 08:42:26PM +0000, Sami Kerola wrote:
> I got the --one and --three outputs working, but I am not completely
> happy about the --three.  Quite frankly better function would take input
> how many horizontal calendar outputs are needed, and would do exactly
> that.  Such function would be more reusable when considering yearly
> output, and the fact it has two column output when in julian mode.

 Yes, in the final output function should not be hardcoded a number of
 months -- it would be better to have a generic function that
 is able to use arbitrary list/array of the months. The list/array of
 the months should be composed in another function.
 
 Now it's possible to print only 1, 3 or 12 months, and all is
 hardcoded. It would be nice to have a way how to print arbitrary
 number of months (or arbitrary range).
 
 For example it would be nice to have a way how to specify a quarter 
 of the company fiscal year (!= calendar year). I can imagine
 something like --month=<list> option or so..

> Karel, it is be best not to merge the last patch.  It is more of
> work-in-progress, comments would be great.

 I'll probably wait for whole code refactoring rather than merge
 an incomplete thing.

    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 07/10] cal: make user request to be part of read-only control struct
  2013-10-31 11:49   ` Karel Zak
@ 2013-11-01  9:29     ` Sami Kerola
  0 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2013-11-01  9:29 UTC (permalink / raw)
  To: Karel Zak; +Cc: util-linux

On 31 October 2013 11:49, Karel Zak <kzak@redhat.com> wrote:
> On Sun, Oct 27, 2013 at 08:42:33PM +0000, Sami Kerola wrote:
>> +struct cal_request {
>> +     int day;
>> +     int month;
>> +     long year;
>> +     int week;
>> +};
>
>  It makes more sense than cal_width :-)
>
>> +                     ctl.req.day = day_in_year(ctl.req.day, ctl.req.month, ctl.req.year);
>
>    req.day = calculate_request_day(&req);
>
>> -static void monthly(int day, int month, long year, const struct cal_control *ctl)
>> +static void monthly(const struct cal_control *ctl)
> ...
>> -     rows = do_monthly(day, month, year, &out, -1, ctl);
>> +     rows = do_monthly(ctl->req.day, ctl->req.month, ctl->req.year, &out, -1, ctl);
>                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>  Well, if you have a request struct then use it!
>
>       do_monthly(req, &out, -1, ctl);
>
>
>  Maybe you can keep request and control structs independent, so then
>  one day you can implement something like
>
>     cal --date=Dec-2013 --date=Dec-2014
>
>  to print more independent calendars :-)

Hi Karel, et.al.,

Thank you for comments, they are useful as usual. You pointed out some
things I already knew being suboptimal, and couple new considerations
to me. Fair conclusion is that all ten patches are not in state for
merge.

How about formalizing the process for changes, and document it in
howto-contribute? It could be something like

1. Tell in mail list you are going to work with some particular piece
for long time and with intention to perform great change. This helps
other to avoid massive merge conflicts. Small or quick work does not
need to be announced.
2. Submit only changes that you think are ready to merge. If something
is not ready, but you want it to get comments tell clearly which
patches you want to be treated this way.
3. When getting comments align the changes with them. Notice that
resubmission without changes is as good as ignoring advice, that is
neither recommended nor polite.
4. Resubmission can be partial or complete. If only few alterations
are needed here and there resubmit particular patches. When comments
cause greater effect resubmit everything again. Later is true
especially true in cases when maintainer send comment 'could you
resubmit all when done'.
5. All patch submissions, big or small, will end either to final
reject or merge. When maintainer rejects a patch (series) it is
pointless to resubmit.

-- 
Sami Kerola
http://www.iki.fi/kerolasa/

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2013-11-01  9:29 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-27 20:42 [0000/0010] cal: code revisit part I Sami Kerola
2013-10-27 20:42 ` [PATCH 01/10] cal: use control structure for run time configuration Sami Kerola
2013-10-31 11:29   ` Karel Zak
2013-10-27 20:42 ` [PATCH 02/10] cal: add input variable names to function prototypes Sami Kerola
2013-10-27 20:42 ` [PATCH 03/10] cal: make day_in_week() use same variable names as other functions Sami Kerola
2013-10-27 20:42 ` [PATCH 04/10] cal: simplify ascii_wnum() function Sami Kerola
2013-10-27 20:42 ` [PATCH 05/10] cal: determine output width at beginning of run and reuse result Sami Kerola
2013-10-31 11:34   ` Karel Zak
2013-10-27 20:42 ` [PATCH 06/10] tests: cal: take account week numbers when determing month lenght Sami Kerola
2013-10-27 20:42 ` [PATCH 07/10] cal: make user request to be part of read-only control struct Sami Kerola
2013-10-31 11:49   ` Karel Zak
2013-11-01  9:29     ` Sami Kerola
2013-10-27 20:42 ` [PATCH 08/10] cal: determine how many header lines are needed at initialization Sami Kerola
2013-10-27 20:42 ` [PATCH 09/10] cal: add month contents structure Sami Kerola
2013-10-27 20:42 ` [PATCH 10/10] cal: make cal --three to use content structures Sami Kerola
2013-10-31 12:14 ` [0000/0010] cal: code revisit part I Karel Zak

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.