print_wiki: fix columns calculations

For
- chipsets
- boards, and
- chips

Previously the chipset columns were not uniformly divided at all,
which led to very odd table bottoms. This patches fixes this as far
as wiki code can do (browser rendering can still create odd effects
because we do not define cell heights).

Corresponding to flashrom svn r1556.

Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
diff --git a/print_wiki.c b/print_wiki.c
index 68a69a9..617053c 100644
--- a/print_wiki.c
+++ b/print_wiki.c
@@ -35,15 +35,21 @@
 generated by pasting '''flashrom -z''' output.<br />\
 '''Last update:''' %s(generated by flashrom %s)\n</small></div>\n";
 
+static const char th_start[] = "| valign=\"top\"|\n\n\
+{| border=\"0\" style=\"font-size: smaller\" valign=\"top\"\n\
+|- bgcolor=\"#6699dd\"\n";
+
 #if CONFIG_INTERNAL == 1
-static const char chipset_th[] = "{| border=\"0\" style=\"font-size: smaller\"\n\
-|- bgcolor=\"#6699dd\"\n! align=\"left\" | Vendor\n\
-! align=\"left\" | Southbridge\n! align=\"center\" | PCI IDs\n\
+static const char chipset_th[] = "\
+! align=\"left\" | Vendor\n\
+! align=\"left\" | Southbridge\n\
+! align=\"center\" | PCI IDs\n\
 ! align=\"center\" | Status\n\n";
 
-static const char board_th[] = "{| border=\"0\" style=\"font-size: smaller\" \
-valign=\"top\"\n|- bgcolor=\"#6699dd\"\n! align=\"left\" | Vendor\n\
-! align=\"left\" | Mainboard\n! align=\"left\" | Required option\n\
+static const char board_th[] = "\
+! align=\"left\" | Vendor\n\
+! align=\"left\" | Mainboard\n\
+! align=\"left\" | Required option\n\
 ! align=\"center\" | Status\n\n";
 
 static const char board_intro[] = "\
@@ -59,9 +65,7 @@
 further verified mainboards on the [[Mailinglist|mailing list]].\n";
 #endif
 
-static const char chip_th[] = "{\
-| border=\"0\" style=\"font-size: smaller\" valign=\"top\"\n\
-|- bgcolor=\"#6699dd\"\n\
+static const char chip_th[] = "\
 ! align=\"left\" | Vendor\n\
 ! align=\"left\" | Device\n\
 ! align=\"center\" | Size [kB]\n\
@@ -72,14 +76,16 @@
 | Probe\n| Read\n| Erase\n| Write\n\
 | align=\"center\" | Min \n| align=\"center\" | Max\n\n";
 
-static const char programmer_section[] = "\
-\n== Supported programmers ==\n\nThis is a list \
-of supported PCI devices flashrom can use as programmer:\n\n{| border=\"0\" \
-valign=\"top\"\n| valign=\"top\"|\n\n{| border=\"0\" style=\"font-size: \
-smaller\" valign=\"top\"\n|- bgcolor=\"#6699dd\"\n! align=\"left\" | Vendor\n\
-! align=\"left\" | Device\n! align=\"center\" | PCI IDs\n\
+static const char programmer_th[] = "\
+! align=\"left\" | Vendor\n\
+! align=\"left\" | Device\n\
+! align=\"center\" | PCI IDs\n\
 ! align=\"center\" | Status\n\n";
 
+static const char programmer_intro[] = "\
+\n== Supported programmers ==\n\n\
+This is a list of supported PCI devices flashrom can use as programmer:\n\n{";
+
 #if CONFIG_INTERNAL == 1
 static const char laptop_intro[] = "\n== Supported laptops/notebooks ==\n\n\
 In general, flashing laptops is more difficult because laptops\n\n\
@@ -94,18 +100,25 @@
 
 static void print_supported_chipsets_wiki(int cols)
 {
-	int i, j, enablescount = 0, color = 1;
+	int i;
+	unsigned int lines_per_col;
 	const struct penable *e;
+	int enablescount = 0, color = 1;
 
 	for (e = chipset_enables; e->vendor_name != NULL; e++)
 		enablescount++;
 
-	printf("\n== Supported chipsets ==\n\nTotal amount of supported "
-	       "chipsets: '''%d'''\n\n{| border=\"0\" valign=\"top\"\n| "
-	       "valign=\"top\"|\n\n%s", enablescount, chipset_th);
+	/* +1 to force the resulting number of columns to be < cols */
+	lines_per_col = enablescount / cols + ((enablescount%cols) > 0 ? 1 : 0);
+
+	printf("\n== Supported chipsets ==\n\nTotal amount of supported chipsets: '''%d'''\n\n"
+	       "{| border=\"0\" valign=\"top\"\n", enablescount);
 
 	e = chipset_enables;
-	for (i = 0, j = 0; e[i].vendor_name != NULL; i++, j++) {
+	for (i = 0; e[i].vendor_name != NULL; i++) {
+		if ((i % lines_per_col) == 0)
+			printf("%s%s", th_start, chipset_th);
+
 		/* Alternate colors if the vendor changes. */
 		if (i > 0 && strcmp(e[i].vendor_name, e[i - 1].vendor_name))
 			color = !color;
@@ -116,20 +129,20 @@
 		       e[i].vendor_id, e[i].device_id,
 		       (e[i].status == OK) ? "{{OK}}" : "{{?3}}");
 
-		/* Split table in 'cols' columns. */
-		if (j >= (enablescount / cols + 1)) {
-			printf("\n|}\n\n| valign=\"top\"|\n\n%s", chipset_th);
-			j = 0;
-		}
+		if (((i % lines_per_col) + 1) == lines_per_col)
+			printf("\n|}\n\n");
 	}
 
-	printf("\n|}\n\n|}\n");
+	/* end inner table if it did not fill the last column fully */
+	if (((i % lines_per_col)) > 0)
+		printf("\n|}\n\n");
+	printf("\n\n|}\n");
 }
 
-static void wiki_helper(const char *devicetype, int cols,
-			const struct board_info boards[])
+static void wiki_helper(const char *devicetype, int cols, const struct board_info boards[])
 {
-	int i, j, k;
+	int i, k;
+	unsigned int boardcount, lines_per_col;
 	unsigned int boardcount_good = 0, boardcount_bad = 0, boardcount_nt = 0;
 	int num_notes = 0, color = 1;
 	char *notes = calloc(1, 1);
@@ -144,14 +157,19 @@
 		else
 			boardcount_bad++;
 	}
+	boardcount = boardcount_good + boardcount_nt + boardcount_bad;
+
+	/* +1 to force the resulting number of columns to be < cols */
+	lines_per_col = boardcount / cols + ((boardcount%cols) > 0 ? 1 : 0);
 
 	printf("\n\nTotal amount of known good boards %s: '''%d'''; "
 	       "Untested (e.g. user vanished before testing new code): '''%d'''; "
 	       "Not yet supported (i.e. known-bad): '''%d'''.\n\n"
-	       "{| border=\"0\" valign=\"top\"\n| valign=\"top\"|\n\n%s",
-	       devicetype, boardcount_good, boardcount_nt, boardcount_bad, board_th);
+	       "{| border=\"0\" valign=\"top\"\n", devicetype, boardcount_good, boardcount_nt, boardcount_bad);
 
-	for (i = 0, j = 0; boards[i].vendor != NULL; i++, j++) {
+	for (i = 0; boards[i].vendor != NULL; i++) {
+		if ((i % lines_per_col) == 0)
+			printf("%s%s", th_start, board_th);
 
 		/* Alternate colors if the vendor changes. */
 		if (i > 0 && strcmp(boards[i].vendor, boards[i - 1].vendor))
@@ -187,14 +205,14 @@
 			printf("\n");
 		}
 
-		/* Split table in 'cols' columns. */
-		if (j >= ((boardcount_good + boardcount_bad) / cols + 1)) {
-			printf("\n|}\n\n| valign=\"top\"|\n\n%s", board_th);
-			j = 0;
-		}
+		if (((i % lines_per_col) + 1) == lines_per_col)
+			printf("\n|}\n\n");
 	}
 
-	printf("\n|}\n\n|}\n");
+	/* end inner table if it did not fill the last column fully */
+	if (((i % lines_per_col)) > 0)
+		printf("\n|}\n\n");
+	printf("\n\n|}\n");
 
 	if (num_notes > 0)
 		printf("\n<small>\n%s</small>\n", notes);
@@ -213,12 +231,13 @@
 
 static void print_supported_chips_wiki(int cols)
 {
-	int i = 0, c = 1, chipcount = 0;
-	const struct flashchip *f, *old = NULL;
+	unsigned int lines_per_col;
 	uint32_t t;
 	char *s;
 	char vmax[6];
 	char vmin[6];
+	const struct flashchip *f, *old = NULL;
+	int i = 0, c = 1, chipcount = 0;
 
 	for (f = flashchips; f->name != NULL; f++) {
 		/* Don't count generic entries. */
@@ -229,21 +248,27 @@
 		chipcount++;
 	}
 
-	printf("\n== Supported chips ==\n\nTotal amount of supported "
-	       "chips: '''%d'''\n\n{| border=\"0\" valign=\"top\"\n"
-		"| valign=\"top\"|\n\n%s", chipcount, chip_th);
+	/* +1 to force the resulting number of columns to be < cols */
+	lines_per_col = chipcount / cols + ((chipcount%cols) > 0 ? 1 : 0);
 
-	for (f = flashchips; f->name != NULL; f++, i++) {
+	printf("\n== Supported chips ==\n\nTotal amount of supported chips: '''%d'''\n\n"
+	       "{| border=\"0\" valign=\"top\"\n", chipcount);
+
+	for (f = flashchips; f->name != NULL; f++) {
 		/* Don't print generic entries. */
 		if (!strncmp(f->vendor, "Unknown", 7) ||
 		    !strncmp(f->vendor, "Programmer", 10) ||
 		    !strncmp(f->name, "unknown", 7))
 			continue;
 
+		if ((i % lines_per_col) == 0)
+			printf("%s%s", th_start, chip_th);
+
 		/* Alternate colors if the vendor changes. */
 		if (old != NULL && strcmp(old->vendor, f->vendor))
 			c = !c;
 
+		old = f;
 		t = f->tested;
 		s = flashbuses_to_text(f->bustype);
 		sprintf(vmin, "%0.03f", f->voltage.min / (double)1000);
@@ -267,16 +292,14 @@
 		       f->voltage.min ? vmax : "N/A");
 		free(s);
 
-		/* Split table into 'cols' columns. */
-		if (i >= (chipcount / cols + 1)) {
-			printf("\n|}\n\n| valign=\"top\"|\n\n%s", chip_th);
-			i = 0;
-		}
-
-		old = f;
+		if (((i % lines_per_col) + 1) == lines_per_col)
+			printf("\n|}\n\n");
+		i++;
 	}
-
-	printf("\n|}\n\n|}\n");
+	/* end inner table if it did not fill the last column fully */
+	if (((i % lines_per_col)) > 0)
+		printf("\n|}\n\n");
+	printf("|}\n\n");
 }
 
 /* Not needed for CONFIG_INTERNAL, but for all other PCI-based programmers. */
@@ -309,7 +332,8 @@
 	print_supported_chipsets_wiki(3);
 	print_supported_boards_wiki();
 #endif
-	printf("%s", programmer_section);
+	printf("%s%s%s", programmer_intro, th_start, programmer_th);
+
 #if CONFIG_NIC3COM == 1
 	print_supported_pcidevs_wiki(nics_3com);
 #endif
@@ -343,6 +367,6 @@
 #if CONFIG_SATAMV == 1
 	print_supported_pcidevs_wiki(satas_mv);
 #endif
-	printf("\n|}\n");
+	printf("\n|}\n\n|}\n");
 }