/* Textual dumping of CTF data.
   Copyright (C) 2019-2024 Free Software Foundation, Inc.

   This file is part of libctf.

   libctf 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, 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; see the file COPYING.  If not see
   <http://www.gnu.org/licenses/>.  */

#include <ctf-impl.h>
#include <string.h>

#define str_append(s, a) ctf_str_append_noerr (s, a)

/* One item to be dumped, in string form.  */

typedef struct ctf_dump_item
{
  ctf_list_t cdi_list;
  char *cdi_item;
} ctf_dump_item_t;

/* Cross-call state for dumping.  Basically just enough to track the section in
   use and a list of return strings.  */

struct ctf_dump_state
{
  ctf_sect_names_t cds_sect;
  ctf_dict_t *cds_fp;
  ctf_dump_item_t *cds_current;
  ctf_list_t cds_items;
};

/* Cross-call state for ctf_dump_member. */

typedef struct ctf_dump_membstate
{
  char **cdm_str;
  ctf_dict_t *cdm_fp;
  const char *cdm_toplevel_indent;
} ctf_dump_membstate_t;

static int
ctf_dump_append (ctf_dump_state_t *state, char *str)
{
  ctf_dump_item_t *cdi;

  if ((cdi = malloc (sizeof (struct ctf_dump_item))) == NULL)
    return (ctf_set_errno (state->cds_fp, ENOMEM));

  cdi->cdi_item = str;
  ctf_list_append (&state->cds_items, cdi);
  return 0;
}

static void
ctf_dump_free (ctf_dump_state_t *state)
{
  ctf_dump_item_t *cdi, *next_cdi;

  if (state == NULL)
    return;

  for (cdi = ctf_list_next (&state->cds_items); cdi != NULL;
       cdi = next_cdi)
    {
      free (cdi->cdi_item);
      next_cdi = ctf_list_next (cdi);
      free (cdi);
    }
}

/* Return a dump for a single type, without member info: but do optionally show
   the type's references.  */

#define CTF_FT_REFS     0x2 	/* Print referenced types.  */
#define CTF_FT_BITFIELD 0x4	/* Print :BITS if a bitfield.  */
#define CTF_FT_ID       0x8	/* Print "ID: " in front of type IDs.  */

static char *
ctf_dump_format_type (ctf_dict_t *fp, ctf_id_t id, int flag)
{
  ctf_id_t new_id;
  char *str = NULL, *bit = NULL, *buf = NULL;

  ctf_set_errno (fp, 0);
  new_id = id;
  do
    {
      ctf_encoding_t ep;
      ctf_arinfo_t ar;
      int kind, unsliced_kind;
      ssize_t size, align;
      const char *nonroot_leader = "";
      const char *nonroot_trailer = "";
      const char *idstr = "";

      id = new_id;
      if (flag == CTF_ADD_NONROOT)
	{
	  nonroot_leader = "{";
	  nonroot_trailer = "}";
	}

      buf = ctf_type_aname (fp, id);
      if (!buf)
	{
	  if (id == 0 || ctf_errno (fp) == ECTF_NONREPRESENTABLE)
	    {
	      ctf_set_errno (fp, ECTF_NONREPRESENTABLE);
	      str = str_append (str, " (type not represented in CTF)");
	      return str;
	    }

	  goto err;
	}

      if (flag & CTF_FT_ID)
	idstr = "ID ";
      if (asprintf (&bit, "%s%s0x%lx: (kind %i) ", nonroot_leader, idstr,
		    id, ctf_type_kind (fp, id)) < 0)
	goto oom;
      str = str_append (str, bit);
      free (bit);
      bit = NULL;

      if (buf[0] != '\0')
	str = str_append (str, buf);

      free (buf);
      buf = NULL;

      unsliced_kind = ctf_type_kind_unsliced (fp, id);
      kind = ctf_type_kind (fp, id);

      /* Report encodings of everything with an encoding other than enums:
	 base-type enums cannot have a nonzero cte_offset or cte_bits value.
	 (Slices of them can, but they are of kind CTF_K_SLICE.)  */
      if (unsliced_kind != CTF_K_ENUM && ctf_type_encoding (fp, id, &ep) == 0)
	{
	  if ((ssize_t) ep.cte_bits != ctf_type_size (fp, id) * CHAR_BIT
	      && flag & CTF_FT_BITFIELD)
	    {
	      if (asprintf (&bit, ":%i", ep.cte_bits) < 0)
		goto oom;
	      str = str_append (str, bit);
	      free (bit);
	      bit = NULL;
	    }

	  if ((ssize_t) ep.cte_bits != ctf_type_size (fp, id) * CHAR_BIT
	      || ep.cte_offset != 0)
	    {
	      const char *slice = "";

	      if (unsliced_kind == CTF_K_SLICE)
		slice = "slice ";

	      if (asprintf (&bit, " [%s0x%x:0x%x]",
			    slice, ep.cte_offset, ep.cte_bits) < 0)
		goto oom;
	      str = str_append (str, bit);
	      free (bit);
	      bit = NULL;
	    }

	  if (asprintf (&bit, " (format 0x%x)", ep.cte_format) < 0)
	    goto oom;
	  str = str_append (str, bit);
	  free (bit);
	  bit = NULL;
	}

      size = ctf_type_size (fp, id);
      if (kind != CTF_K_FUNCTION && size >= 0)
	{
	  if (asprintf (&bit, " (size 0x%lx)", (unsigned long int) size) < 0)
	    goto oom;

	  str = str_append (str, bit);
	  free (bit);
	  bit = NULL;
	}

      align = ctf_type_align (fp, id);
      if (align >= 0)
	{
	  if (asprintf (&bit, " (aligned at 0x%lx)",
			(unsigned long int) align) < 0)
	    goto oom;

	  str = str_append (str, bit);
	  free (bit);
	  bit = NULL;
	}

      if (nonroot_trailer[0] != 0)
	str = str_append (str, nonroot_trailer);

      /* Just exit after one iteration if we are not showing the types this type
	 references.  */
      if (!(flag & CTF_FT_REFS))
	return str;

      /* Keep going as long as this type references another.  We consider arrays
	 to "reference" their element type. */

      if (kind == CTF_K_ARRAY)
	{
	  if (ctf_array_info (fp, id, &ar) < 0)
	    goto err;
	  new_id = ar.ctr_contents;
	}
      else
	new_id = ctf_type_reference (fp, id);
      if (new_id != CTF_ERR)
	str = str_append (str, " -> ");
    }
  while (new_id != CTF_ERR);

  if (ctf_errno (fp) != ECTF_NOTREF)
    {
      free (str);
      return NULL;
    }

  return str;

 oom:
  ctf_set_errno (fp, errno);
 err:
  ctf_err_warn (fp, 1, ctf_errno (fp), _("cannot format name dumping type 0x%lx"),
		id);
  free (buf);
  free (str);
  free (bit);
  return NULL;
}

/* Dump one string field from the file header into the cds_items.  */
static int
ctf_dump_header_strfield (ctf_dict_t *fp, ctf_dump_state_t *state,
			  const char *name, uint32_t value)
{
  char *str;
  if (value)
    {
      if (asprintf (&str, "%s: %s\n", name, ctf_strptr (fp, value)) < 0)
	goto err;
      ctf_dump_append (state, str);
    }
  return 0;

 err:
  return (ctf_set_errno (fp, errno));
}

/* Dump one section-offset field from the file header into the cds_items.  */
static int
ctf_dump_header_sectfield (ctf_dict_t *fp, ctf_dump_state_t *state,
			   const char *sect, uint32_t off, uint32_t nextoff)
{
  char *str;
  if (nextoff - off)
    {
      if (asprintf (&str, "%s:\t0x%lx -- 0x%lx (0x%lx bytes)\n", sect,
		    (unsigned long) off, (unsigned long) (nextoff - 1),
		    (unsigned long) (nextoff - off)) < 0)
	goto err;
      ctf_dump_append (state, str);
    }
  return 0;

 err:
  return (ctf_set_errno (fp, errno));
}

/* Dump the file header into the cds_items.  */
static int
ctf_dump_header (ctf_dict_t *fp, ctf_dump_state_t *state)
{
  char *str;
  char *flagstr = NULL;
  const ctf_header_t *hp = fp->ctf_header;
  const char *vertab[] =
    {
     NULL, "CTF_VERSION_1",
     "CTF_VERSION_1_UPGRADED_3 (latest format, version 1 type "
     "boundaries)",
     "CTF_VERSION_2",
     "CTF_VERSION_3", NULL
    };
  const char *verstr = NULL;

  if (asprintf (&str, "Magic number: 0x%x\n", hp->cth_magic) < 0)
      goto err;
  ctf_dump_append (state, str);

  if (hp->cth_version <= CTF_VERSION)
    verstr = vertab[hp->cth_version];

  if (verstr == NULL)
    verstr = "(not a valid version)";

  if (asprintf (&str, "Version: %i (%s)\n", hp->cth_version,
		verstr) < 0)
    goto err;
  ctf_dump_append (state, str);

  /* Everything else is only printed if present.  */

  /* The flags are unusual in that they represent the ctf_dict_t *in memory*:
     flags representing compression, etc, are turned off as the file is
     decompressed.  So we store a copy of the flags before they are changed, for
     the dumper.  */

  if (fp->ctf_openflags > 0)
    {
      if (asprintf (&flagstr, "%s%s%s%s%s%s%s",
		    fp->ctf_openflags & CTF_F_COMPRESS
		    ? "CTF_F_COMPRESS": "",
		    (fp->ctf_openflags & CTF_F_COMPRESS)
		    && (fp->ctf_openflags & ~CTF_F_COMPRESS)
		    ? ", " : "",
		    fp->ctf_openflags & CTF_F_NEWFUNCINFO
		    ? "CTF_F_NEWFUNCINFO" : "",
		    (fp->ctf_openflags & (CTF_F_NEWFUNCINFO))
		    && (fp->ctf_openflags & ~(CTF_F_COMPRESS | CTF_F_NEWFUNCINFO))
		    ? ", " : "",
		    fp->ctf_openflags & CTF_F_IDXSORTED
		    ? "CTF_F_IDXSORTED" : "",
		    fp->ctf_openflags & (CTF_F_IDXSORTED)
		    && (fp->ctf_openflags & ~(CTF_F_COMPRESS | CTF_F_NEWFUNCINFO
					      | CTF_F_IDXSORTED))
		    ? ", " : "",
		    fp->ctf_openflags & CTF_F_DYNSTR
		    ? "CTF_F_DYNSTR" : "") < 0)
	goto err;

      if (asprintf (&str, "Flags: 0x%x (%s)", fp->ctf_openflags, flagstr) < 0)
	goto err;
      ctf_dump_append (state, str);
    }

  if (ctf_dump_header_strfield (fp, state, "Parent label",
				hp->cth_parlabel) < 0)
    goto err;

  if (ctf_dump_header_strfield (fp, state, "Parent name", hp->cth_parname) < 0)
    goto err;

  if (ctf_dump_header_strfield (fp, state, "Compilation unit name",
				hp->cth_cuname) < 0)
    goto err;

  if (ctf_dump_header_sectfield (fp, state, "Label section", hp->cth_lbloff,
				 hp->cth_objtoff) < 0)
    goto err;

  if (ctf_dump_header_sectfield (fp, state, "Data object section",
				 hp->cth_objtoff, hp->cth_funcoff) < 0)
    goto err;

  if (ctf_dump_header_sectfield (fp, state, "Function info section",
				 hp->cth_funcoff, hp->cth_objtidxoff) < 0)
    goto err;

  if (ctf_dump_header_sectfield (fp, state, "Object index section",
				 hp->cth_objtidxoff, hp->cth_funcidxoff) < 0)
    goto err;

  if (ctf_dump_header_sectfield (fp, state, "Function index section",
				 hp->cth_funcidxoff, hp->cth_varoff) < 0)
    goto err;

  if (ctf_dump_header_sectfield (fp, state, "Variable section",
				 hp->cth_varoff, hp->cth_typeoff) < 0)
    goto err;

  if (ctf_dump_header_sectfield (fp, state, "Type section",
				 hp->cth_typeoff, hp->cth_stroff) < 0)
    goto err;

  if (ctf_dump_header_sectfield (fp, state, "String section", hp->cth_stroff,
				 hp->cth_stroff + hp->cth_strlen + 1) < 0)
    goto err;

  return 0;
 err:
  free (flagstr);
  return (ctf_set_errno (fp, errno));
}

/* Dump a single label into the cds_items.  */

static int
ctf_dump_label (const char *name, const ctf_lblinfo_t *info,
		void *arg)
{
  char *str;
  char *typestr;
  ctf_dump_state_t *state = arg;

  if (asprintf (&str, "%s -> ", name) < 0)
    return (ctf_set_errno (state->cds_fp, errno));

  if ((typestr = ctf_dump_format_type (state->cds_fp, info->ctb_type,
				       CTF_ADD_ROOT | CTF_FT_REFS)) == NULL)
    {
      free (str);
      return 0;				/* Swallow the error.  */
    }

  str = str_append (str, typestr);
  free (typestr);

  ctf_dump_append (state, str);
  return 0;
}

/* Dump all the object or function entries into the cds_items.  */

static int
ctf_dump_objts (ctf_dict_t *fp, ctf_dump_state_t *state, int functions)
{
  const char *name;
  ctf_id_t id;
  ctf_next_t *i = NULL;
  char *str = NULL;

  if ((functions && fp->ctf_funcidx_names)
      || (!functions && fp->ctf_objtidx_names))
    str = str_append (str, _("Section is indexed.\n"));
  else if (fp->ctf_ext_symtab.cts_data == NULL)
    str = str_append (str, _("No symbol table.\n"));

  while ((id = ctf_symbol_next (fp, &i, &name, functions)) != CTF_ERR)
    {
      char *typestr = NULL;

      /* Emit the name, if we know it.  No trailing space: ctf_dump_format_type
	 has a leading one.   */
      if (name)
	{
	  if (asprintf (&str, "%s -> ", name) < 0)
	    goto oom;
	}
      else
	str = xstrdup ("");

      if ((typestr = ctf_dump_format_type (state->cds_fp, id,
					   CTF_ADD_ROOT | CTF_FT_REFS)) == NULL)
	{
	  ctf_dump_append (state, str);
	  continue;				/* Swallow the error.  */
	}

      str = str_append (str, typestr);
      free (typestr);
      ctf_dump_append (state, str);
      continue;

    oom:
      ctf_set_errno (fp, ENOMEM);
      ctf_next_destroy (i);
      return -1;
    }
  return 0;
}

/* Dump a single variable into the cds_items.  */
static int
ctf_dump_var (const char *name, ctf_id_t type, void *arg)
{
  char *str;
  char *typestr;
  ctf_dump_state_t *state = arg;

  if (asprintf (&str, "%s -> ", name) < 0)
    return (ctf_set_errno (state->cds_fp, errno));

  if ((typestr = ctf_dump_format_type (state->cds_fp, type,
				       CTF_ADD_ROOT | CTF_FT_REFS)) == NULL)
    {
      free (str);
      return 0;			/* Swallow the error.  */
    }

  str = str_append (str, typestr);
  free (typestr);

  ctf_dump_append (state, str);
  return 0;
}

/* Dump a single struct/union member into the string in the membstate.  */
static int
ctf_dump_member (const char *name, ctf_id_t id, unsigned long offset,
		 int depth, void *arg)
{
  ctf_dump_membstate_t *state = arg;
  char *typestr = NULL;
  char *bit = NULL;

  /* The struct/union itself has already been printed.  */
  if (depth == 0)
    return 0;

  if (asprintf (&bit, "%s%*s", state->cdm_toplevel_indent, (depth-1)*4, "") < 0)
    goto oom;
  *state->cdm_str = str_append (*state->cdm_str, bit);
  free (bit);

  if ((typestr = ctf_dump_format_type (state->cdm_fp, id,
				       CTF_ADD_ROOT | CTF_FT_BITFIELD
				       | CTF_FT_ID)) == NULL)
    return -1;				/* errno is set for us.  */

  if (asprintf (&bit, "[0x%lx] %s: %s\n", offset, name, typestr) < 0)
    goto oom;

  *state->cdm_str = str_append (*state->cdm_str, bit);
  free (typestr);
  free (bit);
  typestr = NULL;
  bit = NULL;

  return 0;

 oom:
  free (typestr);
  free (bit);
  return (ctf_set_errno (state->cdm_fp, errno));
}

/* Report the number of digits in the hexadecimal representation of a type
   ID.  */

static int
type_hex_digits (ctf_id_t id)
{
  int i = 0;

  if (id == 0)
    return 1;

  for (; id > 0; id >>= 4, i++);
  return i;
}

/* Dump a single type into the cds_items.  */
static int
ctf_dump_type (ctf_id_t id, int flag, void *arg)
{
  char *str;
  char *indent;
  ctf_dump_state_t *state = arg;
  ctf_dump_membstate_t membstate = { &str, state->cds_fp, NULL };

  /* Indent neatly.  */
  if (asprintf (&indent, "    %*s", type_hex_digits (id), "") < 0)
    return (ctf_set_errno (state->cds_fp, ENOMEM));

  /* Dump the type itself.  */
  if ((str = ctf_dump_format_type (state->cds_fp, id,
				   flag | CTF_FT_REFS)) == NULL)
    goto err;
  str = str_append (str, "\n");

  membstate.cdm_toplevel_indent = indent;

  /* Member dumping for structs, unions...  */
  if (ctf_type_kind (state->cds_fp, id) == CTF_K_STRUCT
      || ctf_type_kind (state->cds_fp, id) == CTF_K_UNION)
    {
      if ((ctf_type_visit (state->cds_fp, id, ctf_dump_member, &membstate)) < 0)
	{
	  if (id == 0 || ctf_errno (state->cds_fp) == ECTF_NONREPRESENTABLE)
	    {
	      ctf_dump_append (state, str);
	      return 0;
	    }
	  ctf_err_warn (state->cds_fp, 1, ctf_errno (state->cds_fp),
			_("cannot visit members dumping type 0x%lx"), id);
	  goto err;
	}
    }

  /* ... and enums, for which we dump the first and last few members and skip
     the ones in the middle.  */
  if (ctf_type_kind (state->cds_fp, id) == CTF_K_ENUM)
    {
      int enum_count = ctf_member_count (state->cds_fp, id);
      ctf_next_t *it = NULL;
      int i = 0;
      const char *enumerand;
      char *bit;
      int value;

      while ((enumerand = ctf_enum_next (state->cds_fp, id,
					 &it, &value)) != NULL)
	{
	  i++;
	  if ((i > 5) && (i < enum_count - 4))
	    continue;

	  str = str_append (str, indent);

	  if (asprintf (&bit, "%s: %i\n", enumerand, value) < 0)
	    {
	      ctf_next_destroy (it);
	      goto oom;
	    }
	  str = str_append (str, bit);
	  free (bit);

	  if ((i == 5) && (enum_count > 10))
	    {
	      str = str_append (str, indent);
	      str = str_append (str, "...\n");
	    }
	}
      if (ctf_errno (state->cds_fp) != ECTF_NEXT_END)
	{
	  ctf_err_warn (state->cds_fp, 1, ctf_errno (state->cds_fp),
			_("cannot visit enumerands dumping type 0x%lx"), id);
	  goto err;
	}
    }

  ctf_dump_append (state, str);
  free (indent);

  return 0;

 err:
  free (indent);
  free (str);

  /* Swallow the error: don't cause an error in one type to abort all
     type dumping.  */
  return 0;

 oom:
  free (indent);
  free (str);
  return ctf_set_errno (state->cds_fp, ENOMEM);
}

/* Dump the string table into the cds_items.  */

static int
ctf_dump_str (ctf_dict_t *fp, ctf_dump_state_t *state)
{
  const char *s = fp->ctf_str[CTF_STRTAB_0].cts_strs;

  for (; s < fp->ctf_str[CTF_STRTAB_0].cts_strs +
	 fp->ctf_str[CTF_STRTAB_0].cts_len;)
    {
      char *str;
      if (asprintf (&str, "0x%lx: %s",
		    (unsigned long) (s - fp->ctf_str[CTF_STRTAB_0].cts_strs),
		    s) < 0)
	return (ctf_set_errno (fp, errno));
      ctf_dump_append (state, str);
      s += strlen (s) + 1;
    }

  return 0;
}

/* Dump a particular section of a CTF file, in textual form.  Call with a
   pointer to a NULL STATE: each call emits a dynamically allocated string
   containing a description of one entity in the specified section, in order.
   Only the first call (with a NULL state) may vary SECT.  Once the CTF section
   has been entirely dumped, the call returns NULL and frees and annuls the
   STATE, ready for another section to be dumped.  The returned textual content
   may span multiple lines: between each call the FUNC is called with one
   textual line at a time, and should return a suitably decorated line (it can
   allocate a new one and return it if it likes).  */

char *
ctf_dump (ctf_dict_t *fp, ctf_dump_state_t **statep, ctf_sect_names_t sect,
	  ctf_dump_decorate_f *func, void *arg)
{
  char *str;
  char *line;
  ctf_dump_state_t *state = NULL;

  if (*statep == NULL)
    {
      /* Data collection.  Transforming a call-at-a-time iterator into a
	 return-at-a-time iterator in a language without call/cc is annoying. It
	 is easiest to simply collect everything at once and then return it bit
	 by bit.  The first call will take (much) longer than otherwise, but the
	 amortized time needed is the same.  */

      if ((*statep = malloc (sizeof (struct ctf_dump_state))) == NULL)
	{
	  ctf_set_errno (fp, ENOMEM);
	  goto end;
	}
      state = *statep;

      memset (state, 0, sizeof (struct ctf_dump_state));
      state->cds_fp = fp;
      state->cds_sect = sect;

      switch (sect)
	{
	case CTF_SECT_HEADER:
	  ctf_dump_header (fp, state);
	  break;
	case CTF_SECT_LABEL:
	  if (ctf_label_iter (fp, ctf_dump_label, state) < 0)
	    {
	      if (ctf_errno (fp) != ECTF_NOLABELDATA)
		goto end;		/* errno is set for us.  */
	      ctf_set_errno (fp, 0);
	    }
	  break;
	case CTF_SECT_OBJT:
	  if (ctf_dump_objts (fp, state, 0) < 0)
	    goto end;			/* errno is set for us.  */
	  break;
	case CTF_SECT_FUNC:
	  if (ctf_dump_objts (fp, state, 1) < 0)
	    goto end;			/* errno is set for us.  */
	  break;
	case CTF_SECT_VAR:
	  if (ctf_variable_iter (fp, ctf_dump_var, state) < 0)
	    goto end;			/* errno is set for us.  */
	  break;
	case CTF_SECT_TYPE:
	  if (ctf_type_iter_all (fp, ctf_dump_type, state) < 0)
	    goto end;			/* errno is set for us.  */
	  break;
	case CTF_SECT_STR:
	  ctf_dump_str (fp, state);
	  break;
	default:
	  ctf_set_errno (fp, ECTF_DUMPSECTUNKNOWN);
	  goto end;
	}
    }
  else
    {
      state = *statep;

      if (state->cds_sect != sect)
	{
	  ctf_set_errno (fp, ECTF_DUMPSECTCHANGED);
	  goto end;
	}
    }

  if (state->cds_current == NULL)
    state->cds_current = ctf_list_next (&state->cds_items);
  else
    state->cds_current = ctf_list_next (state->cds_current);

  if (state->cds_current == NULL)
    goto end;

  /* Hookery.  There is some extra complexity to preserve linefeeds within each
     item while removing linefeeds at the end.  */
  if (func)
    {
      size_t len;

      str = NULL;
      for (line = state->cds_current->cdi_item; line && *line; )
	{
	  char *nline = line;
	  char *ret;

	  nline = strchr (line, '\n');
	  if (nline)
	    nline[0] = '\0';

	  ret = func (sect, line, arg);
	  str = str_append (str, ret);
	  str = str_append (str, "\n");
	  if (ret != line)
	    free (ret);

	  if (nline)
	    {
	      nline[0] = '\n';
	      nline++;
	    }

	  line = nline;
	}

      len = strlen (str);

      if (str[len-1] == '\n')
	str[len-1] = '\0';
    }
  else
    {
      str = strdup (state->cds_current->cdi_item);
      if (!str)
	{
	  ctf_set_errno (fp, ENOMEM);
	  return str;
	}
    }

  ctf_set_errno (fp, 0);
  return str;

 end:
  ctf_dump_free (state);
  free (state);
  ctf_set_errno (fp, 0);
  *statep = NULL;
  return NULL;
}
