/* This testcase is part of GDB, the GNU debugger.

   Copyright 2019 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see  <http://www.gnu.org/licenses/>.  */

#include <stdlib.h>
#include <string.h>

#define FIXED_MAP_SIZE 10

struct key_t
{
  int a;
  int b;
};

struct value_t
{
  int x;
  int y;
  int z;
};

struct map_t
{
  const char *name;
  int length;
  struct key_t *keys;
  struct value_t *values;

  /* This field is used only by the pretty printer.  */
  int show_header;
};

struct map_map_t
{
  int length;
  struct map_t **values;

  /* This field is used only by the pretty printer.  */
  int show_header;
};

struct map_t *
create_map (const char *name)
{
  struct map_t *m = malloc (sizeof (struct map_t));
  m->name = strdup (name);
  m->length = 0;
  m->keys = NULL;
  m->values = NULL;
  m->show_header = 0;
}

void
add_map_element (struct map_t *m, struct key_t k, struct value_t v)
{
  if (m->length == 0)
    {
      m->keys = malloc (sizeof (struct key_t) * FIXED_MAP_SIZE);
      m->values = malloc (sizeof (struct value_t) * FIXED_MAP_SIZE);
    }

  m->keys[m->length] = k;
  m->values[m->length] = v;
  m->length++;
}

struct map_map_t *
create_map_map (void)
{
  struct map_map_t *mm = malloc (sizeof (struct map_map_t));
  mm->length = 0;
  mm->values = NULL;
  mm->show_header = 0;
}

void
add_map_map_element (struct map_map_t *mm, struct map_t *map)
{
  if (mm->length == 0)
    mm->values = malloc (sizeof (struct map_t *) * FIXED_MAP_SIZE);

  mm->values[mm->length] = map;
  mm->length++;
}

int
main (void)
{
  struct map_t *m1 = create_map ("m1");
  struct key_t k1 = {3, 4};
  struct key_t k2 = {4, 5};
  struct key_t k3 = {5, 6};
  struct key_t k4 = {6, 7};
  struct key_t k5 = {7, 8};
  struct key_t k6 = {8, 9};
  struct value_t v1 = {0, 1, 2};
  struct value_t v2 = {3, 4, 5};
  struct value_t v3 = {6, 7, 8};
  struct value_t v4 = {9, 0, 1};
  struct value_t v5 = {2, 3, 4};
  struct value_t v6 = {5, 6, 7};
  add_map_element (m1, k1, v1);
  add_map_element (m1, k2, v2);
  add_map_element (m1, k3, v3);

  struct map_t *m2 = create_map ("m2");
  add_map_element (m2, k4, v4);
  add_map_element (m2, k5, v5);
  add_map_element (m2, k6, v6);

  struct map_map_t *mm = create_map_map ();
  add_map_map_element (mm, m1);
  add_map_map_element (mm, m2);

  return 0; /* Break here.  */
}
