/* Copyright (C) 2021-2026 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 <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 (xstrdup (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 *) xmalloc (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);
}

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;
	  const char *s;
	  if (index > 0 && mitem->get_type () == Metric::ONAME)
	    {
	      s = " ";
	      name_offset = strlen (line1);
	    }
	  else
	    s = "";
	  int width = (int) hitem->width;
	  size_t len = strlen (line1);
	  snprintf (line1 + len, sizeof (line1) - len, "%s%-*s", s, width,
		    hitem->legend1);
	  len = strlen (line2);
	  snprintf (line2 + len, sizeof (line2) - len, "%s%-*s", s, width,
		    hitem->legend2);
	  len = strlen (line3);
	  snprintf (line3 + len, sizeof (line3) - len, "%s%-*s", s, width,
		    hitem->legend3);
	  len = strlen (line0);
	  snprintf (line0 + len, sizeof (line0) - len, "%s%-*s", s, 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;
}

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)
{
  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);
  Metric::HistMetric *hist_metric = layout_data->get_histmetrics ();

//  snprintf (hist_metric[name_index].legend2, MAX_LEN, GTXT ("* +offset .element"));
  layout_data->print_label (out_file, hist_metric, 3);
  fprintf (out_file, nl);
  StringBuilder sb;

  for (long i = 0; i < layout_data->size (); i++)
    {
      sb.setLength (0);
      if (marks->find (i) != -1)
	sb.append ("## ");
      else
	sb.append ("   ");
      layout_data->print_row (&sb, i, hist_metric, " ");
      sb.toFileLn (out_file);
    }
  fprintf (out_file, nl);
  delete layout_data;
}

static int
max_length(size_t len, size_t str_len)
{
  if (str_len > len)
    return str_len;
  return len;
}

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;
  Module *module;
  LoadObject *loadobject;
  char *sname, *oname, *lname, *alias, *mangle;

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

  // Check max. length of metrics names
  size_t len = 0, slen = 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 = max_length (len, hist_data->value_maxlen (index));
	slen = max_length (slen, strlen (mitem->get_name ()));
      }
  }

  // now get the length of the other (non-performance-data) messages
  if (hist_data->type == Histable::FUNCTION)
    {
      slen = max_length (slen, strlen (GTXT ("Source File")));
      slen = max_length (slen, strlen (GTXT ("Object File")));
      slen = max_length (slen, strlen (GTXT ("Load Object")));
      slen = max_length (slen, strlen (GTXT ("Mangled Name")));
      slen = max_length (slen, strlen (GTXT ("Aliases")));
    }
  else if (hist_data->type == Histable::DOBJECT)
    {
      slen = max_length (slen, strlen (GTXT ("Scope")));
      slen = max_length (slen, strlen (GTXT ("Type")));
      slen = max_length (slen, strlen (GTXT ("Member of")));
      slen = max_length (slen, strlen (GTXT ("Offset (bytes)")));
      slen = max_length (slen, strlen (GTXT ("Size (bytes)")));
      slen = max_length (slen, strlen (GTXT ("Elements")));
    }
  int max_len = (int) len;
  int smax_len = (int) slen;

#define PR_TITLE(t)   fprintf (out_file, "\t%*s:", smax_len, t)
#define PR(title, nm) PR_TITLE(title); \
		      if (nm) \
		        fprintf (out_file, " %s", nm); \
		      fprintf (out_file, "\n")

  // 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;
	PR_TITLE (mitem->get_name ());

	char buf[128];
	char *s = values[index].to_str (buf, sizeof (buf));
	if (mitem->get_value_styles () & VAL_PERCENT)
	  {
	    dvalue = values[index].to_double ();
	    percent = 100.0 * current_data->get_percentage (dvalue, index);
	    if (!mitem->is_time_val ())
	      {
		fprintf (out_file, " %*s", max_len, s);
		if (dvalue == 0.)
		  fprintf (out_file, " (  0. %%)\n");
		else
		  fprintf (out_file, " (%5.1f%%)\n", percent);
		continue;
	      }

	    TValue v;
	    v.tag = VT_DOUBLE;
	    v.sign = false;
	    v.d = dvalue / (1.e+6 * dbeSession->get_clock (-1));
	    char buf1[128];
	    char *s1 = v.to_str (buf1, sizeof (buf1));
	    fprintf (out_file, " %*s", max_len, s1);
	    if (dvalue == 0.)
	      fprintf (out_file, " (  0. %%)\n");
	    else
	      fprintf (out_file, " (%5.1f%%)\n", percent);
	    PR_TITLE (GTXT ("Count"));
	  }

	int max_len1 = max_len;
	for (int j = (int) strlen (s) - 1; j >= 0 && s[j] == ' '; j--)
	  {
	    s[j] = 0;
	    max_len1--;
	  }
	fprintf (out_file, " %*s\n", max_len1, s);
      }

      // 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 ();

	      PR (GTXT ("Source File"), sname);
	      PR (GTXT ("Object File"), oname);
	      PR (GTXT ("Load Object"), lname);
	      PR (GTXT ("Mangled Name"), mangle);
	      PR (GTXT ("Aliases"), alias);
	    }
	}
      else
	{
	  // Print the dataobject information
	  DataObject *dobj = (DataObject*) obj;
	  Histable *scope = dobj->get_scope ();

	  // print the scope
	  PR_TITLE (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
	  PR_TITLE (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 ())
		{
		  PR_TITLE (GTXT ("Member of"));
		  fprintf (out_file, NTXT ("%s\n"), dobj->get_parent ()->get_name ());
		}
	      PR_TITLE (GTXT ("Offset (bytes)"));
	      fprintf (out_file, NTXT ("%lld\n"), (long long) dobj->get_offset ());
	    }
	  // print the size
	  if (dobj->get_size ())
	    {
	      PR_TITLE (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 lspace, mspace, tspace, remain, mindex, next_mark, hidx, index;
  Metric *mitem;
  char 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 ();
  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 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)
    {
      max_len1 = 50;
      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)
    {
      max_len1 = 50;
      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, "\n\n%*s\n\n", max_len1, GTXT ("Individual samples"));

  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, "%*s: %d\n\n", max_len1, GTXT ("Sample Number"),
	       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;
  max_len2 = maxlen;
  max_len3 = maxlen;
  fprintf (out_file, "%*s\n\n", max_len1,
	   GTXT ("Aggregated statistics for selected samples"));

  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, "%*s: %s\n", max_len1, GTXT ("Start Label"),
	   ovw_item->start_label);
  fprintf (out_file, "%*s: %s\n", max_len1, GTXT ("End Label"),
	   ovw_item->end_label);

  fprintf (out_file, "%*s: ", max_len1, GTXT ("Start Time (sec.)"));
  if (start == -1.0)
    fprintf (out_file, GTXT ("N/A"));
  else
    fprintf (out_file, "%*.3f", max_len2, start);
  fprintf (out_file, nl);
  fprintf (out_file, "%*s: ", max_len1, GTXT ("End Time (sec.)"));
  if (end == -1.0)
    fprintf (out_file, GTXT ("N/A"));
  else
    fprintf (out_file, "%*.3f", max_len2, end);
  fprintf (out_file, nl);
  fprintf (out_file, "%*s: ", max_len1, GTXT ("Duration (sec.)"));
  fprintf (out_file, "%*.3f", max_len2, 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, "%*s: %*.3f", max_len1, GTXT ("Total Thread Time (sec.)"),
	   max_len2, tstodouble (ovw_item->tlwp));
  fprintf (out_file, NTXT ("\n"));
  fprintf (out_file, "%*s: ", max_len1, GTXT ("Average number of Threads"));
  if (tstodouble (ovw_item->duration) != 0)
    fprintf (out_file, "%*.3f", max_len2, ovw_item->nlwp);
  else
    fprintf (out_file, GTXT ("N/A"));
  fprintf (out_file, NTXT ("\n\n"));
  fprintf (out_file, "%*s:\n", max_len1, GTXT ("Process Times (sec.)"));
  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, "%*s: ", max_len1, value->l);
      break;
    case VT_HRTIME:
      dvalue = tstodouble (value->t);
      if (dvalue == 0.0)
	fprintf (out_file, "%*s (  0. %%)", max_len3, "0.   ");
      else
	fprintf (out_file, "%*.3f (%5.1f%%)", max_len3, dvalue,
		 100.0 * dvalue / total_value);
      break;
    case VT_INT:
      fprintf (out_file, NTXT ("%d"), value->i);
      break;
    default:
      fprintf (out_file, "%*.3f", max_len3, total_value);
    }
}

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
  max_len2 = 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
  max_len2 = 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, "%*s: %*s\n", max_len1, stats_item.label,
	       max_len2, 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 (get_basename (srcFile),
				 get_basename (fitem->get_name ())) == 0;
	    }
	  else
	    {
	      Vec_loop (SourceFile*, sources, index, fitem)
	      {
		if (strcmp (get_basename (srcFile), get_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 = xstrdup (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 = xstrdup (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;
}
