/* Standard argp argument parsers for tools using libdwfl.
   Copyright (C) 2005 Red Hat, Inc.

   This program is Open Source software; you can redistribute it and/or
   modify it under the terms of the Open Software License version 1.0 as
   published by the Open Source Initiative.

   You should have received a copy of the Open Software License along
   with this program; if not, you may obtain a copy of the Open Software
   License version 1.0 from http://www.opensource.org/licenses/osl.php or
   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
   3001 King Ranch Road, Ukiah, CA 95482.   */

#include "libdwflP.h"
#include <argp.h>
#include <stdlib.h>
#include <assert.h>
#include <libintl.h>

/* gettext helper macros.  */
#define _(Str) dgettext ("elfutils", Str)


#define OPT_DEBUGINFO 0x100

static const struct argp_option options[] =
{
  { NULL, 0, NULL, 0, N_("Input Selection:"), 0 },
  { "executable", 'e', "FILE", 0, N_("Find addresses in FILE"), 0 },
  { "pid", 'p', "PID", 0,
    N_("Find addresses in files mapped into process PID"), 0 },
  { "kernel", 'k', NULL, 0, N_("Find addresses in the running kernel"), 0 },
  { "debuginfo-path", OPT_DEBUGINFO, "PATH", 0,
    N_("Search path for separate debuginfo files"), 0 },
  { NULL, 0, NULL, 0, NULL, 0 }
};

static char *debuginfo_path;

static const Dwfl_Callbacks proc_callbacks =
  {
    .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
    .debuginfo_path = &debuginfo_path,

    .find_elf = INTUSE(dwfl_linux_proc_find_elf),
  };

static const Dwfl_Callbacks kernel_callbacks =
  {
    .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
    .debuginfo_path = &debuginfo_path,

    .find_elf = INTUSE(dwfl_linux_kernel_find_elf),
    .section_address = INTUSE(dwfl_linux_kernel_module_section_address),
  };

static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
  inline void failure (int errnum, const char *msg)
    {
      if (errnum == -1)
	argp_failure (state, EXIT_FAILURE, 0, "%s: %s",
		      msg, INTUSE(dwfl_errmsg) (-1));
      else
	argp_failure (state, EXIT_FAILURE, errnum, "%s", msg);
    }
  inline error_t fail (int errnum, const char *msg)
    {
      failure (errnum, msg);
      return errnum == -1 ? EIO : errnum;
    }

  switch (key)
    {
    case OPT_DEBUGINFO:
      debuginfo_path = arg;
      break;

    case 'e':
      if (state->hook == NULL)
	{
	  Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
	  if (INTUSE(dwfl_report_elf) (dwfl, "", arg, -1, 0) == NULL)
	    return fail (-1, arg);
	  state->hook = dwfl;
	}
      else
	{
	toomany:
	  argp_error (state, "%s", _("only one -e, -p, or -k option allowed"));
	  return EINVAL;
	}
      break;

    case 'p':
      if (state->hook == NULL)
	{
	  Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
	  int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg));
	  if (result != 0)
	    return fail (result, arg);
	  state->hook = dwfl;
	}
      else
	goto toomany;
      break;

    case 'k':
      if (state->hook == NULL)
	{
	  Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks);
	  int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl);
	  if (result != 0)
	    return fail (result, _("cannot load kernel symbols"));
	  result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl);
	  if (result != 0)
	    /* Non-fatal to have no modules since we do have the kernel.  */
	    failure (result, _("cannot find kernel modules"));
	  state->hook = dwfl;
	}
      else
	goto toomany;
      break;

    case ARGP_KEY_SUCCESS:
      {
	Dwfl *dwfl = state->hook;

	if (dwfl == NULL)
	  {
	    /* Default if no -e, -p, or -k, is "-e a.out".  */
	    arg = "a.out";
	    dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
	    if (INTUSE(dwfl_report_elf) (dwfl, "", arg, -1, 0) == NULL)
	      return fail (-1, arg);
	    state->hook = dwfl;
	  }

	/* One of the three flavors has done dwfl_begin and some reporting
	   if we got here.  Tie up the Dwfl and return it to the caller of
	   argp_parse.  */

	int result = INTUSE(dwfl_report_end) (dwfl, NULL, NULL);
	assert (result == 0);

	*(Dwfl **) state->input = dwfl;
      }
      break;

    default:
      return ARGP_ERR_UNKNOWN;
    }
  return 0;
}

static const struct argp libdwfl_argp =
  { .options = options, .parser = parse_opt };

const struct argp *
dwfl_standard_argp (void)
{
  return &libdwfl_argp;
}
