Use a stack of structures (instead of a simple array) to keep track of
authorAndrew Cagney <cagney@redhat.com>
Wed, 9 May 2001 00:23:23 +0000 (00:23 +0000)
committerAndrew Cagney <cagney@redhat.com>
Wed, 9 May 2001 00:23:23 +0000 (00:23 +0000)
the top list.

gdb/ChangeLog
gdb/ui-out.c
gdb/ui-out.h

index a315257..4067ea8 100644 (file)
@@ -1,3 +1,23 @@
+2001-05-07  Andrew Cagney  <ac131313@redhat.com>
+
+       * ui-out.h (list_begin_ftype, list_end_ftype): Rename argument
+       ``list_flag'' to ``depth''.
+       * ui-out.c (default_list_begin, default_list_end): Update.
+       (uo_list_begin, uo_list_end): Update.
+       (MAX_UI_OUT_LEVELS): Define.
+       (struct ui_out_level): Define.
+       (top-level): Include "gdb_assert.h".
+       (struct ui_out): Add fields ``level'' and ``levels''.  Delete
+       fields ``list_flag'' and ``field_count''.
+       (ui_out_new): Update.
+       (verify_field_proper_position): Update.
+       (current_level, push_level, pop_level): New functions.
+       (ui_out_list_begin): Use push_level.
+       (ui_out_list_end): Use pop_level.
+       (ui_out_field_int): Use current_level.
+       (ui_out_field_skip): Ditto.
+       (ui_out_field_fmt): Ditto.
+
 2001-05-08  Michael Snyder  <msnyder@redhat.com>
 
        * language.c (longest_local_hex_string_custom): Strlen test is 
index b6f9c7a..9fcabd4 100644 (file)
@@ -25,6 +25,7 @@
 #include "expression.h"                /* For language.h */
 #include "language.h"
 #include "ui-out.h"
+#include "gdb_assert.h"
 
 /* Convenience macro for allocting typesafe memory. */
 
@@ -42,6 +43,18 @@ struct ui_out_hdr
     struct ui_out_hdr *next;
   };
 
+/* Maintain a stack so that the info applicable to the inner most list
+   is always available.  Stack/nested level 0 is reserved for the
+   top-level result. */
+
+enum { MAX_UI_OUT_LEVELS = 5 };
+
+struct ui_out_level
+  {
+    /* Count each field; the first element is for non-list fields */
+    int field_count;
+  };
+
 /* The ui_out structure */
 /* Any change here requires a corresponding one in the initialization
    of the default uiout, which is statically initialized */
@@ -65,11 +78,9 @@ struct ui_out
     /* strinf identifying the table (as specified in the table_begin call) */
     char *table_id;
 
-    /* if on, a list is being generated.  The value is the level of nesting */
-    int list_flag;
-
-    /* we count each field; the first element is for non-list fields */
-    int field_count[5];
+    /* Sub structure tracking the table depth. */
+    int level;
+    struct ui_out_level levels[MAX_UI_OUT_LEVELS];
 
     /* points to the first header (if any) */
     struct ui_out_hdr *headerfirst;
@@ -82,6 +93,39 @@ struct ui_out
 
   };
 
+/* The current (inner most) level. */
+static struct ui_out_level *
+current_level (struct ui_out *uiout)
+{
+  return &uiout->levels[uiout->level];
+}
+
+/* Create a new level, of TYPE.  Return the new level's index. */
+static int
+push_level (struct ui_out *uiout,
+           const char *id)
+{
+  struct ui_out_level *current;
+  /* We had better not overflow the buffer. */
+  uiout->level++;
+  gdb_assert (uiout->level > 0 && uiout->level < MAX_UI_OUT_LEVELS);
+  current = current_level (uiout);
+  current->field_count = 0;
+  return uiout->level;
+}
+
+/* Discard the current level, return the discarded level's index.
+   TYPE is the type of the level being discarded. */
+static int
+pop_level (struct ui_out *uiout)
+{
+  /* We had better not underflow the buffer. */
+  gdb_assert (uiout->level > 0 && uiout->level < MAX_UI_OUT_LEVELS);
+  uiout->level--;
+  return uiout->level + 1;
+}
+
+
 /* These are the default implementation functions */
 
 static void default_table_begin (struct ui_out *uiout, int nbrofcols,
@@ -90,9 +134,9 @@ static void default_table_body (struct ui_out *uiout);
 static void default_table_end (struct ui_out *uiout);
 static void default_table_header (struct ui_out *uiout, int width,
                                  enum ui_align alig, char *colhdr);
-static void default_list_begin (struct ui_out *uiout, int list_flag,
+static void default_list_begin (struct ui_out *uiout, int level,
                                char *lstid);
-static void default_list_end (struct ui_out *uiout, int list_flag);
+static void default_list_end (struct ui_out *uiout, int level);
 static void default_field_int (struct ui_out *uiout, int fldno, int width,
                               enum ui_align alig, char *fldname, int value);
 static void default_field_skip (struct ui_out *uiout, int fldno, int width,
@@ -152,8 +196,8 @@ static void uo_table_body (struct ui_out *uiout);
 static void uo_table_end (struct ui_out *uiout);
 static void uo_table_header (struct ui_out *uiout, int width,
                             enum ui_align align, char *colhdr);
-static void uo_list_begin (struct ui_out *uiout, int list_flag, char *lstid);
-static void uo_list_end (struct ui_out *uiout, int list_flag);
+static void uo_list_begin (struct ui_out *uiout, int level, char *lstid);
+static void uo_list_end (struct ui_out *uiout, int level);
 static void uo_field_int (struct ui_out *uiout, int fldno, int width,
                          enum ui_align align, char *fldname, int value);
 static void uo_field_skip (struct ui_out *uiout, int fldno, int width,
@@ -261,33 +305,22 @@ and before table_body.");
 void
 ui_out_list_begin (struct ui_out *uiout, char *lstid)
 {
+  int new_level;
   if (uiout->table_flag && !uiout->body_flag)
     internal_error (__FILE__, __LINE__,
                    "table header or table_body expected; lists must be \
 specified after table_body.");
-  if (uiout->list_flag >= 4)
-    internal_error (__FILE__, __LINE__,
-                   "list depth exceeded; only 4 levels of lists can be \
-nested.");
-
-  uiout->list_flag++;
-  uiout->field_count[uiout->list_flag] = 0;
-  if (uiout->table_flag && (uiout->list_flag == 1))
+  new_level = push_level (uiout, lstid);
+  if (uiout->table_flag && (new_level == 1))
     uiout->headercurr = uiout->headerfirst;
-
-  uo_list_begin (uiout, uiout->list_flag, lstid);
+  uo_list_begin (uiout, new_level, lstid);
 }
 
 void
 ui_out_list_end (struct ui_out *uiout)
 {
-  if (!uiout->list_flag)
-    internal_error (__FILE__, __LINE__,
-                   "misplaced list_end; there is no list to be closed.");
-
-  uo_list_end (uiout, uiout->list_flag);
-
-  uiout->list_flag--;
+  int old_level = pop_level (uiout);
+  uo_list_end (uiout, old_level);
 }
 
 static void
@@ -308,11 +341,12 @@ ui_out_field_int (struct ui_out *uiout, char *fldname, int value)
   int fldno;
   int width;
   int align;
+  struct ui_out_level *current = current_level (uiout);
 
   verify_field_proper_position (uiout);
 
-  uiout->field_count[uiout->list_flag] += 1;
-  fldno = uiout->field_count[uiout->list_flag];
+  current->field_count += 1;
+  fldno = current->field_count;
 
   verify_field_alignment (uiout, fldno, &width, &align);
 
@@ -353,11 +387,12 @@ ui_out_field_skip (struct ui_out *uiout, char *fldname)
   int fldno;
   int width;
   int align;
+  struct ui_out_level *current = current_level (uiout);
 
   verify_field_proper_position (uiout);
 
-  uiout->field_count[uiout->list_flag] += 1;
-  fldno = uiout->field_count[uiout->list_flag];
+  current->field_count += 1;
+  fldno = current->field_count;
 
   verify_field_alignment (uiout, fldno, &width, &align);
 
@@ -372,11 +407,12 @@ ui_out_field_string (struct ui_out *uiout,
   int fldno;
   int width;
   int align;
+  struct ui_out_level *current = current_level (uiout);
 
   verify_field_proper_position (uiout);
 
-  uiout->field_count[uiout->list_flag] += 1;
-  fldno = uiout->field_count[uiout->list_flag];
+  current->field_count += 1;
+  fldno = current->field_count;
 
   verify_field_alignment (uiout, fldno, &width, &align);
 
@@ -391,11 +427,12 @@ ui_out_field_fmt (struct ui_out *uiout, char *fldname, char *format,...)
   int fldno;
   int width;
   int align;
+  struct ui_out_level *current = current_level (uiout);
 
   verify_field_proper_position (uiout);
 
-  uiout->field_count[uiout->list_flag] += 1;
-  fldno = uiout->field_count[uiout->list_flag];
+  current->field_count += 1;
+  fldno = current->field_count;
 
   /* will not align, but has to call anyway */
   verify_field_alignment (uiout, fldno, &width, &align);
@@ -592,12 +629,12 @@ default_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
 }
 
 static void
-default_list_begin (struct ui_out *uiout, int list_flag, char *lstid)
+default_list_begin (struct ui_out *uiout, int level, char *lstid)
 {
 }
 
 static void
-default_list_end (struct ui_out *uiout, int list_flag)
+default_list_end (struct ui_out *uiout, int level)
 {
 }
 
@@ -691,19 +728,19 @@ uo_table_header (struct ui_out *uiout, int width, enum ui_align align, char *col
 }
 
 void
-uo_list_begin (struct ui_out *uiout, int list_flag, char *lstid)
+uo_list_begin (struct ui_out *uiout, int level, char *lstid)
 {
   if (!uiout->impl->list_begin)
     return;
-  uiout->impl->list_begin (uiout, list_flag, lstid);
+  uiout->impl->list_begin (uiout, level, lstid);
 }
 
 void
-uo_list_end (struct ui_out *uiout, int list_flag)
+uo_list_end (struct ui_out *uiout, int level)
 {
   if (!uiout->impl->list_end)
     return;
-  uiout->impl->list_end (uiout, list_flag);
+  uiout->impl->list_end (uiout, level);
 }
 
 void
@@ -862,7 +899,7 @@ verify_field_proper_position (struct ui_out *uiout)
        internal_error (__FILE__, __LINE__,
                        "table_body missing; table fields must be \
 specified after table_body and inside a list.");
-      if (!uiout->list_flag)
+      if (uiout->level == 0)
        internal_error (__FILE__, __LINE__,
                        "list_begin missing; table fields must be \
 specified after table_body and inside a list.");
@@ -922,8 +959,8 @@ ui_out_new (struct ui_out_impl *impl,
   uiout->flags = flags;
   uiout->table_flag = 0;
   uiout->body_flag = 0;
-  uiout->list_flag = 0;
-  uiout->field_count[0] = 0;
+  uiout->level = 0;
+  memset (uiout->levels, 0, sizeof (uiout->levels));
   uiout->headerfirst = NULL;
   uiout->headerlast = NULL;
   uiout->headercurr = NULL;
index a7be1ed..33c3308 100644 (file)
@@ -162,9 +162,11 @@ typedef void (table_body_ftype) (struct ui_out * uiout);
 typedef void (table_end_ftype) (struct ui_out * uiout);
 typedef void (table_header_ftype) (struct ui_out * uiout, int width,
                                   enum ui_align align, char *colhdr);
+/* Note: level 0 is the top-level so LEVEL is always greater than
+   zero. */
 typedef void (list_begin_ftype) (struct ui_out * uiout,
-                                int list_flag, char *lstid);
-typedef void (list_end_ftype) (struct ui_out * uiout, int list_flag);
+                                int level, char *lstid);
+typedef void (list_end_ftype) (struct ui_out * uiout, int level);
 typedef void (field_int_ftype) (struct ui_out * uiout, int fldno, int width,
                             enum ui_align align, char *fldname, int value);
 typedef void (field_skip_ftype) (struct ui_out * uiout, int fldno, int width,