besides adding output for the voltage ranges, this patch also changes
various aspects of the -L output:
- sizes are right aligned now with a fixed length of 5
- space between columns is selectable with a constant
- test results are always shown in the same column ("PR" and " R"
  instead of "PR" and "R ")
- vendor and device names are split on a delimiter (currently '/') and
  spread over mutliple lines but only if the tokens are not too short.
  all other columns are printed on the first line of a chip.
- voltage ranges are printed in verbose mode only

it also gets rid of POS_PRINT and digits

Signed-off-by: Stefan Tauner <stefan.tau...@student.tuwien.ac.at>
---
 print.c |  273 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 216 insertions(+), 57 deletions(-)

diff --git a/print.c b/print.c
index b9f7a43..3f1fb3a 100644
--- a/print.c
+++ b/print.c
@@ -59,40 +59,68 @@ char *flashbuses_to_text(enum chipbustype bustype)
        return ret;
 }
 
-#define POS_PRINT(x) do { pos += strlen(x); msg_ginfo(x); } while (0)
-
-static int digits(int n)
-{
-       int i;
-
-       if (!n)
-               return 1;
-
-       for (i = 0; n; ++i)
-               n /= 10;
-
-       return i;
-}
-
 static void print_supported_chips(void)
 {
-       int okcol = 0, pos = 0, i, chipcount = 0;
+       const char *delim = "/";
+       const int mintoklen = 5;
+       const int border = 2;
+       int i, chipcount = 0;
        int maxvendorlen = strlen("Vendor") + 1;
        int maxchiplen = strlen("Device") + 1;
+       int maxtypelen = strlen("Type") + 1;
        const struct flashchip *f;
        char *s;
+       char *tmpven, *tmpdev;
+       int tmpvenlen, tmpdevlen, curvenlen, curdevlen;
 
+       /* calculate maximum column widths and by iterating over all chips */
        for (f = flashchips; f->name != NULL; f++) {
                /* Ignore "unknown XXXX SPI chip" entries. */
                if (!strncmp(f->name, "unknown", 7))
                        continue;
                chipcount++;
-               maxvendorlen = max(maxvendorlen, strlen(f->vendor));
-               maxchiplen = max(maxchiplen, strlen(f->name));
+
+               /* Find maximum vendor length (respecting line splitting). */
+               tmpven = (char *)f->vendor;
+               do {
+                       /* and take minimum token lengths into account */
+                       tmpvenlen = 0;
+                       do {
+                               tmpvenlen += strcspn(tmpven, delim);
+                               /* skip to the address after the first token */
+                               tmpven += tmpvenlen;
+                               if (tmpven[0] == '\0')
+                                       break;
+                               tmpven++;
+                       } while (tmpvenlen < mintoklen);
+                       maxvendorlen = max(maxvendorlen, tmpvenlen);
+                       if (tmpven[0] == '\0')
+                               break;
+               } while (1);
+
+               /* same for device name */
+               tmpdev = (char *)f->name;
+               do {
+                       tmpdevlen = 0;
+                       do {
+                               tmpdevlen += strcspn(tmpdev, delim);
+                               tmpdev += tmpdevlen;
+                               if (tmpdev[0] == '\0')
+                                       break;
+                               tmpdev++;
+                       } while (tmpdevlen < mintoklen);
+                       maxchiplen = max(maxchiplen, tmpdevlen);
+                       if (tmpdev[0] == '\0')
+                               break;
+               } while (1);
+
+               s = flashbuses_to_text(f->bustype);
+               maxtypelen = max(maxtypelen, strlen(s));
+               free(s);
        }
-       maxvendorlen++;
-       maxchiplen++;
-       okcol = maxvendorlen + maxchiplen;
+       maxvendorlen += border;
+       maxchiplen += border;
+       maxtypelen += border;
 
        msg_ginfo("Supported flash chips (total: %d):\n\n", chipcount);
        msg_ginfo("Vendor");
@@ -102,10 +130,35 @@ static void print_supported_chips(void)
        for (i = strlen("Device"); i < maxchiplen; i++)
                msg_ginfo(" ");
 
-       msg_ginfo("Tested   Known    Size/kB:  Type:\n");
-       for (i = 0; i < okcol; i++)
+       msg_ginfo("Test");
+       for (i = 0; i < border; i++)
+               msg_ginfo(" ");
+       msg_ginfo("Known");
+       for (i = 0; i < border; i++)
+               msg_ginfo(" ");
+       msg_ginfo(" Size");
+       for (i = 0; i < border; i++)
+               msg_ginfo(" ");
+
+       msg_ginfo("Type");
+       for (i = strlen("Type"); i < maxtypelen; i++)
+               msg_ginfo(" ");
+       msg_gdbg("Voltage");
+       msg_ginfo("\n");
+
+       for (i = 0; i < maxvendorlen + maxchiplen; i++)
+               msg_ginfo(" ");
+       msg_ginfo("OK  ");
+       for (i = 0; i < border; i++)
+               msg_ginfo(" ");
+       msg_ginfo("Broken");
+       for (i = 0; i < border; i++)
                msg_ginfo(" ");
-       msg_ginfo("OK       Broken\n\n");
+       msg_ginfo("[kB]");
+       for (i = 0; i < border + maxtypelen; i++)
+               msg_ginfo(" ");
+       msg_gdbg("range [V]");
+       msg_ginfo("\n\n");
        msg_ginfo("(P = PROBE, R = READ, E = ERASE, W = WRITE)\n\n");
 
        for (f = flashchips; f->name != NULL; f++) {
@@ -113,50 +166,156 @@ static void print_supported_chips(void)
                if (!strncmp(f->name, "unknown", 7))
                        continue;
 
-               msg_ginfo("%s", f->vendor);
-               for (i = strlen(f->vendor); i < maxvendorlen; i++)
-                       msg_ginfo(" ");
-               msg_ginfo("%s", f->name);
-               for (i = strlen(f->name); i < maxchiplen; i++)
-                       msg_ginfo(" ");
-
-               pos = maxvendorlen + maxchiplen;
-               if ((f->tested & TEST_OK_MASK)) {
-                       if ((f->tested & TEST_OK_PROBE))
-                               POS_PRINT("P ");
-                       if ((f->tested & TEST_OK_READ))
-                               POS_PRINT("R ");
-                       if ((f->tested & TEST_OK_ERASE))
-                               POS_PRINT("E ");
-                       if ((f->tested & TEST_OK_WRITE))
-                               POS_PRINT("W ");
+               /* support for multiline vendor names:
+                * - make a copy of the original vendor name
+                * - use strok to put the first token in tmpven
+                * - keep track of the length of all tokens on the current line
+                *   for ' '-padding in curvenlen
+                * - check if additional tokens should be printed on the current
+                *   line
+                * - after all other values are printed print the surplus tokens
+                *   on fresh lines
+                */
+               tmpven = malloc(strlen(f->vendor) + 1);
+               if (tmpven == NULL) {
+                       msg_gerr("Out of memory!\n");
+                       exit(1);
                }
-               while (pos < okcol + 9) {
+               strcpy(tmpven, f->vendor);
+
+               tmpven = strtok(tmpven, delim);
+               msg_ginfo("%s", tmpven);
+               curvenlen = strlen(tmpven);
+               while ((tmpven = strtok(NULL, delim)) != NULL) {
+                       msg_ginfo("%s", delim);
+                       curvenlen++;
+                       tmpvenlen = strlen(tmpven);
+                       if (tmpvenlen >= mintoklen)
+                               break; /* big enough to be on its own line */
+                       msg_ginfo("%s", tmpven);
+                       curvenlen += tmpvenlen;
+               }
+
+               for (i = curvenlen; i < maxvendorlen; i++)
                        msg_ginfo(" ");
-                       pos++;
+
+               /* support for multiline device names as above */
+               tmpdev = malloc(strlen(f->name) + 1);
+               if (tmpdev == NULL) {
+                       msg_gerr("Out of memory!\n");
+                       exit(1);
                }
-               if ((f->tested & TEST_BAD_MASK)) {
-                       if ((f->tested & TEST_BAD_PROBE))
-                               POS_PRINT("P ");
-                       if ((f->tested & TEST_BAD_READ))
-                               POS_PRINT("R ");
-                       if ((f->tested & TEST_BAD_ERASE))
-                               POS_PRINT("E ");
-                       if ((f->tested & TEST_BAD_WRITE))
-                               POS_PRINT("W ");
+               strcpy(tmpdev, f->name);
+
+               tmpdev = strtok(tmpdev, delim);
+               msg_ginfo("%s", tmpdev);
+               curdevlen = strlen(tmpdev);
+               while ((tmpdev = strtok(NULL, delim)) != NULL) {
+                       msg_ginfo("%s", delim);
+                       curdevlen++;
+                       tmpdevlen = strlen(tmpdev);
+                       if (tmpdevlen >= mintoklen)
+                               break; /* big enough to be on its own line */
+                       msg_ginfo("%s", tmpdev);
+                       curdevlen += tmpdevlen;
                }
 
-               while (pos < okcol + 18) {
+               for (i = curdevlen; i < maxchiplen; i++)
                        msg_ginfo(" ");
-                       pos++;
-               }
-               msg_ginfo("%d", f->total_size);
-               for (i = 0; i < 10 - digits(f->total_size); i++)
+
+               if ((f->tested & TEST_OK_PROBE))
+                       msg_ginfo("P");
+               else
+                       msg_ginfo(" ");
+               if ((f->tested & TEST_OK_READ))
+                       msg_ginfo("R");
+               else
+                       msg_ginfo(" ");
+               if ((f->tested & TEST_OK_ERASE))
+                       msg_ginfo("E");
+               else
+                       msg_ginfo(" ");
+               if ((f->tested & TEST_OK_WRITE))
+                       msg_ginfo("W");
+               else
+                       msg_ginfo(" ");
+               for (i = 0; i < border; i++)
+                       msg_ginfo(" ");
+
+               if ((f->tested & TEST_BAD_PROBE))
+                       msg_ginfo("P");
+               else
+                       msg_ginfo(" ");
+               if ((f->tested & TEST_BAD_READ))
+                       msg_ginfo("R");
+               else
+                       msg_ginfo(" ");
+               if ((f->tested & TEST_BAD_ERASE))
+                       msg_ginfo("E");
+               else
+                       msg_ginfo(" ");
+               if ((f->tested & TEST_BAD_WRITE))
+                       msg_ginfo("W");
+               else
+                       msg_ginfo(" ");
+               for (i = 0; i < border + 1; i++)
+                       msg_ginfo(" ");
+
+               msg_ginfo("%5d", f->total_size);
+               for (i = 0; i < border; i++)
                        msg_ginfo(" ");
 
                s = flashbuses_to_text(f->bustype);
-               msg_ginfo("%s\n", s);
+               msg_ginfo("%s", s);
+               for (i = strlen(s); i < maxtypelen; i++)
+                       msg_ginfo(" ");
                free(s);
+
+               if (f->voltage.min == 0 && f->voltage.max == 0)
+                       msg_gdbg("no info");
+               else
+                       msg_gdbg("%0.02f;%0.02f",
+                                f->voltage.min/(double)1000,
+                                f->voltage.max/(double)1000);
+
+               /* print surplus vendor and device name tokens */
+               while (tmpven != NULL || tmpdev != NULL) {
+                       msg_ginfo("\n");
+                       if (tmpven != NULL){
+                               msg_ginfo("%s", tmpven);
+                               curvenlen = strlen(tmpven);
+                               while ((tmpven = strtok(NULL, delim)) != NULL) {
+                                       msg_ginfo("%s", delim);
+                                       curvenlen++;
+                                       tmpvenlen = strlen(tmpven);
+                                       /* big enough to be on its own line */
+                                       if (tmpvenlen >= mintoklen)
+                                               break;
+                                       msg_ginfo("%s", tmpven);
+                                       curvenlen += tmpvenlen;
+                               }
+                       } else
+                               curvenlen = 0;
+
+                       for (i = curvenlen; i < maxvendorlen; i++)
+                               msg_ginfo(" ");
+
+                       if (tmpdev != NULL){
+                               msg_ginfo("%s", tmpdev);
+                               curdevlen = strlen(tmpdev);
+                               while ((tmpdev = strtok(NULL, delim)) != NULL) {
+                                       msg_ginfo("%s", delim);
+                                       curdevlen++;
+                                       tmpdevlen = strlen(tmpdev);
+                                       /* big enough to be on its own line */
+                                       if (tmpdevlen >= mintoklen)
+                                               break;
+                                       msg_ginfo("%s", tmpdev);
+                                       curdevlen += tmpdevlen;
+                               }
+                       }
+               }
+               msg_ginfo("\n");
        }
 }
 
-- 
1.7.1


_______________________________________________
flashrom mailing list
flashrom@flashrom.org
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to