/* 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 <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>

#include "enums.h"
#include "Settings.h"
#include "DbeSession.h"
#include "Command.h"
#include "Application.h"
#include "MemorySpace.h"
#include "StringBuilder.h"
#include "Table.h"
#include "Emsg.h"
#include "util.h"
#include "i18n.h"

// Commands for compiler commentary
static const char *comp_cmd[] = {
  NTXT ("basic"),
  NTXT ("version"),
  NTXT ("warn"),
  NTXT ("parallel"),
  NTXT ("query"),
  NTXT ("loop"),
  NTXT ("pipe"),
  NTXT ("inline"),
  NTXT ("memops"),
  NTXT ("fe"),
  NTXT ("codegen"),
  NTXT ("src"),
  NTXT ("asrc"),
  NTXT ("nosrc"),
  NTXT ("hex"),
  NTXT ("nohex"),
  NTXT ("threshold"),
  NTXT ("cf")
};

static const int comp_vis[] = {
  CCMV_BASIC,
  CCMV_VER,
  CCMV_WARN,
  CCMV_PAR,
  CCMV_QUERY,
  CCMV_LOOP,
  CCMV_PIPE,
  CCMV_INLINE,
  CCMV_MEMOPS,
  CCMV_FE,
  CCMV_CG,
  COMP_SRC,
  COMP_SRC_METRIC,
  COMP_NOSRC,
  COMP_HEX,
  COMP_NOHEX,
  COMP_THRESHOLD,
  COMP_CMPLINE
};

const int comp_size = sizeof (comp_cmd) / sizeof (char *);

// Commands for timeline
typedef enum
{
  TLCMD_INVALID,
  TLCMD_ENTITY_MODE,
  TLCMD_ALIGN,
  TLCMD_DEPTH
} TLModeSubcommand;

typedef struct
{
  const char * cmdText;
  TLModeSubcommand cmdType;
  int cmdId;
} TLModeCmd;
static const TLModeCmd tlmode_cmd[] = {
  // MODE commands
  {NTXT ("lwp"),        TLCMD_ENTITY_MODE, PROP_LWPID},
  {NTXT ("thread"),     TLCMD_ENTITY_MODE, PROP_THRID},
  {NTXT ("cpu"),        TLCMD_ENTITY_MODE, PROP_CPUID},
  {NTXT ("experiment"), TLCMD_ENTITY_MODE, PROP_EXPID},
  // ALIGN commands
  {NTXT ("root"),       TLCMD_ALIGN, TLSTACK_ALIGN_ROOT},
  {NTXT ("leaf"),       TLCMD_ALIGN, TLSTACK_ALIGN_LEAF},
  // DEPTH commands
  {NTXT ("depth"),      TLCMD_DEPTH, 0 /* don't care */}
};

static const int tlmode_size = sizeof (tlmode_cmd) / sizeof (TLModeCmd);

// Constructor

Settings::Settings (Application *_app)
{
  // Remember the application
  app = _app;

  // Clear all default strings
  str_vmode = NULL;
  str_en_desc = NULL;
  str_datamode = NULL;
  str_scompcom = NULL;
  str_sthresh = NULL;
  str_dcompcom = NULL;
  str_dthresh = NULL;
  str_dmetrics = NULL;
  str_dsort = NULL;
  str_tlmode = NULL;
  str_tldata = NULL;
  str_tabs = NULL;
  str_rtabs = NULL;
  str_search_path = NULL;
  str_name_format = NULL;
  str_limit = NULL;
  str_printmode = NULL;
  str_compare = NULL;
  preload_libdirs = NULL;
  pathmaps = new Vector<pathmap_t*>;
  lo_expands = new Vector<lo_expand_t*>;
  lo_expand_default = LIBEX_SHOW;
  is_loexpand_default = true;
  tabs_processed = false;

  // set default-default values
  name_format = Histable::NA;
  view_mode = VMODE_USER;
  en_desc = false;
  en_desc_cmp = NULL;
  en_desc_usr = NULL;
  src_compcom = 2147483647;
  dis_compcom = 2147483647;
#define DEFAULT_SRC_DIS_THRESHOLD 75
  threshold_src = DEFAULT_SRC_DIS_THRESHOLD;
  threshold_dis = DEFAULT_SRC_DIS_THRESHOLD;
  src_visible = true;
  srcmetric_visible = false;
  hex_visible = false;
  cmpline_visible = true;
  funcline_visible = true;
  tldata = NULL;
  tlmode = 0;
  stack_align = 0;
  stack_depth = 0;
  limit = 0;
  // print mode is initialized after the .rc files are read
  print_delim = ',';
  compare_mode = CMP_DISABLE;
  machinemodel = NULL;
  ignore_no_xhwcprof = false;
  ignore_fs_warn = false;

  // construct the master list of tabs
  buildMasterTabList ();

  indx_tab_state = new Vector<bool>;
  indx_tab_order = new Vector<int>;
  mem_tab_state = new Vector<bool>;
  mem_tab_order = new Vector<int>;

  // note that the .rc files are not read here, but later
}

// Constructor for duplicating an existing Settings class

Settings::Settings (Settings * _settings)
{
  int index;
  app = _settings->app;

  // Copy all default strings
  str_vmode = dbe_strdup (_settings->str_vmode);
  str_en_desc = dbe_strdup (_settings->str_en_desc);
  str_datamode = dbe_strdup (_settings->str_datamode);
  str_scompcom = dbe_strdup (_settings->str_scompcom);
  str_sthresh = dbe_strdup (_settings->str_sthresh);
  str_dcompcom = dbe_strdup (_settings->str_dcompcom);
  str_dthresh = dbe_strdup (_settings->str_dthresh);
  str_dmetrics = dbe_strdup (_settings->str_dmetrics);
  str_dsort = dbe_strdup (_settings->str_dsort);
  str_tlmode = dbe_strdup (_settings->str_tlmode);
  str_tldata = dbe_strdup (_settings->str_tldata);
  str_tabs = dbe_strdup (_settings->str_tabs);
  str_rtabs = dbe_strdup (_settings->str_rtabs);
  str_search_path = dbe_strdup (_settings->str_search_path);
  str_name_format = dbe_strdup (_settings->str_name_format);
  str_limit = dbe_strdup (_settings->str_limit);
  str_printmode = dbe_strdup (_settings->str_printmode);
  str_compare = dbe_strdup (_settings->str_compare);
  preload_libdirs = dbe_strdup (_settings->preload_libdirs);

  // replicate the pathmap vector
  pathmap_t *thismap;
  pathmap_t *newmap;
  pathmaps = new Vector<pathmap_t*>;

  Vec_loop (pathmap_t*, _settings->pathmaps, index, thismap)
  {
    newmap = new pathmap_t;
    newmap->old_prefix = dbe_strdup (thismap->old_prefix);
    newmap->new_prefix = dbe_strdup (thismap->new_prefix);
    pathmaps->append (newmap);
  }

  // replicate the lo_expand vector and default
  lo_expand_t *this_lo_ex;
  lo_expand_t *new_lo_ex;
  lo_expand_default = _settings->lo_expand_default;
  is_loexpand_default = _settings->is_loexpand_default;
  lo_expands = new Vector<lo_expand_t*>;

  Vec_loop (lo_expand_t*, _settings->lo_expands, index, this_lo_ex)
  {
    new_lo_ex = new lo_expand_t;
    new_lo_ex->libname = dbe_strdup (this_lo_ex->libname);
    new_lo_ex->expand = this_lo_ex->expand;
    lo_expands->append (new_lo_ex);
  }
  tabs_processed = _settings->tabs_processed;

  // Copy the various values from the _settings instance
  name_format = _settings->name_format;
  view_mode = _settings->view_mode;
  en_desc = false;
  en_desc_cmp = NULL;
  en_desc_usr = NULL;
  if (_settings->en_desc_usr)
    set_en_desc (_settings->en_desc_usr, true);
  src_compcom = _settings->src_compcom;
  dis_compcom = _settings->dis_compcom;
  threshold_src = _settings->threshold_src;
  threshold_dis = _settings->threshold_dis;
  src_visible = _settings->src_visible;
  srcmetric_visible = _settings->srcmetric_visible;
  hex_visible = _settings->hex_visible;
  cmpline_visible = _settings->cmpline_visible;
  funcline_visible = _settings->funcline_visible;
  tldata = dbe_strdup (_settings->tldata);
  tlmode = _settings->tlmode;
  stack_align = _settings->stack_align;
  stack_depth = _settings->stack_depth;
  limit = _settings->limit;
  print_mode = _settings->print_mode;
  print_delim = _settings->print_delim;
  compare_mode = _settings->compare_mode;
  machinemodel = dbe_strdup (_settings->machinemodel);
  ignore_no_xhwcprof = _settings->ignore_no_xhwcprof;
  ignore_fs_warn = _settings->ignore_fs_warn;

  // copy the tab list, too
  tab_list = new Vector<DispTab*>;
  DispTab *dsptab;

  Vec_loop (DispTab*, _settings->tab_list, index, dsptab)
  {
    DispTab *ntab;
    ntab = new DispTab (dsptab->type, dsptab->order, dsptab->visible, dsptab->cmdtoken);
    ntab->setAvailability (dsptab->available);
    tab_list->append (ntab);
  }

  // construct the master list of memory tabs & copy order
  index = _settings->mem_tab_state->size ();
  mem_tab_state = new Vector<bool>(index);
  mem_tab_order = new Vector<int>(index);
  for (int i = 0; i < index; i++)
    {
      mem_tab_state->append (false);
      mem_tab_order->append (_settings->mem_tab_order->fetch (i));
    }

  // construct the master list of index tabs & copy order
  index = _settings->indx_tab_state->size ();
  indx_tab_state = new Vector<bool>(index);
  indx_tab_order = new Vector<int>(index);
  for (int i = 0; i < index; i++)
    indx_tab_order->append (_settings->indx_tab_order->fetch (i));
  set_IndxTabState (_settings->indx_tab_state);
}

Settings::~Settings ()
{
  for (int i = 0; i < pathmaps->size (); ++i)
    {
      pathmap_t *pmap = pathmaps->fetch (i);
      free (pmap->old_prefix);
      free (pmap->new_prefix);
      delete pmap;
    }
  delete pathmaps;

  for (int i = 0; i < lo_expands->size (); ++i)
    {
      lo_expand_t *lo_ex = lo_expands->fetch (i);
      free (lo_ex->libname);
      delete lo_ex;
    }
  delete lo_expands;

  tab_list->destroy ();
  delete tab_list;
  delete indx_tab_state;
  delete indx_tab_order;
  delete mem_tab_state;
  delete mem_tab_order;

  free (str_vmode);
  free (str_en_desc);
  free (str_datamode);
  free (str_scompcom);
  free (str_sthresh);
  free (str_dcompcom);
  free (str_dthresh);
  free (str_dmetrics);
  free (str_dsort);
  free (str_tlmode);
  free (str_tldata);
  free (str_tabs);
  free (str_rtabs);
  free (str_search_path);
  free (str_name_format);
  free (str_limit);
  free (str_compare);
  free (str_printmode);
  free (preload_libdirs);
  free (tldata);
  free (en_desc_usr);
  if (en_desc_cmp)
    {
      regfree (en_desc_cmp);
      delete en_desc_cmp;
    }
}

/**
 * Read .er.rc file from the specified location
 * @param path
 * @return
 */
char *
Settings::read_rc (char *path)
{
  StringBuilder sb;
  Emsgqueue *commentq = new Emsgqueue (NTXT ("setting_commentq"));

  // Check file name
  if (NULL == path)
    return dbe_strdup (GTXT ("Error: empty file name"));
  bool override = true;
  set_rc (path, true, commentq, override);
  Emsg *msg = commentq->fetch ();
  while (msg != NULL)
    {
      char *str = msg->get_msg ();
      sb.append (str);
      msg = msg->next;
    }
  return sb.toString ();
}

void
Settings::read_rc (bool ipc_or_rdt_mode)
{
  bool override = false;

  // Read file from the current working directory
  char *rc_path = realpath (NTXT ("./.gprofng.rc"), NULL);
  if (rc_path)
    set_rc (rc_path, true, app->get_comments_queue (), override, ipc_or_rdt_mode);

  // Read file from the user's home directory
  char *home = getenv (NTXT ("HOME"));
  if (home)
    {
      char *strbuf = dbe_sprintf (NTXT ("%s/.gprofng.rc"), home);
      char *home_rc_path = realpath (strbuf, NULL);
      if (home_rc_path)
	{
	  if (rc_path == NULL || strcmp (rc_path, home_rc_path) != 0)
	    set_rc (home_rc_path, true, app->get_comments_queue (), override, ipc_or_rdt_mode);
	  free (home_rc_path);
	}
      free (strbuf);
    }
  free (rc_path);

  // Read system-wide file
  const char *sysconfdir = getenv("GPROFNG_SYSCONFDIR");
  if (sysconfdir == NULL)
    sysconfdir = SYSCONFDIR;
  rc_path = dbe_sprintf (NTXT ("%s/gprofng.rc"), sysconfdir);
  if (access (rc_path, R_OK | F_OK) != 0)
    {
      StringBuilder sb;
      sb.sprintf (GTXT ("Warning: Default gprofng.rc file (%s) missing; configuration error "), rc_path);
      Emsg *m = new Emsg (CMSG_COMMENT, sb);
      app->get_comments_queue ()->append (m);
    }
  else
    set_rc (rc_path, false, app->get_comments_queue (), override);
  free (rc_path);
  is_loexpand_default = true;
  if (str_printmode == NULL)
    {
      // only if there's none set
      print_mode = PM_TEXT;
      str_printmode = dbe_strdup (NTXT ("text"));
    }
}


//  Handle various settings from reading the name .rc file
//	This function is called for each .rc file read, and, for
//	some settings, it accumulates the strings from the files.
//	For others, it accepts the first appearance for a setting in a
//	.rc file, and ignores subsequent appearances from other files.
//  Error messages are appended to the Emsgqueue specified by the caller

#define MAXARGS 20

void
Settings::set_rc (const char *path, bool msg, Emsgqueue *commentq,
		  bool override, bool ipc_or_rdt_mode)
{
  CmdType cmd_type;
  int arg_count, cparam;
  char *cmd, *end_cmd, *strbuf;
  char *arglist[MAXARGS];
  StringBuilder sb;

  FILE *fptr = fopen (path, NTXT ("r"));
  if (fptr == NULL)
    return;

  if (msg)
    {
      sb.sprintf (GTXT ("Processed %s for default settings"), path);
      Emsg *m = new Emsg (CMSG_COMMENT, sb);
      commentq->append (m);
    }
  int line_no = 0;
  end_cmd = NULL;
  while (!feof (fptr))
    {
      char *script = read_line (fptr);
      if (script == NULL)
	continue;
      line_no++;
      strtok (script, NTXT ("\n"));

      // extract the command
      cmd = strtok (script, NTXT (" \t"));
      if (cmd == NULL || *cmd == '#' || *cmd == '\n')
	{
	  free (script);
	  continue;
	}
      char *remainder = strtok (NULL, NTXT ("\n"));
      // now extract the arguments
      int nargs = 0;
      for (;;)
	{
	  if (nargs >= MAXARGS)
	    {
	      if (!msg)
		{
		  msg = true; // suppress repeats of header
		  Emsg *m = new Emsg (CMSG_COMMENT, GTXT ("Processed system gprofng.rc file for default settings"));
		  commentq->append (m);
		}
	      sb.sprintf (GTXT ("Warning: more than %d arguments to %s command, line %d\n"),
			  MAXARGS, cmd, line_no);
	      Emsg *m = new Emsg (CMSG_COMMENT, sb);
	      commentq->append (m);
	      break;
	    }

	  char *nextarg = strtok (remainder, NTXT ("\n"));
	  if (nextarg == NULL || *nextarg == '#')
	    break;
	  arglist[nargs++] = parse_qstring (nextarg, &end_cmd);
	  remainder = end_cmd;
	  if (remainder == NULL)
	    break;
	  // skip any blanks or tabs to get to next argument
	  while (*remainder == ' ' || *remainder == '\t')
	    remainder++;
	}
      cmd_type = Command::get_command (cmd, arg_count, cparam);
      // check for extra arguments
      if ((cmd_type != UNKNOWN_CMD && cmd_type != INDXOBJDEF) && (nargs > arg_count))
	{
	  if (!msg)
	    {
	      msg = true; // suppress repeats of header
	      Emsg *m = new Emsg (CMSG_COMMENT, GTXT ("Processed system gprofng.rc file for default settings"));
	      commentq->append (m);
	    }
	  sb.sprintf (GTXT ("Warning: extra arguments to %s command, line %d\n"), cmd, line_no);
	  Emsg *m = new Emsg (CMSG_COMMENT, sb);
	  commentq->append (m);
	}
      if (nargs < arg_count)
	{
	  if (!msg)
	    {
	      msg = true; // suppress repeats of header
	      Emsg *m = new Emsg (CMSG_COMMENT, GTXT ("Processed system gprofng.rc file for default settings"));
	      commentq->append (m);
	    }
	  sb.sprintf (GTXT ("Error: missing arguments to %s command, line %d\n"),
		      cmd, line_no);
	  Emsg *m = new Emsg (CMSG_COMMENT, sb);
	  commentq->append (m);

	  // ignore this command
	  free (script);
	  continue;
	}
      if (ipc_or_rdt_mode && (cmd_type != ADDPATH) && (cmd_type != PATHMAP))
	{
	  free (script);
	  continue;
	}
      switch (cmd_type)
	{
	case SCOMPCOM:
	  if (!str_scompcom || override)
	    {
	      str_scompcom = dbe_strdup (arglist[0]);
	      proc_compcom (arglist[0], true, true);
	    }
	  break;
	case STHRESH:
	  if (!str_sthresh || override)
	    {
	      str_sthresh = dbe_strdup (arglist[0]);
	      proc_thresh (arglist[0], true, true);
	      break;
	    }
	  break;
	case DCOMPCOM:
	  if (!str_dcompcom || override)
	    {
	      str_dcompcom = dbe_strdup (arglist[0]);
	      proc_compcom (arglist[0], false, true);
	    }
	  break;
	case COMPCOM:
	  // process as if it were for both source and disassembly
	  //	note that if it is set, subsequent SCOMPCOM and DCOMPCOM
	  //	will be ignored
	  if (!str_scompcom || override)
	    {
	      str_scompcom = dbe_strdup (arglist[0]);
	      proc_compcom (arglist[0], true, true);
	    }
	  if (!str_dcompcom || override)
	    {
	      str_dcompcom = dbe_strdup (arglist[0]);
	      proc_compcom (arglist[0], false, true);
	    }
	  break;
	case DTHRESH:
	  if (!str_dthresh || override)
	    {
	      str_dthresh = dbe_strdup (arglist[0]);
	      proc_thresh (arglist[0], false, true);
	    }
	  break;
	case DMETRICS:
	  // append new settings to old, if necessary
	  if (str_dmetrics)
	    {
	      char *name = strstr (str_dmetrics, ":name");
	      if (name == NULL)
		strbuf = dbe_sprintf ("%s:%s", str_dmetrics, arglist[0]);
	      else
		{
		  char * next = strstr (name + 1, ":");
		  if (next == NULL)
		    {
		      name[0] = '\0';
		      strbuf = dbe_sprintf ("%s:%s:name", str_dmetrics, arglist[0]);
		    }
		  else
		    strbuf = dbe_sprintf ("%s:%s", str_dmetrics, arglist[0]);
		}
	      free (str_dmetrics);
	      str_dmetrics = strbuf;
	    }
	  else
	    str_dmetrics = dbe_strdup (arglist[0]);
	  break;
	case DSORT:
	  // append new settings to old, if necessary
	  if (str_dsort)
	    {
	      strbuf = dbe_sprintf (NTXT ("%s:%s"), str_dsort, arglist[0]);
	      free (str_dsort);
	      str_dsort = strbuf;
	    }
	  else
	    str_dsort = dbe_strdup (arglist[0]);
	  break;
	case TLMODE:
	  if (!str_tlmode || override)
	    {
	      str_tlmode = dbe_strdup (arglist[0]);
	      proc_tlmode (arglist[0], true);
	    }
	  break;
	case TLDATA:
	  if (!str_tldata || override)
	    {
	      str_tldata = dbe_strdup (arglist[0]);
	      proc_tldata (arglist[0], true);
	    }
	  break;
	case TABS:
	  if (!str_tabs || override)
	    // the string is processed later, after all .rc files are read
	    str_tabs = dbe_strdup (arglist[0]);
	  break;
	case RTABS:
	  if (!str_rtabs || override)
	    // the string is processed later, after all .rc files are read
	    str_rtabs = dbe_strdup (arglist[0]);
	  break;
	case ADDPATH:
	  if (str_search_path)
	    {
	      strbuf = dbe_sprintf (NTXT ("%s:%s"), str_search_path, arglist[0]);
	      free (str_search_path);
	      str_search_path = strbuf;
	    }
	  else
	    str_search_path = dbe_strdup (arglist[0]);
	  break;
	case PATHMAP:
	  {
	    char *err = add_pathmap (pathmaps, arglist[0], arglist[1]);
	    free (err);     // XXX error is not reported
	    break;
	  }
	case LIBDIRS:
	  if (preload_libdirs == NULL)
	    preload_libdirs = dbe_strdup (arglist[0]);
	  break;
	case NAMEFMT:
	  if (name_format == Histable::NA)
	    set_name_format (arglist[0]);
	  break;
	case VIEWMODE:
	  if (!str_vmode || override)
	    {
	      str_vmode = dbe_strdup (arglist[0]);
	      set_view_mode (arglist[0], true);
	    }
	  break;
	case EN_DESC:
	  if (!str_en_desc || override)
	    {
	      str_en_desc = dbe_strdup (arglist[0]);
	      set_en_desc (arglist[0], true);
	    }
	  break;
	case LIMIT:
	  if (!str_limit || override)
	    {
	      str_limit = dbe_strdup (arglist[0]);
	      set_limit (arglist[0], true);
	    }
	  break;
	case PRINTMODE:
	  if (!str_printmode || override)
	    set_printmode (arglist[0]);
	  break;
	case COMPARE:
	  if (!str_compare || override)
	    {
	      char *s = arglist[0];
	      if (s)
		str_compare = dbe_strdup (s);
	      else
		s = NTXT ("");
	      if (strcasecmp (s, NTXT ("OFF")) == 0
		  || strcmp (s, NTXT ("0")) == 0)
		set_compare_mode (CMP_DISABLE);
	      else if (strcasecmp (s, NTXT ("ON")) == 0
		       || strcmp (s, NTXT ("1")) == 0)
		set_compare_mode (CMP_ENABLE);
	      else if (strcasecmp (s, NTXT ("DELTA")) == 0)
		set_compare_mode (CMP_DELTA);
	      else if (strcasecmp (s, NTXT ("RATIO")) == 0)
		set_compare_mode (CMP_RATIO);
	      else
		{
		  sb.sprintf (GTXT ("   .er.rc:%d The argument of 'compare' should be 'on', 'off', 'delta', or 'ratio'"),
			      (int) line_no);
		  Emsg *m = new Emsg (CMSG_COMMENT, sb);
		  commentq->append (m);
		}
	    }
	  break;

	case INDXOBJDEF:
	  {
	    char *ret = dbeSession->indxobj_define (arglist[0], NULL, arglist[1], (nargs >= 3) ? PTXT (arglist[2]) : NULL, (nargs >= 4) ? PTXT (arglist[3]) : NULL);
	    if (ret != NULL)
	      {
		sb.sprintf (GTXT ("   %s: line %d `%s %s %s'\n"),
			    ret, line_no, cmd, arglist[0], arglist[1]);
		Emsg *m = new Emsg (CMSG_COMMENT, sb);
		commentq->append (m);
	      }
	    break;
	  }
#ifdef sparc
	  //XXX: should be conditional on the experiment ARCH, not dbe ARCH
	case IGNORE_NO_XHWCPROF:
	  // ignore absence of -xhwcprof info for dataspace profiling
	  set_ignore_no_xhwcprof (true);
	  break;
#endif // sparc
	case IGNORE_FS_WARN:
	  // ignore file system warning in experiments
	  set_ignore_fs_warn (true);
	  break;
	case OBJECT_SHOW:
	  // Add the named libraries to the lib_expands array
	  set_libexpand (arglist[0], LIBEX_SHOW, true);
	  break;
	case OBJECT_HIDE:
	  // Add the named libraries to the lib_expands array
	  set_libexpand (arglist[0], LIBEX_HIDE, true);
	  break;
	case OBJECT_API:
	  // Add the named libraries to the lib_expands array
	  set_libexpand (arglist[0], LIBEX_API, true);
	  break;
	case COMMENT:
	  // ignore the line
	  break;
	default:
	  {
	    // unexpected command in an rc file
	    if (!msg)
	      {
		// if quiet, can remain so no longer
		msg = true;
		Emsg *m = new Emsg (CMSG_COMMENT, GTXT ("Processed system gprofng.rc file for default settings"));
		commentq->append (m);
	      }
	    sb.sprintf (GTXT ("   Unrecognized .gprofng.rc command on line %d: `%.64s'"),
			line_no, cmd);
	    Emsg *m = new Emsg (CMSG_COMMENT, sb);
	    commentq->append (m);
	    break;
	  }
	}
      free (script);
    }
  fclose (fptr);
}

Cmd_status
Settings::set_view_mode (char *arg, bool rc)
{
  if (!strcasecmp (arg, NTXT ("user")))
    view_mode = VMODE_USER;
  else if (!strcasecmp (arg, NTXT ("expert")))
    view_mode = VMODE_EXPERT;
  else if (!strcasecmp (arg, NTXT ("machine")))
    view_mode = VMODE_MACHINE;
  else if (!rc)
    return CMD_BAD_ARG;
  return CMD_OK;
}

Cmd_status
Settings::set_en_desc (char *arg, bool rc)
{
  regex_t *regex_desc = NULL;

  // cases below should be similar to Coll_Ctrl::set_follow_mode() cases
  if (!strcasecmp (arg, NTXT ("on")))
    en_desc = true;
  else if (!strcasecmp (arg, NTXT ("off")))
    en_desc = false;
  else if (arg[0] == '=' && arg[1] != 0)
    {
      // user has specified a string matching specification
      int ercode;
      { // compile regex_desc
	char * str = dbe_sprintf (NTXT ("^%s$"), arg + 1);
	regex_desc = new regex_t;
	memset (regex_desc, 0, sizeof (regex_t));
	ercode = regcomp (regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
	free (str);
      }
      if (ercode)
	{
	  // syntax error in parsing string
	  delete regex_desc;
	  if (!rc)
	    return CMD_BAD_ARG;
	  return CMD_OK;
	}
      en_desc = true;
    }
  else
    {
      if (!rc)
	return CMD_BAD_ARG;
      return CMD_OK;
    }
  free (en_desc_usr);
  en_desc_usr = dbe_strdup (arg);
  if (en_desc_cmp)
    {
      regfree (en_desc_cmp);
      delete en_desc_cmp;
    }
  en_desc_cmp = regex_desc;
  return CMD_OK;
}

// See if a descendant matches either the lineage or the executable name
bool
Settings::check_en_desc (const char *lineage, const char *targname)
{
  bool rc;
  if (en_desc_cmp == NULL)
    return en_desc;     // no specification was set, use the binary on/off value
  if (lineage == NULL)  // user doesn't care about specification
    return en_desc;     // use the binary on/off specification
  if (!regexec (en_desc_cmp, lineage, 0, NULL, 0))
    rc = true;          // this one matches user specification
  else if (targname == NULL)
    rc = false;         //a NULL name does not match any expression
  else if (!regexec (en_desc_cmp, targname, 0, NULL, 0))
    rc = true;          // this one matches the executable name
  else
    rc = false;
  return rc;
}

char *
Settings::set_limit (char *arg, bool)
{
  limit = (int) strtol (arg, (char **) NULL, 10);
  return NULL;
}

char *
Settings::set_printmode (char *arg)
{
  if (arg == NULL)
    return dbe_sprintf (GTXT ("The argument to '%s' must be '%s' or '%s' or a single-character"),
			NTXT ("printmode"), NTXT ("text"), NTXT ("html"));
  if (strlen (arg) == 1)
    {
      print_mode = PM_DELIM_SEP_LIST;
      print_delim = arg[0];
    }
  else if (!strcasecmp (arg, NTXT ("text")))
    print_mode = PM_TEXT;
  else if (!strcasecmp (arg, NTXT ("html")))
    print_mode = PM_HTML;
  else
    return dbe_sprintf (GTXT ("The argument to '%s' must be '%s' or '%s' or a single-character"),
			NTXT ("printmode"), NTXT ("text"), NTXT ("html"));
  free (str_printmode);
  str_printmode = dbe_strdup (arg);
  return NULL;
}

Cmd_status
Settings::proc_compcom (const char *cmd, bool isSrc, bool rc)
{
  int ck_compcom_bits, ck_threshold;
  bool ck_hex_visible = false;
  bool ck_src_visible = false;
  bool ck_srcmetric_visible = false;
  bool got_compcom_bits, got_threshold, got_src_visible, got_srcmetric_visible;
  bool got_hex_visible, got;
  int len, i;
  char *mcmd, *param;
  int flag, value = 0;
  Cmd_status status;
  char buf[BUFSIZ], *list;

  if (cmd == NULL)
    return CMD_BAD;
  ck_compcom_bits = 0;
  ck_threshold = 0;
  got_compcom_bits = got_threshold = got_src_visible = false;
  got_srcmetric_visible = got_hex_visible = false;
  snprintf (buf, sizeof (buf), NTXT ("%s"), cmd);
  list = buf;
  while ((mcmd = strtok (list, NTXT (":"))) != NULL)
    {
      list = NULL;
      // if "all" or "none"
      if (!strcasecmp (mcmd, Command::ALL_CMD))
	{
	  got_compcom_bits = true;
	  ck_compcom_bits = CCMV_ALL;
	  continue;
	}
      else if (!strcasecmp (mcmd, Command::NONE_CMD))
	{
	  got_compcom_bits = true;
	  ck_compcom_bits = 0;
	  continue;
	}

      // Find parameter after '='
      param = strchr (mcmd, '=');
      if (param)
	{
	  *param = '\0';
	  param++;
	}
      status = CMD_OK;
      got = false;
      flag = 0;
      len = (int) strlen (mcmd);
      for (i = 0; status == CMD_OK && i < comp_size; i++)
	if (!strncasecmp (mcmd, comp_cmd[i], len))
	  {
	    if (got) // Ambiguous comp_com command
	      status = CMD_AMBIGUOUS;
	    else
	      {
		got = true;
		flag = comp_vis[i];
		// Check argument
		if (flag == COMP_THRESHOLD)
		  {
		    if (param == NULL)
		      status = CMD_BAD_ARG;
		    else
		      {
			value = (int) strtol (param, &param, 10);
			if (value < 0 || value > 100)
			  status = CMD_OUTRANGE;
		      }
		  }
		else if (param != NULL)
		  status = CMD_BAD_ARG;
	      }
	  }

      // Not valid comp_com command
      if (!got)
	status = CMD_INVALID;
      if (status != CMD_OK)
	{
	  if (!rc)
	    return status;
	  continue;
	}

      // Set bits
      switch (flag)
	{
	case COMP_CMPLINE:
	  cmpline_visible = true;
	  break;
	case COMP_FUNCLINE:
	  funcline_visible = true;
	  break;
	case COMP_THRESHOLD:
	  got_threshold = true;
	  ck_threshold = value;
	  break;
	case COMP_SRC:
	  got_src_visible = true;
	  ck_src_visible = true;
	  break;
	case COMP_SRC_METRIC:
	  got_srcmetric_visible = true;
	  ck_srcmetric_visible = true;
	  got_src_visible = true;
	  ck_src_visible = true;
	  break;
	case COMP_NOSRC:
	  got_src_visible = true;
	  ck_src_visible = false;
	  break;
	case COMP_HEX:
	  got_hex_visible = true;
	  ck_hex_visible = true;
	  break;
	case COMP_NOHEX:
	  got_hex_visible = true;
	  ck_hex_visible = false;
	  break;
	case CCMV_BASIC:
	  got_compcom_bits = true;
	  ck_compcom_bits = CCMV_BASIC;
	  break;
	default:
	  got_compcom_bits = true;
	  ck_compcom_bits |= flag;
	}
    }

  // No error, update
  if (got_compcom_bits)
    {
      if (isSrc)
	src_compcom = ck_compcom_bits;
      else
	dis_compcom = ck_compcom_bits;
    }
  if (got_threshold)
    {
      if (isSrc)
	threshold_src = ck_threshold;
      else
	threshold_dis = ck_threshold;
    }
  if (got_src_visible)
      src_visible = ck_src_visible;
  if (got_srcmetric_visible)
      srcmetric_visible = ck_srcmetric_visible;
  if (got_hex_visible)
      hex_visible = ck_hex_visible;
  return CMD_OK;
}

// Process a threshold setting
Cmd_status
Settings::proc_thresh (char *cmd, bool isSrc, bool rc)
{
  int value;
  if (cmd == NULL)
    value = DEFAULT_SRC_DIS_THRESHOLD; // the default
  else
    value = (int) strtol (cmd, &cmd, 10);
  if (value < 0 || value > 100)
    {
      if (!rc)
	return CMD_OUTRANGE;
      value = DEFAULT_SRC_DIS_THRESHOLD;
    }
  if (isSrc)
    threshold_src = value;
  else
    threshold_dis = value;
  return CMD_OK;
}

// return any error string from processing visibility settings
char *
Settings::get_compcom_errstr (Cmd_status status, const char *cmd)
{
  int i;
  StringBuilder sb;
  switch (status)
    {
    case CMD_BAD:
      sb.append (GTXT ("No commentary classes has been specified."));
      break;
    case CMD_AMBIGUOUS:
      sb.append (GTXT ("Ambiguous commentary classes: "));
      break;
    case CMD_BAD_ARG:
      sb.append (GTXT ("Invalid argument for commentary classes: "));
      break;
    case CMD_OUTRANGE:
      sb.append (GTXT ("Out of range commentary classes argument: "));
      break;
    case CMD_INVALID:
      sb.append (GTXT ("Invalid commentary classes: "));
      break;
    case CMD_OK:
      break;
    }
  if (cmd)
    sb.append (cmd);
  sb.append (GTXT ("\nAvailable commentary classes: "));
  for (i = 0; i < comp_size; i++)
    {
      sb.append (comp_cmd[i]);
      if (i == comp_size - 1)
	sb.append (NTXT ("=#\n"));
      else
	sb.append (NTXT (":"));
    }
  return sb.toString ();
}

// Process a timeline-mode setting
Cmd_status
Settings::proc_tlmode (char *cmd, bool rc)
{
  bool got_tlmode, got_stack_align, got_stack_depth, got;
  int ck_tlmode = 0, ck_stack_align = 0, ck_stack_depth = 0;
  int len, i;
  char *mcmd, *param;
  int cmd_id, value = 0;
  TLModeSubcommand cmd_type;
  Cmd_status status;
  char buf[BUFSIZ], *list;
  if (cmd == NULL)
    return CMD_BAD;
  got_tlmode = got_stack_align = got_stack_depth = false;
  snprintf (buf, sizeof (buf), NTXT ("%s"), cmd);
  list = buf;
  while ((mcmd = strtok (list, NTXT (":"))) != NULL)
    {
      list = NULL;

      // Find parameter after '='
      param = strchr (mcmd, '=');
      if (param)
	{
	  *param = '\0';
	  param++;
	}
      status = CMD_OK;
      got = false;
      cmd_id = 0;
      cmd_type = TLCMD_INVALID;
      len = (int) strlen (mcmd);
      for (i = 0; status == CMD_OK && i < tlmode_size; i++)
	{
	  if (!strncasecmp (mcmd, tlmode_cmd[i].cmdText, len))
	    {
	      if (got) // Ambiguous timeline mode
		status = CMD_AMBIGUOUS;
	      else
		{
		  got = true;
		  cmd_type = tlmode_cmd[i].cmdType;
		  cmd_id = tlmode_cmd[i].cmdId;

		  // Check argument
		  if (cmd_type == TLCMD_DEPTH)
		    {
		      if (param == NULL)
			status = CMD_BAD_ARG;
		      else
			{
			  value = (int) strtol (param, &param, 10);
			  if (value <= 0 || value > 256)
			    status = CMD_OUTRANGE;
			}
		    }
		  else if (param != NULL)
		    status = CMD_BAD_ARG;
		}
	    }
	}

      // Not valid timeline mode
      if (!got)
	status = CMD_INVALID;
      if (status != CMD_OK)
	{
	  if (!rc)
	    return status;
	  continue;
	}

      // Set bits
      switch (cmd_type)
	{
	case TLCMD_ENTITY_MODE:
	  got_tlmode = true;
	  ck_tlmode = cmd_id;
	  break;
	case TLCMD_ALIGN:
	  got_stack_align = true;
	  ck_stack_align = cmd_id;
	  break;
	case TLCMD_DEPTH:
	  got_stack_depth = true;
	  ck_stack_depth = value;
	  break;
	default:
	  break;
	}
    }

  // No error, update
  if (got_tlmode)
    tlmode = ck_tlmode;
  if (got_stack_align)
    stack_align = ck_stack_align;
  if (got_stack_depth)
    stack_depth = ck_stack_depth;
  return CMD_OK;
}

// Process timeline data specification
Cmd_status
Settings::proc_tldata (const char *cmd, bool /* if true, ignore any error */)
{
  free (tldata);
  tldata = dbe_strdup (cmd); // let GUI parse it
  return CMD_OK;
}

void
Settings::set_tldata (const char* _tldata_str)
{
  free (tldata);
  tldata = dbe_strdup (_tldata_str);
}

char*
Settings::get_tldata ()
{
  return dbe_strdup (tldata);
}

Cmd_status
Settings::set_name_format (char *arg)
{
  char *colon = strchr (arg, ':');
  size_t arg_len = (colon) ? (colon - arg) : strlen (arg);
  Histable::NameFormat fname_fmt = Histable::NA;
  if (!strncasecmp (arg, NTXT ("long"), arg_len))
    fname_fmt = Histable::LONG;
  else if (!strncasecmp (arg, NTXT ("short"), arg_len))
    fname_fmt = Histable::SHORT;
  else if (!strncasecmp (arg, NTXT ("mangled"), arg_len))
    fname_fmt = Histable::MANGLED;
  else
    return CMD_BAD_ARG;

  bool soname_fmt = false;
  if (colon && (colon + 1))
    {
      colon++;
      if (!strcasecmp (colon, NTXT ("soname")))
	soname_fmt = true;
      else if (!strcasecmp (colon, NTXT ("nosoname")))
	soname_fmt = false;
      else
	return CMD_BAD_ARG;
    }
  name_format = Histable::make_fmt (fname_fmt, soname_fmt);
  return CMD_OK;
}

void
Settings::buildMasterTabList ()
{
  tab_list = new Vector<DispTab*>;
  int i = -1;

  // Add tabs for all the known reports
  tab_list->append (new DispTab (DSP_DEADLOCKS, i, false, DEADLOCK_EVNTS));
  tab_list->append (new DispTab (DSP_FUNCTION, i, false, FUNCS));
  tab_list->append (new DispTab (DSP_TIMELINE, i, false, TIMELINE));
  tab_list->append (new DispTab (DSP_CALLTREE, i, false, CALLTREE));
  tab_list->append (new DispTab (DSP_CALLFLAME, i, false, CALLFLAME));
  tab_list->append (new DispTab (DSP_DUALSOURCE, i, false, DUALSOURCE));
  tab_list->append (new DispTab (DSP_SOURCE_DISASM, i, false, SOURCEDISAM));
  tab_list->append (new DispTab (DSP_SOURCE, i, false, SOURCE));
  tab_list->append (new DispTab (DSP_LINE, i, false, HOTLINES));
  tab_list->append (new DispTab (DSP_DISASM, i, false, DISASM));
  tab_list->append (new DispTab (DSP_PC, i, false, HOTPCS));
  tab_list->append (new DispTab (DSP_LEAKLIST, i, false, LEAKS));
  tab_list->append (new DispTab (DSP_IOACTIVITY, i, false, IOACTIVITY));
  tab_list->append (new DispTab (DSP_HEAPCALLSTACK, i, false, HEAP));
  tab_list->append (new DispTab (DSP_IFREQ, i, false, IFREQ));
  tab_list->append (new DispTab (DSP_CALLER, i, false, GPROF));
  tab_list->append (new DispTab (DSP_STATIS, i, false, STATISTICS));
  tab_list->append (new DispTab (DSP_EXP, i, false, HEADER));
}

// Update tablist based on data availability
void
Settings::updateTabAvailability ()
{
  int index;
  DispTab *dsptab;

  Vec_loop (DispTab*, tab_list, index, dsptab)
  {
    if (dsptab->type == DSP_DATAOBJ)
      dsptab->setAvailability (dbeSession->is_datamode_available ());
    else if (dsptab->type == DSP_DLAYOUT)
      dsptab->setAvailability (dbeSession->is_datamode_available ());
    else if (dsptab->type == DSP_LEAKLIST)
      dsptab->setAvailability (false);
    else if (dsptab->type == DSP_IOACTIVITY)
      dsptab->setAvailability (dbeSession->is_iodata_available ());
    else if (dsptab->type == DSP_HEAPCALLSTACK)
      dsptab->setAvailability (dbeSession->is_heapdata_available ());
    else if (dsptab->type == DSP_TIMELINE)
      dsptab->setAvailability (dbeSession->is_timeline_available ());
    else if (dsptab->type == DSP_IFREQ)
      dsptab->setAvailability (dbeSession->is_ifreq_available ());
    else if (dsptab->type == DSP_RACES)
      dsptab->setAvailability (dbeSession->is_racelist_available ());
    else if (dsptab->type == DSP_DEADLOCKS)
      dsptab->setAvailability (dbeSession->is_deadlocklist_available ());
    else if (dsptab->type == DSP_DUALSOURCE)
      dsptab->setAvailability (dbeSession->is_racelist_available ()
			       || dbeSession->is_deadlocklist_available ());
  }
}

// Process a tab setting
Cmd_status
Settings::proc_tabs (bool _rdtMode)
{
  int arg_cnt, cparam;
  int count = 0;
  int index;
  DispTab *dsptab;
  char *cmd;
  if (tabs_processed == true)
    return CMD_OK;
  tabs_processed = true;
  if (_rdtMode == true)
    {
      if (str_rtabs == NULL)
	str_rtabs = strdup ("header");
      cmd = str_rtabs;
    }
  else
    {
      if (str_tabs == NULL)
	str_tabs = strdup ("header");
      cmd = str_tabs;
    }
  if (strcmp (cmd, NTXT ("none")) == 0)
    return CMD_OK;
  Vector <char *> *tokens = split_str (cmd, ':');
  for (long j = 0, sz = VecSize (tokens); j < sz; j++)
    {
      char *tabname = tokens->get (j);
      // search for this tab command token
      CmdType c = Command::get_command (tabname, arg_cnt, cparam);
      if (c == INDXOBJ)
	{
	  // set the bit for this subtype
	  indx_tab_state->store (cparam, true);
	  indx_tab_order->store (cparam, count++);
	}
      else
	{
	  // search for this tab type in the regular tabs
	  Vec_loop (DispTab*, tab_list, index, dsptab)
	  {
	    if (dsptab->cmdtoken == c)
	      {
		dsptab->visible = true;
		dsptab->order = count++;
		break;
	      }
	  }
	}
      free (tabname);
    }
  delete tokens;
  return CMD_OK;
}

void
Settings::set_MemTabState (Vector<bool>*selected)
{
  if (selected->size () == 0)
    return;
  for (int j = 0; j < mem_tab_state->size (); j++)
    mem_tab_state->store (j, selected->fetch (j));
}

// define a new memory object type

void
Settings::mobj_define (MemObjType_t */* mobj */, bool state)
{
  if (mem_tab_state->size () == 0)
    state = true;
  mem_tab_state->append (state);
  mem_tab_order->append (-1);
}

void
Settings::set_IndxTabState (Vector<bool>*selected)
{
  for (int j = 0; j < selected->size (); j++)
    indx_tab_state->store (j, selected->fetch (j));
}

// define a new index object type
void
Settings::indxobj_define (int type, bool state)
{
  indx_tab_state->store (type, state);
  indx_tab_order->store (type, -1);
}

void
Settings::set_pathmaps (Vector<pathmap_t*> *newPathMap)
{
  if (pathmaps)
    {
      pathmaps->destroy ();
      delete pathmaps;
    }
  pathmaps = newPathMap;
}

static char *
get_canonical_name (const char *fname)
{
  char *nm = dbe_strdup (fname);
  for (size_t len = strlen (nm); (len > 0) && (nm[len - 1] == '/'); len--)
    nm[len - 1] = 0;
  return nm;
}

char *
Settings::add_pathmap (Vector<pathmap_t*> *v, const char *from, const char *to)
{
  // Check for errors
  if (from == NULL || to == NULL)
    return dbe_strdup (GTXT ("Pathmap can have neither from nor to as NULL\n"));
  if (strcmp (from, to) == 0)
    return dbe_strdup (GTXT ("Pathmap from must differ from to\n"));
  char *old_prefix = get_canonical_name (from);
  char *new_prefix = get_canonical_name (to);

  // Check the pathmap list
  for (int i = 0, sz = v->size (); i < sz; i++)
    {
      pathmap_t *pmp = v->get (i);
      if ((strcmp (pmp->old_prefix, old_prefix) == 0) &&(strcmp (pmp->new_prefix, new_prefix) == 0))
	{
	  char *s = dbe_sprintf (GTXT ("Pathmap from `%s' to `%s' already exists\n"), old_prefix, new_prefix);
	  free (old_prefix);
	  free (new_prefix);
	  return s;
	}
    }
  // construct a map for this pair
  pathmap_t *thismap = new pathmap_t;
  thismap->old_prefix = old_prefix;
  thismap->new_prefix = new_prefix;
  v->append (thismap);
  return NULL;
}

// Set all shared object expands back to .rc file defaults,
//	as stored in the DbeSession Settings
bool
Settings::set_libdefaults ()
{
  // See if this is unchanged
  if (is_loexpand_default == true)
    return false; // no change

  // replicate the DbeSession's lo_expand vector and default settings
  lo_expand_t *this_lo_ex;
  lo_expand_t *new_lo_ex;
  int index;
  lo_expand_default = dbeSession->get_settings ()->lo_expand_default;
  lo_expands = new Vector<lo_expand_t*>;
  Vec_loop (lo_expand_t*, dbeSession->get_settings ()->lo_expands, index, this_lo_ex)
  {
    new_lo_ex = new lo_expand_t;
    new_lo_ex->libname = dbe_strdup (this_lo_ex->libname);
    new_lo_ex->expand = this_lo_ex->expand;
    lo_expands->append (new_lo_ex);
  }
  is_loexpand_default = true;
  return true;
}

bool
Settings::set_libexpand (char *cov, enum LibExpand expand, bool rc)
{
  int index;
  lo_expand_t *loe;
  bool change = false;
  if (cov == NULL || !strcasecmp (cov, Command::ALL_CMD))
    { // set all libraries
      // set the default
      if (lo_expand_default != expand)
	{
	  lo_expand_default = expand;
	  change = true;
	  is_loexpand_default = false;
	}

      // and force any explicit settings to match, too
      Vec_loop (lo_expand_t*, lo_expands, index, loe)
      {
	if (loe->expand != expand)
	  {
	    loe->expand = expand;
	    change = true;
	    is_loexpand_default = false;
	  }
      }

    }
  else
    { // parsing coverage
      Vector <char *> *tokens = split_str (cov, ',');
      for (long j = 0, sz = VecSize (tokens); j < sz; j++)
	{
	  char *lo_name = tokens->get (j);
	  char *newname = get_basename (lo_name);
	  bool found = false;
	  Vec_loop (lo_expand_t*, lo_expands, index, loe)
	  {
	    if (strcmp (loe->libname, newname) == 0)
	      {
		if (loe->expand != expand)
		  {
		    if (rc == false)
		      {
			loe->expand = expand;
			change = true;
			is_loexpand_default = false;
		      }
		  }
		found = true;
		break;
	      }
	  }

	  if (found == false)
	    {
	      // construct a map for this pair
	      lo_expand_t *thisloe;
	      thisloe = new lo_expand_t;
	      thisloe->libname = dbe_strdup (newname);
	      thisloe->expand = expand;
	      change = true;
	      is_loexpand_default = false;

	      // add it to the vector
	      lo_expands->append (thisloe);
	    }
	  free (lo_name);
	}
      delete tokens;
    }
  return change;
}

enum LibExpand
Settings::get_lo_setting (char *name)
{
  int index;
  lo_expand_t *loe;
  char *lo_name = get_basename (name);
  Vec_loop (lo_expand_t*, lo_expands, index, loe)
  {
    if (strcmp (loe->libname, lo_name) == 0)
      return loe->expand;
  }
  return lo_expand_default;
}
