[lib] Make message lookup function more robust.

2007-03-20 Andrew J. Schorr <ajschorr@alumni.princeton.edu>

	* log.c: (mes_lookup) Make the function more robust: check for
	  cases where the index does not match the key value at that position.
	  If so, give a warning and fall back to a linear search.
	  And improve the error message in cases where even that fails.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 914cc5e..99b82b1 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,10 @@
+2007-03-20 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
+	* log.c: (mes_lookup) Make the function more robust: check for
+	  cases where the index does not match the key value at that position.
+	  If so, give a warning and fall back to a linear search.
+	  And improve the error message in cases where even that fails.
+
 2006-12-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
 
 	* if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating
diff --git a/lib/log.c b/lib/log.c
index 3eb0bd5..c123f24 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -693,17 +693,32 @@
   return "";
 }
 
-/* Very old hacky version of message lookup function.  Still partly
-   used in bgpd and ospfd. FIXME Seems that it's not used any more. */
+/* Older/faster version of message lookup function, but requires caller to pass
+   in the array size (instead of relying on a 0 key to terminate the search). */
 const char *
 mes_lookup (struct message *meslist, int max, int index)
 {
-  if (index < 0 || index >= max) 
-    {
-      zlog_err ("message index out of bound: %d", max);
-      return NULL;
-    }
-  return meslist[index].str;
+  /* first check for best case: index is in range and matches the key
+     value in that slot */
+  if ((index >= 0) && (index < max) && (meslist[index].key == index))
+    return meslist[index].str;
+
+  /* fall back to linear search */
+  {
+    int i;
+
+    for (i = 0; i < max; i++, meslist++)
+      {
+	if (meslist->key == index)
+	  {
+	    zlog_warn("message index %d [%s] found in position %d (max is %d)",
+		      index, meslist->str, i, max);
+	    return meslist->str;
+	  }
+      }
+  }
+  zlog_err("message index %d not found (max is %d)", index, max);
+  return NULL;
 }
 
 /* Wrapper around strerror to handle case where it returns NULL. */