/* Copyright (C) 2021-2025 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   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, 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, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <unistd.h>     // isatty
#include <errno.h>

#include "gp-print.h"
#include "ipcio.h"
#include "Command.h"
#include "Dbe.h"
#include "DbeApplication.h"
#include "DbeSession.h"
#include "Experiment.h"
#include "Emsg.h"
#include "DbeView.h"
#include "DataObject.h"
#include "Function.h"
#include "Hist_data.h"
#include "PathTree.h"
#include "LoadObject.h"
#include "Function.h"
#include "FilterSet.h"
#include "Filter.h"
#include "MetricList.h"
#include "MemorySpace.h"
#include "Module.h"
#include "util.h"
#include "i18n.h"
#include "StringBuilder.h"
#include "debug.h"
#include "UserLabel.h"

static char *exe_name;
static char **new_argv;

void
reexec ()
{
  if (dbeSession != NULL)
    dbeSession->unlink_tmp_files ();
  execvp (exe_name, new_argv);
  fprintf (stderr, GTXT ("Error: reexec() failed (%d: %s)\n"), errno,
	   STR(strerror (errno)));
  fflush (stderr);
  exit (1);
}

/**
 * Run application under enhance if the following requirements are satisfied:
 * 1. Environment variable GPROFNG_ENHANCE is not set to "no"
 * 2. Standard input is terminal
 * 3. Standard output is terminal
 * 4. /bin/enhance exists and can work on this system
 */
static void
reexec_enhance (int argc, char *argv[])
{
  char *gp_enhance = getenv ("GPROFNG_ENHANCE");
  if (NULL != gp_enhance && 0 == strcasecmp (gp_enhance, "no"))
    return; // Do not enhance
  // Verify that input and output are tty
  if (!isatty (fileno (stdin)))     // stdin is not a terminal
    return; // Do not enhance
  if (!isatty (fileno (stdout)))    // stdout is not a terminal
    return; // Do not enhance
  char *enhance_name = NTXT ("/bin/enhance");
  struct stat sbuf;
  int res = stat (enhance_name, &sbuf); // Check if enhance exists
  if (res == 0)
    res = system (NTXT ("/bin/enhance /bin/true")); // Check if enhance can work
  if (res != 0)
    {
      fflush (stdout);
      printf (GTXT ("Warning: History and command editing is not supported on this system.\n"));
      fflush (stdout);
      return;
    }
  else
    {
      printf (GTXT ("Note: History and command editing is supported on this system.\n"));
      fflush (stdout);
    }
  char **nargv = new char*[argc + 2];
  for (int i = 0; i < argc; i++)
    nargv[i + 1] = argv[i];
  nargv[0] = enhance_name;
  nargv[argc + 1] = NULL;
  putenv (NTXT ("GPROFNG_ENHANCE=no")); // prevent recursion
  execv (enhance_name, nargv);
  // execv failed. Continue to run the program
  delete[] nargv;
}

int
main (int argc, char *argv[])
{
  xmalloc_set_program_name (argv[0]);
  er_print *erprint;
  int ind = 1;
  if (argc > ind && *argv[ind] == '-')
    {
      int arg_count, cparam;
      if (Command::get_command (argv[ind] + 1, arg_count, cparam) == WHOAMI)
	ind = ind + 1 + arg_count;
    }
  if (argc > ind && argv[ind] != NULL && *argv[ind] != '-')
    reexec_enhance (argc, argv);

  // Save argv for reexec())
  exe_name = argv[0];
  new_argv = argv;

  if (argc > ind && argv[ind] != NULL && strcmp (argv[ind], "-IPC") == 0)
    {
      putenv (NTXT ("LC_NUMERIC=C")); // Use non-localized numeric data in IPC packets
      erprint = new er_print (argc, argv);
      theDbeApplication->rdtMode = false;
      ipc_mainLoop (argc, argv);
    }
  else
    {
      erprint = new er_print (argc, argv);
      erprint->start (argc, argv);
    }

  dbeSession->unlink_tmp_files ();
  if (DUMP_CALL_STACK)
    {
      extern long total_calls_add_stack, total_stacks, total_nodes, call_stack_size[201];
      fprintf (stderr, NTXT ("total_calls_add_stack=%lld\ntotal_stacks=%lld\ntotal_nodes=%lld\n"),
	       (long long) total_calls_add_stack, (long long) total_stacks, (long long) total_nodes);
      for (int i = 0; i < 201; i++)
	if (call_stack_size[i] != 0)
	    fprintf (stderr, NTXT ("   call_stack_size[%d] = %6lld\n"), i,
		     (long long) call_stack_size[i]);
    }
#if defined(DEBUG)
  delete erprint;
#endif
  return 0;
}

er_print::er_print (int argc, char *argv[])
: DbeApplication (argc, argv)
{
  out_fname = GTXT ("<stdout>");
  inp_file = stdin;
  out_file = stdout;
  dis_file = stdout;
  cov_string = NULL;
  limit = 0;
  cstack = new Vector<Histable*>();
  was_QQUIT = false;
}

er_print::~er_print ()
{
  free (cov_string);
  delete cstack;
  if (inp_file != stdin)
    fclose (inp_file);
}

void
er_print::start (int argc, char *argv[])
{
  Vector<String> *res = theDbeApplication->initApplication (NULL, NULL, NULL);
  res->destroy ();
  delete res;

  // Create a view on the session
  dbevindex = dbeSession->createView (0, -1);
  dbev = dbeSession->getView (dbevindex);
  limit = dbev->get_limit ();
  (void) check_args (argc, argv);
  int ngood = dbeSession->ngoodexps ();
  if (ngood == 0)
    {
      fprintf (stderr, GTXT ("No valid experiments loaded; exiting\n"));
      return;
    }
  dbeDetectLoadMachineModel (dbevindex);
  run (argc, argv);
}

bool
er_print::free_memory_before_exit ()
{
  return was_QQUIT;
}

void
er_print::usage ()
{

/*
  Ruud - Isolate this line because it has an argument.  Otherwise it would be at the
  end of the long option list.
*/
  printf ( GTXT (
    "Usage: gprofng display text [OPTION(S)] [COMMAND(S)] [-script <script_file>] EXPERIMENT(S)\n"));

  printf ( GTXT (
    "\n"
    "Print a plain text version of the various displays supported by gprofng.\n"
    "\n"
    "Options:\n"
    "\n"
    " --version           print the version number and exit.\n"
    " --help              print usage information and exit.\n"
    " --verbose {on|off}  enable (on) or disable (off) verbose mode; the default is \"off\".\n"
    "\n"
    " -script <script-file>  execute the commands stored in the script file;\n"
    "                        this feature may be combined with commands specified\n"
    "                        at the command line.\n"
    "\n"
    "Commands:\n"
    "\n"
    "This tool supports a rich set of commands to control the display of the\n"
    "data; instead of, or in addition to, including these commands in a script\n"
    "file, it is also allowed to include such commands at the command line;\n"
    "in this case, the commands need to be prepended with the \"-\" symbol; the\n"
    "commands are processed and interpreted left from right, so the order matters;\n"
    "The gprofng manual documents the commands that are supported.\n"
    "\n"
    "If this tool is invoked without options, commands, or a script file, it starts\n"
    "in interpreter mode. The user can then issue the commands interactively; the\n"
    "session is terminated with the \"exit\" command in the interpreter.\n"
    "\n"
    "Documentation:\n"
    "\n"
    "A getting started guide for gprofng is maintained as a Texinfo manual. If the info and\n"
    "gprofng programs are properly installed at your site, the command \"info gprofng\"\n"
    "should give you access to this document.\n"
    "\n"
    "See also:\n"
    "\n"
    "gprofng(1), gprofng-archive(1), gprofng-collect-app(1), "
    "gprofng-display-html(1), gprofng-display-src(1)\n"
    "\nReport bugs to <https://sourceware.org/bugzilla/>\n"));
}

int // returns count of experiments read
er_print::check_args (int argc, char *argv[])
{
  CmdType cmd_type;
  int arg_count;
  int cparam;
  int exp_no;
  error_msg = NULL;

  Emsg *rcmsg = fetch_comments ();
  while (rcmsg != NULL)
    {
      fprintf (stderr, NTXT ("%s: %s\n"), prog_name, rcmsg->get_msg ());
      rcmsg = rcmsg->next;
    }
  delete_comments ();

  // Set up the list of experiments to add after checking the args
  Vector<Vector<char*>*> *exp_list = new Vector<Vector<char*>*>();

  // Prescan the command line arguments, processing only a few
  for (int i = 1; i < argc; i++)
    {
      if (*argv[i] != '-')
	{
	  // we're at the end -- get the list of experiments
	  //  Build the list of experiments, and set the searchpath
	  Vector<char*> *list = dbeSession->get_group_or_expt (argv[i]);
	  if (list->size () > 0)
	    {
	      for (int j = 0, list_sz = list->size (); j < list_sz; j++)
		{
		  char *path = list->fetch (j);
		  if (strlen (path) == 0 || strcmp (path, NTXT ("\\")) == 0)
		    continue;
		  char *p = strrchr (path, '/');
		  if (p)
		    {
		      // there's a directory in front of the name; add it to search path
		      *p = '\0';
		      dbeSession->set_search_path (path, false);
		    }
		}
	      list->destroy ();
	      list->append (dbe_strdup (argv[i]));
	      exp_list->append (list);
	    }
	  else
	    delete list;
	  continue;
	}

      // Not at the end yet, treat the next argument as a command
      switch (cmd_type = Command::get_command (argv[i] + 1, arg_count, cparam))
	{
	case WHOAMI:
	  whoami = argv[i] + 1 + cparam;
	  break;
	case HELP:
	  if (i + 1 + arg_count == argc)
	    {
	      usage();
	      exit (0);
	    }
	  break;
	case HHELP:
	  Command::print_help (whoami, true, false, stdout);
	  fprintf (stdout, "\n");
	  indxo_list (false, stdout);
	  fprintf (stdout, "\n");
	  mo_list (false, stdout);
	  if (!getenv ("_BUILDING_MANPAGE"))
	    fprintf (stdout, GTXT ("\nSee gprofng(1) for more details\n"));
	  exit (0);
	case ADD_EXP:
	case DROP_EXP:
	case OPEN_EXP:
	  printf (GTXT ("Error: command %s can not appear on the command line\n"), argv[i]);
	  exit (2);
	case VERSION_cmd:
	  Application::print_version_info ();
	  exit (0);
	case AMBIGUOUS_CMD:
	  fprintf (stderr, GTXT ("Error: Ambiguous command: %s\n"), argv[i]);
	  exit (2);
	case UNKNOWN_CMD:
	  fprintf (stderr, GTXT ("Error: Invalid command: %s\n"), argv[i]);
	  exit (2);
	  // it's a plausible argument; see if we process now or later
	case SOURCE:
	case DISASM:
	case CSINGLE:
	case CPREPEND:
	case CAPPEND:
	case FSINGLE:
	case SAMPLE_DETAIL:
	case STATISTICS:
	case HEADER:
	  //skip the arguments to that command
	  i += arg_count;
	  if (i >= argc || end_command (argv[i]))
	    i--;
	  break;
	case PRINTMODE:
	case INDXOBJDEF:
	case ADDPATH:
	case SETPATH:
	case PATHMAP:
	case OBJECT_SHOW:
	case OBJECT_HIDE:
	case OBJECT_API:
	case OBJECTS_DEFAULT:
	case EN_DESC:
	  // these are processed in the initial pass over the arguments
	  proc_cmd (cmd_type, cparam, (arg_count > 0) ? argv[i + 1] : NULL,
		    (arg_count > 1) ? argv[i + 2] : NULL,
		    (arg_count > 2) ? argv[i + 3] : NULL,
		    (arg_count > 3) ? argv[i + 4] : NULL);
	  i += arg_count;
	  break;
	default:
	  // any others, we skip for now
	  i += arg_count;
	  break;
	}
    }

  // Make sure some experiments were specified
  exp_no = exp_list->size ();
  if (exp_no == 0)
    { // no experiment name
      fprintf (stderr, GTXT ("%s: Missing experiment directory (use the --help option to get a usage overview)\n"), whoami);
      exit (1);
    }

  // add the experiments to the session
  char *errstr = dbeOpenExperimentList (0, exp_list, false);
  for (long i = 0; i < exp_list->size (); i++)
    {
      Vector<char*>* p = exp_list->get (i);
      Destroy (p);
    }
  delete exp_list;
  if (errstr != NULL)
    {
      fprintf (stderr, NTXT ("%s"), errstr);
      free (errstr);
    }

  return exp_no;
}

int
er_print::is_valid_seg_name (char *lo_name, int prev)
{
  // prev is the loadobject segment index that was last returned
  // search starts following that loadobject
  int index;
  LoadObject *lo;
  char *p_lo_name = lo_name;
  char *name = NULL;

  // strip angle brackets from all but <Unknown> and <Total>
  if (strcmp (lo_name, "<Unknown>") && strcmp (lo_name, "<Total>"))
    {
      if (*lo_name == '<')
	{
	  name = dbe_strdup (lo_name + 1);
	  p_lo_name = name;
	  char *p = strchr (name, '>');
	  if (p)
	    *p = '\0';
	}
    }

  // get the load object list from the session
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
  Vec_loop (LoadObject*, lobjs, index, lo)
  {
    if (prev > 0)
      {
	if (lo->seg_idx == prev)    // this is where we left off
	  prev = -1;
	continue;
      }

    // does this one match?
    if (cmp_seg_name (lo->get_pathname (), p_lo_name))
      {
	delete lobjs;
	free (name);
	size_t len = strlen (lo_name);
	if ((len > 7 && streq (lo_name + len - 7, NTXT (".class>"))) ||
	    (len > 6 && streq (lo_name + len - 6, NTXT (".class"))))
	  {
	    fprintf (stderr, GTXT ("Error: Java class `%s' is not selectable\n"), lo_name);
	    return -1;
	  }
	return lo->seg_idx;
      }
  }
  delete lobjs;
  free (name);
  return -1;
}

int
er_print::cmp_seg_name (char *full_name, char *lo_name)
{
  char *cmp_name;
  if (!strchr (lo_name, '/') && (cmp_name = strrchr (full_name, '/')))
    cmp_name++; // basename
  else
    cmp_name = full_name; // full path name
  return !strcmp (lo_name, cmp_name);
}

// processing object_select
//	Note that this does not affect the strings in Settings,
//	unlike object_show, object_hide, and object_api
int
er_print::process_object_select (char *names)
{
  int index;
  LoadObject *lo;
  int no_lobj = 0;
  bool got_err = false;
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
  if ((names == NULL) || !strcasecmp (names, Command::ALL_CMD))
    { // full coverage
      Vec_loop (LoadObject*, lobjs, index, lo)
      {
	dbev->set_lo_expand (lo->seg_idx, LIBEX_SHOW);
      }
    }
  else
    { // parsing coverage
      // first, hide functions from all loadobjects
      // except the java ones
      Vec_loop (LoadObject*, lobjs, index, lo)
      {
	char *lo_name = lo->get_name ();
	if (lo_name != NULL)
	  {
	    size_t len = strlen (lo_name);
	    if ((len > 7 && streq (lo_name + len - 7, NTXT (".class>"))) ||
		(len > 6 && streq (lo_name + len - 6, NTXT (".class"))))
	      continue;
	  }
	dbev->set_lo_expand (lo->seg_idx, LIBEX_HIDE);
      }

      Vector <char *> *tokens = split_str (names, ',');
      for (long j = 0, sz = VecSize (tokens); j < sz; j++)
	{
	  // loop over the provided names
	  char *lo_name = tokens->get (j);
	  int seg_idx = -1;
	  seg_idx = is_valid_seg_name (lo_name, seg_idx);
	  while (seg_idx != -1)
	    {
	      dbev->set_lo_expand (seg_idx, LIBEX_SHOW);
	      no_lobj++;
	      seg_idx = is_valid_seg_name (lo_name, seg_idx);
	    }
	  if (no_lobj == 0)
	    {
	      got_err = true;
	      fprintf (stderr, GTXT ("Error: Unknown load object: `%s'\n"), lo_name);
	    }
	  free (lo_name);
	}
      delete tokens;
    }

  if (!got_err)
    { // good coverage string
      free (cov_string);
      cov_string = xstrdup (names);
    }
  else
    { // bad, restore original coverage
      no_lobj = -1;
      process_object_select (cov_string);
    }
  delete lobjs;
  return no_lobj;
}

int
er_print::set_libexpand (char *cov, enum LibExpand expand)
{
  bool changed = dbev->set_libexpand (cov, expand);
  if (changed == true)
    dbev->update_lo_expands ();
  return 0;
}

int
er_print::set_libdefaults ()
{
  dbev->set_libdefaults ();
  return 0;
}

bool
er_print::end_command (char *cmd)
{
  if (cmd == NULL || *cmd == '-')
    return true;
  size_t len = strlen (cmd);
  if (cmd[len - 1] == '/')
    len--;
  if ((len > 3 && !strncmp (&cmd[len - 3], NTXT (".er"), 3)) ||
      (len > 4 && !strncmp (&cmd[len - 4], NTXT (".erg"), 4)))
    return true;
  return false;
}

// Now actually start processing the arguments
void
er_print::run (int argc, char *argv[])
{
  CmdType cmd_type;
  int arg_count, cparam, i;
  bool got = false;
  char *arg1, *arg2;
  for (i = 1; i < argc; i++)
    {
      if (*argv[i] != '-') // open experiment pointer files
	continue;
      switch (cmd_type = Command::get_command (argv[i] + 1, arg_count, cparam))
	{
	case WHOAMI:
	  whoami = argv[i] + 1 + cparam;
	  break;
	case SCRIPT:
	  got = true;
	  inp_file = fopen (argv[++i], "r");
	  if (inp_file == NULL)
	    {
	      fprintf (stderr, GTXT ("Error: Script file cannot be opened: %s\n"), argv[i]);
	      exit (3);
	    }
	  proc_script ();
	  break;
	case STDIN:
	  got = true;
	  inp_file = stdin;
	  proc_script ();
	  break;
	case SOURCE: // with option arg_count == 2
	case DISASM:
	  got = true;
	  i += arg_count;
	  if ((i >= argc) || end_command (argv[i]))
	    {
	      i--;
	      arg1 = argv[i];
	      arg2 = NTXT ("");
	    }
	  else
	    {
	      arg1 = argv[i - 1];
	      arg2 = argv[i];
	    }
	  proc_cmd (cmd_type, cparam, arg1, arg2, NULL, NULL, true);
	  break;
	case CSINGLE:
	case CPREPEND:
	case CAPPEND:
	case FSINGLE:
	  got = true;
	  i += arg_count;
	  if ((i >= argc) || end_command (argv[i]))
	    {
	      i--;
	      proc_cmd (cmd_type, cparam, argv[i], NTXT ("1"));
	    }
	  else
	    proc_cmd (cmd_type, cparam, argv[i - 1], argv[i]);
	  break;
	case SAMPLE_DETAIL: // with option arg_count == 1
	case STATISTICS:
	case HEADER:
	  got = true;
	  // now fall through to process the command
	case COMPARE:
	  got = true;
	  i += arg_count;
	  if ((i >= argc) || end_command (argv[i]))
	    {
	      i--;
	      proc_cmd (cmd_type, cparam, NULL, NULL);
	    }
	  else
	    proc_cmd (cmd_type, cparam, argv[i], NULL);
	  break;
	case PRINTMODE:
	case INDXOBJDEF:
	case ADDPATH:
	case SETPATH:
	case PATHMAP:
	case OBJECT_SHOW:
	case OBJECT_HIDE:
	case OBJECT_API:
	case OBJECTS_DEFAULT:
	case EN_DESC:
	  got = true;
	  // these have been processed already
	  i += arg_count;
	  break;
	case LIMIT:
	  got = true;
	  proc_cmd (cmd_type, cparam, (arg_count > 0) ? argv[i + 1] : NULL,
		    (arg_count > 1) ? argv[i + 2] : NULL);
	  i += arg_count;
	  break;
	default:
	  got = true;
	  proc_cmd (cmd_type, cparam, (arg_count > 0) ? argv[i + 1] : NULL,
		    (arg_count > 1) ? argv[i + 2] : NULL);
	  i += arg_count;
	  break;
	}
    }
  if (!got) // no command has been specified
    proc_script ();
}

#define MAXARGS 20

void
er_print::proc_script ()
{
  CmdType cmd_type;
  int arg_count, cparam;
  char *cmd, *end_cmd;
  char *script = NULL;
  char *arglist[MAXARGS];
  char *line = NULL;
  int lineno = 0;
  while (!feof (inp_file))
    {
      if (inp_file == stdin)
	printf (NTXT ("(%s) "), get_basename (prog_name));
      free (script);
      script = read_line (inp_file);
      if (script == NULL)
	continue;
      free (line);
      line = dbe_strdup (script);
      lineno++;
      for (int i = 0; i < MAXARGS; i++)
	arglist[i] = NULL;

      // ensure it's terminated by a \n, and remove that character
      strtok (script, NTXT ("\n"));

      // extract the command
      cmd = strtok (script, NTXT (" \t"));
      if (cmd == NULL)
	continue;
      if (*cmd == '#')
	{
	  fprintf (stderr, NTXT ("%s"), line);
	  continue;
	}
      if (*cmd == '\n')
	continue;

      char *remainder = strtok (NULL, NTXT ("\n"));
      // now extract the arguments
      int nargs = 0;
      for (;;)
	{
	  end_cmd = NULL;
	  if (nargs >= MAXARGS)
	    fprintf (stderr, GTXT ("Warning: more than %d arguments to %s command, line %d\n"),
		     MAXARGS, cmd, lineno);
	  char *nextarg = strtok (remainder, NTXT ("\n"));
	  if ((nextarg == NULL) || (*nextarg == '#'))
	    // either the end of the line, or a comment indicator
	    break;
	  if (nargs >= MAXARGS)
	    {
	      parse_qstring (nextarg, &end_cmd);
	      nargs++;
	    }
	  else
	    arglist[nargs++] = parse_qstring (nextarg, &end_cmd);
	  remainder = end_cmd;
	  if (remainder == NULL)
	    break;
	  // skip any blanks or tabs to get to next argument
	  while (*remainder == ' ' || *remainder == '\t')
	    remainder++;
	}

      cmd_type = Command::get_command (cmd, arg_count, cparam);

      // check for extra arguments
      if (cmd_type != UNKNOWN_CMD && cmd_type != INDXOBJDEF && nargs > arg_count)
	fprintf (stderr, GTXT ("Warning: extra arguments to %s command, line %d\n"),
		 cmd, lineno);
      switch (cmd_type)
	{
	case SOURCE:
	case DISASM:
	  // ignore any third parameter
	  // if there was, we have written a warning
	  proc_cmd (cmd_type, cparam, arglist[0], arglist[1], NULL, NULL,
		    (inp_file != stdin));
	  break;
	case QUIT:
	  free (script);
	  free (line);
	  exit (0);
	case QQUIT:
	  was_QQUIT = true;
	  free (script);
	  free (line);
	  return;
	case STDIN:
	  break;
	case COMMENT:
	  fprintf (dis_file, NTXT ("%s"), line);
	  break;
	case AMBIGUOUS_CMD:
	  fprintf (stderr, GTXT ("Error: Ambiguous command: %s\n"), cmd);
	  break;
	case UNKNOWN_CMD:
	  if (*cmd != '\n')
	    fprintf (stderr, GTXT ("Error: Invalid command: %s\n"), cmd);
	  break;
	default:
	  proc_cmd (cmd_type, cparam, arglist[0], arglist[1]);
	  break;
	}
    }
  // free up the input line
  free (script);
  free (line);
}

void
er_print::proc_cmd (CmdType cmd_type, int cparam,
		    char *arg1, char *arg2, char *arg3, char *arg4, bool xdefault)
{
  er_print_common_display *cd;
  FILE *ck_file, *save_file;
  char *name;
  int bgn_index, end_index, index;
  Cmd_status status;
  char *scratch, *scratch1;
  switch (cmd_type)
    {
    case FUNCS:
      print_func (Histable::FUNCTION, MODE_LIST,
		  dbev->get_metric_list (MET_NORMAL), dbev->get_metric_list (MET_NORMAL));
      break;
    case FDETAIL:
      print_func (Histable::FUNCTION, MODE_DETAIL,
		  dbev->get_metric_list (MET_NORMAL), dbev->get_metric_ref (MET_NORMAL));
      break;
    case FSINGLE:
      print_func (Histable::FUNCTION, MODE_DETAIL,
		  dbev->get_metric_list (MET_NORMAL), dbev->get_metric_ref (MET_NORMAL),
		  arg1, arg2);
      break;
    case HOTPCS:
      print_func (Histable::INSTR, MODE_LIST,
		  dbev->get_metric_list (MET_NORMAL), dbev->get_metric_list (MET_NORMAL));
      break;
    case PDETAIL:
      print_func (Histable::INSTR, MODE_DETAIL,
		  dbev->get_metric_list (MET_NORMAL), dbev->get_metric_ref (MET_NORMAL));
      break;
    case HOTLINES:
      print_func (Histable::LINE, MODE_LIST,
		  dbev->get_metric_list (MET_NORMAL), dbev->get_metric_list (MET_NORMAL));
      break;
    case LDETAIL:
      print_func (Histable::LINE, MODE_DETAIL,
		  dbev->get_metric_list (MET_NORMAL), dbev->get_metric_ref (MET_NORMAL));
      break;
    case OBJECTS:
      print_objects ();
      break;
    case OVERVIEW_NEW:
      print_overview ();
      break;
    case LOADOBJECT:
      print_segments ();
      break;
    case GPROF:
      print_func (Histable::FUNCTION, MODE_GPROF,
		  dbev->get_metric_list (MET_CALL), dbev->get_metric_list (MET_NORMAL));
      break;
    case CALLTREE:
      if (dbev->comparingExperiments ())
	{
	  fprintf (out_file, GTXT ("\nNot available when comparing experiments\n\n"));
	  break;
	}
      print_ctree (cmd_type);
      break;
    case CSINGLE:
    case CPREPEND:
    case CAPPEND:
    case CRMFIRST:
    case CRMLAST:
      print_gprof (cmd_type, arg1, arg2);
      break;
    case EXP_LIST:
      exp_list ();
      break;
    case DESCRIBE:
      describe ();
      break;
    case SCOMPCOM:
      status = dbev->proc_compcom (arg1, true, false);
      if (status != CMD_OK)
	fprintf (stderr, GTXT ("Error: %s: %s\n"), Command::get_err_string (status), arg1);
      break;
    case STHRESH:
      status = dbev->proc_thresh (arg1, true, false);
      if (status != CMD_OK)
	fprintf (stderr, GTXT ("Error: %s: %s\n"), Command::get_err_string (status), arg1);
      break;
    case DCOMPCOM:
      status = dbev->proc_compcom (arg1, false, false);
      if (status != CMD_OK)
	fprintf (stderr, GTXT ("Error: %s: %s\n"), Command::get_err_string (status), arg1);
      break;
    case COMPCOM:
      status = dbev->proc_compcom (arg1, true, false);
      if (status != CMD_OK)
	fprintf (stderr, GTXT ("Error: %s: %s\n"), Command::get_err_string (status), arg1);
      status = dbev->proc_compcom (arg1, false, false);
      if (status != CMD_OK)
	fprintf (stderr, GTXT ("Error: %s: %s\n"), Command::get_err_string (status), arg1);
      break;
    case DTHRESH:
      status = dbev->proc_thresh (arg1, false, false);
      if (status != CMD_OK)
	fprintf (stderr, GTXT ("Error: %s: %s\n"), Command::get_err_string (status), arg1);
      break;
    case SOURCE:
    case DISASM:
      {
	if (arg3 != NULL)
	  abort ();
	if (arg1 == NULL)
	  {
	    fprintf (stderr, GTXT ("Error: Invalid function/file setting: \n"));
	    break;
	  }
	char *fcontext = NULL;
	char *arg = parse_fname (arg1, &fcontext);
	if (arg == NULL)
	  {
	    fprintf (stderr, GTXT ("Error: Invalid function/file setting: %s\n"), arg1);
	    free (fcontext);
	    break;
	  }
	if (arg2 && (strlen (arg2) == 0))
	  arg2 = NULL;
	print_anno_file (arg, arg2, fcontext, cmd_type == DISASM,
			 dis_file, inp_file, out_file, dbev, xdefault);
	free (arg);
	free (fcontext);
	break;
      }
    case METRIC_LIST:
      proc_cmd (METRICS, cparam, NULL, NULL);
      dbev->get_metric_ref (MET_NORMAL)->print_metric_list (dis_file,
							    GTXT ("Available metrics:\n"), false);
      break;
    case METRICS:
      if (arg1)
	{
	  char *ret = dbev->setMetrics (arg1, false);
	  if (ret != NULL)
	    {
	      fprintf (stderr, GTXT ("Error: %s\n"), ret);
	      proc_cmd (METRIC_LIST, cparam, NULL, NULL);
	      break;
	    }
	}
      scratch = dbev->get_metric_list (MET_NORMAL)->get_metrics ();
      fprintf (dis_file, GTXT ("Current metrics: %s\n"), scratch);
      free (scratch);
      proc_cmd (SORT, cparam, NULL, NULL);
      break;
    case GMETRIC_LIST:
      scratch = dbev->get_metric_list (MET_CALL)->get_metrics ();
      fprintf (dis_file, GTXT ("Current caller-callee metrics: %s\n"), scratch);
      free (scratch);
      fprintf (dis_file, GTXT ("Current caller-callee sort Metric: %s\n"),
	       dbev->getSort (MET_DATA));
      break;
    case INDX_METRIC_LIST:
      scratch = dbev->get_metric_list (MET_INDX)->get_metrics ();
      fprintf (dis_file, GTXT ("Current index-object metrics: %s\n"), scratch);
      free (scratch);
      scratch = dbev->getSort (MET_INDX);
      fprintf (dis_file, GTXT ("Current index-object sort Metric: %s\n"), scratch);
      free (scratch);
      break;
    case SORT:
      if (arg1)
	{
	  char *ret = dbev->setSort (arg1, MET_NORMAL, false);
	  if (ret != NULL)
	    {
	      fprintf (stderr, GTXT ("Error: %s\n"), ret);
	      proc_cmd (METRICS, cparam, NULL, NULL);
	      break;
	    }
	  dbev->setSort (arg1, MET_SRCDIS, false);
	  dbev->setSort (arg1, MET_CALL, false);
	  dbev->setSort (arg1, MET_DATA, false);
	  dbev->setSort (arg1, MET_INDX, false);
	  dbev->setSort (arg1, MET_CALL_AGR, false);
	  dbev->setSort (arg1, MET_IO, false);
	  dbev->setSort (arg1, MET_HEAP, false);
	}
      scratch = dbev->getSort (MET_NORMAL);
      scratch1 = dbev->getSortCmd (MET_NORMAL);
      fprintf (dis_file,
	       GTXT ("Current Sort Metric: %s ( %s )\n"), scratch, scratch1);
      free (scratch1);
      free (scratch);
      break;
    case OBJECT_SHOW:
      if (arg1)
	set_libexpand (arg1, LIBEX_SHOW);
      obj_list ();
      break;
    case OBJECT_HIDE:
      if (arg1)
	set_libexpand (arg1, LIBEX_HIDE);
      obj_list ();
      break;
    case OBJECT_API:
      if (arg1)
	set_libexpand (arg1, LIBEX_API);
      obj_list ();
      break;
    case OBJECTS_DEFAULT:
      set_libdefaults ();
      obj_list ();
      break;
    case OBJECT_LIST:
      obj_list ();
      break;
    case OBJECT_SELECT:
      if (arg1)
	{
	  if (process_object_select (arg1) != -1)
	    proc_cmd (OBJECT_LIST, cparam, NULL, NULL);
	  else
	    fprintf (stderr, GTXT ("Error: Type \"object_list\" for a list of all load objects.\n"));
	}
      else
	fprintf (stderr, GTXT ("Error: No load object has been specified.\n"));
      break;
    case LOADOBJECT_LIST:
      seg_list ();
      break;
    case LOADOBJECT_SELECT:
      if (arg1)
	{
	  if (process_object_select (arg1) != -1)
	    proc_cmd (LOADOBJECT_LIST, cparam, NULL, NULL);
	  else
	    fprintf (stderr, GTXT ("Error: Type \"segment_list\" for a list of all segments.\n"));
	}
      else
	fprintf (stderr, GTXT ("Error: No segment has been specified.\n"));
      break;
    case SAMPLE_LIST:
      filter_list (SAMPLE_LIST);
      break;
    case SAMPLE_SELECT:
      if (arg1 && !dbev->set_pattern (SAMPLE_FILTER_IDX, arg1))
	fprintf (stderr, GTXT ("Error: Invalid filter pattern specification %s\n"), arg1);
      proc_cmd (SAMPLE_LIST, cparam, NULL, NULL);
      break;
    case THREAD_LIST:
      filter_list (THREAD_LIST);
      break;
    case THREAD_SELECT:
      if (arg1 && !dbev->set_pattern (THREAD_FILTER_IDX, arg1))
	fprintf (stderr, GTXT ("Error: Invalid filter pattern specification %s\n"), arg1);
      proc_cmd (THREAD_LIST, cparam, NULL, NULL);
      break;
    case LWP_LIST:
      filter_list (LWP_LIST);
      break;
    case LWP_SELECT:
      if (arg1 && !dbev->set_pattern (LWP_FILTER_IDX, arg1))
	fprintf (stderr, GTXT ("Error: Invalid filter pattern specification %s\n"), arg1);
      proc_cmd (LWP_LIST, cparam, NULL, NULL);
      break;
    case CPU_LIST:
      filter_list (CPU_LIST);
      break;
    case CPU_SELECT:
      if (arg1 && !dbev->set_pattern (CPU_FILTER_IDX, arg1))
	fprintf (stderr, GTXT ("Error: Invalid filter pattern specification %s\n"), arg1);
      proc_cmd (CPU_LIST, cparam, NULL, NULL);
      break;
    case FILTERS:
      if (arg1 != NULL)
	{
	  if (strcmp (arg1, NTXT ("True")) == 0)
	    scratch = dbev->set_filter (NULL);
	  else
	    scratch = dbev->set_filter (arg1);
	  if (scratch != NULL)
	    fprintf (stderr, GTXT ("Error: %s\n"), scratch);
	}
      scratch = dbev->get_filter ();
      fprintf (dis_file, GTXT ("current filter setting: \"%s\"\n"),
	       scratch == NULL ? GTXT ("<none>") : scratch);
      break;
    case OUTFILE:
      if (arg1)
	{
	  set_outfile (arg1, out_file, false);
	  if (inp_file != stdin)
	    dis_file = out_file;
	}
      break;
    case APPENDFILE:
      if (arg1)
	{
	  set_outfile (arg1, out_file, true);
	  if (inp_file != stdin)
	    dis_file = out_file;
	}
      break;
    case LIMIT:
      if (arg1)
	{
	  limit = (int) strtol (arg1, (char **) NULL, 10);
	  char *res = dbeSetPrintLimit (dbevindex, limit);
	  if (res != NULL)
	    fprintf (stderr, NTXT ("%s\n"), res);
	}

      limit = dbeGetPrintLimit (dbevindex);
      fprintf (stderr, GTXT ("Print limit set to %d\n"), limit);
      break;
    case NAMEFMT:
      if (arg1)
	{
	  status = dbev->set_name_format (arg1);
	  if (status != CMD_OK)
	    fprintf (stderr, GTXT ("Error: %s: %s\n"), Command::get_err_string (status), arg1);
	}
      else
	fprintf (stderr, GTXT ("Error: No format has been specified.\n"));
      break;
    case VIEWMODE:
      {
	if (arg1)
	  {
	    status = dbev->set_view_mode (arg1, false);
	    if (status != CMD_OK)
	      fprintf (stderr, GTXT ("Error: %s: %s\n"), Command::get_err_string (status), arg1);
	  }
	const char *vname = "unknown";
	int vm = dbev->get_view_mode ();
	switch (vm)
	  {
	  case VMODE_USER:
	    vname = "user";
	    break;
	  case VMODE_EXPERT:
	    vname = "expert";
	    break;
	  case VMODE_MACHINE:
	    vname = "machine";
	    break;
	  }
	fprintf (stderr, GTXT ("Viewmode set to %s\n"), vname);
      }
      break;

      // EN_DESC does not make sense after experiments are read, but it does make sense on the command line,
      //	processed before the experiments are read.
    case EN_DESC:
      if (arg1)
	{
	  status = dbev->set_en_desc (arg1, false);
	  if (status != CMD_OK)
	    fprintf (stderr, GTXT ("Error: %s: %s\n"), Command::get_err_string (status), arg1);
	}
      else
	fprintf (stderr, GTXT ("Error: No descendant processing has been specified.\n"));
      break;
    case SETPATH:
    case ADDPATH:
      if (arg1)
	dbeSession->set_search_path (arg1, (cmd_type == SETPATH));
      fprintf (dis_file, GTXT ("search path:\n"));
      Vec_loop (char*, dbeSession->get_search_path (), index, name)
      {
	fprintf (dis_file, NTXT ("\t%s\n"), name);
      }
      break;
    case PATHMAP:
      {
	Vector<pathmap_t*> *pathMaps = dbeSession->get_pathmaps ();
	if (arg1 != NULL)
	  {
	    if (arg2 == NULL)
	      {
		fprintf (stderr, GTXT ("Error: No replacement path prefix has been specified.\n"));
		break;
	      }
	    // add this mapping to the session
	    char *err = Settings::add_pathmap (pathMaps, arg1, arg2);
	    if (err != NULL)
	      {
		fprintf (stderr, NTXT ("%s"), err);
		free (err);
	      }
	  }
	fprintf (dis_file, GTXT ("Path mappings: from -> to\n"));
	for (int i = 0, sz = pathMaps->size (); i < sz; i++)
	  {
	    pathmap_t *thismap = pathMaps->get (i);
	    fprintf (dis_file, NTXT ("\t`%s' -> `%s'\n"), thismap->old_prefix, thismap->new_prefix);
	  }
      }
      break;
    case SAMPLE_DETAIL:
      if (get_exp_id (arg1, bgn_index, end_index) != -1)
	{
	  cd = new er_print_experiment (dbev, bgn_index, end_index, false,
					false, false, true, true);
	  print_cmd (cd);
	  delete cd;
	}
      break;
    case STATISTICS:
      if (get_exp_id (arg1, bgn_index, end_index) != -1)
	{
	  cd = new er_print_experiment (dbev, bgn_index, end_index, false,
					false, true, true, false);
	  print_cmd (cd);
	  delete cd;
	}
      break;
    case PRINTMODE:
      {
	if (arg1 == NULL)
	  {
	    fprintf (stderr, GTXT ("printmode is set to `%s'\n\n"), dbeGetPrintModeString (dbevindex));
	    break;
	  }
	char *s = dbeSetPrintMode (dbevindex, arg1);
	if (s != NULL)
	  {
	    fprintf (stderr, NTXT ("%s\n"), s);
	    break;
	  }
	fprintf (stderr, GTXT ("printmode is set to `%s'\n\n"), dbeGetPrintModeString (dbevindex));
      }
      break;
    case HEADER:
      if (get_exp_id (arg1, bgn_index, end_index) != -1)
	{
	  cd = new er_print_experiment (dbev, bgn_index, end_index, false,
					true, false, false, false);
	  print_cmd (cd);
	  delete cd;
	}
      break;
    case COMPARE:
      if (arg1 == NULL)
	{
	  fprintf (out_file, GTXT ("The argument to `compare' must be `on', `off', `delta', or `ratio'\n\n"));
	  break;
	}
      else
	{
	  int cmp;
	  if (strcasecmp (arg1, NTXT ("OFF")) == 0 || strcmp (arg1, NTXT ("0")) == 0)
	    cmp = CMP_DISABLE;
	  else if (strcasecmp (arg1, NTXT ("ON")) == 0 || strcmp (arg1, NTXT ("1")) == 0)
	    cmp = CMP_ENABLE;
	  else if (strcasecmp (arg1, NTXT ("DELTA")) == 0)
	    cmp = CMP_DELTA;
	  else if (strcasecmp (arg1, NTXT ("RATIO")) == 0)
	    cmp = CMP_RATIO;
	  else
	    {
	      fprintf (out_file, GTXT ("The argument to `compare' must be `on', `off', `delta', or `ratio'\n\n"));
	      break;
	    }
	  int oldMode = dbev->get_compare_mode ();
	  dbev->set_compare_mode (cmp);
	  if (oldMode != cmp)
	    {
	      dbev->reset_data (false);
	      dbeSession->reset_data ();
	    }
	}
      break;
    case LEAKS:
      if (!dbeSession->is_leaklist_available ())
	{
	  fprintf (out_file, GTXT ("\nHeap trace information was not requested when recording experiments\n\n"));
	  break;
	}
      if (dbev->comparingExperiments ())
	{ // XXXX show warning for compare
	  fprintf (out_file, GTXT ("\nNot available when comparing experiments\n\n"));
	  break;
	}
      cd = new er_print_leaklist (dbev, true, false, dbev->get_limit ());
      print_cmd (cd);
      delete cd;
      break;
    case ALLOCS:
      if (!dbeSession->is_leaklist_available ())
	{
	  fprintf (out_file, GTXT ("\nHeap trace information was not requested when recording experiments\n\n"));
	  break;
	}
      cd = new er_print_leaklist (dbev, false, true, dbev->get_limit ());
      print_cmd (cd);
      delete cd;
      break;
    case HEAP:
      if (!dbeSession->is_heapdata_available ())
	{
	  fprintf (out_file, GTXT ("Heap trace information was not requested when recording experiments\n\n"));
	  break;
	}
      cd = new er_print_heapactivity (dbev, Histable::HEAPCALLSTACK, false, dbev->get_limit ());
      print_cmd (cd);
      delete cd;
      break;
    case HEAPSTAT:
      if (!dbeSession->is_heapdata_available ())
	{
	  fprintf (out_file, GTXT ("Heap trace information was not requested when recording experiments\n\n"));
	  break;
	}
      cd = new er_print_heapactivity (dbev, Histable::HEAPCALLSTACK, true, dbev->get_limit ());
      print_cmd (cd);
      delete cd;
      break;
    case IOACTIVITY:
      if (!dbeSession->is_iodata_available ())
	{
	  fprintf (out_file, GTXT ("I/O trace information was not requested when recording experiments\n\n"));
	  break;
	}
      if (dbev->comparingExperiments ())
	{ // XXXX show warning for compare
	  fprintf (out_file, GTXT ("\nNot available when comparing experiments\n\n"));
	  break;
	}
      cd = new er_print_ioactivity (dbev, Histable::IOACTFILE, false, dbev->get_limit ());
      print_cmd (cd);
      delete cd;
      break;
    case IOVFD:
      if (!dbeSession->is_iodata_available ())
	{
	  fprintf (out_file, GTXT ("I/O trace information was not requested when recording experiments\n\n"));
	  break;
	}
      cd = new er_print_ioactivity (dbev, Histable::IOACTVFD, false, dbev->get_limit ());
      print_cmd (cd);
      delete cd;
      break;
    case IOCALLSTACK:
      if (!dbeSession->is_iodata_available ())
	{
	  fprintf (out_file, GTXT ("I/O trace information was not requested when recording experiments\n\n"));
	  break;
	}
      cd = new er_print_ioactivity (dbev, Histable::IOCALLSTACK, false, dbev->get_limit ());
      print_cmd (cd);
      delete cd;
      break;
    case IOSTAT:
      if (!dbeSession->is_iodata_available ())
	{
	  fprintf (out_file, GTXT ("I/O trace information was not requested when recording experiments\n\n"));
	  break;
	}
      cd = new er_print_ioactivity (dbev, Histable::IOACTVFD, true, dbev->get_limit ());
      print_cmd (cd);
      delete cd;
      break;
    case HELP:
      Command::print_help(whoami, false, true, out_file);
      break;
    case VERSION_cmd:
      Application::print_version_info ();
      break;
    case SCRIPT:
      if (arg1)
	{
	  ck_file = fopen (arg1, NTXT ("r"));
	  if (ck_file == NULL)
	    fprintf (stderr, GTXT ("Error: Script file cannot be opened: %s\n"), arg1);
	  else
	    {
	      save_file = inp_file;
	      inp_file = ck_file;
	      proc_script ();
	      inp_file = save_file;
	    }
	}
      else
	fprintf (stderr, GTXT ("Error: No filename has been specified.\n"));
      break;
    case QUIT:
      exit (0);
      break;

      // commands relating to index Objects
    case INDXOBJ:
      if ((cparam == -1) && (arg1 == NULL))
	{
	  fprintf (stderr, GTXT ("Error: No index object name has been specified.\n"));
	  break;
	}
      // automatically load machine model if applicable
      dbeDetectLoadMachineModel (dbevindex);
      indxobj (arg1, cparam);
      break;
    case INDXOBJLIST:
      // automatically load machine model if applicable
      dbeDetectLoadMachineModel (dbevindex);
      indxo_list (false, out_file);
      break;

      // define a new IndexObject type
    case INDXOBJDEF:
      if (arg1 == NULL)
	{
	  fprintf (stderr, GTXT ("Error: No index object name has been specified.\n"));
	  break;
	}
      if (arg2 == NULL)
	{
	  fprintf (stderr, GTXT ("Error: No index-expr has been specified.\n"));
	  break;
	}
      indxo_define (arg1, arg2, arg3, arg4);
      break;

      // the commands following this are unsupported/hidden
    case IFREQ:
      if (!dbeSession->is_ifreq_available ())
	{
	  fprintf (out_file, GTXT ("\nInstruction frequency data was not requested when recording experiments\n\n"));
	  break;
	}
      ifreq ();
      break;
    case DUMPNODES:
      dump_nodes ();
      break;
    case DUMPSTACKS:
      dump_stacks ();
      break;
    case DUMPUNK:
      dump_unk_pcs ();
      break;
    case DUMPFUNC:
      dump_funcs (arg1);
      break;
    case DUMPDOBJS:
      dump_dataobjects (arg1);
      break;
    case DUMPMAP:
      dump_map ();
      break;
    case DUMPENTITIES:
      dump_entities ();
      break;
    case DUMP_PROFILE:
      dbev->dump_profile (out_file);
      break;
    case DUMP_SYNC:
      dbev->dump_sync (out_file);
      break;
    case DUMP_HWC:
      dbev->dump_hwc (out_file);
      break;
    case DUMP_HEAP:
      if (!dbeSession->is_leaklist_available ())
	{
	  fprintf (out_file, GTXT ("\nHeap trace information was not requested when recording experiments\n\n"));
	  break;
	}
      dbev->dump_heap (out_file);
      break;
    case DUMP_IOTRACE:
      if (!dbeSession->is_iodata_available ())
	{
	  fprintf (out_file, GTXT ("\nI/O trace information was not requested when recording experiments\n\n"));
	  break;
	}
      dbev->dump_iotrace (out_file);
      break;
    case DMEM:
      if (arg1 == NULL)
	fprintf (stderr, GTXT ("Error: No sample has been specified.\n"));
      else
	{
	  Experiment *exp = dbeSession->get_exp (0);
	  if (exp != NULL)
	    exp->DBG_memuse (arg1);
	}
      break;
    case DUMP_GC:
      if (!dbeSession->has_java ())
	{
	  fprintf (out_file, GTXT ("\nJava garbage collection information was not requested when recording experiments\n\n"));
	  break;
	}
      dbev->dump_gc_events (out_file);
      break;
    case DKILL:
      {
	if (arg1 == NULL)
	  {
	    fprintf (stderr, GTXT ("Error: No process has been specified.\n"));
	    break;
	  }
	if (arg2 == NULL)
	  {
	    fprintf (stderr, GTXT ("Error: No signal has been specified.\n"));
	    break;
	  }
	pid_t p = (pid_t) atoi (arg1);
	int signum = atoi (arg2);
	char *ret = dbeSendSignal (p, signum);
	if (ret != NULL)
	  fprintf (stderr, GTXT ("Error: %s"), ret);
      }
      break;
    case PROCSTATS:
      dump_stats ();
      break;
    case ADD_EXP:
    case OPEN_EXP:
      if (arg1 == NULL)
	fprintf (stderr, GTXT ("Error: No experiment name has been specified.\n"));
      else
	{
	  Vector<Vector<char*>*> *groups = new Vector<Vector<char*>*>(1);
	  Vector<char*> *list = new Vector<char*>(1);
	  list->append (arg1);
	  groups->append (list);
	  char *res = dbeOpenExperimentList (dbevindex, groups, cmd_type == OPEN_EXP);
	  if (cmd_type == OPEN_EXP)
	    fprintf (stderr, GTXT ("Previously loaded experiment have been dropped.\n"));
	  if (res != NULL)
	    fprintf (stderr, NTXT ("%s"), res);
	  else
	    fprintf (stderr, GTXT ("Experiment %s has been loaded\n"), arg1);
	  free (res);
	  delete list;
	  delete groups;
	}
      break;
    case DROP_EXP:
      {
	if (arg1 == NULL)
	  fprintf (stderr, GTXT ("Error: No experiment name has been specified.\n"));
	else
	  {
	    int exp_index = dbeSession->find_experiment (arg1);
	    if (exp_index < 0)
	      fprintf (stderr, GTXT ("Error: experiment %s has not been opened.\n"), arg1);
	    else
	      {
		Vector<int> *expid = new Vector<int> (1);
		expid->append (exp_index);
		char *res = dbeDropExperiment (dbevindex, expid);
		if (res != NULL)
		  fprintf (stderr, NTXT ("%s"), res);
		else
		  fprintf (stderr, GTXT ("Experiment %s has been dropped\n"), arg1);
		delete expid;
		free (res);
	      }
	  }
      }
      break;
    case HHELP:
      // automatically load machine model if applicable
      dbeDetectLoadMachineModel (dbevindex);
      Command::print_help (whoami, false, false, out_file);
      fprintf (out_file, NTXT ("\n"));
      indxo_list (false, out_file);
      fprintf (out_file, NTXT ("\n"));
      mo_list (false, out_file);
      if (!getenv ("_BUILDING_MANPAGE"))
	fprintf (out_file, GTXT ("\nSee gprofng(1) for more details\n"));
      break;
    case QQUIT:
      was_QQUIT = true;
      return;
    default:
      fprintf (stderr, GTXT ("Error: Invalid option\n"));
      break;
    }

  // check for any processing error messages
  dump_proc_warnings ();
  fflush (out_file);
}

#define MAX_NUM_HEADER      4

void
er_print::disp_list (int num_header, int size, int align[], char *header[],
		     char **lists[])
{
  size_t maxlen[MAX_NUM_HEADER];
  char fmt[MAX_NUM_HEADER][64];
  if (num_header > MAX_NUM_HEADER)
    abort ();
  for (int i = 0; i < num_header; i++)
    {
      maxlen[i] = strlen (header[i]);
      for (int j = 0; j < size; j++)
	{
	  size_t len = strlen (lists[i][j]);
	  if (maxlen[i] < len)
	    maxlen[i] = len;
	}

      // get format string
      if ((align[i] == -1) && (i == num_header - 1))
	snprintf (fmt[i], sizeof (fmt[i]), NTXT ("%%s "));
      else
	snprintf (fmt[i], sizeof (fmt[i]), NTXT ("%%%ds "), (int) (align[i] * maxlen[i]));

      // write header
      fprintf (out_file, fmt[i], header[i]);
    }
  putc ('\n', out_file);

  // write separator "==="
  size_t np = 0;
  for (int i = 0; (i < num_header) && (np < 132); i++)
    {
      size_t nc = maxlen[i];
      if (nc + np > 132)
	nc = 132 - np;
      for (size_t j = 0; j < nc; j++)
	putc ('=', out_file);
      putc (' ', out_file);
      np += nc + 1;
    }
  putc ('\n', out_file);

  // write lists
  for (int j = 0; j < size; j++)
    {
      for (int i = 0; i < num_header; i++)
	fprintf (out_file, fmt[i], lists[i][j]);
      putc ('\n', out_file);
    }
}

void
er_print::exp_list ()
{
  int size, index;
  int align[MAX_NUM_HEADER];
  char *header[MAX_NUM_HEADER];
  char **lists[MAX_NUM_HEADER];

  align[0] = 1;     // right-justify
  align[1] = 1;     // right-justify
  align[2] = 1;     // right-justify
  align[3] = -1;    // left-justify
  header[0] = GTXT ("ID");
  header[1] = GTXT ("Sel");
  header[2] = GTXT ("PID");
  header[3] = GTXT ("Experiment");

  size = dbeSession->nexps ();
  lists[0] = new char*[size];
  lists[1] = new char*[size];
  lists[2] = new char*[size];
  lists[3] = new char*[size];
  for (index = 0; index < size; index++)
    {
      lists[0][index] = dbe_sprintf (NTXT ("%d"), index + 1);
      lists[1][index] = xstrdup (dbev->get_exp_enable (index) ? GTXT ("yes") : GTXT ("no"));
      lists[2][index] = dbe_sprintf (NTXT ("%d"), dbeSession->get_exp (index)->getPID ());
      lists[3][index] = xstrdup (dbeSession->get_exp (index)->get_expt_name ());
    }
  disp_list (4, size, align, header, lists);
  for (int i = 0; i < 4; i++)
    {
      for (int j = 0; j < size; j++)
	free (lists[i][j]);
      delete[] lists[i];
    }
}

void
er_print::describe ()
{
  Vector<void*> *res = dbeGetFilterKeywords (dbev->vindex);
  if (res == NULL)
    return;
  Vector <char*> *kwCategoryI18N = (Vector<char*>*) res->fetch (1);
  Vector <char*> *kwKeyword = (Vector<char*>*) res->fetch (3);
  Vector <char*> *kwFormula = (Vector<char*>*) res->fetch (4);
  Vector <char*> *kwDescrip = (Vector<char*>*) res->fetch (5);
  Vector <void*> *kwEnumDescs = (Vector<void*>*) res->fetch (6);
  String sectionFormat = NTXT ("\n------ %s ------\n");
  String categoryFormat = NTXT ("\n%s\n");
  String keywordFormat = NTXT ("   %-20s  %s\n");
  String empty = NTXT ("");
  String previousCategory = empty;

  for (int i = 0; i < kwKeyword->size (); i++)
    {
      if (kwKeyword->fetch (i) == NULL)
	{
	  fprintf (dis_file, sectionFormat, kwCategoryI18N->fetch (i));
	  continue;
	}
      String cat = kwCategoryI18N->fetch (i);
      if (dbe_strcmp (previousCategory, cat) != 0)
	fprintf (dis_file, categoryFormat, cat);
      previousCategory = cat;
      Vector <String> *enumDescs = (Vector <String> *) kwEnumDescs->fetch (i);
      String keyword = kwKeyword->fetch (i);
      if (kwDescrip->fetch (i) != NULL)
	{
	  fprintf (dis_file, keywordFormat, keyword, kwDescrip->fetch (i));
	  keyword = empty;
	}
      if (kwFormula->fetch (i) != NULL)
	{
	  fprintf (dis_file, keywordFormat, keyword, kwFormula->fetch (i));
	  keyword = empty;
	  continue;
	}
      int numEnums = enumDescs != NULL ? enumDescs->size () : 0;
      for (int jj = 0; jj < numEnums; jj++)
	{
	  fprintf (dis_file, keywordFormat, keyword, enumDescs->fetch (jj));
	  keyword = empty;
	}
    }
  destroy (res);
}

void
er_print::obj_list ()
{
  LoadObject *lo;
  int index;
  int align[MAX_NUM_HEADER];
  char *header[MAX_NUM_HEADER];
  char **lists[MAX_NUM_HEADER];
  Vector<LoadObject*> *text_segments = dbeSession->get_text_segments ();
  if (text_segments->size () == 0)
    {
      fprintf (dis_file, GTXT ("There are no load objects in this experiment\n"));
      return;
    }
  align[0] = -1; // left-justify
  align[1] = -1; // left-justify
  align[2] = -1; // left-justify
  align[3] = -1; // left-justify
  header[0] = GTXT ("Sel");
  header[1] = GTXT ("Load Object");
  header[2] = GTXT ("Index");
  header[3] = GTXT ("Path");

  int size = text_segments->size ();
  lists[0] = new char*[size];
  lists[1] = new char*[size];
  lists[2] = new char*[size];
  lists[3] = new char*[size];

  char *lo_name;
  int new_index = 0;
  Vec_loop (LoadObject*, text_segments, index, lo)
  {
    lo_name = lo->get_name ();
    if (lo_name != NULL)
      {
	size_t len = strlen (lo_name);
	if (len > 7 && streq (lo_name + len - 7, NTXT (".class>")))
	  continue;
      }
    LibExpand expand = dbev->get_lo_expand (lo->seg_idx);
    switch (expand)
      {
      case LIBEX_SHOW:
	lists[0][new_index] = dbe_strdup (GTXT ("show"));
	break;
      case LIBEX_HIDE:
	lists[0][new_index] = dbe_strdup (GTXT ("hide"));
	break;
      case LIBEX_API:
	lists[0][new_index] = dbe_strdup (GTXT ("API-only"));
	break;
      }
    lists[1][new_index] = dbe_strdup (lo_name);
    lists[2][new_index] = dbe_sprintf (NTXT ("%d"), lo->seg_idx);
    lists[3][new_index] = dbe_strdup (lo->get_pathname ());
    new_index++;
  }
  disp_list (4, new_index, align, header, lists);
  for (int i = 0; i < 4; i++)
    {
      for (int j = 0; j < new_index; j++)
	free (lists[i][j]);
      delete[] lists[i];
    }
  delete text_segments;
}

void
er_print::seg_list ()
{
  LoadObject *lo;
  int index;
  int align[MAX_NUM_HEADER];
  char *header[MAX_NUM_HEADER];
  char **lists[MAX_NUM_HEADER];

  // XXX seg_list only prints text segments; should extend to all
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
  if (lobjs->size () == 0)
    {
      fprintf (dis_file, GTXT ("There are no segments in this experiment\n"));
      return;
    }
  align[0] = -1; // left-justify
  align[1] = 1;  // right-justify
  align[2] = -1; // left-justify
  header[0] = GTXT ("Sel");
  header[1] = GTXT ("Size");
  header[2] = GTXT ("Segment");

  int size = lobjs->size ();
  lists[0] = new char*[size];
  lists[1] = new char*[size];
  lists[2] = new char*[size];

  char *lo_name;
  int new_index = 0;
  Vec_loop (LoadObject*, lobjs, index, lo)
  {
    lo_name = lo->get_name ();
    if (lo_name != NULL)
      {
	size_t len = strlen (lo_name);
	if (len > 7 && streq (lo_name + len - 7, NTXT (".class>")))
	  continue;
      }
    bool expand = dbev->get_lo_expand (lo->seg_idx);
    lists[0][new_index] = xstrdup (expand ? GTXT ("yes") : GTXT ("no"));
    lists[1][new_index] = dbe_sprintf (NTXT ("%lld"), (ll_t) lo->get_size ());
    lists[2][new_index] = xstrdup (lo->get_pathname ());
    new_index++;
  }

  disp_list (3, new_index, align, header, lists);
  for (int i = 0; i < 4; i++)
    {
      for (int j = 0; j < new_index; j++)
	free (lists[i][j]);
      delete[] lists[i];
    }
  delete lobjs;
}

void
er_print::filter_list (CmdType cmd_type)
{
  FilterNumeric *select;
  int index;
  int align[MAX_NUM_HEADER];
  char *header[MAX_NUM_HEADER];
  char **lists[MAX_NUM_HEADER];
  char *pattern;

  // first ensure that the data has been read
  MetricList *mlist = dbev->get_metric_list (MET_INDX);
  Hist_data *data = dbev->get_hist_data (mlist, Histable::INDEXOBJ, 0, Hist_data::ALL);
  delete data;

  align[0] = 1;  // right-justify
  align[1] = -1; // left-justify
  align[2] = 1;  // right-justify
  align[3] = 1;  // right-justify
  header[0] = GTXT ("Exp");
  header[1] = GTXT ("Sel");
  header[2] = GTXT ("Total");
  header[3] = GTXT ("Status");

  int size = dbeSession->nexps ();
  lists[0] = new char*[size];
  lists[1] = new char*[size];
  lists[2] = new char*[size];
  lists[3] = new char*[size];
  int new_index = 0;
  for (index = 0; index < size; index++)
    {
      switch (cmd_type)
	{
	case SAMPLE_LIST:
	  select = dbev->get_FilterNumeric (index, SAMPLE_FILTER_IDX);
	  break;
	case THREAD_LIST:
	  select = dbev->get_FilterNumeric (index, THREAD_FILTER_IDX);
	  break;
	case LWP_LIST:
	  select = dbev->get_FilterNumeric (index, LWP_FILTER_IDX);
	  break;
	case CPU_LIST:
	  select = dbev->get_FilterNumeric (index, CPU_FILTER_IDX);
	  break;
	default:
	  abort (); // internal error
	}
      if (select == NULL)
	continue;
      lists[0][new_index] = dbe_sprintf (NTXT ("%d"), index + 1);
      pattern = dbev->get_exp_enable (index) ? select->get_pattern () : NULL;
      lists[1][new_index] = xstrdup (pattern && *pattern ? pattern : GTXT ("none"));
      lists[2][new_index] = dbe_sprintf (NTXT ("%lld"), (ll_t) select->nelem ());
      lists[3][new_index] = select->get_status ();
      new_index++;
    }
  disp_list (3, size, align, header, lists);
  for (int i = 0; i < 4; i++)
    {
      for (int j = 0; j < new_index; j++)
	free (lists[i][j]);
      delete[] lists[i];
    }
}

int
er_print::check_exp_id (int exp_id, char *sel)
{
  if (exp_id < 0 || exp_id >= dbeSession->nexps ())
    {
      fprintf (stderr, GTXT ("Error: Invalid number entered: %s\nType \"exp_list\" for a list of all experiments.\n"),
	       sel);
      return -1;
    }
  return exp_id;
}

int
er_print::get_exp_id (char *sel, int &bgn_index, int &end_index)
{
  int id, exp_id;
  if (sel == NULL || strcmp (sel, NTXT ("all")) == 0)
    {
      // loop over all experiments
      bgn_index = 0;
      end_index = dbeSession->nexps () - 1;
    }
  else
    {
      id = (int) strtol (sel, (char **) NULL, 10) - 1;
      exp_id = check_exp_id (id, sel);
     if (exp_id == -1)
	return -1;
      bgn_index = end_index = exp_id;
    }
  return 0;
}

void
er_print::print_objects ()
{
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
  char *msg = pr_load_objects (lobjs, NTXT (""));
  delete lobjs;
  fprintf (out_file, NTXT ("%s\n"), msg);
  free (msg);
}

void
er_print::print_overview ()
{
  //fprintf(out_file, NTXT("%s\n"), GTXT("Not implemented yet."));//YXXX
  Vector<char*> *status = dbeGetOverviewText (dbevindex);
  StringBuilder sb;
  sb.append (GTXT ("Experiment(s):\n\n"));
  for (int i = 0; i < status->size (); i++)
    sb.appendf (NTXT ("%s\n"), status->fetch (i));
  sb.append (GTXT ("Metrics:\n"));
  sb.toFile (out_file);

  Vector<void*> *data = dbeGetRefMetricTree (dbevindex, false);
  Vector<char *> *metric_cmds = new Vector<char *>();
  Vector<char *> *non_metric_cmds = new Vector<char *>();
  print_overview_nodes (data, 0, metric_cmds, non_metric_cmds);
  Vector<void*> *values = dbeGetRefMetricTreeValues (0, metric_cmds, non_metric_cmds);
  print_overview_tree (data, 0, values, metric_cmds, non_metric_cmds);

  StringBuilder sb2;
  sb2.append (GTXT ("\nNotes: '*' indicates hot metrics, '[X]' indicates currently enabled metrics.\n"));
  sb2.append (GTXT ("       The metrics command can be used to change selections. The metric_list command lists all available metrics.\n"));
  sb2.toFile (out_file);
}

void
er_print::print_overview_nodes (Vector<void*> * data, int level, Vector<char *> *metric_cmds, Vector<char *> *non_metric_cmds)
{
  Vector<void*> *fields = (Vector<void*> *) data->fetch (0);
  Vector<void*> *children = (Vector<void*> *) data->fetch (1);
  char *name = ((Vector<char*> *)fields->fetch (0))->fetch (0);
  int vstyles_capable = ((Vector<int>*) fields->fetch (5))->fetch (0); //bitmask e.g.VAL_TIMEVAL
  bool has_value = ((Vector<bool>*) fields->fetch (10))->fetch (0);
  bool selectable = (vstyles_capable != 0) ? true : false;
  if (selectable)
    metric_cmds->append (name);
  else if (has_value)
    non_metric_cmds->append (name);

  level++;
  for (int i = 0; i < children->size (); i++)
    print_overview_nodes ((Vector<void*> *)(children->fetch (i)), level, metric_cmds, non_metric_cmds);
}

void
er_print::print_overview_tree (Vector<void*> * data, int level, Vector<void*> * values, Vector<char *> *metric_cmds, Vector<char *> *non_metric_cmds)
{
  Vector<void*> * fields = (Vector<void*> *) data->fetch (0);
  Vector<void*> * children = (Vector<void*> *) data->fetch (1);
  char *name = ((Vector<char*> *)fields->fetch (0))->fetch (0);
  char *username = ((Vector<char*> *)fields->fetch (1))->fetch (0);
  int flavors = ((Vector<int>*) fields->fetch (3))->fetch (0); //bitmask e.g. EXCLUSIVE
  int vstyles_capable = ((Vector<int>*) fields->fetch (5))->fetch (0); //bitmask e.g.VAL_TIMEVAL
  //    bool aggregation = ((Vector<bool>*) fields->fetch(9))->fetch(0);
  //    bool has_value = ((Vector<bool>*) fields->fetch(10))->fetch(0);
  char *unit = ((Vector<char*> *) fields->fetch (11))->fetch (0);

  StringBuilder sb;
  for (int i = 0; i < level * 2; i++)
    sb.append (NTXT (" ")); // NOI18N

  bool selectable = (vstyles_capable != 0) ? true : false;
  if (selectable)
    {
      bool isSelected = dbev->get_metric_list (MET_NORMAL)->find_metric_by_name (name) == NULL ? false : true;
      if (isSelected)
	sb.append (NTXT ("[X]"));
      else
	sb.append (NTXT ("[ ]"));
    }
  if ((unit != NULL && dbe_strcmp (unit, UNIT_SECONDS) == 0)
      || (unit == NULL && vstyles_capable & VAL_TIMEVAL))
    unit = GTXT ("Seconds");

  bool isHiddenInOverview = ((flavors & BaseMetric::STATIC) != 0);
  if (name != NULL && dbe_strcmp (name, L1_STATIC) == 0)
    isHiddenInOverview = true;
  if (!dbeSession->has_java () && name != NULL && dbe_strcmp (name, L1_GCDURATION) == 0)
    isHiddenInOverview = true;
  if (isHiddenInOverview)
    return;

  sb.append (username == NULL ? NTXT ("") : username); // NOI18N
  int show = 0;
  if (name == NULL)
    show = 0;
  else if (strstr (name, NTXT ("PROFDATA_TYPE_")) == NULL)
    show = 1;

  if (show)
    {
      sb.append (username == NULL ? NTXT ("") : NTXT (" - ")); // NOI18N
      sb.append (name == NULL ? NTXT ("") : name); // NOI18N
    }

  // "Bugs 16624403 and 19539622" (leave this string intact for searches)
  // add an extra condition for now
  // once we have proper fixes, eliminate test on Bug16624402_extra_condition
  int Bug16624402_extra_condition = 1;
  if (username)
    {
      if (strcmp (username, NTXT ("Block Covered %")) == 0) Bug16624402_extra_condition = 0;
      if (strcmp (username, NTXT ("Instr Covered %")) == 0) Bug16624402_extra_condition = 0;
    }
  if (Bug16624402_extra_condition > 0 && values->size () > 0)
    {
      Vector<void*> * valueColumns = (Vector<void*> *)values->fetch (0);
      Vector<void*> * highlightColumns = (Vector<void*> *)values->fetch (1);
      int jj = 0;
      int found = 0;
      for (jj = 0; jj < valueColumns->size (); jj++)
	{
	  const char *value_name = "";
	  if (jj < metric_cmds->size ())
	    value_name = metric_cmds->fetch (jj);
	  else
	    value_name = non_metric_cmds->fetch (jj - metric_cmds->size ());
	  if (dbe_strcmp (value_name, name) != 0)
	    continue;
	  else
	    {
	      found = 1;
	      break;
	    }
	}
      if (found)
	{
	  Vector<void*> * valueVec = (Vector<void*> *)valueColumns->fetch (jj);
	  Vector<bool> * highlights = (Vector<bool> *)highlightColumns->fetch (jj);
	  for (int kk = 0; kk < valueVec->size (); kk++)
	    {
	      char * value_str;
	      int show_value = 0;
	      switch (valueVec->type ())
		{
		case VEC_INTEGER:
		  value_str = dbe_sprintf (NTXT ("%ld"), (long) (((Vector<int> *)valueVec)->fetch (kk)));
		  show_value = 1;
		  break;
		case VEC_DOUBLE:
		  value_str = dbe_sprintf (NTXT ("%.3f"), (double) (((Vector<double> *)valueVec)->fetch (kk)));
		  show_value = 1;
		  break;
		case VEC_LLONG:
		  value_str = dbe_sprintf (NTXT ("%lld"), (long long) (((Vector<long> *)valueVec)->fetch (kk)));
		  show_value = 1;
		  break;
		case VEC_STRING:
		  value_str = NTXT ("");
		  break;
		default:
		  value_str = NTXT ("");
		}
	      if (show_value)
		{
		  if (kk == 0)
		    {
		      sb.append (unit == NULL ? NTXT ("") : NTXT (" ("));
		      sb.append (unit == NULL ? NTXT ("") : unit);
		      sb.append (unit == NULL ? NTXT ("") : NTXT (")"));
		      sb.append (NTXT (":"));
		    }
		  bool highlight = highlights->fetch (kk);
		  const char * hilite = highlight ? NTXT ("*") : NTXT ("");
		  sb.append (NTXT (" ["));
		  sb.append (hilite);
		  sb.append (value_str);
		  sb.append (NTXT ("]"));
		}
	    }
	}
    }
  sb.append (NTXT ("\n"));
  sb.toFile (out_file);
  level++;
  for (int i = 0; i < children->size (); i++)
    print_overview_tree ((Vector<void*> *)(children->fetch (i)), level, values, metric_cmds, non_metric_cmds);
}

void
er_print::print_segments ()
{
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
  char *msg = pr_load_objects (lobjs, NTXT (""));
  delete lobjs;
  fprintf (dis_file, NTXT ("Not implemented yet!\n"));
  free (msg);
}

void
er_print::print_dobj (Print_mode mode, MetricList *mlist1,
		      char *dobj_name, char *sel)
{
  Hist_data *hist_data = NULL;
  char *errstr;
  er_print_common_display *cd;
  int list_limit = limit;
  Histable *sobj = NULL;
  Dprintf (DEBUG_DATAOBJ, NTXT ("er_print::print_dobj(mode=%d,dobj=%s,sel=%s)\n"),
	   mode, (dobj_name == NULL) ? NTXT ("0") : dobj_name, (sel == NULL) ? NTXT ("0") : sel);
  char *name = dbev->getSort (MET_DATA);
  switch (mode)
    {
    case MODE_LIST:
      hist_data = dbev->get_hist_data (mlist1, Histable::DOBJECT, 0, Hist_data::ALL);
      break;
    case MODE_DETAIL:
      // if specified, find the dataobject from the name
      if (dobj_name && strcmp (dobj_name, NTXT ("<All>")))
	{
	  if (!dbeSession->find_obj (dis_file, inp_file, sobj, dobj_name,
				     sel, Histable::DOBJECT, (inp_file != stdin)))
	    return;
	  if (sobj == NULL)
	    { // dataobject/segment not found
	      hist_data = dbev->get_hist_data (mlist1, Histable::DOBJECT, 0, Hist_data::DETAIL);
	      if (!dbeSession->find_obj (dis_file, inp_file, sobj, dobj_name,
					 sel, Histable::DOBJECT, (inp_file != stdin)))
		return;
	      if (sobj == NULL)
		{ // dataobject/segment not found
		  fprintf (stderr, GTXT ("Error: No dataobject with given name `%s' found.\n"),
			   dobj_name);
		  return;
		}
	    }

	  list_limit = 1;
	}
      if (!hist_data)
	hist_data = dbev->get_hist_data (mlist1, Histable::DOBJECT, 0, Hist_data::DETAIL);
      break;
    case MODE_ANNOTATED:
      hist_data = dbev->get_hist_data (mlist1, Histable::DOBJECT, 0, Hist_data::LAYOUT);
      break;
    default: // MODE_GPROF is not relevant for DataObjects
      abort ();
    }

  if (hist_data->get_status () != Hist_data::SUCCESS)
    {
      // XXXX is this error message adequate?
      errstr = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
      if (errstr)
	{
	  fprintf (stderr, GTXT ("Error: %s\n"), errstr);
	  free (errstr);
	}
      delete hist_data;
      return;
    }
  cd = (er_print_common_display *) new er_print_histogram (dbev, hist_data,
							   hist_data->get_metric_list (), mode, list_limit, name, sobj, false, false);
  free (name);
  print_cmd (cd);

  delete hist_data;
  delete cd;
}

void
er_print::print_func (Histable::Type type, Print_mode mode, MetricList *mlist1,
		      MetricList *mlist2, char *func_name, char *sel)
{
  Hist_data *hist_data;
  Hist_data::HistItem *hitem;
  int index;
  char *errstr;
  int list_limit = limit;
  Histable *sobj = NULL;
  MetricList *mlist;
  StringBuilder sb;
  char *sname = dbev->getSort (MET_NORMAL);
  sb.append (sname);
  free (sname);

  switch (mode)
    {
    case MODE_DETAIL:
      {
	// The first metric list, mlist1, is only used to pick out the sort
	//    mlist2 is the one used to generate the data
	char *prevsort = NULL;
	// if specified, find the function from the function name
	if (func_name && strcmp (func_name, NTXT ("<All>")))
	  {
	    if ((!dbeSession->find_obj (dis_file, inp_file, sobj, func_name,
					sel, Histable::FUNCTION, (inp_file != stdin)) || (sobj == NULL)) &&
		!dbeSession->find_obj (dis_file, inp_file, sobj, func_name,
				       sel, Histable::LOADOBJECT, (inp_file != stdin)))
	      return;
	    if (sobj == NULL)
	      { // function/segment object not found
		fprintf (stderr, GTXT ("Error: No function with given name `%s' found.\n"),
			 func_name);
		return;
	      }
	    list_limit = 1;
	  }
	else
	  {
	    // find the sort metric from the reference list
	    prevsort = mlist2->get_sort_cmd ();

	    // find the current sort metric from the current list
	    char *cursort = mlist1->get_sort_cmd ();

	    // find the corresponding metric in the reference list
	    (void) mlist2->set_sort (cursort, false);
	    free (cursort);
	    // if it fails, nothing is needed
	  }
	hist_data = dbev->get_hist_data (mlist2, type, 0, Hist_data::ALL);

	// restore
	if (sobj == NULL)
	  {
	    if (prevsort == NULL)
	      abort ();
	    (void) mlist2->set_sort (prevsort, false);
	  }
	mlist = mlist2;
	free (prevsort);
	break;
      }
    case MODE_GPROF:
      // if specified, find the function from the function name
      if (func_name && strcmp (func_name, NTXT ("<All>")))
	{
	  if (!dbeSession->find_obj (dis_file, inp_file, sobj, func_name,
				     sel, Histable::FUNCTION, (inp_file != stdin)))
	    return;
	  if (sobj == NULL)
	    { // function/segment object not found
	      fprintf (stderr, GTXT ("Error: No function with given name `%s' found.\n"),
		       func_name);
	      return;
	    }
	  list_limit = 1;
	  sb.setLength (0);
	}
      sb.append (GTXT ("\nCallers and callees sorted by metric: "));
      sname = dbev->getSort (MET_CALL);
      sb.append (sname);
      free (sname);

      // Use mlist2 to generate the sort order.
      // mlist1 is used to generate the data.
      hist_data = dbev->get_hist_data (mlist2, type, 0, Hist_data::ALL);
      mlist = mlist1;
      break;
    default:
      hist_data = dbev->get_hist_data (mlist1, type, 0, Hist_data::ALL);
      mlist = mlist1;
    }

  if (hist_data->get_status () != Hist_data::SUCCESS)
    {
      errstr = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
      if (errstr)
	{
	  fprintf (stderr, GTXT ("Error: %s\n"), errstr);
	  free (errstr);
	}
      delete hist_data;
      return;
    }

  if (type == Histable::FUNCTION)
    {
      for (index = 0; index < hist_data->size (); index++)
	{
	  hitem = hist_data->fetch (index);
	  if (hitem->obj->get_type () == Histable::FUNCTION)
	    // fetch the name, since that will force a format conversion
	    ((Function *) hitem->obj)->get_name ();
	}
    }

  char *name = sb.toString ();
  er_print_histogram *cd = new er_print_histogram (dbev, hist_data,
						   mlist, mode, list_limit, name, sobj, false, false);
  print_cmd (cd);
  delete hist_data;
  free (name);
  delete cd;
}

void
er_print::print_gprof (CmdType cmd_type, char *func_name, char *sel)
{
  Histable *sobj = NULL;
  if (func_name != NULL)
    {
      if ((!dbeSession->find_obj (dis_file, inp_file, sobj, func_name,
				  sel, Histable::FUNCTION, (inp_file != stdin))
	   || sobj == NULL)
	  && !dbeSession->find_obj (dis_file, inp_file, sobj, func_name,
				    sel, Histable::LOADOBJECT, (inp_file != stdin)))
	return;
      if (sobj == NULL)
	{ // function/segment object not found
	  fprintf (stderr, GTXT ("Error: No function with given name `%s' found.\n"),
		   func_name);
	  return;
	}
    }
  if (cmd_type == CPREPEND)
    {
      if (sobj == NULL)
	{
	  fprintf (stderr, GTXT ("Error: No function name has been specified.\n"));
	  return;
	}
      cstack->insert (0, sobj);
    }
  else if (cmd_type == CAPPEND)
    {
      if (sobj == NULL)
	{
	  fprintf (stderr, GTXT ("Error: No function name has been specified.\n"));
	  return;
	}
      cstack->append (sobj);
    }
  else if (cmd_type == CSINGLE)
    {
      if (sobj != NULL)
	{
	  cstack->reset ();
	  cstack->append (sobj);
	}
      else if (cstack->size () == 0)
	{
	  fprintf (stderr, GTXT ("Error: No function name has been specified.\n"));
	  return;
	}
    }
  else if (cmd_type == CRMFIRST)
    {
      if (cstack->size () <= 1)
	{
	  fprintf (stderr, GTXT ("Warning: there is only one function in the stack segment; cannot remove it.\n"));
	  return;
	}
      cstack->remove (0);
    }
  else if (cmd_type == CRMLAST)
    {
      if (cstack->size () <= 1)
	{
	  fprintf (stderr, GTXT ("Warning: there is only one function in the stack segment; cannot remove it.\n"));
	  return;
	}
      cstack->remove (cstack->size () - 1);
    }

  er_print_gprof *cd = new er_print_gprof (dbev, cstack);
  print_cmd (cd);
  delete cd;
}

/*
 * Method print_ctree() prints Functions Call Tree.
 */
void
er_print::print_ctree (CmdType cmd_type)
{
  if (cmd_type != CALLTREE)
    {
      fprintf (stderr, GTXT ("Error: Invalid command type: %d\n"), cmd_type);
      return;
    }

  Histable *sobj = dbeSession->get_Total_Function ();
  Vector<Histable*> *ctree_cstack = new Vector<Histable*>();
  ctree_cstack->reset ();
  er_print_ctree *cd = new er_print_ctree (dbev, ctree_cstack, sobj, limit);
  print_cmd (cd);
  delete ctree_cstack;
  delete cd;
}

void
er_print::memobj (char *name, int cparam)
{
  int type;
  if (name != NULL)
    {
      // find the memory object index for the name
      MemObjType_t *mot = MemorySpace::findMemSpaceByName (name);
      if (mot == NULL)
	{
	  // unknown type, report the error
	  fprintf (stderr, GTXT ("Error: Unknown Memory Object type: %s\n"), name);
	  return;
	}
      type = mot->type;
    }
  else
    {
      MemObjType_t *mot = MemorySpace::findMemSpaceByIndex (cparam);
      if (mot == NULL)
	{
	  // unknown type, report the error
	  fprintf (stderr, GTXT ("Error: Unknown Memory Object type: %s\n"), name);
	  return;
	}
      type = cparam;
    }
  dbePrintData (0, DSP_MEMOBJ, type, NULL, NULL, out_file);
}

void
er_print::mo_define (char *moname, char *mo_index_exp, char *machmodel, char *short_desc, char *long_desc)
{
  char *ret = MemorySpace::mobj_define (moname, mo_index_exp, machmodel, short_desc, long_desc);
  if (ret != NULL)
    fprintf (stderr, GTXT ("mobj_define for %s failed: %s\n"), moname, ret);
}

void
er_print::mo_list (bool showtab, FILE *outf)
{
  Vector<bool> *mtab = NULL;
  Vector<void*>*res = MemorySpace::getMemObjects ();
  if (showtab)
    mtab = dbev->get_MemTabState ();
  if (res == NULL)
    // Since we checked already, this is an internal error
    abort ();

  // unpack the return
  // Vector<char*> *index = (Vector<int> *)res->fetch(0);  // not used
  Vector<char*> *mo_names = (Vector<char*> *)res->fetch (1);
  // Vector<char*> *mnemonic = (Vector<char> *)res->fetch(2);  // not used
  Vector<char*> *mo_expr = (Vector<char*> *)res->fetch (3);
  Vector<char*> *mo_mach_m = (Vector<char*> *)res->fetch (4);
  // Vector<char*> *tmpOrder = (Vector<int> *)res->fetch(5);  // not used

  int size = mo_names->size ();
  if (size == 0)
    {
      if (!getenv ("_BUILDING_MANPAGE"))
	fprintf (outf, GTXT (" No Memory Object Types Defined\n"));
    }
  else
    {
      if (!getenv ("_BUILDING_MANPAGE"))
	fprintf (outf, GTXT (" Memory Object Types Available:\n"));
      else
	fprintf (outf, GTXT ("*Memory Object Types*\n"));
      for (int i = 0; i < size; i++)
	{
	  if (mtab)
	    fprintf (outf, NTXT ("  %c %s\n"), mtab->fetch (i) ? 'T' : 'F',
		     mo_names->fetch (i));
	  else
	    {
	      if (mo_mach_m->fetch (i) != NULL)
		fprintf (outf, NTXT ("  %s\t\t\"%s\"\t\t(machinemodel: %s)\n"),
			 mo_names->fetch (i), mo_expr->fetch (i), mo_mach_m->fetch (i));
	      else
		fprintf (outf, NTXT ("  %s\t\t\"%s\"\n"),
			 mo_names->fetch (i), mo_expr->fetch (i));
	    }
	}
    }
  delete mo_names;
  delete mo_expr;
  delete mo_mach_m;
  delete res;
}

void
er_print::indxobj (char *name, int cparam)
{
  int type;
  if (name != NULL)
    {
      // find the index object index for the name
      type = dbeSession->findIndexSpaceByName (name);
      if (type < 0)
	{
	  // unknown type, report the error
	  fprintf (stderr, GTXT ("Error: Unknown Index Object type: %s\n"), name);
	  return;
	}
    }
  else
    {
      char *indxname = dbeSession->getIndexSpaceName (cparam);
      if (indxname == NULL)
	{
	  // unknown type, report the error
	  fprintf (stderr, GTXT ("Error: Unknown Index Object type: %d\n"), cparam);
	  return;
	}
      type = cparam;
    }
  dbePrintData (0, DSP_INDXOBJ, type, NULL, NULL, out_file);
}

void
er_print::indxo_define (char *ioname, char *io_index_exp, char *sdesc, char *ldesc)
{
  char *ret = dbeDefineIndxObj (ioname, io_index_exp, sdesc, ldesc);
  if (ret != NULL)
    fprintf (stderr, GTXT ("indxobj_define for %s failed: %s\n"), ioname, ret);
}

void
er_print::indxo_list (bool showtab, FILE *outf)
{
  Vector<bool> *indxtab = NULL;
  char *name;
  char *i18n_name;
  if (!getenv ("_BUILDING_MANPAGE"))
    fprintf (outf, GTXT (" Index Object Types Available:\n"));
  else
    fprintf (outf, GTXT ("*Index Object Types*\n"));
  Vector<void*>*res = dbeGetIndxObjDescriptions (0);
  if (showtab)
    indxtab = dbev->get_IndxTabState ();
  if (res == NULL)  // If none is defined
    return;
  Vector<char*> *indxo_names = (Vector<char*> *)res->fetch (1);
  Vector<char*> *indxo_i18nnames = (Vector<char*> *)res->fetch (3);
  Vector<char*> *indxo_exprlist = (Vector<char*> *)res->fetch (5);
  int size = indxo_names->size ();
  for (int i = 0; i < size; i++)
    {
      name = indxo_names->fetch (i);
      i18n_name = indxo_i18nnames->fetch (i);
      if (indxtab)
	{
	  if ((i18n_name != NULL) && (strcmp (i18n_name, name) != 0))
	    fprintf (outf, NTXT ("  %c %s (%s)\n"), indxtab->fetch (i) ? 'T' : 'F',
		     i18n_name, name);
	  else
	    fprintf (outf, NTXT ("  %c %s\n"), indxtab->fetch (i) ? 'T' : 'F', name);
	}
      else
	{
	  if (i18n_name != NULL && strcmp (i18n_name, indxo_names->fetch (i)) != 0)
	    fprintf (outf, NTXT ("  %s (%s)"), i18n_name, name);
	  else
	    fprintf (outf, NTXT ("  %s"), name);
	}
      char *exprs = indxo_exprlist->fetch (i);
      if (exprs != NULL)
	fprintf (outf, NTXT (" \t%s\n"), exprs);
      else
	fprintf (outf, NTXT ("\n"));
    }
  delete indxo_names;
  if (showtab)
    delete res;
}

void
er_print::ifreq ()
{
  dbev->ifreq (out_file);
}

void
er_print::dump_nodes ()
{
  dbev->dump_nodes (out_file);
}

void
er_print::dump_stacks ()
{
  dbeSession->dump_stacks (out_file);
}

void
er_print::dump_unk_pcs ()
{
  // Dump the nodes associated with the <Unknown> function
  dbev->get_path_tree ()->dumpNodes (out_file, dbeSession->get_Unknown_Function ());

  // Dump the nodes associated with the <no Java callstack recorded> function
  Vector<Function *> *matches = dbeSession->match_func_names ("<no Java callstack recorded>", dbev->get_name_format ());
  if (matches == NULL || matches->size () == 0)
    fprintf (out_file, GTXT ("No %s functions found\n"), "<no Java callstack recorded>");
  else
    {
      Function *fitem;
      int index;
      Vec_loop (Function*, matches, index, fitem)
      {
	dbev->get_path_tree ()->dumpNodes (out_file, fitem);
      }
      delete matches;
    }
}

void
er_print::dump_funcs (char *arg1)
{
  if (arg1 == NULL || strlen (arg1) == 0)
    dbeSession->dump_segments (out_file);
  else
    {
      Vector<Function *> *matches = dbeSession->match_func_names (arg1, dbev->get_name_format ());
      if (matches == NULL)
	{
	  fprintf (stderr, GTXT ("Invalid argument `%s' -- not a regular expression\n"), arg1);
	  return;
	}
      fprintf (out_file, GTXT ("%d Function's match `%s'\n"), (int) matches->size (), arg1);
      Function *fitem;
      int index;
      Vec_loop (Function*, matches, index, fitem)
      {
	fprintf (out_file, NTXT (" %5lld -- %s (%s) [%s]\n"),
		 (ll_t) fitem->id, fitem->get_name (),
		 (fitem->module ? fitem->module->file_name : NTXT ("<unknown>")),
		 ((fitem->module && fitem->module->loadobject) ?
		  get_basename (fitem->module->loadobject->get_name ()) : NTXT ("<unknown>")));
      }
      delete matches;
    }
}

void
er_print::dump_dataobjects (char *arg1)
{
  // Force computation of data objects, to update master table; discard it
  MetricList *mlist1 = dbev->get_metric_list (MET_DATA);
  Hist_data *data = dbev->get_hist_data (mlist1, Histable::DOBJECT, 0, Hist_data::ALL);
  delete data;

  if (arg1 == NULL || strlen (arg1) == 0)
    dbeSession->dump_dataobjects (out_file);
  else
    {
      Vector<DataObject *> *matches = dbeSession->match_dobj_names (arg1);
      if (matches == NULL)
	{
	  fprintf (stderr, GTXT ("Invalid argument `%s' -- not a regular expression\n"), arg1);
	  return;
	}
      fprintf (out_file, GTXT ("%d DataObject's match `%s'\n"), (int) matches->size (), arg1);
      DataObject *ditem;
      int index;
      Vec_loop (DataObject*, matches, index, ditem)
      {
	fprintf (out_file, NTXT (" %5lld -- %s\n"), (ll_t) ditem->id, ditem->get_name ());
      }
      delete matches;
    }
}

void
er_print::dump_map ()
{
  dbeSession->dump_map (out_file);
}

void
er_print::dump_entities ()
{
  int ent_prop_ids[] = {PROP_THRID, PROP_LWPID, PROP_CPUID, PROP_EXPID, -1};

  // loop over experiments
  for (int exp_id = 0; exp_id < dbeSession->nexps (); exp_id++)
    {
      Experiment *exp = dbeSession->get_exp (exp_id);
      fprintf (out_file, GTXT ("Experiment %d (%s)\n"),
	       exp_id, exp->get_expt_name ());

      for (int kk = 0; ent_prop_ids[kk] != -1; kk++)
	{
	  int ent_prop_id = ent_prop_ids[kk];
	  Vector<void*> *elist = dbeGetEntities (0, exp_id, ent_prop_id);
	  if (!elist)
	    continue;
	  Vector<int> *entity_vals = (Vector<int> *) elist->fetch (0);
	  Vector<char*> *jthr_names = (Vector<char*> *)elist->fetch (1);
	  Vector<char*> *jthr_g_names = (Vector<char*> *)elist->fetch (2);
	  Vector<char*> *jthr_p_names = (Vector<char*> *)elist->fetch (3);
	  Vector<char*> *entity_name = (Vector<char*> *)elist->fetch (4);
	  int nent = entity_vals->size ();
	  char *entName = entity_name->fetch (0);
	  if (!entName)
	    entName = NTXT ("<unknown>");
	  fprintf (out_file, GTXT ("  %s\n"), entName);
	  for (int i = 0; i < nent; i++)
	      fprintf (out_file, GTXT ("    %s=%d: %s, %s, %s\n"),
		       entName, entity_vals->fetch (i),
		       jthr_names->fetch (i) != NULL ? jthr_names->fetch (i) : NTXT ("N/A"),
		       jthr_g_names->fetch (i) != NULL ? jthr_g_names->fetch (i) : NTXT ("N/A"),
		       jthr_p_names->fetch (i) != NULL ? jthr_names->fetch (i) : NTXT ("N/A"));
	  destroy (elist);
	}
    }
}

void
er_print::dump_stats ()
{
  Emsg *m = dbev->get_path_tree ()->fetch_stats ();
  while (m != NULL)
    {
      fprintf (out_file, NTXT ("%s\n"), m->get_msg ());
      m = m->next;
    }
  dbev->get_path_tree ()->delete_stats ();
}

void
er_print::dump_proc_warnings ()
{
  PathTree *p = dbev->get_path_tree ();
  if (p == NULL)
    return;
  Emsg *m = p->fetch_warnings ();
  while (m != NULL)
    {
      fprintf (out_file, NTXT ("%s\n"), m->get_msg ());
      m = m->next;
    }
  dbev->get_path_tree ()->delete_warnings ();
}

void
er_print::print_cmd (er_print_common_display *cd)
{
  cd->set_out_file (out_file);
  cd->data_dump ();
}

FILE *
er_print::set_outfile (char *cmd, FILE *&set_file, bool append)
{
  FILE *new_file;
  char *home;
  if (!strcasecmp (cmd, NTXT ("-")))
    {
      new_file = stdout;
      out_fname = NTXT ("<stdout>");
    }
  else if (!strcasecmp (cmd, NTXT ("--")))
    {
      new_file = stderr;
      out_fname = NTXT ("<stderr>");
    }
  else
    {
      char *fname;
      char *path = NULL;
      // Handle ~ in file names
      home = getenv (NTXT ("HOME"));
      if ((fname = strstr (cmd, NTXT ("~/"))) != NULL && home != NULL)
	path = dbe_sprintf (NTXT ("%s/%s"), home, fname + 2);
      else if ((fname = strstr (cmd, NTXT ("~"))) != NULL && home != NULL)
	path = dbe_sprintf (NTXT ("/home/%s"), fname + 1);
      else
	path = xstrdup (cmd);
      new_file = fopen (path, append ? NTXT ("a") : NTXT ("w"));
      if (new_file == NULL)
	{
	  fprintf (stderr, GTXT ("Error: Unable to open file: %s\n"), cmd);
	  free (path);
	  return NULL;
	}
      out_fname = path;
    }
  if (set_file && set_file != stdout)
    fclose (set_file);
  set_file = new_file;
  return set_file;
}
