urjtag maintains a bunch of lists -- lists of commands, lists of cables,
etc...  personally, when trying to read the 'help cable' output, i find the
unordered list to be kind of crappy.  i'm forced to read the whole thing
carefully to see if the bus i want is there.  in my mind though, it really
needs to be sorted.

so to that end, i whipped up a little bit of code that automatically sorts the
lists before displaying them.  the only thing is that it requires the type to
have the name field as the first item in the structure.  this way i can assume
the pointers given end up at the string we want to sort by without having to
take arbitrary offsets into account.

any comments before i commit this ?
-mike

diff --git a/urjtag/include/urjtag/flash.h b/urjtag/include/urjtag/flash.h
index 38123cc..acff105 100644
--- a/urjtag/include/urjtag/flash.h
+++ b/urjtag/include/urjtag/flash.h
@@ -43,9 +43,9 @@ typedef struct URJ_FLASH_CFI_ARRAY urj_flash_cfi_array_t;
 
 typedef struct
 {
-    unsigned int bus_width;     /* 1 for 8 bits, 2 for 16 bits, 4 for 32 bits, 
etc. */
     const char *name;
     const char *description;
+    unsigned int bus_width;     /* 1 for 8 bits, 2 for 16 bits, 4 for 32 bits, 
etc. */
     /** @return 1 if autodetected, 0 otherwise */
     int (*autodetect) (urj_flash_cfi_array_t *cfi_array);
     void (*print_info) (urj_log_level_t ll, urj_flash_cfi_array_t *cfi_array);
diff --git a/urjtag/src/cmd/cmd.h b/urjtag/src/cmd/cmd.h
index 79df511..dc9143b 100644
--- a/urjtag/src/cmd/cmd.h
+++ b/urjtag/src/cmd/cmd.h
@@ -34,6 +34,7 @@
 #ifndef URJ_SRC_CMD_H
 #define URJ_SRC_CMD_H
 
+#include <stdlib.h> /* qsort */
 #include <sysdep.h>
 
 #include <urjtag/types.h>
@@ -112,4 +113,16 @@ int urj_cmd_params (char *params[]);
  */
 int urj_cmd_get_number (const char *s, long unsigned *i);
 
+/**
+ * Internal command to help with sorting structures
+ */
+int _urj_cmd_alphasort (const void *a, const void *b);
+#define urj_cmd_sort(arr) \
+       do { \
+               size_t nmemb; \
+               for (nmemb = 0; (arr)[nmemb]; ++nmemb) \
+                       continue; \
+               qsort (arr, nmemb, sizeof(*arr), _urj_cmd_alphasort); \
+       } while (0)
+
 #endif /* URJ_CMD_H */
diff --git a/urjtag/src/cmd/cmd_cable.c b/urjtag/src/cmd/cmd_cable.c
index 67020f1..f503db5 100644
--- a/urjtag/src/cmd/cmd_cable.c
+++ b/urjtag/src/cmd/cmd_cable.c
@@ -174,6 +174,7 @@ cmd_cable_help (void)
                "\n" "List of supported cables:\n"),
              "cable");
 
+    urj_cmd_sort (urj_tap_cable_drivers);
     for (i = 0; urj_tap_cable_drivers[i]; i++)
         urj_log (URJ_LOG_LEVEL_NORMAL,
                  _("%-13s %s\n"), urj_tap_cable_drivers[i]->name,
diff --git a/urjtag/src/cmd/cmd_cmd.c b/urjtag/src/cmd/cmd_cmd.c
index 68452f0..c62ae24 100644
--- a/urjtag/src/cmd/cmd_cmd.c
+++ b/urjtag/src/cmd/cmd_cmd.c
@@ -214,3 +214,13 @@ urj_cmd_get_number (const char *s, long unsigned *i)
 
     return URJ_STATUS_FAIL;
 }
+
+/*
+ * We could leverage offsetof() so that we don't assume the name is
+ * always the first member, but that requires passing state.
+ */
+#define qsort_ptr(p) (**(char ***)p)
+int _urj_cmd_alphasort(const void *a, const void *b)
+{
+       return strcmp (qsort_ptr(a), qsort_ptr(b));
+}
diff --git a/urjtag/src/cmd/cmd_eraseflash.c b/urjtag/src/cmd/cmd_eraseflash.c
index 20277b2..9f9e7af 100644
--- a/urjtag/src/cmd/cmd_eraseflash.c
+++ b/urjtag/src/cmd/cmd_eraseflash.c
@@ -81,6 +81,7 @@ cmd_eraseflash_help (void)
                "\n" "Supported Flash Memories:\n"),
              "eraseflash");
 
+    urj_cmd_sort (urj_flash_flash_drivers);
     for (i = 0; urj_flash_flash_drivers[i]; i++)
         urj_log (URJ_LOG_LEVEL_NORMAL,
                  _("%s\n     %s\n"), _(urj_flash_flash_drivers[i]->name),
diff --git a/urjtag/src/cmd/cmd_flashmem.c b/urjtag/src/cmd/cmd_flashmem.c
index 0e667ae..ca290cf 100644
--- a/urjtag/src/cmd/cmd_flashmem.c
+++ b/urjtag/src/cmd/cmd_flashmem.c
@@ -107,6 +107,7 @@ cmd_flashmem_help (void)
                "Supported Flash Memories:\n"),
              "flashmem", "flashmem msbin", "msbin", "noverify");
 
+    urj_cmd_sort (urj_flash_flash_drivers);
     for (i = 0; urj_flash_flash_drivers[i]; i++)
         urj_log (URJ_LOG_LEVEL_NORMAL,
                  _("%s\n     %s\n"), _(urj_flash_flash_drivers[i]->name),
diff --git a/urjtag/src/cmd/cmd_help.c b/urjtag/src/cmd/cmd_help.c
index b4a0c92..e8acfb5 100644
--- a/urjtag/src/cmd/cmd_help.c
+++ b/urjtag/src/cmd/cmd_help.c
@@ -48,6 +48,7 @@ cmd_help_run (urj_chain_t *chain, char *params[])
     /* short description generation */
     if (urj_cmd_params (params) == 1)
     {
+        urj_cmd_sort (urj_cmds);
         urj_log (URJ_LOG_LEVEL_NORMAL, _("Command list:\n\n"));
         for (i = 0; urj_cmds[i]; i++)
             urj_log (URJ_LOG_LEVEL_NORMAL, _("%-13s %s\n"), urj_cmds[i]->name,
diff --git a/urjtag/src/cmd/cmd_initbus.c b/urjtag/src/cmd/cmd_initbus.c
index 93b91e6..ded259e 100644
--- a/urjtag/src/cmd/cmd_initbus.c
+++ b/urjtag/src/cmd/cmd_initbus.c
@@ -100,6 +100,7 @@ cmd_initbus_help (void)
                "\n" "List of available buses:\n"),
              "initbus");
 
+    urj_cmd_sort (urj_bus_drivers);
     for (i = 0; urj_bus_drivers[i] != NULL; i++)
         urj_log (URJ_LOG_LEVEL_NORMAL,
                  _("%-10s %s\n"), urj_bus_drivers[i]->name,
diff --git a/urjtag/src/flash/amd.c b/urjtag/src/flash/amd.c
index b4c0081..39d08aa 100644
--- a/urjtag/src/flash/amd.c
+++ b/urjtag/src/flash/amd.c
@@ -643,9 +643,9 @@ amd_flash_program32 (urj_flash_cfi_array_t *cfi_array, 
uint32_t adr,
 }
 
 urj_flash_driver_t urj_flash_amd_32_flash_driver = {
-    4,                          /* buswidth */
     N_("AMD/Fujitsu Standard Command Set"),
     N_("supported: AMD 29LV640D, 29LV641D, 29LV642D; 2x16 Bit"),
+    4,                          /* buswidth */
     amd_flash_autodetect32,
     amd_flash_print_info,
     amd_flash_erase_block,
@@ -655,9 +655,9 @@ urj_flash_driver_t urj_flash_amd_32_flash_driver = {
 };
 
 urj_flash_driver_t urj_flash_amd_16_flash_driver = {
-    2,                          /* buswidth */
     N_("AMD/Fujitsu Standard Command Set"),
     N_("supported: AMD 29LV800B, S29GLxxxN; MX29LV640B, W19B320AT/B; 1x16 
Bit"),
+    2,                          /* buswidth */
     amd_flash_autodetect16,
     amd_flash_print_info,
     amd_flash_erase_block,
@@ -667,9 +667,9 @@ urj_flash_driver_t urj_flash_amd_16_flash_driver = {
 };
 
 urj_flash_driver_t urj_flash_amd_8_flash_driver = {
-    1,                          /* buswidth */
     N_("AMD/Fujitsu Standard Command Set"),
     N_("supported: AMD 29LV160, AMD 29LV065D, AMD 29LV040B, S29GLxxxN, 
W19B320AT/B; 1x8 Bit"),
+    1,                          /* buswidth */
     amd_flash_autodetect8,
     amd_flash_print_info,
     amd_flash_erase_block,
diff --git a/urjtag/src/flash/amd_flash.c b/urjtag/src/flash/amd_flash.c
index 414037f..717e8b8 100644
--- a/urjtag/src/flash/amd_flash.c
+++ b/urjtag/src/flash/amd_flash.c
@@ -410,9 +410,9 @@ amd_29xx040_unlock_block (urj_flash_cfi_array_t *cfi_array,
 
 
 urj_flash_driver_t urj_flash_amd_29xx040_flash_driver = {
-    1,                          /* buswidth */
     N_("AMD Standard Command Set"),
     N_("supported: AMD 29LV040B, 29C040B, 1x8 Bit"),
+    1,                          /* buswidth */
     amd_29xx040_autodetect,
     amd_29xx040_print_info,
     amd_29xx040_erase_block,
diff --git a/urjtag/src/flash/intel.c b/urjtag/src/flash/intel.c
index e800eb9..8b90391 100644
--- a/urjtag/src/flash/intel.c
+++ b/urjtag/src/flash/intel.c
@@ -526,9 +526,9 @@ intel_flash_readarray (urj_flash_cfi_array_t *cfi_array)
 }
 
 urj_flash_driver_t urj_flash_intel_32_flash_driver = {
-    4,                          /* buswidth */
     N_("Intel Standard Command Set"),
     N_("supported: 28Fxxxx, 2 x 16 bit"),
+    4,                          /* buswidth */
     intel_flash_autodetect32,
     intel_flash_print_info32,
     intel_flash_erase_block32,
@@ -538,9 +538,9 @@ urj_flash_driver_t urj_flash_intel_32_flash_driver = {
 };
 
 urj_flash_driver_t urj_flash_intel_16_flash_driver = {
-    2,                          /* buswidth */
     N_("Intel Standard Command Set"),
     N_("supported: 28Fxxxx, 1 x 16 bit"),
+    2,                          /* buswidth */
     intel_flash_autodetect,
     intel_flash_print_info,
     intel_flash_erase_block,
@@ -550,9 +550,9 @@ urj_flash_driver_t urj_flash_intel_16_flash_driver = {
 };
 
 urj_flash_driver_t urj_flash_intel_8_flash_driver = {
-    1,                          /* buswidth */
     N_("Intel Standard Command Set"),
     N_("supported: 28Fxxxx, 1 x 8 bit"),
+    1,                          /* buswidth */
     intel_flash_autodetect8,
     intel_flash_print_info,
     intel_flash_erase_block,

Attachment: signature.asc
Description: This is a digitally signed message part.

------------------------------------------------------------------------------
Throughout its 18-year history, RSA Conference consistently attracts the
world's best and brightest in the field, creating opportunities for Conference
attendees to learn about information security's most important issues through
interactions with peers, luminaries and emerging and established companies.
http://p.sf.net/sfu/rsaconf-dev2dev
_______________________________________________
UrJTAG-development mailing list
UrJTAG-development@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/urjtag-development

Reply via email to