/* Copyright (C) 2021 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 <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <libintl.h>
//#include <libgen.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "util.h"
#include "Dbe.h"
#include "StringBuilder.h"
#include "DbeSession.h"
#include "DbeView.h"
#include "Settings.h"
#include "Print.h"
#include "DbeView.h"
#include "Experiment.h"
#include "MetricList.h"
#include "Module.h"
#include "Function.h"
#include "DataSpace.h"
#include "DataObject.h"
#include "FilterExp.h"
#include "LoadObject.h"
#include "Emsg.h"
#include "Table.h"
#include "DbeFile.h"
#include "CallStack.h"

int
er_print_common_display::open (Print_params *params)
{
  pr_params = *params;
  pr_params.name = dbe_strdup (params->name);
  if (params->dest == DEST_PRINTER)
    {
      tmp_file = dbeSession->get_tmp_file_name (NTXT ("print"), false);
      dbeSession->tmp_files->append (strdup (tmp_file));
      out_file = fopen (tmp_file, NTXT ("w"));
    }
  else if (params->dest == DEST_OPEN_FILE)
    out_file = pr_params.openfile;
  else
    out_file = fopen (pr_params.name, NTXT ("w"));

  if (out_file == NULL)
    // Failure
    return 1;
  return 0;
}

bool
er_print_common_display::print_output ()
{
  char *sys_call;
  bool ret = true;
  if (pr_params.dest != DEST_OPEN_FILE)
    fclose (out_file);

  if (pr_params.dest == DEST_PRINTER)
    {
      if (streq ((char *) pr_params.name, NTXT ("")))
	sys_call = dbe_sprintf ("(/usr/bin/lp -c -n%d %s) 2>/dev/null 1>&2",
				pr_params.ncopies, tmp_file);
      else
	sys_call = dbe_sprintf ("(/usr/bin/lp -c -d%s -n%d %s) 2>/dev/null 1>&2",
				pr_params.name, pr_params.ncopies, tmp_file);
      if (system (sys_call) != 0)
	ret = false;
      unlink (tmp_file);
      free (sys_call);
    }

  return ret;
}

// Return the report. If the report size is greater than max, return truncated report
// Allocates memory, so the caller should free this memory.

char *
er_print_common_display::get_output (int maxsize)
{
  off_t max = (off_t) maxsize;
  if (out_file != (FILE *) NULL)
    {
      fclose (out_file); // close tmp_file
      out_file = (FILE *) NULL;
    }
  struct stat sbuf;
  int st = stat (tmp_file, &sbuf);
  if (st == 0)
    {
      off_t sz = sbuf.st_size;
      if (sz > max)
	return dbe_sprintf (GTXT ("Error: report is too long.\n"));
      if (sz <= 0)
	return dbe_sprintf (GTXT ("Error: empty temporary file: %s\n"),
			    tmp_file);
      max = sz;
    }

  FILE *f = fopen (tmp_file, "r");
  if (f == NULL)
    return dbe_sprintf (GTXT ("Error: cannot open temporary file: %s\n"),
			tmp_file);
  char *report = (char *) malloc (max);
  if (report)
    {
      if (1 != fread (report, max - 1, 1, f))
	{
	  fclose (f);
	  free (report);
	  return dbe_sprintf (GTXT ("Error: cannot read temporary file: %s\n"),
			      tmp_file);
	}
      report[max - 1] = 0;
    }
  fclose (f);
  return report;
}

void
er_print_common_display::header_dump (int exp_idx)
{
  if (load && (exp_idx == exp_idx1))
    {
      load = false;
      print_load_object (out_file);
    }
  print_header (dbeSession->get_exp (exp_idx), out_file);
}

char *
pr_load_objects (Vector<LoadObject*> *loadobjects, char *lead)
{
  int size, i;
  LoadObject *lo;
  Emsg *m;
  char *msg;
  StringBuilder sb;
  char *lo_name;
  size = loadobjects->size ();
  for (i = 0; i < size; i++)
    {
      lo = loadobjects->fetch (i);
      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;
	}

      // print the segment name
      sb.append (lead);
      sb.append (NTXT (" "));
      sb.append (lo->get_name ());
      sb.append (NTXT (" ("));
      sb.append (lo->get_pathname ());
      sb.append (NTXT (")\n"));

      // and any warnings
      m = lo->fetch_warnings ();
      if (m != NULL)
	{
	  msg = pr_mesgs (m, NULL, NTXT ("       "));
	  sb.append (msg);
	  free (msg);
	}
    }
  return sb.toString ();
}

char *
pr_mesgs (Emsg *msg, const char *null_str, const char *lead)
{
  Emsg *m;
  StringBuilder sb;
  if (msg == NULL)
    return dbe_strdup (null_str);
  for (m = msg; m; m = m->next)
    {
      sb.append (lead);
      sb.append (m->get_msg ());
      sb.append (NTXT ("\n"));
    }
  return sb.toString ();
}

void
print_load_object (FILE *out_file)
{
  Vector<LoadObject*> *loadobjects = dbeSession->get_text_segments ();
  char *msg = pr_load_objects (loadobjects, NTXT ("\t"));
  fprintf (out_file, GTXT ("Load Object Coverage:\n"));
  fprintf (out_file, NTXT ("%s"), msg);
  fprintf (out_file,
	   "----------------------------------------------------------------\n");
  free (msg);
  delete loadobjects;
}

void
print_header (Experiment *exp, FILE *out_file)
{
  fprintf (out_file, GTXT ("Experiment: %s\n"), exp->get_expt_name ());
  char *msg = pr_mesgs (exp->fetch_notes (), NTXT (""), NTXT (""));
  fprintf (out_file, NTXT ("%s"), msg);
  free (msg);

  msg = pr_mesgs (exp->fetch_errors (), GTXT ("No errors\n"), NTXT (""));
  fprintf (out_file, NTXT ("%s"), msg);
  free (msg);

  msg = pr_mesgs (exp->fetch_warnings (), GTXT ("No warnings\n"), NTXT (""));
  fprintf (out_file, NTXT ("%s"), msg);
  free (msg);

  msg = pr_mesgs (exp->fetch_comments (), NTXT (""), NTXT (""));
  fprintf (out_file, NTXT ("%s"), msg);
  free (msg);

  msg = pr_mesgs (exp->fetch_pprocq (), NTXT (""), NTXT (""));
  fprintf (out_file, NTXT ("%s"), msg);
  free (msg);
}

void
get_width (Hist_data *data,
	   MetricList *metrics_list, Metric::HistMetric *hist_metric)
{
  Metric *mitem;
  Metric::HistMetric *hitem;
  int last_column;
  int index;

  // find the last visible column.
  last_column = 0;
  Vec_loop (Metric*, metrics_list->get_items (), index, mitem)
  {
    if (mitem->is_visible () || mitem->is_tvisible () || mitem->is_pvisible ())
      last_column = index;
  }

  // find the width for each column.

  Vec_loop (Metric*, metrics_list->get_items (), index, mitem)
  {
    hitem = &hist_metric[index];

    if (mitem->is_visible ())
      {
	if (mitem->get_vtype () == VT_LABEL)
	  {
	    if (index == last_column)
	      hitem->maxvalue_width = 0;
	    else
	      hitem->maxvalue_width = data->name_maxlen ();
	    // truncate names which will be too long
	    if (hitem->maxvalue_width > MAX_LEN - 3)
	      hitem->maxvalue_width = MAX_LEN - 3;
	  }
	else if (mitem->get_vtype () == VT_ADDRESS)
	  {
	    hitem->maxvalue_width = data->value_maxlen (index);
	    if (hitem->maxvalue_width < 13)
	      hitem->maxvalue_width = 13;
	  }
	else
	  hitem->maxvalue_width = data->value_maxlen (index);
      }
    else
      hitem->maxvalue_width = 0;

    if (mitem->is_tvisible ())
      {
	if (mitem->get_visbits () & VAL_RATIO)
	  hitem->maxtime_width = data->value_maxlen (index);
	else
	  hitem->maxtime_width = data->time_maxlen (index,
						    dbeSession->get_clock (-1));
      }
    else
      {
	hitem->maxtime_width = 0;
      }
  }
}

void
get_format (char **fmt_int, char **fmt_real0, char **fmt_real1,
	    MetricList *metrics_list, Metric::HistMetric *hist_metric,
	    int nspace)
{
  Metric *mitem;
  Metric::HistMetric *hitem;
  int index;
  int visible, tvisible, pvisible;
  size_t maxlen;
  bool prev;
  char numstr[MAX_LEN], pstr_int[MAX_LEN],
	  pstr_real0[MAX_LEN], pstr_real1[MAX_LEN];

  // find the width for each column.
  Vec_loop (Metric*, metrics_list->get_items (), index, mitem)
  {
    hitem = &hist_metric[index];
    visible = mitem->is_visible ();
    tvisible = mitem->is_tvisible ();
    pvisible = mitem->is_pvisible ();
    *pstr_int = *pstr_real0 = *pstr_real1 = '\0';

    // Get 'Show Value' format
    const char *sign = (mitem->get_visbits () & VAL_DELTA) ? "+" : "";
    if (visible)
      {
	maxlen = hitem->maxvalue_width;
	switch (mitem->get_vtype2 ())
	  {
	  case VT_DOUBLE:
	    if (mitem->get_visbits () & VAL_RATIO)
	      {
		snprintf (numstr, sizeof (numstr), "x %%#%d.0lf    ",
			  (int) (maxlen - 3));
		snprintf (pstr_real0, sizeof (pstr_real0), numstr, 0.0);
		snprintf (pstr_real1, sizeof (pstr_real1), "x%%s%%%d.3lf ",
			  (int) maxlen);
	      }
	    else
	      {
		snprintf (numstr, sizeof (numstr), "%%#%s%d.0lf    ", sign,
			  (int) (maxlen - 3));
		snprintf (pstr_real0, sizeof (pstr_real0), numstr, 0.0);
		snprintf (pstr_real1, sizeof (pstr_real1), "%%s%%%s%d.3lf ",
			  sign, (int) maxlen);
	      }
	    break;
	  case VT_INT:
	    snprintf (pstr_int, sizeof (pstr_int), "%%%s%dd ", sign,
		      (int) maxlen);
	    break;
	  case VT_LLONG:
	    snprintf (pstr_int, sizeof (pstr_int), "%%%s%dlld ", sign,
		      (int) maxlen);
	    break;
	  case VT_ULLONG:
	    snprintf (pstr_int, sizeof (pstr_int), "%%%s%dllu ", sign,
		      (int) maxlen);
	    break;
	  case VT_ADDRESS:
	    if (maxlen <= 13)
	      {
		snprintf (pstr_int, sizeof (pstr_int), "%%%dd:0x%%08x", 2);
	      }
	    else
	      {
		snprintf (pstr_int, sizeof (pstr_int), "%%%dd:0x%%08x",
			  (int) (maxlen - 13));
	      }
	    break;
	  case VT_FLOAT:
	    snprintf (numstr, sizeof (numstr), "%%#%d.0f    ",
		      (int) (maxlen - 3));
	    snprintf (pstr_real0, sizeof (pstr_real0), numstr, 0.0);
	    snprintf (pstr_real1, sizeof (pstr_real1), "%%%d.3f ",
		      (int) maxlen);
	    break;
	  case VT_SHORT:
	    snprintf (pstr_int, sizeof (pstr_int), "%%%dhu ", (int) maxlen);
	    break;
	  case VT_LABEL:
	    if (maxlen == 0) // last column
	      snprintf (pstr_int, sizeof (pstr_int), NTXT ("%%s%%s"));
	    else if (maxlen + nspace >= MAX_LEN - 3)
	      snprintf (pstr_int, sizeof (pstr_int), NTXT ("%%s%%-%d.%ds "),
			MAX_LEN - 7, MAX_LEN - 7);
	    else
	      snprintf (pstr_int, sizeof (pstr_int), NTXT ("%%s%%-%ds "),
			(int) (maxlen + nspace));
	    break;
	  default:
	    break;
	  }
      }

    // Get 'Show Time' format
    if (tvisible)
      {
	maxlen = hitem->maxtime_width;
	if (mitem->get_visbits () & VAL_RATIO)
	  {
	    snprintf (numstr, sizeof (numstr), " %%%s#%d.0lf    ",
		      sign, (int) (maxlen - 3));
	    snprintf (pstr_real0, sizeof (pstr_real0), numstr, 0.0);
	    snprintf (pstr_real1, sizeof (pstr_real1), "%%s%%%s%d.3lf ",
		      sign, (int) maxlen);
	  }
	else
	  {
	    snprintf (numstr, sizeof (numstr), "%%%s#%d.0lf    ",
		      sign, (int) (maxlen - 3));
	    snprintf (pstr_real0, sizeof (pstr_real0), numstr, 0.0);
	    snprintf (pstr_real1, sizeof (pstr_real1), "%%s%%%s%d.3lf ",
		      sign, (int) maxlen);
	  }
      }

    // Copy format
    if (*pstr_int)
      fmt_int[index] = dbe_strdup (pstr_int);
    else
      fmt_int[index] = NULL;

    if (*pstr_real0)
      fmt_real0[index] = dbe_strdup (pstr_real0);
    else
      fmt_real0[index] = NULL;

    if (*pstr_real1)
      fmt_real1[index] = dbe_strdup (pstr_real1);
    else
      fmt_real1[index] = NULL;

    // Set total width
    hitem->width = 0;
    if (hitem->maxvalue_width > 0)
      {
	hitem->width += hitem->maxvalue_width;
	prev = true;
      }
    else
      prev = false;

    if (hitem->maxtime_width > 0)
      {
	if (prev)
	  hitem->width++;
	hitem->width += hitem->maxtime_width;
	prev = true;
      }

    if (pvisible)
      {
	if (prev)
	  hitem->width++;
	hitem->width += 6; // adjust to change format from xx.yy%
      }
    if (visible || tvisible || pvisible)
      mitem->legend_width (hitem, 2);
  }
}

static char *
delTrailingBlanks (char *s)
{
  for (int i = (int) strlen (s) - 1; i >= 0 && s[i] == ' '; i--)
    s[i] = 0;
  return s;
}

/**
 * Print the 3-line header with column heads for the metrics
 * Return offset of "Name" column (this is needed to print Callers-Callees)
 */
int
print_label (FILE *out_file, MetricList *metrics_list,
	     Metric::HistMetric *hist_metric, int space)
{
  char line0[2 * MAX_LEN], line1[2 * MAX_LEN];
  char line2[2 * MAX_LEN], line3[2 * MAX_LEN];
  int name_offset = 0;
  *line0 = *line1 = *line2 = *line3 = '\0';
  Vector<Metric*> *mlist = metrics_list->get_items ();
  for (int index = 0, mlist_sz = mlist->size (); index < mlist_sz; index++)
    {
      Metric *mitem = mlist->fetch (index);
      if (mitem->is_visible () || mitem->is_tvisible () || mitem->is_pvisible ())
	{
	  Metric::HistMetric *hitem = hist_metric + index;
	  char *fmt;
	  if (index > 0 && mitem->get_type () == Metric::ONAME)
	    {
	      fmt = NTXT (" %-*s");
	      name_offset = strlen (line1);
	    }
	  else
	    fmt = NTXT ("%-*s");
	  int width = (int) hitem->width;
	  size_t len = strlen (line1);
	  snprintf (line1 + len, sizeof (line1) - len, fmt, width,
		    hitem->legend1);
	  len = strlen (line2);
	  snprintf (line2 + len, sizeof (line2) - len, fmt, width,
		    hitem->legend2);
	  len = strlen (line3);
	  snprintf (line3 + len, sizeof (line3) - len, fmt, width,
		    hitem->legend3);
	  len = strlen (line0);
	  snprintf (line0 + len, sizeof (line0) - len, fmt, width,
		    mitem->legend ? mitem->legend : NTXT (""));
	}
    }
  char *s = delTrailingBlanks (line0);
  if (*s)
    fprintf (out_file, NTXT ("%*s%s\n"), space, NTXT (""), s);
  fprintf (out_file, NTXT ("%*s%s\n"), space, NTXT (""), delTrailingBlanks (line1));
  fprintf (out_file, NTXT ("%*s%s\n"), space, NTXT (""), delTrailingBlanks (line2));
  fprintf (out_file, NTXT ("%*s%s\n"), space, NTXT (""), delTrailingBlanks (line3));
  return name_offset;
}

static int
print_one_visible (FILE *out_file, char *fmt_int, char *fmt_real0, char *fmt_real1,
		   TValue *value, int visbits)
{
  int nc = 0;
  switch (value->tag)
    {
    case VT_DOUBLE:
      if (value->d == 0.0)
	nc = fprintf (out_file, fmt_real0);
      else
	{
	  if (visbits & VAL_RATIO)
	    {
	      if (value->d > 99.999)
		nc = fprintf (out_file, fmt_real1, NTXT (">"), 99.999);
	      else
		nc = fprintf (out_file, fmt_real1, NTXT (" "), value->d);
	    }
	  else
	    nc = fprintf (out_file, fmt_real1, NTXT (""), value->d);
	}
      break;
    case VT_INT:
      nc = fprintf (out_file, fmt_int, value->i);
      break;
    case VT_LLONG:
    case VT_ULLONG:
      nc = fprintf (out_file, fmt_int, value->ll);
      break;
    case VT_ADDRESS:
      nc = fprintf (out_file, fmt_int, ADDRESS_SEG (value->ll),
		    ADDRESS_OFF (value->ll));
      break;
    case VT_FLOAT:
      if (value->f == 0.0)
	nc = fprintf (out_file, fmt_real0);
      else
	nc = fprintf (out_file, fmt_real1, value->f);
      break;
    case VT_SHORT:
      nc = fprintf (out_file, fmt_int, value->s);
      break;
      // ignoring the following cases (why?)
    case VT_HRTIME:
    case VT_LABEL:
    case VT_OFFSET:
      break;
    }
  return nc;
}

static int
print_one_tvisible (FILE *out_file, char *fmt_real0, char *fmt_real1,
		    TValue *value, int visbits, int clock)
{
  int nc;
  if (value->ll == 0LL)
    nc = fprintf (out_file, fmt_real0);
  else
    {
      if (visbits & VAL_RATIO)
	{
	  if (value->d > 99.999)
	    nc = fprintf (out_file, fmt_real1, NTXT (">"), 99.999);
	  else
	    nc = fprintf (out_file, fmt_real1, NTXT (" "), value->d);
	}
      else
	nc = fprintf (out_file, fmt_real1, "", 1.e-6 * value->ll / clock);
    }
  return nc;
}

static void
print_one (FILE *out_file, Hist_data *data, Hist_data::HistItem *item,
	   char **fmt_int, char **fmt_real0, char **fmt_real1,
	   MetricList *metrics_list, Metric::HistMetric *hist_metric,
	   char *mark, Histable::NameFormat nfmt)
{
  Metric *mitem;
  Metric::HistMetric *hitem;
  int index, nc, np, i;
  int visible, tvisible, pvisible;
  TValue *value;
  double percent;

  if (item->type == Module::AT_EMPTY)
    {
      fprintf (out_file, nl);
      return;
    }

  // set name_is_Total
  int name_is_Total = 0;

  Vec_loop (Metric*, metrics_list->get_items (), index, mitem)
  {
    if (mitem->get_type () != Metric::ONAME)
      continue;
    name_is_Total = strcmp (item->obj->get_name (), GTXT ("<Total>")) == 0;
    break;
  }

  np = 0;
  Vec_loop (Metric*, metrics_list->get_items (), index, mitem)
  {
    visible = mitem->is_visible ();
    tvisible = mitem->is_tvisible ();
    pvisible = mitem->is_pvisible ();

    // alignment
    for (i = 0; i < np; i++)
      fputc (' ', out_file);

    hitem = &hist_metric[index];
    nc = 0;
    if (tvisible)
      {
	value = &(item->value[index]);
	nc = print_one_tvisible (out_file, fmt_real0[index], fmt_real1[index],
				 value, mitem->get_visbits (),
				 dbeSession->get_clock (-1));
      }
    else
      nc = 0;

    if (visible)
      {
	if (mitem->get_vtype () == VT_LABEL)
	  {
	    value = &(item->value[index]);
	    if (value->tag == VT_OFFSET)
	      nc += fprintf (out_file, fmt_int[index], mark,
			     ((DataObject*) (item->obj))->get_offset_name ());
	    else
	      nc += fprintf (out_file, fmt_int[index], mark,
			     item->obj->get_name (nfmt));
	  }
	else if (name_is_Total &&
		 (strcmp (mitem->get_username (), "Block Covered %") == 0
		  || strcmp (mitem->get_username (), "Instr Covered %") == 0))
	  {
	    char stmp[128];
	    snprintf (stmp, sizeof (stmp), fmt_int[index], 0);

	    /* and now blank that '0' out */
	    for (int ii = 0; ii < 128; ii++)
	      {
		if (stmp[ii] != '0')
		  continue;
		stmp[ii] = ' ';
		break;
	      }
	    nc += fprintf (out_file, stmp);
	  }
	else
	  nc += print_one_visible (out_file, fmt_int[index], fmt_real0[index],
				   fmt_real1[index], &(item->value[index]),
				   mitem->get_visbits ());
      }

    if (pvisible)
      {
	percent = data->get_percentage (item->value[index].to_double (), index);
	if (percent == 0.0)
	  // adjust to change format from xx.yy%
	  nc += fprintf (out_file, NTXT ("%#4.0f   "), 0.);
	else
	  // adjust format below to change format from xx.yy%
	  nc += fprintf (out_file, NTXT ("%6.2f "), (100.0 * percent));
      }
    np = (int) (hitem->width - nc);
  }
  fprintf (out_file, nl);
}

void
print_content (FILE *out_file, Hist_data *data,
	       char **fmt_int, char **fmt_real0, char **fmt_real1,
	       MetricList *metrics_list, Metric::HistMetric *hist_metric,
	       int limit, Histable::NameFormat nfmt)
{
  // printing contents.
  for (int i = 0; i < limit; i++)
    {
      Hist_data::HistItem *item = data->fetch (i);
      print_one (out_file, data, item, fmt_int, fmt_real0, fmt_real1,
		 metrics_list, hist_metric, NTXT (" "), nfmt);
    }
}

er_print_histogram::er_print_histogram (DbeView *_dbev, Hist_data *data,
					MetricList *metrics_list,
					Print_mode disp_type, int limit,
					char *sort_name, Histable *sobj,
					bool show_load, bool show_header)
{
  hist_data = data;
  mlist = metrics_list;
  type = disp_type;
  number_entries = limit;
  sort_metric = sort_name;
  sel_obj = sobj;
  dbev = _dbev;
  exp_idx1 = 0;
  exp_idx2 = dbeSession->nexps () - 1;
  load = show_load;
  header = show_header;
}

void
er_print_histogram::dump_list (int limit)
{
  Histable::NameFormat nfmt = dbev->get_name_format ();
  StringBuilder sb;
  char *title = NULL; // No title for some formats
  enum PrintMode pm = dbev->get_printmode ();

  // create a header line, except for delimiter-separated list output
  if (pm != PM_DELIM_SEP_LIST)
    {
      if (hist_data->type == Histable::FUNCTION)
	sb.append (GTXT ("Functions sorted by metric: "));
      else if (hist_data->type == Histable::INSTR)
	sb.append (GTXT ("PCs sorted by metric: "));
      else if (hist_data->type == Histable::LINE)
	sb.append (GTXT ("Lines sorted by metric: "));
      else if (hist_data->type == Histable::DOBJECT)
	sb.append (GTXT ("Dataobjects sorted by metric: "));
      else
	sb.append (GTXT ("Objects sorted by metric: "));
      sb.append (sort_metric);
      title = sb.toString ();
    }

  switch (pm)
    {
    case PM_TEXT:
      {
	Metric::HistMetric *hist_metric = hist_data->get_histmetrics ();
	fprintf (out_file, NTXT ("%s\n\n"), title); //print title
	hist_data->print_label (out_file, hist_metric, 0);
	hist_data->print_content (out_file, hist_metric, limit);
	fprintf (out_file, nl);
	break;
      }
    case PM_HTML:
      {
	print_html_title (out_file, title);
	print_html_label (out_file, mlist);
	print_html_content (out_file, hist_data, mlist, limit, nfmt);
	print_html_trailer (out_file);
	break;
      }
    case PM_DELIM_SEP_LIST:
      {
	char delim = dbev->get_printdelimiter ();
	print_delim_label (out_file, mlist, delim);
	print_delim_content (out_file, hist_data, mlist, limit, nfmt, delim);
	print_delim_trailer (out_file, delim);
	break;
      }
    }
  free (title);
}

void
er_print_histogram::dump_annotated_dataobjects (Vector<int> *marks,
						int ithreshold)
{
  Metric::HistMetric *hist_metric;
  char **fmt_int, **fmt_real0, **fmt_real1;
  int no_metrics = mlist->get_items ()->size ();
  int name_index = -1;
  Histable::NameFormat nfmt = dbev->get_name_format ();
  if (!dbeSession->is_datamode_available ())
    fprintf (out_file,
	     GTXT ("No dataspace information recorded in experiments\n\n"));

  Hist_data *layout_data = dbev->get_data_space ()->get_layout_data (hist_data, marks, ithreshold);

  for (int mind = 0; mind < no_metrics; mind++)
    if (mlist->get_items ()->fetch (mind)->get_type () == Metric::ONAME)
      name_index = mind;

  fmt_int = new char*[no_metrics];
  fmt_real0 = new char*[no_metrics];
  fmt_real1 = new char*[no_metrics];
  hist_metric = new Metric::HistMetric[no_metrics];

  // use new layout_data to set metric format
  get_width (hist_data, mlist, hist_metric);
  get_format (fmt_int, fmt_real0, fmt_real1, mlist, hist_metric, 0);
  snprintf (hist_metric[name_index].legend2, MAX_LEN, GTXT ("* +offset .element"));
  print_label (out_file, mlist, hist_metric, 3);
  fprintf (out_file, nl);
  for (long i = 0; i < layout_data->size (); i++)
    {
      Hist_data::HistItem* item = layout_data->fetch (i);
      if (marks->find (i) != -1)
	fprintf (out_file, NTXT ("## "));
      else
	fprintf (out_file, NTXT ("   "));
      print_one (out_file, layout_data, item, fmt_int, fmt_real0, fmt_real1,
		 mlist, hist_metric, NTXT (" "), nfmt);
    }
  fprintf (out_file, nl);

  // free format strings.
  for (int i = 0; i < no_metrics; i++)
    {
      free (fmt_int[i]);
      free (fmt_real0[i]);
      free (fmt_real1[i]);
    }
  delete[] fmt_int;
  delete[] fmt_real0;
  delete[] fmt_real1;
  delete[] hist_metric;
  delete layout_data;
}

void
er_print_histogram::dump_detail (int limit)
{
  Histable *obj;
  Hist_data *current_data;
  Histable::Type htype;
  TValue *values;
  double dvalue, percent;
  MetricList *prop_mlist = new MetricList (mlist);
  Metric *mitem;
  int index, i;
  size_t max_len, len, smax_len, slen;
  Vaddr pc;
  Module *module;
  LoadObject *loadobject;
  char *sname, *oname, *lname, *alias, *mangle;
  char fmt_name[MAX_LEN];
  char fmt_elem[MAX_LEN];
  char fmt_real1[MAX_LEN], fmt_real2[MAX_LEN];
  char fmt_int1[MAX_LEN], fmt_int2[MAX_LEN];
  char fmt_long1[MAX_LEN], fmt_long2[MAX_LEN], fmt_long3[MAX_LEN];
  char fmt_int0[MAX_LEN], fmt_long0[MAX_LEN];
  char numstr[MAX_LEN];

  Histable::NameFormat nfmt = dbev->get_name_format ();

  // Check max. length of metrics names
  max_len = smax_len = 0;

  Vec_loop (Metric*, prop_mlist->get_items (), index, mitem)
  {
    mitem->set_vvisible (true);
    if (mitem->get_vtype () == VT_LABEL)
      continue;

    if (mitem->get_subtype () != Metric::STATIC)
      {
	mitem->set_pvisible (true);
	len = hist_data->value_maxlen (index);
	if (max_len < len)
	  max_len = len;
	slen = strlen (mitem->get_name ());
	if (smax_len < slen)
	  smax_len = slen;
      }
  }

  // now get the length of the other (non-performance-data) messages
  if (hist_data->type == Histable::FUNCTION)
    {
      slen = strlen (GTXT ("Source File"));
      if (smax_len < slen)
	smax_len = slen;
      slen = strlen (GTXT ("Object File"));
      if (smax_len < slen)
	smax_len = slen;
      slen = strlen (GTXT ("Load Object"));
      if (smax_len < slen)
	smax_len = slen;
      slen = strlen (GTXT ("Mangled Name"));
      if (smax_len < slen)
	smax_len = slen;
      slen = strlen (GTXT ("Aliases"));
      if (smax_len < slen)
	smax_len = slen;
    }
  else if (hist_data->type == Histable::DOBJECT)
    {
      slen = strlen (GTXT ("Scope"));
      if (smax_len < slen)
	smax_len = slen;
      slen = strlen (GTXT ("Type"));
      if (smax_len < slen)
	smax_len = slen;
      slen = strlen (GTXT ("Member of"));
      if (smax_len < slen)
	smax_len = slen;
      slen = strlen (GTXT ("Offset (bytes)"));
      if (smax_len < slen)
	smax_len = slen;
      slen = strlen (GTXT ("Size (bytes)"));
      if (smax_len < slen)
	smax_len = slen;
      slen = strlen (GTXT ("Elements"));
      if (smax_len < slen)
	smax_len = slen;
    }
  snprintf (fmt_name, sizeof (fmt_name), NTXT ("\t%%%ds: "), (int) smax_len);
  snprintf (fmt_elem, sizeof (fmt_elem), NTXT ("\t%%%ds  "), (int) smax_len);
  snprintf (numstr, sizeof (numstr), "%%#%d.0lf    (  %#1.0f %%%%%%%%)\n",
	    (int) (max_len - 3), 0.);
  snprintf (fmt_real1, sizeof (fmt_real1), numstr, 0.0);
  snprintf (fmt_real2, sizeof (fmt_real2), NTXT ("%%%d.3lf (%%5.1f%%%%)\n"),
	    (int) max_len);
  snprintf (fmt_int0, sizeof (fmt_int0), NTXT ("%%%dd\n"), (int) max_len);
  snprintf (numstr, sizeof (numstr), NTXT ("%%%dd (  %#1.0f %%%%%%%%)\n"),
	    (int) max_len, 0.);
  snprintf (fmt_int1, sizeof (fmt_int1), numstr, 0);
  snprintf (fmt_int2, sizeof (fmt_int2), NTXT ("%%%dd (%%5.1f%%%%)\n"),
	    (int) max_len);
  snprintf (fmt_long0, sizeof (fmt_long0), NTXT ("%%%dllu\n"), (int) max_len);
  snprintf (numstr, sizeof (numstr), NTXT ("%%%dd (  %#1.0f %%%%%%%%)\n"),
	    (int) max_len, 0.);
  snprintf (fmt_long1, sizeof (fmt_long1), numstr, 0);
  snprintf (fmt_long2, sizeof (fmt_long2), "%%%dllu (%%5.1f%%%%)\n",
	    (int) max_len);
  snprintf (numstr, sizeof (numstr), NTXT ("\t%%%ds %%%%%dllu\n"),
	    (int) (smax_len + 1), (int) max_len);
  snprintf (fmt_long3, sizeof (fmt_long3), numstr, GTXT ("Count:"));
  snprintf (numstr, sizeof (numstr), "%%%dd (  %#1.0f %%%%%%%%) %%#%d.0lf\n",
	    (int) max_len, 0., (int) (max_len - 6));

  // now loop over the objects
  int num_printed_items = 0;
  for (i = 0; i < hist_data->size (); i++)
    {
      if (hist_data->type == Histable::FUNCTION)
	{
	  if (num_printed_items >= limit)
	    break;
	  obj = sel_obj ? sel_obj : hist_data->fetch (i)->obj;
	  htype = obj->get_type ();

	  // ask the view for all the data for the object
	  // xxxxx may be expensive to rescan all packets via get_hist_data()
	  current_data = dbev->get_hist_data (prop_mlist,
					      htype, 0, Hist_data::SELF, obj);
	  if (current_data->size () == 0)
	    continue;
	  values = current_data->fetch (0)->value;
	}
      else
	{
	  obj = hist_data->fetch (i)->obj;
	  DataObject *dobj = (DataObject*) obj;
	  if (sel_obj)
	    {
	      // print selected item and its members
	      if (sel_obj != obj
		  && (DataObject*) sel_obj != dobj->get_parent ())
		// not a match, advance to next item
		continue;
	    }
	  else if (num_printed_items >= limit)
	    break;
	  htype = obj->get_type ();
	  values = hist_data->fetch (i)->value;
	  current_data = hist_data;
	}

      if (num_printed_items)
	// if this isn't the first one, add a blank line
	fprintf (out_file, NTXT ("\n"));
      num_printed_items++;

      // Print full object name
      if (htype != Histable::DOBJECT)
	fprintf (out_file, NTXT ("%s\n"), obj->get_name (nfmt));
      else
	{
	  DataObject *dobj = (DataObject*) obj;
	  if (!dobj->get_parent ())
	    fprintf (out_file, NTXT ("%s\n"), obj->get_name (nfmt));
	  else
	    fprintf (out_file, NTXT ("    %s\n"), obj->get_name (nfmt));
	}

      Vec_loop (Metric*, prop_mlist->get_items (), index, mitem)
      {
	if (mitem->get_vtype () == VT_LABEL)
	  continue;
	if (mitem->get_subtype () == Metric::STATIC
	    && htype == Histable::DOBJECT)
	  continue;
	fprintf (out_file, fmt_name, mitem->get_name ());

	if (mitem->get_value_styles () & VAL_PERCENT)
	  {
	    dvalue = values[index].to_double ();
	    switch (mitem->get_vtype ())
	      {
	      case VT_DOUBLE:
		if (dvalue == 0.0)
		  fprintf (out_file, fmt_real1);
		else
		  fprintf (out_file, fmt_real2, dvalue, 100.0
			  * current_data->get_percentage (dvalue, index));
		break;
	      case VT_INT:
		if (dvalue == 0.0)
		  fprintf (out_file, fmt_int1);
		else
		  fprintf (out_file, fmt_int2, (int) dvalue, 100.0
			  * current_data->get_percentage (dvalue, index));
		break;
	      case VT_LLONG:
	      case VT_ULLONG:
		if (values[index].ll == 0LL)
		  {
		    if (mitem->is_time_val ())
		      {
			fprintf (out_file, fmt_real1);
			fprintf (out_file, fmt_long3, 0LL);
		      }
		    else
		      fprintf (out_file, fmt_long1);
		  }
		else
		  {
		    percent = 100.0 *
			    current_data->get_percentage (dvalue, index);
		    if (mitem->is_time_val ())
		      {
			dvalue /= 1.e+6 * dbeSession->get_clock (-1);
			fprintf (out_file, fmt_real2, dvalue, percent);
			fprintf (out_file, fmt_long3, values[index].ll);
		      }
		    else
		      fprintf (out_file, fmt_long2, values[index].ll,
			       percent);
		  }
		break;
	      default:
		break;
	      }
	  }
	else
	  {
	    switch (mitem->get_vtype ())
	      {
	      case VT_INT:
		fprintf (out_file, fmt_int0, values[index].i);
		break;
	      case VT_LLONG:
	      case VT_ULLONG:
		fprintf (out_file, fmt_long0, values[index].ll);
		break;
	      case VT_ADDRESS:
		pc = values[index].ll;
		fprintf (out_file, NTXT ("%u:0x%08x\n"), ADDRESS_SEG (pc),
			 ADDRESS_OFF (pc));
		break;
	      case VT_DOUBLE:
		if (values[index].d == 0.0)
		  fprintf (out_file, fmt_real1);
		else
		  fprintf (out_file, "\t%*.3lf\n", (int) (max_len - 5), values[index].d);
		break;
	      default:
		break;
	      }
	  }
      }

      // now add the descriptive information about the object
      if (htype != Histable::DOBJECT)
	{
	  Function *func = (Function*) obj->convertto (Histable::FUNCTION);
	  if (func && func->get_type () == Histable::FUNCTION)
	    {
	      // Print the source/object/load-object files & aliases
	      oname = lname = alias = NULL;
	      sname = func->getDefSrcName ();
	      mangle = func->get_mangled_name ();
	      if (mangle && streq (func->get_name (), mangle))
		mangle = NULL;
	      module = func->module;
	      if (module)
		{
		  oname = module->get_name ();
		  loadobject = module->loadobject;
		  if (loadobject)
		    {
		      lname = loadobject->get_pathname ();
		      alias = loadobject->get_alias (func);
		    }
		}

	      if (htype == Histable::INSTR && dbeSession->is_datamode_available ())
		alias = ((DbeInstr*) obj)->get_descriptor ();

	      fprintf (out_file, fmt_name, GTXT ("Source File"));
	      if (sname)
		fprintf (out_file, NTXT ("%s"), sname);
	      fprintf (out_file, NTXT ("\n"));

	      fprintf (out_file, fmt_name, GTXT ("Object File"));
	      if (oname)
		fprintf (out_file, NTXT ("%s"), oname);
	      fprintf (out_file, NTXT ("\n"));

	      fprintf (out_file, fmt_name, GTXT ("Load Object"));
	      if (lname)
		fprintf (out_file, NTXT ("%s"), lname);
	      fprintf (out_file, NTXT ("\n"));

	      fprintf (out_file, fmt_name, GTXT ("Mangled Name"));
	      if (mangle)
		fprintf (out_file, NTXT ("%s"), mangle);
	      fprintf (out_file, NTXT ("\n"));
	      fprintf (out_file, fmt_name, GTXT ("Aliases"));
	      if (alias)
		fprintf (out_file, NTXT ("%s"), alias);
	      fprintf (out_file, NTXT ("\n"));
	    }
	}
      else
	{
	  // Print the dataobject information
	  DataObject *dobj = (DataObject*) obj;
	  Histable *scope = dobj->get_scope ();

	  // print the scope
	  fprintf (out_file, fmt_name, GTXT ("Scope"));
	  if (!scope)
	    fprintf (out_file, GTXT ("(Global)\n"));
	  else switch (scope->get_type ())
	      {
	      case Histable::FUNCTION:
		fprintf (out_file, NTXT ("%s(%s)\n"),
			 ((Function*) scope)->module->get_name (),
			 scope->get_name ());
		break;
	      case Histable::LOADOBJECT:
	      case Histable::MODULE:
	      default:
		fprintf (out_file, NTXT ("%s\n"), scope->get_name ());
	      }

	  // print the type name
	  fprintf (out_file, fmt_name, GTXT ("Type"));
	  if (dobj->get_typename ())
	    fprintf (out_file, NTXT ("%s\n"), dobj->get_typename ());
	  else
	    fprintf (out_file, GTXT ("(Synthetic)\n"));

	  // print the offset
	  if (dobj->get_offset () != -1)
	    {
	      if (dobj->get_parent ())
		{
		  fprintf (out_file, fmt_name, GTXT ("Member of"));
		  fprintf (out_file, NTXT ("%s\n"), dobj->get_parent ()->get_name ());
		}
	      fprintf (out_file, fmt_name, GTXT ("Offset (bytes)"));
	      fprintf (out_file, NTXT ("%lld\n"), (long long) dobj->get_offset ());
	    }
	  // print the size
	  if (dobj->get_size ())
	    {
	      fprintf (out_file, fmt_name, GTXT ("Size (bytes)"));
	      fprintf (out_file, NTXT ("%lld\n"), (long long) dobj->get_size ());
	    }
	}
      if (hist_data->type == Histable::FUNCTION)
	delete current_data;
    }
  if (num_printed_items == 0 && sel_obj)
    fprintf (stderr,
	     GTXT ("Error: Specified item `%s' had no recorded metrics.\n"),
	     sel_obj->get_name ());
  delete prop_mlist;
}

static Metric::HistMetric *
allocateHistMetric (int no_metrics)
{
  Metric::HistMetric *hist_metric = new Metric::HistMetric[no_metrics];
  for (int i = 0; i < no_metrics; i++)
    {
      Metric::HistMetric *hm = &hist_metric[i];
      hm->init ();
    }
  return hist_metric;
}

void
er_print_histogram::dump_gprof (int limit)
{
  StringBuilder sb;
  Histable *obj;
  Hist_data *callers;
  Hist_data *callees;
  Hist_data *center;

  int no_metrics = mlist->get_items ()->size ();
  Metric::HistMetric *hist_metric = allocateHistMetric (no_metrics);
  for (int i = 0; i < limit; i++)
    {
      obj = sel_obj ? sel_obj : hist_data->fetch (i)->obj;
      callers = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
				     Hist_data::CALLERS, obj);
      callees = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
				     Hist_data::CALLEES, obj);
      center = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
				    Hist_data::SELF, obj);
      callers->update_max (hist_metric);
      callees->update_max (hist_metric);
      center->update_max (hist_metric);
      callers->update_legend_width (hist_metric);
      callers->print_label (out_file, hist_metric, 0);
      callers->print_content (out_file, hist_metric, callers->size ());

      if (center->size () > 0)
	{
	  center->update_total (callers->get_totals ());
	  sb.setLength (0);
	  center->print_row (&sb, 0, hist_metric, NTXT ("*"));
	  sb.toFileLn (out_file);
	}
      callees->print_content (out_file, hist_metric, callees->size ());
      fprintf (out_file, nl);
      delete callers;
      delete callees;
      delete center;
    }
  delete[] hist_metric;
}

// dump an annotated file
void
dump_anno_file (FILE *fp, Histable::Type type, Module *module, DbeView *dbev,
		MetricList *mlist, TValue *ftotal, const char *srcFile,
		Function *func, Vector<int> *marks, int threshold, int vis_bits,
		int src_visible, bool hex_visible, bool src_only)
{
  int no_metrics, lspace, mspace, tspace,
	  remain, mindex, next_mark, hidx,
	  index;
  Metric *mitem;
  char **fmt_int, **fmt_real0, **fmt_real1, buf[MAX_LEN];
  Hist_data::HistItem *item;

  SourceFile *srcContext = NULL;
  bool func_scope = dbev == NULL ? false : dbev->get_func_scope ();
  if (srcFile)
    {
      srcContext = module->findSource (srcFile, false);
      if (srcContext == NULL)
	{
	  Vector<SourceFile*> *includes = module->includes;
	  char *bname = get_basename (srcFile);
	  for (int i = 0, sz = includes ? includes->size () : 0; i < sz; i++)
	    {
	      SourceFile *sf = includes->fetch (i);
	      if (streq (get_basename (sf->get_name ()), bname))
		{
		  srcContext = sf;
		  break;
		}
	    }
	}
      if (func)
	func_scope = true;
    }
  else if (func)
    srcContext = func->getDefSrc ();

  Hist_data *hdata = module->get_data (dbev, mlist, type, ftotal, srcContext,
				       func, marks, threshold, vis_bits,
				       src_visible, hex_visible,
				       func_scope, src_only);

  if (hdata == NULL)
    return;

  // force the name metric to be invisible
  MetricList *nmlist = hdata->get_metric_list ();
  nmlist->find_metric (GTXT ("name"), Metric::STATIC)->clear_all_visbits ();
  no_metrics = nmlist->get_items ()->size ();
  fmt_int = new char*[no_metrics];
  fmt_real0 = new char*[no_metrics];
  fmt_real1 = new char*[no_metrics];
  Metric::HistMetric *hist_metric = hdata->get_histmetrics ();

  // lspace is for max line number that's inserted; use to set width
  int max_lineno = 0;
  Vec_loop (Hist_data::HistItem*, hdata, hidx, item)
  {
    if (!item->obj)
      continue;
    if (item->obj->get_type () == Histable::LINE
	&& ((DbeLine*) item->obj)->lineno > max_lineno)
      max_lineno = ((DbeLine*) item->obj)->lineno;
    else if (item->obj->get_type () == Histable::INSTR
	     && ((DbeInstr*) item->obj)->lineno > max_lineno)
      max_lineno = ((DbeInstr*) item->obj)->lineno;
  }

  lspace = snprintf (buf, sizeof (buf), NTXT ("%d"), max_lineno);

  // mspace is the space needed for all metrics, and the mark, if any
  mspace = 0;
  if (nmlist->get_items ()->size () > 0)
    {
      mspace = 3; // mark "## "
      Vec_loop (Metric*, nmlist->get_items (), index, mitem)
      {
	if (mitem->is_visible () || mitem->is_tvisible ()
	    || mitem->is_pvisible ())
	  mspace += (int) hist_metric[index].width;
      }
    }
  tspace = 0;
  remain = (mspace + lspace + 3) % 8; // " " before, ". " after line#
  if (remain)
    { // tab alignment
      tspace = 8 - remain;
      mspace += tspace;
    }
  mindex = 0;
  next_mark = (mindex < marks->size ()) ? marks->fetch (mindex) : -1;

  // Print the header for this list
  SourceFile *sf = srcContext ? srcContext : module->getMainSrc ();
  char *src_name = sf->dbeFile->get_location_info ();
  DbeFile *df = module->dbeFile;
  if (df == NULL || (df->filetype & DbeFile::F_JAVACLASS) == 0)
    df = module->loadobject->dbeFile;
  char *lo_name = df->get_location_info ();
  char *dot_o_name = lo_name;
  if (module->dot_o_file)
    dot_o_name = module->dot_o_file->dbeFile->get_location_info ();
  fprintf (fp, GTXT ("Source file: %s\nObject file: %s\nLoad Object: %s\n\n"),
	   src_name, dot_o_name, lo_name);

  // Print metric labels
  if (nmlist->get_items ()->size () != 0)
    print_label (fp, nmlist, hist_metric, 3);

  // determine the name metric (not printed as a metric, though)
  int lind = nmlist->get_listorder (GTXT ("name"), Metric::STATIC);

  // now loop over the data rows -- the lines in the annotated source/disasm,
  //	including index lines, compiler commentary, etc.
  StringBuilder sb;
  Vec_loop (Hist_data::HistItem*, hdata, hidx, item)
  {
    sb.setLength (0);
    if (item->type == Module::AT_DIS || item->type == Module::AT_QUOTE
	|| item->type == Module::AT_SRC)
      {
	// does this line get a high-metric mark?
	if (hidx == next_mark)
	  {
	    sb.append (NTXT ("## "));
	    mindex++;
	    next_mark = (mindex < marks->size ()) ? marks->fetch (mindex) : -1;
	  }
	else
	  sb.append (NTXT ("   "));

	hdata->print_row (&sb, hidx, hist_metric, NTXT (" "));
	sb.toFile (fp);
	for (int i = sb.length (); i < mspace; i++)
	  {
	    fputc (' ', fp);
	  }
      }
    else
      // this line does not get any metrics; insert blanks in lieu of them
      for (int i = 0; i < mspace; i++)
	fputc (' ', fp);

    switch (item->type)
      {
      case Module::AT_SRC_ONLY:
	if (item->obj == NULL)
	  fprintf (fp, NTXT ("%*s. "), lspace + 1, "?");
	else
	  fprintf (fp, "%*d. ", lspace + 1, ((DbeLine*) item->obj)->lineno);
	break;

      case Module::AT_SRC:
	fprintf (fp, "%*d. ", lspace + 1, ((DbeLine*) item->obj)->lineno);
	break;
      case Module::AT_FUNC:
      case Module::AT_QUOTE:
	fprintf (fp, NTXT ("%*c"), lspace + 3, ' ');
	break;
      case Module::AT_DIS:
      case Module::AT_DIS_ONLY:
	if (item->obj == NULL || ((DbeInstr*) item->obj)->lineno == -1)
	  fprintf (fp, "%*c[%*s] ", lspace + 3, ' ', lspace, "?");
	else
	  fprintf (fp, "%*c[%*d] ", lspace + 3, ' ', lspace,
		   ((DbeInstr*) item->obj)->lineno);
	break;
      case Module::AT_COM:
      case Module::AT_EMPTY:
	break;

      }
    if (item->value[lind].l == NULL)
      item->value[lind].l = dbe_strdup (GTXT ("INTERNAL ERROR: missing line text"));
    fprintf (fp, NTXT ("%s\n"), item->value[lind].l);
  }
  delete[] fmt_int;
  delete[] fmt_real0;
  delete[] fmt_real1;
  delete hdata;
}

void
er_print_histogram::dump_annotated ()
{
  Vector<int> *marks = new Vector<int>;
  Function *anno_func = (Function *) sel_obj;
  Module *module = anno_func ? anno_func->module : NULL;

  if (hist_data->type == Histable::DOBJECT)
    dump_annotated_dataobjects (marks, number_entries); // threshold
  else if (number_entries == 0)
      // Annotated source
    dump_anno_file (out_file, Histable::LINE, module, dbev, mlist,
		    hist_data->get_totals ()->value, NULL, anno_func, marks,
		    dbev->get_thresh_src (), dbev->get_src_compcom (),
		    dbev->get_src_visible (), dbev->get_hex_visible (), true);
  else
    // Annotated disassembly
    dump_anno_file (out_file, Histable::INSTR, module, dbev, mlist,
		    hist_data->get_totals ()->value, NULL, anno_func, marks,
		    dbev->get_thresh_dis (), dbev->get_dis_compcom (),
		    dbev->get_src_visible (), dbev->get_hex_visible (), true);
}

void
er_print_histogram::data_dump ()
{
  int limit;
  if (hist_data->get_status () == Hist_data::SUCCESS)
    {
      if (sort_metric[0] == '\n')
	{ // csingle Callers-Callees entry
	  sort_metric++;
	  fprintf (out_file, NTXT ("%s\n\n"), sort_metric);
	}
      else if (!sel_obj && type != MODE_LIST)
	{
	  if (hist_data->type == Histable::FUNCTION)
	    fprintf (out_file,
		     GTXT ("Functions sorted by metric: %s\n\n"), sort_metric);
	  else if (hist_data->type == Histable::DOBJECT)
	    fprintf (out_file, GTXT ("Dataobjects sorted by metric: %s\n\n"),
		     sort_metric);
	  else
	    fprintf (out_file,
		     GTXT ("Objects sorted by metric: %s\n\n"), sort_metric);
	}
      limit = hist_data->size ();
      if ((number_entries > 0) && (number_entries < limit))
	limit = number_entries;

      switch (type)
	{
	case MODE_LIST:
	  dump_list (limit);
	  break;
	case MODE_DETAIL:
	  dump_detail (limit);
	  break;
	case MODE_GPROF:
	  dump_gprof (limit);
	  break;
	case MODE_ANNOTATED:
	  dump_annotated ();
	  break;
	}
    }
  else
    fprintf (out_file, GTXT ("Get_Hist_data call failed %d\n"),
	     (int) hist_data->get_status ());
}

/*
 * Class er_print_ctree to print functions call tree
 */
er_print_ctree::er_print_ctree (DbeView *_dbev, Vector<Histable*> *_cstack,
				Histable *_sobj, int _limit)
{
  dbev = _dbev;
  cstack = _cstack;
  sobj = _sobj;
  limit = _limit;
  print_row = 0;
  exp_idx1 = 0;
  exp_idx2 = dbeSession->nexps () - 1;
  load = false;
  header = false;
}

void
er_print_ctree::data_dump ()
{
  StringBuilder sb;
  Hist_data::HistItem *total;
  sb.append (GTXT ("Functions Call Tree. Metric: "));
  char *s = dbev->getSort (MET_CALL_AGR);
  sb.append (s);
  free (s);
  sb.toFileLn (out_file);
  fprintf (out_file, NTXT ("\n"));
  mlist = dbev->get_metric_list (MET_CALL_AGR);

  // Change cstack: add sobj to the end of cstack
  cstack->append (sobj);
  Hist_data *center = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
					   Hist_data::SELF, cstack);
  Hist_data *callers = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
					    Hist_data::CALLERS, cstack);
  Hist_data *callees = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
					    Hist_data::CALLEES, cstack);

  // Restore cstack
  int last = cstack->size () - 1;
  cstack->remove (last);

  // Prepare formats
  int no_metrics = mlist->size ();

  // calculate max. width using data from callers, callees, center
  hist_metric = allocateHistMetric (no_metrics);
  callers->update_max (hist_metric);
  callees->update_max (hist_metric);
  center->update_max (hist_metric);
  callers->update_legend_width (hist_metric);
  callers->print_label (out_file, hist_metric, 0); // returns Name column offset

  print_row = 0;
  // Pass real total to print_children()
  total = center->get_totals ();
  print_children (center, 0, sobj, NTXT (" "), total);

  // Free memory
  cstack->reset ();
  delete callers;
  delete callees;
  delete center;
  delete[] hist_metric;
}

/*
 * Recursive method print_children prints Call Tree elements.
 */
void
er_print_ctree::print_children (Hist_data *data, int index, Histable *my_obj,
				char * prefix, Hist_data::HistItem *total)
{
  StringBuilder buf;
  const char *P0 = "+-";
  const char *P2 = "  |";
  const char *P1 = "  ";

  // If limit exceeded - return
  ++print_row;
  if (limit > 0 && print_row > limit)
    return;

  if (my_obj == NULL)
    return; // should never happen

  // Prepare prefix
  buf.append (prefix);
  if (buf.endsWith (P2))
    {
      int len = buf.length () - 1;
      buf.setLength (len);
    }
  buf.append (P0);

  // Change cstack: add my_obj to the end of cstack
  cstack->append (my_obj);

  // Print current node info
  char * my_prefix = buf.toString ();

  // Replace parent's total values with real total values
  data->update_total (total); // Needed to to calculate percentage only
  buf.setLength (0);
  data->print_row (&buf, index, hist_metric, my_prefix);
  buf.toFileLn (out_file);
  free (my_prefix);

  // Get children
  Hist_data *callees = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
					    Hist_data::CALLEES, cstack);
  int nc = callees->size ();
  if (nc > 0)
    {
      // Print children
      Hist_data::HistItem *item;
      Histable *ch_obj;
      char *ch_prefix;
      buf.setLength (0);
      buf.append (prefix);
      buf.append (P2);
      ch_prefix = buf.toString ();
      for (int i = 0; i < nc - 1; i++)
	{
	  item = callees->fetch (i);
	  ch_obj = item->obj;
	  print_children (callees, i, ch_obj, ch_prefix, total);
	}
      free (ch_prefix);
      buf.setLength (0);
      buf.append (prefix);
      buf.append (P1);
      ch_prefix = buf.toString ();
      item = callees->fetch (nc - 1);
      ch_obj = item->obj;
      print_children (callees, nc - 1, ch_obj, ch_prefix, total);
      free (ch_prefix);
    }

  // Restore cstack
  int last = cstack->size () - 1;
  cstack->remove (last);
  delete callees;
  return;
}

er_print_gprof::er_print_gprof (DbeView *_dbev, Vector<Histable*> *_cstack)
{
  dbev = _dbev;
  cstack = _cstack;
  exp_idx1 = 0;
  exp_idx2 = dbeSession->nexps () - 1;
  load = false;
  header = false;
}

void
er_print_gprof::data_dump ()
{
  StringBuilder sb;
  sb.append (GTXT ("Callers and callees sorted by metric: "));
  char *s = dbev->getSort (MET_CALL);
  sb.append (s);
  free (s);
  sb.toFileLn (out_file);
  fprintf (out_file, NTXT ("\n"));

  MetricList *mlist = dbev->get_metric_list (MET_CALL);
  Hist_data *center = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
					   Hist_data::SELF, cstack);
  Hist_data *callers = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
					    Hist_data::CALLERS, cstack);
  Hist_data *callees = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
					    Hist_data::CALLEES, cstack);

  mlist = center->get_metric_list ();
  int no_metrics = mlist->get_items ()->size ();

  // update max. width for callers/callees/center function item
  Metric::HistMetric *hist_metric = allocateHistMetric (no_metrics);
  callers->update_max (hist_metric);
  callees->update_max (hist_metric);
  center->update_max (hist_metric);

  callers->update_legend_width (hist_metric);
  int name_offset = callers->print_label (out_file, hist_metric, 0); // returns Name column offset
  // Print Callers
  sb.setLength (0);
  for (int i = 0; i < name_offset; i++)
    sb.append (NTXT ("="));
  if (name_offset > 0)
    sb.append (NTXT (" "));
  char *line1 = sb.toString ();
  char *line2;
  if (callers->size () > 0)
    line2 = GTXT ("Callers");
  else
    line2 = GTXT ("No Callers");
  fprintf (out_file, NTXT ("%s%s\n"), line1, line2);
  callers->print_content (out_file, hist_metric, callers->size ());

  // Print Stack Fragment
  line2 = GTXT ("Stack Fragment");
  fprintf (out_file, NTXT ("\n%s%s\n"), line1, line2);

  for (long i = 0, last = cstack->size () - 1; i <= last; ++i)
    {
      sb.setLength (0);
      if (i == last && center->size () > 0)
	{
	  center->update_total (callers->get_totals ()); // Needed to to calculate percentage only
	  center->print_row (&sb, center->size () - 1, hist_metric, NTXT (" "));
	}
      else
	{
	  for (int n = name_offset; n > 0; n--)
	    sb.append (NTXT (" "));
	  if (name_offset > 0)
	    sb.append (NTXT (" "));
	  sb.append (cstack->get (i)->get_name ());
	}
      sb.toFileLn (out_file);
    }

  // Print Callees
  if (callees->size () > 0)
    line2 = GTXT ("Callees");
  else
    line2 = GTXT ("No Callees");
  fprintf (out_file, NTXT ("\n%s%s\n"), line1, line2);
  callees->print_content (out_file, hist_metric, callees->size ());
  fprintf (out_file, nl);
  free (line1);
  delete callers;
  delete callees;
  delete center;
  delete[] hist_metric;
}

er_print_leaklist::er_print_leaklist (DbeView *_dbev, bool show_leak,
				      bool show_alloca, int _limit)
{
  dbev = _dbev;
  leak = show_leak;
  alloca = show_alloca;
  limit = _limit;
}

// Output routine for leak list only
void
er_print_leaklist::data_dump ()
{
  CStack_data *lam;
  CStack_data::CStack_item *lae;
  int index;
  if (!dbeSession->is_leaklist_available ())
    fprintf (out_file, GTXT ("No leak or allocation information recorded in experiments\n\n"));

  MetricList *origmlist = dbev->get_metric_list (MET_NORMAL);
  if (leak)
    {
      // make a copy of the metric list, and set metrics for leaks
      MetricList *nmlist = new MetricList (origmlist);
      nmlist->set_metrics ("e.heapleakbytes:e.heapleakcnt:name", true,
			   dbev->get_derived_metrics ());

      // now make a compacted version of it to get the right indices
      MetricList *mlist = new MetricList (nmlist);
      delete nmlist;

      // fetch the callstack data
      lam = dbev->get_cstack_data (mlist);

      // now print it
      if (lam && lam->size () != 0)
	{
	  fprintf (out_file, GTXT ("Summary Results: Distinct Leaks = %d, Total Instances = %lld, Total Bytes Leaked = %lld\n\n"),
		   (int) lam->size (), lam->total->value[1].ll,
		   lam->total->value[0].ll);

	  Vec_loop (CStack_data::CStack_item*, lam->cstack_items, index, lae)
	  {
	    fprintf (out_file,
		     GTXT ("Leak #%d, Instances = %lld, Bytes Leaked = %lld\n"),
		     index + 1, lae->value[1].ll, lae->value[0].ll);
	    if (lae->stack != NULL)
	      for (int i = lae->stack->size () - 1; i >= 0; i--)
		{
		  DbeInstr *instr = lae->stack->fetch (i);
		  fprintf (out_file, NTXT ("  %s\n"), instr->get_name ());
		}
	    fprintf (out_file, NTXT ("\n"));
	    if (index + 1 == limit) break;
	  }
	}
      else
	fprintf (out_file, GTXT ("No leak information\n\n"));
      delete lam;
      delete mlist;
    }

  if (alloca)
    {
      // make a copy of the metric list, and set metrics for leaks
      MetricList *nmlist = new MetricList (origmlist);
      nmlist->set_metrics ("e.heapallocbytes:e.heapalloccnt:name",
			   true, dbev->get_derived_metrics ());

      // now make a compacted version of it to get the right indices
      MetricList *mlist = new MetricList (nmlist);
      delete nmlist;

      // fetch the callstack data
      lam = dbev->get_cstack_data (mlist);

      // now print it
      if (lam && lam->size () != 0)
	{
	  fprintf (out_file, GTXT ("Summary Results: Distinct Allocations = %d, Total Instances = %lld, Total Bytes Allocated = %lld\n\n"),
		   (int) lam->size (), lam->total->value[1].ll,
		   lam->total->value[0].ll);
	  Vec_loop (CStack_data::CStack_item*, lam->cstack_items, index, lae)
	  {
	    fprintf (out_file, GTXT ("Allocation #%d, Instances = %lld, Bytes Allocated = %lld\n"),
		     index + 1, lae->value[1].ll, lae->value[0].ll);
	    if (lae->stack != NULL)
	      for (int i = lae->stack->size () - 1; i >= 0; i--)
		{
		  DbeInstr *instr = lae->stack->fetch (i);
		  fprintf (out_file, NTXT ("  %s\n"), instr->get_name ());
		}
	    fprintf (out_file, NTXT ("\n"));
	    if (index + 1 == limit) break;
	  }
	}
      else
	fprintf (out_file, GTXT ("No allocation information\n\n"));
      delete lam;
      delete mlist;
    }
}

er_print_heapactivity::er_print_heapactivity (DbeView *_dbev,
					      Histable::Type _type,
					      bool _printStat, int _limit)
{
  dbev = _dbev;
  type = _type;
  printStat = _printStat;
  limit = _limit;
}

void
er_print_heapactivity::printCallStacks (Hist_data *hist_data)
{
  Hist_data::HistItem *hi;
  HeapData *hData;
  long stackId;
  int size = hist_data->size ();
  if (limit > 0 && limit < size)
    size = limit;

  Histable::NameFormat fmt = dbev->get_name_format ();
  for (int i = 0; i < size; i++)
    {
      hi = hist_data->fetch (i);
      hData = (HeapData*) hi->obj;
      stackId = hData->id;
      if (i != 0)
	fprintf (out_file, NTXT ("\n"));

      fprintf (out_file, NTXT ("%s\n"), hData->get_name (fmt));
      if (hData->getAllocCnt () > 0)
	{
	  fprintf (out_file, GTXT ("Instances = %d  "),
		   (int) (hData->getAllocCnt ()));
	  fprintf (out_file, GTXT ("Bytes Allocated = %lld\n"),
		   (long long) hData->getAllocBytes ());
	}

      if (hData->getLeakCnt () > 0)
	{
	  fprintf (out_file, GTXT ("Instances = %d  "),
		   (int) (hData->getLeakCnt ()));
	  fprintf (out_file, GTXT ("Bytes Leaked = %lld\n"),
		   (long long) hData->getLeakBytes ());
	}

      // There is no stack trace for <Total>
      if (i == 0)
	continue;

      // LIBRARY VISIBILITY pass extra argument if necessary to get hide stack
      Vector<Histable*> *instrs = CallStack::getStackPCs ((void *) stackId);
      if (instrs != NULL)
	{
	  int stSize = instrs->size ();
	  for (int j = 0; j < stSize; j++)
	    {
	      Histable *instr = instrs->fetch (j);
	      if (instr != NULL)
		fprintf (out_file, NTXT ("  %s\n"), instr->get_name ());
	    }
	  delete instrs;
	}
    }
}

void
er_print_heapactivity::printStatistics (Hist_data *hist_data)
{
  Hist_data::HistItem *hi;
  HeapData *hDataTotal;
  hi = hist_data->fetch (0);
  hDataTotal = (HeapData*) hi->obj;
  Vector<hrtime_t> *pTimestamps;
  if (hDataTotal->getPeakMemUsage () > 0)
    {
      fprintf (out_file, GTXT ("\nProcess With Highest Peak Memory Usage\n"));
      fprintf (out_file,
	       "-------------------------------------------------------\n");
      fprintf (out_file, GTXT ("Heap size bytes                   %lld\n"),
	       (long long) hDataTotal->getPeakMemUsage ());
      fprintf (out_file, GTXT ("Experiment Id                     %d\n"),
	       (int) (hDataTotal->getUserExpId ()));
      fprintf (out_file, GTXT ("Process Id                        %d\n"),
	       (int) (hDataTotal->getPid ()));
      pTimestamps = hDataTotal->getPeakTimestamps ();
      if (pTimestamps != NULL)
	for (int i = 0; i < pTimestamps->size (); i++)
	  fprintf (out_file,
		   GTXT ("Time of peak                      %.3f (secs.)\n"),
		   (double) (pTimestamps->fetch (i) / (double) NANOSEC));
    }

  if (hDataTotal->getAllocCnt () > 0)
    {
      fprintf (out_file, GTXT ("\nMemory Allocations Statistics\n"));
      fprintf (out_file,
	       GTXT ("Allocation Size Range             Allocations          \n"));
      fprintf (out_file,
	       "-------------------------------------------------------\n");
      if (hDataTotal->getA0KB1KBCnt () > 0)
	fprintf (out_file, NTXT ("  0KB - 1KB                       %d\n"),
		 hDataTotal->getA0KB1KBCnt ());
      if (hDataTotal->getA1KB8KBCnt () > 0)
	fprintf (out_file, NTXT ("  1KB - 8KB                       %d\n"),
		 hDataTotal->getA1KB8KBCnt ());
      if (hDataTotal->getA8KB32KBCnt () > 0)
	fprintf (out_file, NTXT ("  8KB - 32KB                      %d\n"),
		 hDataTotal->getA8KB32KBCnt ());
      if (hDataTotal->getA32KB128KBCnt () > 0)
	fprintf (out_file, NTXT ("  32KB - 128KB                    %d\n"),
		 hDataTotal->getA32KB128KBCnt ());
      if (hDataTotal->getA128KB256KBCnt () > 0)
	fprintf (out_file, NTXT ("  128KB - 256KB                   %d\n"),
		 hDataTotal->getA128KB256KBCnt ());
      if (hDataTotal->getA256KB512KBCnt () > 0)
	fprintf (out_file, NTXT ("  256KB - 512KB                   %d\n"),
		 hDataTotal->getA256KB512KBCnt ());
      if (hDataTotal->getA512KB1000KBCnt () > 0)
	fprintf (out_file, NTXT ("  512KB - 1000KB                  %d\n"),
		 hDataTotal->getA512KB1000KBCnt ());
      if (hDataTotal->getA1000KB10MBCnt () > 0)
	fprintf (out_file, NTXT ("  1000KB - 10MB                   %d\n"),
		 hDataTotal->getA1000KB10MBCnt ());
      if (hDataTotal->getA10MB100MBCnt () > 0)
	fprintf (out_file, NTXT ("  10MB - 100MB                    %d\n"),
		 hDataTotal->getA10MB100MBCnt ());
      if (hDataTotal->getA100MB1GBCnt () > 0)
	fprintf (out_file, NTXT ("  100MB - 1GB                     %d\n"),
		 hDataTotal->getA100MB1GBCnt ());
      if (hDataTotal->getA1GB10GBCnt () > 0)
	fprintf (out_file, NTXT ("  1GB - 10GB                      %d\n"),
		 hDataTotal->getA1GB10GBCnt ());
      if (hDataTotal->getA10GB100GBCnt () > 0)
	fprintf (out_file, NTXT ("  10GB - 100GB                    %d\n"),
		 hDataTotal->getA10GB100GBCnt ());
      if (hDataTotal->getA100GB1TBCnt () > 0)
	fprintf (out_file, NTXT ("  100GB - 1TB                     %d\n"),
		 hDataTotal->getA100GB1TBCnt ());
      if (hDataTotal->getA1TB10TBCnt () > 0)
	fprintf (out_file, NTXT ("  1TB - 10TB                      %d\n"),
		 hDataTotal->getA1TB10TBCnt ());
      fprintf (out_file, GTXT ("\nSmallest allocation bytes         %lld\n"),
	       (long long) hDataTotal->getASmallestBytes ());
      fprintf (out_file, GTXT ("Largest allocation bytes          %lld\n"),
	       (long long) hDataTotal->getALargestBytes ());
      fprintf (out_file, GTXT ("Total allocations                 %d\n"),
	       hDataTotal->getAllocCnt ());
      fprintf (out_file, GTXT ("Total bytes                       %lld\n"),
	       (long long) hDataTotal->getAllocBytes ());
    }

  if (hDataTotal->getLeakCnt () > 0)
    {
      fprintf (out_file, GTXT ("\nMemory Leaks Statistics\n"));
      fprintf (out_file,
	       GTXT ("Leak Size Range                   Leaks              \n"));
      fprintf (out_file,
	       "-------------------------------------------------------\n");
      if (hDataTotal->getL0KB1KBCnt () > 0)
	fprintf (out_file, NTXT ("  0KB - 1KB                       %d\n"),
		 hDataTotal->getL0KB1KBCnt ());
      if (hDataTotal->getL1KB8KBCnt () > 0)
	fprintf (out_file, NTXT ("  1KB - 8KB                       %d\n"),
		 hDataTotal->getL1KB8KBCnt ());
      if (hDataTotal->getL8KB32KBCnt () > 0)
	fprintf (out_file, NTXT ("  8KB - 32KB                      %d\n"),
		 hDataTotal->getL8KB32KBCnt ());
      if (hDataTotal->getL32KB128KBCnt () > 0)
	fprintf (out_file, NTXT ("  32KB - 128KB                    %d\n"),
		 hDataTotal->getL32KB128KBCnt ());
      if (hDataTotal->getL128KB256KBCnt () > 0)
	fprintf (out_file, NTXT ("  128KB - 256KB                   %d\n"),
		 hDataTotal->getL128KB256KBCnt ());
      if (hDataTotal->getL256KB512KBCnt () > 0)
	fprintf (out_file, NTXT ("  256KB - 512KB                   %d\n"),
		 hDataTotal->getL256KB512KBCnt ());
      if (hDataTotal->getL512KB1000KBCnt () > 0)
	fprintf (out_file, NTXT ("  512KB - 1000KB                  %d\n"),
		 hDataTotal->getL512KB1000KBCnt ());
      if (hDataTotal->getL1000KB10MBCnt () > 0)
	fprintf (out_file, NTXT ("  1000KB - 10MB                   %d\n"),
		 hDataTotal->getL1000KB10MBCnt ());
      if (hDataTotal->getL10MB100MBCnt () > 0)
	fprintf (out_file, NTXT ("  10MB - 100MB                    %d\n"),
		 hDataTotal->getL10MB100MBCnt ());
      if (hDataTotal->getL100MB1GBCnt () > 0)
	fprintf (out_file, NTXT ("  100MB - 1GB                     %d\n"),
		 hDataTotal->getL100MB1GBCnt ());
      if (hDataTotal->getL1GB10GBCnt () > 0)
	fprintf (out_file, NTXT ("  1GB - 10GB                      %d\n"),
		 hDataTotal->getL1GB10GBCnt ());
      if (hDataTotal->getL10GB100GBCnt () > 0)
	fprintf (out_file, NTXT ("  10GB - 100GB                    %d\n"),
		 hDataTotal->getL10GB100GBCnt ());
      if (hDataTotal->getL100GB1TBCnt () > 0)
	fprintf (out_file, NTXT ("  100GB - 1TB                     %d\n"),
		 hDataTotal->getL100GB1TBCnt ());
      if (hDataTotal->getL1TB10TBCnt () > 0)
	fprintf (out_file, NTXT ("  1TB - 10TB                      %d\n"),
		 hDataTotal->getL1TB10TBCnt ());
      fprintf (out_file, GTXT ("\nSmallest leaked bytes             %lld\n"),
	       (long long) hDataTotal->getLSmallestBytes ());
      fprintf (out_file, GTXT ("Largest leaked bytes              %lld\n"),
	       (long long) hDataTotal->getLLargestBytes ());
      fprintf (out_file, GTXT ("Total leaked                      %d \n"),
	       hDataTotal->getLeakCnt ());
      fprintf (out_file, GTXT ("Total bytes                       %lld\n"),
	       (long long) hDataTotal->getLeakBytes ());
    }
  fprintf (out_file, NTXT ("\n"));
}

void
er_print_heapactivity::data_dump ()
{
  // get the list of heap events from DbeView
  int numExps = dbeSession->nexps ();
  if (!numExps)
    {
      fprintf (out_file,
	       GTXT ("There is no heap event information in the experiments\n"));
      return;
    }
  MetricList *mlist = dbev->get_metric_list (MET_HEAP);
  Hist_data *hist_data;
  hist_data = dbev->get_hist_data (mlist, type, 0, Hist_data::ALL);
  if (printStat)
    printStatistics (hist_data);
  else
    printCallStacks (hist_data);
}

er_print_ioactivity::er_print_ioactivity (DbeView *_dbev, Histable::Type _type,
					  bool _printStat, int _limit)
{
  dbev = _dbev;
  type = _type;
  printStat = _printStat;
  limit = _limit;
}

void
er_print_ioactivity::printCallStacks (Hist_data *hist_data)
{
  Hist_data::HistItem *hi;
  FileData *fData;
  long stackId;
  int size = hist_data->size ();
  if (limit > 0 && limit < size)
    size = limit;

  for (int i = 0; i < size; i++)
    {
      hi = hist_data->fetch (i);
      fData = (FileData*) hi->obj;
      stackId = fData->id;
      if (i != 0)
	fprintf (out_file, NTXT ("\n"));
      fprintf (out_file, NTXT ("%s\n"), fData->getFileName ());
      if (fData->getWriteCnt () > 0)
	{
	  fprintf (out_file, GTXT ("Write Time=%.6f (secs.)  "),
		   (double) (fData->getWriteTime () / (double) NANOSEC));
	  fprintf (out_file, GTXT ("Write Bytes=%lld  "),
		   (long long) fData->getWriteBytes ());
	  fprintf (out_file, GTXT ("Write Count=%d\n"),
		   (int) (fData->getWriteCnt ()));
	}
      if (fData->getReadCnt () > 0)
	{
	  fprintf (out_file, GTXT ("Read Time=%.6f (secs.)  "),
		   (double) (fData->getReadTime () / (double) NANOSEC));
	  fprintf (out_file, GTXT ("Read Bytes=%lld  "),
		   (long long) fData->getReadBytes ());
	  fprintf (out_file, GTXT ("Read Count=%d\n"),
		   (int) fData->getReadCnt ());
	}
      if (fData->getOtherCnt () > 0)
	{
	  fprintf (out_file, GTXT ("Other I/O Time=%.6f (secs.)  "),
		   (double) (fData->getOtherTime () / (double) NANOSEC));
	  fprintf (out_file, GTXT ("Other I/O Count=%d\n"),
		   (int) (fData->getOtherCnt ()));
	}
      if (fData->getErrorCnt () > 0)
	{
	  fprintf (out_file, GTXT ("I/O Error Time=%.6f (secs.)  "),
		   (double) (fData->getErrorTime () / (double) NANOSEC));
	  fprintf (out_file, GTXT ("I/O Error Count=%d\n"),
		   (int) (fData->getErrorCnt ()));
	}

      // There is no stack trace for <Total>
      if (i == 0)
	continue;

      // LIBRARY VISIBILITY pass extra argument if necessary to get hide stack
      Vector<Histable*> *instrs = CallStack::getStackPCs ((void *) stackId);
      if (instrs != NULL)
	{
	  int stSize = instrs->size ();
	  for (int j = 0; j < stSize; j++)
	    {
	      Histable *instr = instrs->fetch (j);
	      if (instr != NULL)
		fprintf (out_file, "  %s\n", instr->get_name ());
	    }
	  delete instrs;
	}
    }
}

void
er_print_ioactivity::printStatistics (Hist_data *hist_data)
{
  Hist_data::HistItem *hi;
  FileData *fDataTotal;

  hi = hist_data->fetch (0);
  fDataTotal = (FileData*) hi->obj;

  if (fDataTotal->getWriteCnt () > 0)
    {
      fprintf (out_file,
	       GTXT ("\nWrite Statistics\n"));
      fprintf (out_file,
	       GTXT ("I/O Size Range                    Write Calls          \n"));
      fprintf (out_file,
	       "-------------------------------------------------------\n");
      if (fDataTotal->getW0KB1KBCnt () > 0)
	fprintf (out_file, NTXT ("  0KB - 1KB                       %d\n"),
		 fDataTotal->getW0KB1KBCnt ());
      if (fDataTotal->getW1KB8KBCnt () > 0)
	fprintf (out_file, NTXT ("  1KB - 8KB                       %d\n"),
		 fDataTotal->getW1KB8KBCnt ());
      if (fDataTotal->getW8KB32KBCnt () > 0)
	fprintf (out_file, NTXT ("  8KB - 32KB                      %d\n"),
		 fDataTotal->getW8KB32KBCnt ());
      if (fDataTotal->getW32KB128KBCnt () > 0)
	fprintf (out_file, NTXT ("  32KB - 128KB                    %d\n"),
		 fDataTotal->getW32KB128KBCnt ());
      if (fDataTotal->getW128KB256KBCnt () > 0)
	fprintf (out_file, NTXT ("  128KB - 256KB                   %d\n"),
		 fDataTotal->getW128KB256KBCnt ());
      if (fDataTotal->getW256KB512KBCnt () > 0)
	fprintf (out_file, NTXT ("  256KB - 512KB                   %d\n"),
		 fDataTotal->getW256KB512KBCnt ());
      if (fDataTotal->getW512KB1000KBCnt () > 0)
	fprintf (out_file, NTXT ("  512KB - 1000KB                  %d\n"),
		 fDataTotal->getW512KB1000KBCnt ());
      if (fDataTotal->getW1000KB10MBCnt () > 0)
	fprintf (out_file, NTXT ("  1000KB - 10MB                   %d\n"),
		 fDataTotal->getW1000KB10MBCnt ());
      if (fDataTotal->getW10MB100MBCnt () > 0)
	fprintf (out_file, NTXT ("  10MB - 100MB                    %d\n"),
		 fDataTotal->getW10MB100MBCnt ());
      if (fDataTotal->getW100MB1GBCnt () > 0)
	fprintf (out_file, NTXT ("  100MB - 1GB                     %d\n"),
		 fDataTotal->getW100MB1GBCnt ());
      if (fDataTotal->getW1GB10GBCnt () > 0)
	fprintf (out_file, NTXT ("  1GB - 10GB                     %d\n"),
		 fDataTotal->getW1GB10GBCnt ());
      if (fDataTotal->getW10GB100GBCnt () > 0)
	fprintf (out_file, NTXT ("  10GB - 100GB                   %d\n"),
		 fDataTotal->getW10GB100GBCnt ());
      if (fDataTotal->getW100GB1TBCnt () > 0)
	fprintf (out_file, NTXT ("  100GB - 1TB                    %d\n"),
		 fDataTotal->getW100GB1TBCnt ());
      if (fDataTotal->getW1TB10TBCnt () > 0)
	fprintf (out_file, NTXT ("  1TB - 10TB                     %d\n"),
		 fDataTotal->getW1TB10TBCnt ());
      fprintf (out_file,
	       GTXT ("\nLongest write                     %.6f (secs.)\n"),
	       (double) (fDataTotal->getWSlowestBytes () / (double) NANOSEC));
      fprintf (out_file, GTXT ("Smallest write bytes              %lld\n"),
	       (long long) fDataTotal->getWSmallestBytes ());
      fprintf (out_file, GTXT ("Largest write bytes               %lld\n"),
	       (long long) fDataTotal->getWLargestBytes ());
      fprintf (out_file,
	       GTXT ("Total time                        %.6f (secs.)\n"),
	       (double) (fDataTotal->getWriteTime () / (double) NANOSEC));
      fprintf (out_file, GTXT ("Total calls                       %d\n"),
	       fDataTotal->getWriteCnt ());
      fprintf (out_file, GTXT ("Total bytes                       %lld\n"),
	       (long long) fDataTotal->getWriteBytes ());
    }

  if (fDataTotal->getReadCnt () > 0)
    {
      fprintf (out_file,
	       GTXT ("\nRead Statistics\n"));
      fprintf (out_file,
	       GTXT ("I/O Size Range                    Read Calls         \n"));
      fprintf (out_file,
	       "------------------------------------------------------\n");
      if (fDataTotal->getR0KB1KBCnt () > 0)
	fprintf (out_file, NTXT ("  0KB - 1KB                       %d\n"),
		 fDataTotal->getR0KB1KBCnt ());
      if (fDataTotal->getR1KB8KBCnt () > 0)
	fprintf (out_file, NTXT ("  1KB - 8KB                       %d\n"),
		 fDataTotal->getR1KB8KBCnt ());
      if (fDataTotal->getR8KB32KBCnt () > 0)
	fprintf (out_file, NTXT ("  8KB - 32KB                      %d\n"),
		 fDataTotal->getR8KB32KBCnt ());
      if (fDataTotal->getR32KB128KBCnt () > 0)
	fprintf (out_file, NTXT ("  32KB - 128KB                    %d\n"),
		 fDataTotal->getR32KB128KBCnt ());
      if (fDataTotal->getR128KB256KBCnt () > 0)
	fprintf (out_file, NTXT ("  128KB - 256KB                   %d\n"),
		 fDataTotal->getR128KB256KBCnt ());
      if (fDataTotal->getR256KB512KBCnt () > 0)
	fprintf (out_file, NTXT ("  256KB - 512KB                   %d\n"),
		 fDataTotal->getR256KB512KBCnt ());
      if (fDataTotal->getR512KB1000KBCnt () > 0)
	fprintf (out_file, NTXT ("  512KB - 1000KB                  %d\n"),
		 fDataTotal->getR512KB1000KBCnt ());
      if (fDataTotal->getR1000KB10MBCnt () > 0)
	fprintf (out_file, NTXT ("  1000KB - 10MB                   %d\n"),
		 fDataTotal->getR1000KB10MBCnt ());
      if (fDataTotal->getR10MB100MBCnt () > 0)
	fprintf (out_file, NTXT ("  10MB - 100MB                    %d\n"),
		 fDataTotal->getR10MB100MBCnt ());
      if (fDataTotal->getR100MB1GBCnt () > 0)
	fprintf (out_file, NTXT ("  100MB - 1GB                     %d\n"),
		 fDataTotal->getR100MB1GBCnt ());
      if (fDataTotal->getR1GB10GBCnt () > 0)
	fprintf (out_file, NTXT ("  1GB - 10GB                      %d\n"),
		 fDataTotal->getR1GB10GBCnt ());
      if (fDataTotal->getR10GB100GBCnt () > 0)
	fprintf (out_file, NTXT ("  10GB - 100GB                    %d\n"),
		 fDataTotal->getR10GB100GBCnt ());
      if (fDataTotal->getR100GB1TBCnt () > 0)
	fprintf (out_file, NTXT ("  100GB - 1TB                     %d\n"),
		 fDataTotal->getR100GB1TBCnt ());
      if (fDataTotal->getR1TB10TBCnt () > 0)
	fprintf (out_file, NTXT ("  1TB - 10TB                      %d\n"),
		 fDataTotal->getR1TB10TBCnt ());
      fprintf (out_file,
	       GTXT ("\nLongest time                      %.6f (secs.)\n"),
	       (double) (fDataTotal->getRSlowestBytes () / (double) NANOSEC));
      fprintf (out_file, GTXT ("Smallest read bytes               %lld\n"),
	       (long long) fDataTotal->getRSmallestBytes ());
      fprintf (out_file, GTXT ("Largest read bytes                %lld\n"),
	       (long long) fDataTotal->getRLargestBytes ());
      fprintf (out_file,
	       GTXT ("Total time                        %.6f (secs.)\n"),
	       (double) (fDataTotal->getReadTime () / (double) NANOSEC));
      fprintf (out_file, GTXT ("Total calls                       %d\n"),
	       fDataTotal->getReadCnt ());
      fprintf (out_file, GTXT ("Total bytes                       %lld\n"),
	       (long long) fDataTotal->getReadBytes ());
    }

  if (fDataTotal->getOtherCnt () > 0)
    {
      fprintf (out_file, GTXT ("\nOther I/O Statistics\n"));
      fprintf (out_file,
	       "-----------------------------------------------------\n");
      fprintf (out_file,
	       GTXT ("Total time                        %.6f (secs.)\n"),
	       (double) (fDataTotal->getOtherTime () / (double) NANOSEC));
      fprintf (out_file, GTXT ("Total calls                       %d \n"),
	       fDataTotal->getOtherCnt ());
    }
  if (fDataTotal->getErrorCnt () > 0)
    {
      fprintf (out_file, GTXT ("\nI/O Error Statistics\n"));
      fprintf (out_file,
	       "-----------------------------------------------------\n");
      fprintf (out_file,
	       GTXT ("Total time                        %.6f (secs.)\n"),
	       (double) (fDataTotal->getErrorTime () / (double) NANOSEC));
      fprintf (out_file, GTXT ("Total calls                       %d \n"),
	       fDataTotal->getErrorCnt ());
    }
  fprintf (out_file, NTXT ("\n"));
}

void
er_print_ioactivity::data_dump ()
{
  // get the list of io events from DbeView
  int numExps = dbeSession->nexps ();
  if (!numExps)
    {
      fprintf (out_file,
	       GTXT ("There is no IO event information in the experiments\n"));
      return;
    }

  MetricList *mlist = dbev->get_metric_list (MET_IO);
  Hist_data *hist_data = dbev->get_hist_data (mlist, type, 0, Hist_data::ALL);
  if (type == Histable::IOCALLSTACK)
    printCallStacks (hist_data);
  else if (printStat)
    printStatistics (hist_data);
  else
    {
      Metric::HistMetric *hist_metric = hist_data->get_histmetrics ();
      hist_data->print_label (out_file, hist_metric, 0);
      hist_data->print_content (out_file, hist_metric, limit);
      fprintf (out_file, nl);
    }
}

er_print_experiment::er_print_experiment (DbeView *_dbev, int bgn_idx,
					  int end_idx, bool show_load,
					  bool show_header, bool show_stat,
					  bool show_over, bool show_odetail)
{
  dbev = _dbev;
  exp_idx1 = bgn_idx;
  exp_idx2 = end_idx;
  load = show_load;
  header = show_header;
  stat = show_stat;
  over = show_over;
  odetail = show_odetail;
}

void
er_print_experiment::data_dump ()
{
  int index, maxlen;

  maxlen = 0;

  if (stat)
    {
      snprintf (fmt1, sizeof (fmt1), NTXT ("%%50s"));
      if (exp_idx2 > exp_idx1)
	{
	  statistics_sum (maxlen);
	  fprintf (out_file, nl);
	}

      for (index = exp_idx1; index <= exp_idx2; index++)
	statistics_dump (index, maxlen);
    }
  else if (over)
    {
      snprintf (fmt1, sizeof (fmt1), NTXT ("%%30s"));
      if (exp_idx2 > exp_idx1)
	{
	  overview_sum (maxlen);
	  fprintf (out_file, nl);
	}

      for (index = exp_idx1; index <= exp_idx2; index++)
	overview_dump (index, maxlen);
    }
  else if (header)
    for (index = exp_idx1; index <= exp_idx2; index++)
      {
	if (index != exp_idx1)
	  fprintf (out_file,
		   "----------------------------------------------------------------\n");
       header_dump (index);
      }
}

void
er_print_experiment::overview_sum (int &maxlen)
{
  int index;
  Ovw_data *sum_data = new Ovw_data ();
  for (index = exp_idx1; index <= exp_idx2; index++)
    {
      Ovw_data *ovw_data = dbev->get_ovw_data (index);
      if (ovw_data == NULL)
	continue;
      sum_data->sum (ovw_data);
      delete ovw_data;
    }

  fprintf (out_file, GTXT ("<Sum across selected experiments>"));
  fprintf (out_file, nl);
  overview_summary (sum_data, maxlen);
  fprintf (out_file, nl);
  delete sum_data;
}

void
er_print_experiment::overview_dump (int exp_idx, int &maxlen)
{
  Ovw_data *ovw_data;
  Ovw_data::Ovw_item ovw_item_labels;
  Ovw_data::Ovw_item ovw_item;
  int index;
  int size;

  ovw_data = dbev->get_ovw_data (exp_idx);
  if (ovw_data == NULL)
    return;
  if (pr_params.header)
    header_dump (exp_idx);
  else if (odetail)
    fprintf (out_file, GTXT ("Experiment: %s\n"),
	     dbeSession->get_exp (exp_idx)->get_expt_name ());

  overview_summary (ovw_data, maxlen);
  if (!odetail)
    {
      delete ovw_data;
      return;
    }

  //Get the collection params for the sample selection and display them.
  fprintf (out_file, NTXT ("\n\n"));
  fprintf (out_file, fmt1, GTXT ("Individual samples"));
  fprintf (out_file, NTXT ("\n\n"));

  size = ovw_data->size ();
  ovw_item_labels = ovw_data->get_labels ();

  for (index = 0; index < size; index++)
    {
      ovw_item = ovw_data->fetch (index);
      fprintf (out_file, fmt1, GTXT ("Sample Number"));
      fprintf (out_file, NTXT (": %d\n\n"), ovw_item.number);
      overview_item (&ovw_item, &ovw_item_labels);
      fprintf (out_file, nl);
    }

  delete ovw_data;
}

void
er_print_experiment::overview_summary (Ovw_data *ovw_data, int &maxlen)
{
  char buf[128];
  int len;
  Ovw_data::Ovw_item totals;
  Ovw_data::Ovw_item ovw_item_labels;
  totals = ovw_data->get_totals ();
  len = snprintf (buf, sizeof (buf), "%.3lf", tstodouble (totals.total.t));
  if (maxlen < len)
    maxlen = len;
  snprintf (buf, sizeof (buf), NTXT ("%%#%d.0lf    (  %#1.0f %%%%%%%%)"),
	    maxlen - 3, 0.);
  snprintf (fmt2, sizeof (fmt2), NTXT ("%%%d.3lf"), maxlen);
  snprintf (fmt3, sizeof (fmt3), buf, 0.0);
  snprintf (fmt4, sizeof (fmt4), NTXT ("%%%d.3lf (%%5.1f%%%%)"), maxlen);
  fprintf (out_file, fmt1, GTXT ("Aggregated statistics for selected samples"));
  fprintf (out_file, NTXT ("\n\n"));

  ovw_item_labels = ovw_data->get_labels ();
  overview_item (&totals, &ovw_item_labels);
}

void
er_print_experiment::overview_item (Ovw_data::Ovw_item *ovw_item,
				    Ovw_data::Ovw_item *ovw_item_labels)
{
  double start, end, total_value;
  int index, size;
  timestruc_t total_time = {0, 0};

  start = tstodouble (ovw_item->start);
  end = tstodouble (ovw_item->end);

  fprintf (out_file, fmt1, GTXT ("Start Label"));
  fprintf (out_file, NTXT (": "));
  fprintf (out_file, NTXT ("%s"), ovw_item->start_label);
  fprintf (out_file, nl);
  fprintf (out_file, fmt1, GTXT ("End Label"));
  fprintf (out_file, NTXT (": %s\n"), ovw_item->end_label);

  fprintf (out_file, fmt1, GTXT ("Start Time (sec.)"));
  fprintf (out_file, NTXT (": "));
  if (start == -1.0)
    fprintf (out_file, GTXT ("N/A"));
  else
    fprintf (out_file, fmt2, start);
  fprintf (out_file, nl);
  fprintf (out_file, fmt1, GTXT ("End Time (sec.)"));
  fprintf (out_file, NTXT (": "));
  if (end == -1.0)
    fprintf (out_file, GTXT ("N/A"));
  else
    fprintf (out_file, fmt2, end);
  fprintf (out_file, nl);
  fprintf (out_file, fmt1, GTXT ("Duration (sec.)"));
  fprintf (out_file, NTXT (": "));
  fprintf (out_file, fmt2, tstodouble (ovw_item->duration));
  fprintf (out_file, NTXT ("\n"));

  size = ovw_item->size;
  for (index = 0; index < size; index++)
    tsadd (&total_time, &ovw_item->values[index].t);

  total_value = tstodouble (total_time);
  fprintf (out_file, fmt1, GTXT ("Total Thread Time (sec.)"));
  fprintf (out_file, NTXT (": "));
  fprintf (out_file, fmt2, tstodouble (ovw_item->tlwp));
  fprintf (out_file, NTXT ("\n"));
  fprintf (out_file, fmt1, GTXT ("Average number of Threads"));
  fprintf (out_file, NTXT (": "));
  if (tstodouble (ovw_item->duration) != 0)
    fprintf (out_file, fmt2, ovw_item->nlwp);
  else
    fprintf (out_file, GTXT ("N/A"));
  fprintf (out_file, NTXT ("\n\n"));
  fprintf (out_file, fmt1, GTXT ("Process Times (sec.)"));
  fprintf (out_file, NTXT (":\n"));
  for (index = 1; index < size; index++)
    {
      overview_value (&ovw_item_labels->values[index], ovw_item_labels->type,
		      total_value);
      overview_value (&ovw_item->values[index], ovw_item->type,
		      total_value);
      fprintf (out_file, NTXT ("\n"));
    }
}

void
er_print_experiment::overview_value (Value *value, ValueTag value_tag,
				     double total_value)
{
  double dvalue;
  switch (value_tag)
    {
    case VT_LABEL:
      fprintf (out_file, fmt1, value->l);
      fprintf (out_file, NTXT (": "));
      break;
    case VT_HRTIME:
      dvalue = tstodouble (value->t);
      if (dvalue == 0.0)
	fprintf (out_file, fmt3, 0., 0.);
      else
	fprintf (out_file, fmt4, dvalue, 100.0 * dvalue / total_value);
      break;
    case VT_INT:
      fprintf (out_file, NTXT ("%d"), value->i);
      break;
    default:
      fprintf (out_file, fmt3);
    }
}

void
er_print_experiment::statistics_sum (int &maxlen)
{
  int index;
  int size, len;
  Stats_data *sum_data = new Stats_data ();
  for (index = exp_idx1; index <= exp_idx2; index++)
    {
      Stats_data *stats_data = dbev->get_stats_data (index);
      if (stats_data == NULL)
	continue;
      sum_data->sum (stats_data);
      delete stats_data;
    }

  // get the maximum width of values
  size = sum_data->size ();
  for (index = 0; index < size; index++)
    {
      len = (int) sum_data->fetch (index).value.get_len ();
      if (maxlen < len)
	maxlen = len;
    }

  // print overview average
  overview_sum (maxlen);

  // print statistics data
  snprintf (fmt2, sizeof (fmt2), NTXT (": %%%ds\n"), maxlen);
  statistics_item (sum_data);
  delete sum_data;
}

void
er_print_experiment::statistics_dump (int exp_idx, int &maxlen)
{
  Stats_data *stats_data;
  int index;
  int size, len;
  stats_data = dbev->get_stats_data (exp_idx);
  if (stats_data == NULL)
    return;
  if (pr_params.header)
    {
      header_dump (exp_idx);
      fprintf (out_file, nl);
    }
  else
    fprintf (out_file, GTXT ("Experiment: %s\n"),
	     dbeSession->get_exp (exp_idx)->get_expt_name ());

  // get the maximum width of values
  size = stats_data->size ();
  for (index = 0; index < size; index++)
    {
      len = (int) stats_data->fetch (index).value.get_len ();
      if (maxlen < len)
	maxlen = len;
    }

  // print overview average
  overview_dump (exp_idx, maxlen);
  fprintf (out_file, nl);

  // print statistics data
  snprintf (fmt2, sizeof (fmt2), NTXT (": %%%ds\n"), maxlen);
  statistics_item (stats_data);
  delete stats_data;
}

void
er_print_experiment::statistics_item (Stats_data *stats_data)
{
  int size, index;
  Stats_data::Stats_item stats_item;
  char buf[256];
  size = stats_data->size ();
  for (index = 0; index < size; index++)
    {
      stats_item = stats_data->fetch (index);
      fprintf (out_file, fmt1, stats_item.label);
      fprintf (out_file, fmt2, stats_item.value.to_str (buf, sizeof (buf)));
    }
  fprintf (out_file, nl);
}

// Print annotated source or disassembly -- called by er_print only
void
print_anno_file (char *name, const char *sel, const char *srcFile,
		 bool isDisasm, FILE *dis_file, FILE *inp_file, FILE *out_file,
		 DbeView *dbev, bool xdefault)
{
  Histable *obj;
  Function *func;
  Module *module;
  Vector<int> *marks;
  Hist_data *hist_data;
  char *errstr;
  int index;
  SourceFile *fitem;
  int threshold;
  int compcom_bits;
  int src_visible;
  bool hex_visible;
  bool srcmetrics_visible;

  if ((name == NULL) || (strlen (name) == 0))
    {
      fprintf (stderr, GTXT ("Error: No function or file has been specified.\n"));
      return;
    }

  // find the function from the name
  if (!dbeSession->find_obj (dis_file, inp_file, obj, name, sel,
			     Histable::FUNCTION, xdefault))
    return;

  if (obj != NULL)
    {
      // source or disassembly for <Total>, <Unknown>, or @plt
      if (obj->get_type () != Histable::FUNCTION)
	{
	  fprintf (stderr,
		   GTXT ("Error: %s is not a real function; no source or disassembly available.\n"),
		   name);
	  return;
	}

      func = (Function *) obj;
      if (func->flags & FUNC_FLAG_SIMULATED)
	{
	  fprintf (stderr,
		   GTXT ("Error: %s is not a real function; no source or disassembly available.\n"),
		   name);
	  return;
	}
      else if (dbev != NULL && isDisasm)
	dbev->set_func_scope (true);

      // function found, set module
      module = func->module;
      int ix = module->loadobject->seg_idx;
      if (dbev->get_lo_expand (ix) == LIBEX_HIDE)
	{
	  char *lo_name = module->loadobject->get_name ();
	  fprintf (stderr,
		   GTXT ("Error: No source or disassembly available for hidden object %s.\n"),
		   lo_name);
	  return;
	}

      if (srcFile)
	{
	  Vector<SourceFile*> *sources = func->get_sources ();
	  bool found = false;
	  if (sources == NULL)
	    {
	      fitem = func->getDefSrc ();
	      found = (func->line_first > 0)
		      && strcmp (basename (srcFile),
				 basename (fitem->get_name ())) == 0;
	    }
	  else
	    {
	      Vec_loop (SourceFile*, sources, index, fitem)
	      {
		if (strcmp (basename (srcFile), basename (fitem->get_name ())) == 0)
		  {
		    found = true;
		    break;
		  }
	      }
	    }
	  if (!found)
	    {
	      fprintf (stderr, GTXT ("Error: Source file context %s does not contribute to function `%s'.\n"),
		       srcFile, name);
	      return;
	    }
	}
    }
  else
    {
      // function not found
      if (sel && strrchr (sel, ':'))
	{
	  // 'sel' was "@seg_num:address" or "file_name:address"
	  fprintf (stderr,
		   GTXT ("Error: No function with given name `%s %s' found.\n"),
		   name, sel);
	  return;
	}
      // search for a file of that name
      if (!dbeSession->find_obj (dis_file, inp_file, obj, name, sel,
				 Histable::MODULE, xdefault))
	return;

      if (obj == NULL)
	{ // neither function nor file found
	  fprintf (stderr, GTXT ("Error: No function or file with given name `%s' found.\n"),
		   name);
	  return;
	}

      func = NULL;
      module = (Module *) obj;
      int ix = module->loadobject->seg_idx;
      if (dbev->get_lo_expand (ix) == LIBEX_HIDE)
	{
	  char *lo_name = module->loadobject->get_name ();
	  fprintf (stderr, GTXT ("Error: No source or disassembly available for hidden object %s.\n"),
		   lo_name);
	  return;
	}
      if (name)
	srcFile = name;
    }

  if (module == NULL || module->get_name () == NULL)
    {
      fprintf (stderr, GTXT ("Error: Object name not recorded in experiment\n"));
      return;
    }
  module->read_stabs ();

  if (!isDisasm && (module->file_name == NULL
		    || (module->flags & MOD_FLAG_UNKNOWN) != 0
		    || *module->file_name == 0))
    {
      fprintf (stderr, GTXT ("Error: Source location not recorded in experiment\n"));
      return;
    }

  MetricList *metric_list = dbev->get_metric_list (MET_NORMAL);
  int sort_ref_index = metric_list->get_sort_ref_index ();
  if (isDisasm)
    metric_list->set_sort_ref_index (-1);

  // Ask DbeView to generate function-level data
  //	MSI: I think this is used only to get totals to compute percentages
  hist_data = dbev->get_hist_data (metric_list, Histable::FUNCTION, 0,
				   Hist_data::ALL);
  MetricList *nmlist = hist_data->get_metric_list ();
  metric_list->set_sort_ref_index (sort_ref_index);
  if (nmlist->get_items ()->size () != 0
      && 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);
	}
      return;
    }

  marks = new Vector<int>;
  if (isDisasm)
    {
      threshold = dbev->get_thresh_dis ();
      compcom_bits = dbev->get_dis_compcom ();
      src_visible = dbev->get_src_visible ();
      hex_visible = dbev->get_hex_visible ();
      srcmetrics_visible = dbev->get_srcmetric_visible ();
    }
  else
    {
      threshold = dbev->get_thresh_src ();
      compcom_bits = dbev->get_src_compcom ();
      src_visible = SRC_NA;
      hex_visible = false;
      srcmetrics_visible = false;
    }

  dump_anno_file (out_file, isDisasm ? Histable::INSTR : Histable::LINE,
		  module, dbev, nmlist, hist_data->get_totals ()->value,
		  srcFile, func, marks, threshold, compcom_bits,
		  src_visible, hex_visible, srcmetrics_visible);

  delete marks;

  errstr = module->anno_str ();
  if (errstr)
    {
      fprintf (stderr, GTXT ("Error: %s\n"), errstr);
      free (errstr);
    }
  delete hist_data;
}

void
print_html_title (FILE *out_file, char *title)
{
  // This will print a header row for the report
  fprintf (out_file, "<html><title>%s</title>\n", title);
  fprintf (out_file, "<center><h3>%s</h3></center>\n", title);
}

void
print_html_label (FILE *out_file, MetricList *metrics_list)
{
  int mlist_sz;

  // This will print  a header row for the metrics
  Vector<Metric*> *mlist = metrics_list->get_items ();
  mlist_sz = mlist->size ();

  fprintf (out_file, "<style type=\"text/css\">\n");
  fprintf (out_file, "<!--\nBODY\n");
  fprintf (out_file, ".th_C   { text-align:center; background-color:lightgoldenrodyellow; }\n");
  fprintf (out_file, ".th_CG  { text-align:center; background-color:#ffff33; }\n");
  fprintf (out_file, ".th_L   { text-align:left; background-color:lightgoldenrodyellow; }\n");
  fprintf (out_file, ".th_LG  { text-align:left; background-color:#ffff33; }\n");
  fprintf (out_file, ".td_R   { text-align:right;  }\n");
  fprintf (out_file, ".td_RG  { text-align:right; background-color:#ffff33; }\n");
  fprintf (out_file, ".td_L   { text-align:left; }\n");
  fprintf (out_file, ".td_LG  { text-align:left;  background-color:#ffff33; }\n");
  fprintf (out_file, "-->\n</style>");
  fprintf (out_file, "<center><table border=1 cellspacing=2>\n<tr>");

  for (int index = 0; index < mlist_sz; index++)
    {
      Metric *mitem = mlist->fetch (index);
      int ncols = 0;
      if (mitem->is_visible ())
	ncols++;
      if (mitem->is_tvisible ())
	ncols++;
      if (mitem->is_pvisible ())
	ncols++;
      if (ncols == 0)
	continue;
      char *name = strdup (mitem->get_name ());
      char *name2 = split_metric_name (name);
      const char *style = index == metrics_list->get_sort_ref_index () ? "G" : "";

      // start the column, with colspan setting, legend, and sort metric indicator
      if (ncols == 1)
	{
	  if (mitem->get_vtype () == VT_LABEL)
	    // left-adjust the name metric
	    fprintf (out_file,
		     "<th class=\"th_L%s\">%s&nbsp;<br>%s&nbsp;%s&nbsp;<br>%s&nbsp;</th>",
		     style, mitem->legend == NULL ? "&nbsp;" : mitem->legend,
		     (index == metrics_list->get_sort_ref_index ()) ? "&nabla;" : "&nbsp;",
		     name, name2 == NULL ? "&nbsp;" : name2);
	  else
	    // but center the others
	    fprintf (out_file,
		     "<th class=\"th_C%s\">%s&nbsp;<br>%s&nbsp;%s&nbsp;<br>%s&nbsp;</th>",
		     style, mitem->legend == NULL ? "&nbsp;" : mitem->legend,
		     (index == metrics_list->get_sort_ref_index ()) ?
			 "&nabla;" : "&nbsp;",
		     name, name2 == NULL ? NTXT ("&nbsp;") : name2);
	}
      else
	// name metric can't span columns
	fprintf (out_file,
		 "<th colspan=%d class=\"th_C%s\">%s&nbsp;<br>%s&nbsp;%s&nbsp;<br>%s&nbsp;</th>",
		 ncols, style,
		 mitem->legend == NULL ? "&nbsp;" : mitem->legend,
		 index == metrics_list->get_sort_ref_index () ?
		     "&nabla;" : "&nbsp;",
		 name, name2 == NULL ? "&nbsp;" : name2);

      free (name);
    }

  // end this row, start the units row
  fprintf (out_file, NTXT ("</tr>\n<tr>"));

  // now do the units row
  for (int index = 0; index < mlist_sz; index++)
    {
      Metric *mitem = mlist->fetch (index);
      const char *style = index == metrics_list->get_sort_ref_index () ? "G" : "";

      if (mitem->is_tvisible ())
	fprintf (out_file, "<th class=\"th_C%s\">&nbsp;(%s)</th>", style,
		 GTXT ("sec."));
      if (mitem->is_visible ())
	{
	  if (mitem->get_abbr_unit () == NULL)
	    fprintf (out_file, "<th class=\"th_C%s\">&nbsp;</th>", style);
	  else
	    fprintf (out_file, "<th class=\"th_C%s\">(%s)</th>", style,
		     mitem->get_abbr_unit () == NULL ? "&nbsp;"
		     : mitem->get_abbr_unit ());
	}
      if (mitem->is_pvisible ())
	fprintf (out_file, "<th class=\"th_C%s\">&nbsp;(%%)</th>", style);
    }
  fprintf (out_file, NTXT ("</tr>\n"));
}

void
print_html_content (FILE *out_file, Hist_data *data, MetricList *metrics_list,
		    int limit, Histable::NameFormat nfmt)
{
  Hist_data::HistItem *item;

  // printing contents.
  for (int i = 0; i < limit; i++)
    {
      item = data->fetch (i);
      print_html_one (out_file, data, item, metrics_list, nfmt);
    }
}

void
print_html_one (FILE *out_file, Hist_data *data, Hist_data::HistItem *item,
		MetricList *metrics_list, Histable::NameFormat nfmt)
{
  Metric *mitem;
  int index;
  int visible, tvisible, pvisible;
  TValue *value;
  double percent;

  fprintf (out_file, NTXT ("<tr>"));
  Vec_loop (Metric*, metrics_list->get_items (), index, mitem)
  {
    visible = mitem->is_visible ();
    tvisible = mitem->is_tvisible ();
    pvisible = mitem->is_pvisible ();
    const char *style = index == metrics_list->get_sort_ref_index () ? "G" : "";

    if (tvisible)
      {
	value = &(item->value[index]);
	if (value->ll == 0LL)
	  fprintf (out_file,
		   "<td class=\"td_R%s\"><tt>0.&nbsp;&nbsp;&nbsp;</tt></td>",
		   style);
	else
	  fprintf (out_file, "<td class=\"td_R%s\"><tt>%4.3lf</tt></td>",
		   style, 1.e-6 * value->ll / dbeSession->get_clock (-1));
      }

    if (visible)
      {
	if (mitem->get_vtype () == VT_LABEL)
	  {
	    value = &(item->value[index]);
	    char *r;
	    if (value->tag == VT_OFFSET)
	      r = ((DataObject*) (item->obj))->get_offset_name ();
	    else
	      r = item->obj->get_name (nfmt);
	    char *n = html_ize_name (r);
	    fprintf (out_file, NTXT ("<td class=\"td_L%s\">%s</td>"), style, n);
	    free (n);
	  }
	else
	  {
	    value = &(item->value[index]);
	    switch (value->tag)
	      {
	      case VT_DOUBLE:
		if (value->d == 0.0)
		  fprintf (out_file,
		      "<td class=\"td_R%s\"><tt>0.&nbsp;&nbsp;&nbsp;</tt></td>",
			   style);
		else
		  fprintf (out_file,
			   "<td  class=\"td_R%s\"><tt>%4.3lf</tt></td>", style,
			   value->d);
		break;
	      case VT_INT:
		fprintf (out_file, "<td  class=\"td_R%s\"><tt>%d</tt></td>",
			 style, value->i);
		break;
	      case VT_LLONG:
		fprintf (out_file, "<td  class=\"td_R%s\"><tt>%lld</td></tt>",
			 style, value->ll);
		break;
	      case VT_ULLONG:
		fprintf (out_file, "<td  class=\"td_R%s\"><tt>%llu</td></tt>",
			 style, value->ull);
		break;
	      case VT_ADDRESS:
		fprintf (out_file,
			 "<td  class=\"td_R%s\"><tt>%u:0x%08x</tt></td>", style,
			 ADDRESS_SEG (value->ll), ADDRESS_OFF (value->ll));
		break;
	      case VT_FLOAT:
		if (value->f == 0.0)
		  fprintf (out_file,
			   "<td  class=\"td_R%s\"><tt>0.&nbsp;&nbsp;&nbsp;</tt></td>",
			   style);
		else
		  fprintf (out_file,
			   "<td  class=\"td_R%s\"><tt>%4.3f</tt></td>",
			   style, value->f);
		break;
	      case VT_SHORT:
		fprintf (out_file, "<td  class=\"td_R%s\"><tt>%d</tt></td>",
			 style, value->s);
		break;
		// ignoring the following cases (why?)
	      case VT_HRTIME:
	      case VT_LABEL:
	      case VT_OFFSET:
		break;
	      }
	  }
      }

    if (pvisible)
      {
	percent = data->get_percentage (item->value[index].to_double (), index);
	if (percent == 0.0)
	  // adjust to change format from xx.yy%
	  fprintf (out_file, "<td class=\"td_R%s\">0.&nbsp;&nbsp;&nbsp;</td>",
		   style);
	else
	  // adjust format below to change format from xx.yy%
	  fprintf (out_file, "<td class=\"td_R%s\">%3.2f</td>", style,
		   (100.0 * percent));
      }
  }
  fprintf (out_file, NTXT ("</tr>\n"));
}

void
print_html_trailer (FILE *out_file)
{
  fprintf (out_file, NTXT ("</table></center></html>\n"));
}

static char *
del_delim (char *s)
{
  size_t len = strlen (s);
  if (len > 0)
    s[len - 1] = 0;
  return s;
}

void
print_delim_label (FILE *out_file, MetricList *metrics_list, char delim)
{
  char line0[2 * MAX_LEN], line1[2 * MAX_LEN];
  char line2[2 * MAX_LEN], line3[2 * MAX_LEN];
  size_t len;

  // This will print four header rows for the metrics
  line0[0] = 0;
  line1[0] = 0;
  line2[0] = 0;
  line3[0] = 0;
  Vector<Metric*> *mlist = metrics_list->get_items ();
  for (int index = 0, mlist_sz = mlist->size (); index < mlist_sz; index++)
    {
      Metric *mitem = mlist->fetch (index);
      if (!(mitem->is_visible () || mitem->is_tvisible ()
	    || mitem->is_pvisible ()))
	continue;
      char *name = strdup (mitem->get_name ());
      char *name2 = split_metric_name (name);

      if (mitem->is_tvisible ())
	{
	  len = strlen (line0);
	  snprintf (line0 + len, sizeof (line0) - len, NTXT ("\"%s\"%c"),
		    mitem->legend == NULL ? NTXT ("") : mitem->legend, delim);
	  len = strlen (line1);
	  snprintf (line1 + len, sizeof (line1) - len, NTXT ("\"%s\"%c"),
		    name, delim);
	  len = strlen (line2);
	  snprintf (line2 + len, sizeof (line2) - len, NTXT ("\"%s\"%c"),
		    name2 == NULL ? NTXT ("") : name2, delim);
	  len = strlen (line3);
	  if (index == metrics_list->get_sort_ref_index ())
	    snprintf (line3 + len, sizeof (line3) - len, NTXT ("\"V  %s\"%c"),
		      GTXT ("(sec.)"), delim);
	  else
	    snprintf (line3 + len, sizeof (line3) - len, NTXT ("\"   %s\"%c"),
		      GTXT ("(sec.)"), delim);
	}
      if (mitem->is_visible ())
	{
	  len = strlen (line0);
	  snprintf (line0 + len, sizeof (line0) - len, "\"%s\"%c",
		    mitem->legend == NULL ? "" : mitem->legend, delim);

	  len = strlen (line1);
	  snprintf (line1 + len, sizeof (line1) - len, "\"%s\"%c",
		    name, delim);

	  len = strlen (line2);
	  snprintf (line2 + len, sizeof (line2) - len, "\"%s\"%c",
		    name2 == NULL ? NTXT ("") : name2, delim);

	  len = strlen (line3);
	  char *au = mitem->get_abbr_unit ();

	  if (index == metrics_list->get_sort_ref_index ())
	    {
	      if (au == NULL)
		snprintf (line3 + len, sizeof (line3) - len, "\"V  \"%c", delim);
	      else
		snprintf (line3 + len, sizeof (line3) - len, "\"V  (%s)\"%c",
			    au, delim);
	    }
	  else
	    {
	      if (au == NULL)
		snprintf (line3 + len, sizeof (line3) - len, "\"   \"%c",
			  delim);
	      else
		snprintf (line3 + len, sizeof (line3) - len, "\"   (%s)\"%c",
			  au, delim);
	    }
	}
      if (mitem->is_pvisible ())
	{
	  len = strlen (line0);
	  snprintf (line0 + len, sizeof (line0) - len, NTXT ("\"%s\"%c"),
		    mitem->legend == NULL ? NTXT ("") : mitem->legend, delim);

	  len = strlen (line1);
	  snprintf (line1 + len, sizeof (line1) - len, NTXT ("\"%s\"%c"),
		    name, delim);

	  len = strlen (line2);
	  snprintf (line2 + len, sizeof (line2) - len, NTXT ("\"%s\"%c"),
		    name2 == NULL ? NTXT ("") : name2, delim);

	  len = strlen (line3);
	  if (index == metrics_list->get_sort_ref_index ())
	    snprintf (line3 + len, sizeof (line3) - len, NTXT ("\"V  %s\"%c"),
		      NTXT ("%%"), delim);
	  else
	    snprintf (line3 + len, sizeof (line3) - len, NTXT ("\"   %s\"%c"),
		      NTXT ("%%"), delim);
	}
      free (name);
    }
  // now remove the trailing delimiter, and print the four lines
  fprintf (out_file, NTXT ("%s\n"), del_delim (line0));
  fprintf (out_file, NTXT ("%s\n"), del_delim (line1));
  fprintf (out_file, NTXT ("%s\n"), del_delim (line2));
  fprintf (out_file, NTXT ("%s\n"), del_delim (line3));
}

void
print_delim_content (FILE *out_file, Hist_data *data, MetricList *metrics_list,
		     int limit, Histable::NameFormat nfmt, char delim)
{
  Hist_data::HistItem *item;
  int i;

  // printing contents.
  for (i = 0; i < limit; i++)
    {
      item = data->fetch (i);
      print_delim_one (out_file, data, item, metrics_list, nfmt, delim);
    }
}

void
print_delim_trailer (FILE */*out_file*/, char /*delim*/) { }

// EUGENE does this function work properly when "-compare ratio" is used?
//   how about when the ratio is nonzero-divided-by-zero?
// EUGENE actually, review this entire file

void
print_delim_one (FILE *out_file, Hist_data *data, Hist_data::HistItem *item,
		 MetricList *metrics_list, Histable::NameFormat nfmt,
		 char delim)
{
  Metric *mitem;
  int index;
  int visible, tvisible, pvisible;
  TValue *value;
  double percent;
  size_t len;

  char line1[2 * MAX_LEN];
  *line1 = 0;
  Vec_loop (Metric*, metrics_list->get_items (), index, mitem)
  {
    visible = mitem->is_visible ();
    tvisible = mitem->is_tvisible ();
    pvisible = mitem->is_pvisible ();
    if (tvisible)
      {
	value = &(item->value[index]);
	len = strlen (line1);
	if (value->ll == 0LL)
	  snprintf (line1 + len, sizeof (line1) - len, "\"0.\"%c", delim);
	else
	  snprintf (line1 + len, sizeof (line1) - len, "\"%4.3lf\"%c",
		    1.e-6 * value->ll / dbeSession->get_clock (-1),
		    delim);
      }

    if (visible)
      {
	len = strlen (line1);
	if (mitem->get_vtype () == VT_LABEL)
	  {
	    value = &(item->value[index]);
	    char *r;
	    if (value->tag == VT_OFFSET)
	      r = ((DataObject*) (item->obj))->get_offset_name ();
	    else
	      r = item->obj->get_name (nfmt);
	    char *p = csv_ize_name (r, delim);
	    snprintf (line1 + len, sizeof (line1) - len, "\"%s\"%c", p, delim);
	    free (p);
	  }
	else
	  {
	    value = &(item->value[index]);
	    switch (value->tag)
	      {
	      case VT_DOUBLE:
		if (value->d == 0.0)
		  snprintf (line1 + len, sizeof (line1) - len, "\"0.\"%c",
			    delim);
		else
		  snprintf (line1 + len, sizeof (line1) - len, "\"%4.3lf\"%c",
			    value->d, delim);
		break;
	      case VT_INT:
		snprintf (line1 + len, sizeof (line1) - len, "\"%d\"%c",
			  value->i, delim);
		break;
	      case VT_LLONG:
		snprintf (line1 + len, sizeof (line1) - len, "\"%lld\"%c",
			  value->ll, delim);
		break;
	      case VT_ULLONG:
		snprintf (line1 + len, sizeof (line1) - len, "\"%llu\"%c",
			  value->ull, delim);
		break;
	      case VT_ADDRESS:
		snprintf (line1 + len, sizeof (line1) - len, "\"%u:0x%08x\"%c",
			  ADDRESS_SEG (value->ll),
			  ADDRESS_OFF (value->ll), delim);
		break;
	      case VT_FLOAT:
		if (value->f == 0.0)
		  snprintf (line1 + len, sizeof (line1) - len, "\"0.\"%c",
			    delim);
		else
		  snprintf (line1 + len, sizeof (line1) - len, "\"%4.3f\"%c",
			    value->f, delim);
		break;
	      case VT_SHORT:
		snprintf (line1 + len, sizeof (line1) - len, "\"%d\"%c",
			  value->s, delim);
		break;
		// ignoring the following cases (why?)
	      case VT_HRTIME:
	      case VT_LABEL:
	      case VT_OFFSET:
		break;
	      }
	  }
      }

    if (pvisible)
      {
	len = strlen (line1);
	percent = data->get_percentage (item->value[index].to_double (), index);
	if (percent == 0.0)
	  // adjust to change format from xx.yy%
	  snprintf (line1 + len, sizeof (line1) - len, "\"0.\"%c", delim);
	else
	  // adjust format below to change format from xx.yy%
	  snprintf (line1 + len, sizeof (line1) - len, "\"%3.2f\"%c",
		    (100.0 * percent), delim);
      }
  }
  fprintf (out_file, NTXT ("%s\n"), del_delim (line1));
}

char *
html_ize_name (char *name)
{
  StringBuilder sb;
  for (size_t i = 0; i < strlen (name); i++)
    {
      switch (name[i])
	{
	case ' ': sb.append (NTXT ("&nbsp;"));
	  break;
	case '"': sb.append (NTXT ("&quot;"));
	  break;
	case '&': sb.append (NTXT ("&amp;"));
	  break;
	case '<': sb.append (NTXT ("&lt;"));
	  break;
	case '>': sb.append (NTXT ("&gt;"));
	  break;
	default: sb.append (name[i]);
	  break;
	}
    }
  char *ret = sb.toString ();
  return ret;
}

char *
csv_ize_name (char *name, char /*delim*/)
{
  StringBuilder sb;
  for (size_t i = 0; i < strlen (name); i++)
    sb.append (name[i]);
  char *ret = sb.toString ();
  return ret;
}

// Split a metric name into two parts, replacing a blank with
//	a zero and returning pointer to the rest of the string, or
//	leaving the string unchanged, and returning NULL;

char *
split_metric_name (char *name)
{
  // figure out the most even split of the name
  size_t len = strlen (name);
  char *middle = &name[len / 2];

  // find the first blank
  char *first = strchr (name, (int) ' ');
  if (first == NULL)  // no blanks
    return NULL;
  char *last = first;
  char *p = first;
  for (;;)
    {
      p = strchr (p + 1, (int) ' ');
      if (p == NULL)
	break;
      if (p < middle)
	{
	  first = p;
	  last = p;
	}
      else
	{
	  last = p;
	  break;
	}
    }
  // pick the better of the two
  char *ret;
  int f = (int) (middle - first);
  int l = (int) (last - middle);
  if ((first == last) || (f <= l))
    {
      *first = '\0';
      ret = first + 1;
    }
  else
    {
      *last = '\0';
      ret = last + 1;
    }
  return ret;
}
