/* Labelled ranges of type IDs.
   Copyright (C) 2019-2020 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>

static int
extract_label_info (ctf_file_t *fp, const ctf_lblent_t **ctl,
		    uint32_t *num_labels)
{
  const ctf_header_t *h;

  h = (const ctf_header_t *) fp->ctf_data.cts_data;

  *ctl = (const ctf_lblent_t *) (fp->ctf_buf + h->cth_lbloff);
  *num_labels = (h->cth_objtoff - h->cth_lbloff) / sizeof (ctf_lblent_t);

  return 0;
}

/* Returns the topmost label, or NULL if any errors are encountered.  */

const char *
ctf_label_topmost (ctf_file_t *fp)
{
  const ctf_lblent_t *ctlp = NULL;
  const char *s;
  uint32_t num_labels = 0;

  if (extract_label_info (fp, &ctlp, &num_labels) < 0)
    return NULL;				/* errno is set for us.  */

  if (num_labels == 0)
    {
      (void) ctf_set_errno (fp, ECTF_NOLABELDATA);
      return NULL;
    }

  if ((s = ctf_strraw (fp, (ctlp + num_labels - 1)->ctl_label)) == NULL)
    (void) ctf_set_errno (fp, ECTF_CORRUPT);

  return s;
}

/* Iterate over all labels.  We pass the label string and the lblinfo_t struct
   to the specified callback function.  */
int
ctf_label_iter (ctf_file_t *fp, ctf_label_f *func, void *arg)
{
  const ctf_lblent_t *ctlp = NULL;
  uint32_t i;
  uint32_t num_labels = 0;
  ctf_lblinfo_t linfo;
  const char *lname;
  int rc;

  if (extract_label_info (fp, &ctlp, &num_labels) < 0)
    return -1;			/* errno is set for us.  */

  if (num_labels == 0)
    return (ctf_set_errno (fp, ECTF_NOLABELDATA));

  for (i = 0; i < num_labels; i++, ctlp++)
    {
      if ((lname = ctf_strraw (fp, ctlp->ctl_label)) == NULL)
	{
	  ctf_dprintf ("failed to decode label %u with "
		       "type %u\n", ctlp->ctl_label, ctlp->ctl_type);
	  return (ctf_set_errno (fp, ECTF_CORRUPT));
	}

      linfo.ctb_type = ctlp->ctl_type;
      if ((rc = func (lname, &linfo, arg)) != 0)
	return rc;
    }

  return 0;
}

typedef struct linfo_cb_arg
{
  const char *lca_name;		/* Label we want to retrieve info for.  */
  ctf_lblinfo_t *lca_info;	/* Where to store the info about the label.  */
} linfo_cb_arg_t;

static int
label_info_cb (const char *lname, const ctf_lblinfo_t *linfo, void *arg)
{
  /* If lname matches the label we are looking for, copy the
    lblinfo_t struct for the caller.  */

  if (strcmp (lname, ((linfo_cb_arg_t *) arg)->lca_name) == 0)
    {
      /* * Allow caller not to allocate storage to test if label exists.  */

      if (((linfo_cb_arg_t *) arg)->lca_info != NULL)
	memcpy (((linfo_cb_arg_t *) arg)->lca_info, linfo,
	       sizeof (ctf_lblinfo_t));
      return 1;		/* Indicate we found a match.  */
    }

  return 0;
}

/* Retrieve information about the label with name "lname". */
int
ctf_label_info (ctf_file_t *fp, const char *lname, ctf_lblinfo_t *linfo)
{
  linfo_cb_arg_t cb_arg;
  int rc;

  cb_arg.lca_name = lname;
  cb_arg.lca_info = linfo;

  if ((rc = ctf_label_iter (fp, label_info_cb, &cb_arg)) < 0)
    return rc;

  if (rc != 1)
    return (ctf_set_errno (fp, ECTF_NOLABEL));

  return 0;
}
