Пример #1
0
static void
push_menu_pane (Lisp_Object name, Lisp_Object prefix_vec)
{
  if (menu_items_used + MENU_ITEMS_PANE_LENGTH > menu_items_allocated)
    grow_menu_items ();

  if (menu_items_submenu_depth == 0)
    menu_items_n_panes++;
  XVECTOR (menu_items)->contents[menu_items_used++] = Qt;
  XVECTOR (menu_items)->contents[menu_items_used++] = name;
  XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec;
}
Пример #2
0
/* Compile a regexp and signal a Lisp error if anything goes wrong.  */
void
compile_pattern (Lisp_Object pattern, struct re_pattern_buffer *bufp, char *translate, int backward)
{
  char *val;
  Lisp_Object dummy;

  if (EQ (pattern, last_regexp)
      && translate == bufp->translate /* 92.4.10 by K.Handa */
      /* 93.7.13 by K.Handa */
      && NILP (current_buffer->mc_flag) == !bufp->mc_flag
      && (!bufp->syntax_version
	  || bufp->syntax_version == syntax_table_version)
      && (!bufp->category_version
	  || bufp->category_version == category_table_version))
    return;

  if (CONSP (pattern))			/* pre-compiled regexp */
    {
      Lisp_Object compiled;

      val = 0;
      pattern = XCONS (pattern)->car;
      if (CONSP (pattern)
	  && (compiled = backward ? XCONS(pattern)->cdr : XCONS(pattern)->car)
	  && XTYPE (compiled) == Lisp_Vector
	  && XVECTOR (compiled)->size == 4) {
	/* set_pattern will set bufp->allocated to NULL */
	set_pattern (compiled, bufp, translate);
	return;
      }

      val = "Invalied pre-compiled regexp";
      goto invalid_regexp;
    }

  CHECK_STRING (pattern, 0);

  last_regexp = Qnil;
  bufp->translate = translate;
  bufp->syntax_version = bufp->category_version = 0; /* 93.7.13 by K.Handa */
  /* 92.7.10 by T.Enami
     'bufp->allocated == 0' means bufp->buffer points to pre-compiled pattern
     in a lisp string, which should not be 'realloc'ed. */
  if (bufp->allocated == 0) bufp->buffer = 0; 

  val = re_compile_pattern (XSTRING (pattern)->data,
			    XSTRING (pattern)->size,
			    bufp);

  if (val)
    {
    invalid_regexp:
      dummy = build_string (val);
      while (1)
	Fsignal (Qinvalid_regexp, Fcons (dummy, Qnil));
    }
  last_regexp = pattern;
  return;
}
Пример #3
0
static void
push_left_right_boundary (void)
{
  if (menu_items_used + 1 > menu_items_allocated)
    grow_menu_items ();

  XVECTOR (menu_items)->contents[menu_items_used++] = Qquote;
}
Пример #4
0
/* As above, but return the menu selection instead of storing in kb buffer.
   If keymaps==1, return full prefixes to selection. */
Lisp_Object
find_and_return_menu_selection (FRAME_PTR f, int keymaps, void *client_data)
{
  Lisp_Object prefix, entry;
  int i;
  Lisp_Object *subprefix_stack;
  int submenu_depth = 0;

  prefix = entry = Qnil;
  i = 0;
  subprefix_stack =
    (Lisp_Object *)alloca(menu_items_used * sizeof (Lisp_Object));

  while (i < menu_items_used)
    {
      if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
        {
          subprefix_stack[submenu_depth++] = prefix;
          prefix = entry;
          i++;
        }
      else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
        {
          prefix = subprefix_stack[--submenu_depth];
          i++;
        }
      else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
        {
          prefix
            = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
          i += MENU_ITEMS_PANE_LENGTH;
        }
      /* Ignore a nil in the item list.
         It's meaningful only for dialog boxes.  */
      else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
        i += 1;
      else
        {
          entry
            = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
          if ((EMACS_INT)client_data ==  (EMACS_INT)(&XVECTOR (menu_items)->contents[i]))
            {
              if (keymaps != 0)
                {
                  int j;

                  entry = Fcons (entry, Qnil);
                  if (!NILP (prefix))
                    entry = Fcons (prefix, entry);
                  for (j = submenu_depth - 1; j >= 0; j--)
                    if (!NILP (subprefix_stack[j]))
                      entry = Fcons (subprefix_stack[j], entry);
                }
              return entry;
            }
          i += MENU_ITEMS_ITEM_LENGTH;
        }
    }
  return Qnil;
}
Пример #5
0
static void
push_submenu_end (void)
{
  if (menu_items_used + 1 > menu_items_allocated)
    grow_menu_items ();

  XVECTOR (menu_items)->contents[menu_items_used++] = Qlambda;
  menu_items_submenu_depth--;
}
Пример #6
0
static void
push_submenu_start (void)
{
  if (menu_items_used + 1 > menu_items_allocated)
    grow_menu_items ();

  XVECTOR (menu_items)->contents[menu_items_used++] = Qnil;
  menu_items_submenu_depth++;
}
Пример #7
0
void
set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
{
  HMENU menubar_widget = f->output_data.w32->menubar_widget;
  Lisp_Object items;
  widget_value *wv, *first_wv, *prev_wv = 0;
  int i, last_i;
  int *submenu_start, *submenu_end;
  int *submenu_top_level_items, *submenu_n_panes;

  /* We must not change the menubar when actually in use.  */
  if (f->output_data.w32->menubar_active)
    return;

  XSETFRAME (Vmenu_updating_frame, f);

  if (! menubar_widget)
    deep_p = true;

  if (deep_p)
    {
      /* Make a widget-value tree representing the entire menu trees.  */

      struct buffer *prev = current_buffer;
      Lisp_Object buffer;
      ptrdiff_t specpdl_count = SPECPDL_INDEX ();
      int previous_menu_items_used = f->menu_bar_items_used;
      Lisp_Object *previous_items
	= (Lisp_Object *) alloca (previous_menu_items_used
				  * word_size);

      /* If we are making a new widget, its contents are empty,
	 do always reinitialize them.  */
      if (! menubar_widget)
	previous_menu_items_used = 0;

      buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
      specbind (Qinhibit_quit, Qt);
      /* Don't let the debugger step into this code
	 because it is not reentrant.  */
      specbind (Qdebug_on_next_call, Qnil);

      record_unwind_save_match_data ();

      if (NILP (Voverriding_local_map_menu_flag))
	{
	  specbind (Qoverriding_terminal_local_map, Qnil);
	  specbind (Qoverriding_local_map, Qnil);
	}

      set_buffer_internal_1 (XBUFFER (buffer));

      /* Run the hooks.  */
      safe_run_hooks (Qactivate_menubar_hook);
      safe_run_hooks (Qmenu_bar_update_hook);
      fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));

      items = FRAME_MENU_BAR_ITEMS (f);

      /* Save the frame's previous menu bar contents data.  */
      if (previous_menu_items_used)
	memcpy (previous_items, XVECTOR (f->menu_bar_vector)->contents,
		previous_menu_items_used * word_size);

      /* Fill in menu_items with the current menu bar contents.
	 This can evaluate Lisp code.  */
      save_menu_items ();

      menu_items = f->menu_bar_vector;
      menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
      submenu_start = (int *) alloca (ASIZE (items) * sizeof (int));
      submenu_end = (int *) alloca (ASIZE (items) * sizeof (int));
      submenu_n_panes = (int *) alloca (ASIZE (items) * sizeof (int));
      submenu_top_level_items = (int *) alloca (ASIZE (items) * sizeof (int));
      init_menu_items ();
      for (i = 0; i < ASIZE (items); i += 4)
	{
	  Lisp_Object key, string, maps;

	  last_i = i;

	  key = AREF (items, i);
	  string = AREF (items, i + 1);
	  maps = AREF (items, i + 2);
	  if (NILP (string))
	    break;

	  submenu_start[i] = menu_items_used;

	  menu_items_n_panes = 0;
	  submenu_top_level_items[i]
	    = parse_single_submenu (key, string, maps);
	  submenu_n_panes[i] = menu_items_n_panes;

	  submenu_end[i] = menu_items_used;
	}

      finish_menu_items ();

      /* Convert menu_items into widget_value trees
	 to display the menu.  This cannot evaluate Lisp code.  */

      wv = make_widget_value ("menubar", NULL, true, Qnil);
      wv->button_type = BUTTON_TYPE_NONE;
      first_wv = wv;

      for (i = 0; i < last_i; i += 4)
	{
	  menu_items_n_panes = submenu_n_panes[i];
	  wv = digest_single_submenu (submenu_start[i], submenu_end[i],
				      submenu_top_level_items[i]);
	  if (prev_wv)
	    prev_wv->next = wv;
	  else
	    first_wv->contents = wv;
	  /* Don't set wv->name here; GC during the loop might relocate it.  */
	  wv->enabled = true;
	  wv->button_type = BUTTON_TYPE_NONE;
	  prev_wv = wv;
	}

      set_buffer_internal_1 (prev);

      /* If there has been no change in the Lisp-level contents
	 of the menu bar, skip redisplaying it.  Just exit.  */

      for (i = 0; i < previous_menu_items_used; i++)
	if (menu_items_used == i
	    || (!EQ (previous_items[i], AREF (menu_items, i))))
	  break;
      if (i == menu_items_used && i == previous_menu_items_used && i != 0)
	{
	  free_menubar_widget_value_tree (first_wv);
	  discard_menu_items ();
          unbind_to (specpdl_count, Qnil);
	  return;
	}

      fset_menu_bar_vector (f, menu_items);
      f->menu_bar_items_used = menu_items_used;

      /* This undoes save_menu_items.  */
      unbind_to (specpdl_count, Qnil);

      /* Now GC cannot happen during the lifetime of the widget_value,
	 so it's safe to store data from a Lisp_String, as long as
	 local copies are made when the actual menu is created.
	 Windows takes care of this for normal string items, but
	 not for owner-drawn items or additional item-info.  */
      wv = first_wv->contents;
      for (i = 0; i < ASIZE (items); i += 4)
	{
	  Lisp_Object string;
	  string = AREF (items, i + 1);
	  if (NILP (string))
	    break;
	  wv->name = SSDATA (string);
	  update_submenu_strings (wv->contents);
	  wv = wv->next;
	}
    }
  else
    {
      /* Make a widget-value tree containing
	 just the top level menu bar strings.  */

      wv = make_widget_value ("menubar", NULL, true, Qnil);
      wv->button_type = BUTTON_TYPE_NONE;
      first_wv = wv;

      items = FRAME_MENU_BAR_ITEMS (f);
      for (i = 0; i < ASIZE (items); i += 4)
	{
	  Lisp_Object string;

	  string = AREF (items, i + 1);
	  if (NILP (string))
	    break;

	  wv = make_widget_value (SSDATA (string), NULL, true, Qnil);
	  wv->button_type = BUTTON_TYPE_NONE;
	  /* This prevents lwlib from assuming this
	     menu item is really supposed to be empty.  */
	  /* The EMACS_INT cast avoids a warning.
	     This value just has to be different from small integers.  */
	  wv->call_data = (void *) (EMACS_INT) (-1);

	  if (prev_wv)
	    prev_wv->next = wv;
	  else
	    first_wv->contents = wv;
	  prev_wv = wv;
	}

      /* Forget what we thought we knew about what is in the
	 detailed contents of the menu bar menus.
	 Changing the top level always destroys the contents.  */
      f->menu_bar_items_used = 0;
    }

  /* Create or update the menu bar widget.  */

  block_input ();

  if (menubar_widget)
    {
      /* Empty current menubar, rather than creating a fresh one.  */
      while (DeleteMenu (menubar_widget, 0, MF_BYPOSITION))
	;
    }
  else
    {
      menubar_widget = CreateMenu ();
    }
  fill_in_menu (menubar_widget, first_wv->contents);

  free_menubar_widget_value_tree (first_wv);

  {
    HMENU old_widget = f->output_data.w32->menubar_widget;

    f->output_data.w32->menubar_widget = menubar_widget;
    SetMenu (FRAME_W32_WINDOW (f), f->output_data.w32->menubar_widget);
    /* Causes flicker when menu bar is updated
    DrawMenuBar (FRAME_W32_WINDOW (f)); */

    /* Force the window size to be recomputed so that the frame's text
       area remains the same, if menubar has just been created.  */
    if (old_widget == NULL)
      {
	windows_or_buffers_changed = 23;
	adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
      }
  }

  unblock_input ();
}
Пример #8
0
void
find_and_call_menu_selection (FRAME_PTR f, int menu_bar_items_used, Lisp_Object vector, void *client_data)
{
  Lisp_Object prefix, entry;
  Lisp_Object *subprefix_stack;
  int submenu_depth = 0;
  int i;

  entry = Qnil;
  subprefix_stack = (Lisp_Object *) alloca (menu_bar_items_used * sizeof (Lisp_Object));
  prefix = Qnil;
  i = 0;

  while (i < menu_bar_items_used)
    {
      if (EQ (XVECTOR (vector)->contents[i], Qnil))
	{
	  subprefix_stack[submenu_depth++] = prefix;
	  prefix = entry;
	  i++;
	}
      else if (EQ (XVECTOR (vector)->contents[i], Qlambda))
	{
	  prefix = subprefix_stack[--submenu_depth];
	  i++;
	}
      else if (EQ (XVECTOR (vector)->contents[i], Qt))
	{
	  prefix = XVECTOR (vector)->contents[i + MENU_ITEMS_PANE_PREFIX];
	  i += MENU_ITEMS_PANE_LENGTH;
	}
      else
	{
	  entry = XVECTOR (vector)->contents[i + MENU_ITEMS_ITEM_VALUE];
	  /* The EMACS_INT cast avoids a warning.  There's no problem
	     as long as pointers have enough bits to hold small integers.  */
	  if ((int) (EMACS_INT) client_data == i)
	    {
	      int j;
	      struct input_event buf;
	      Lisp_Object frame;
	      EVENT_INIT (buf);

	      XSETFRAME (frame, f);
	      buf.kind = MENU_BAR_EVENT;
	      buf.frame_or_window = frame;
	      buf.arg = frame;
	      kbd_buffer_store_event (&buf);

	      for (j = 0; j < submenu_depth; j++)
		if (!NILP (subprefix_stack[j]))
		  {
		    buf.kind = MENU_BAR_EVENT;
		    buf.frame_or_window = frame;
		    buf.arg = subprefix_stack[j];
		    kbd_buffer_store_event (&buf);
		  }

	      if (!NILP (prefix))
		{
		  buf.kind = MENU_BAR_EVENT;
		  buf.frame_or_window = frame;
		  buf.arg = prefix;
		  kbd_buffer_store_event (&buf);
		}

	      buf.kind = MENU_BAR_EVENT;
	      buf.frame_or_window = frame;
	      buf.arg = entry;
	      kbd_buffer_store_event (&buf);

	      return;
	    }
	  i += MENU_ITEMS_ITEM_LENGTH;
	}
    }
}
Пример #9
0
widget_value *
digest_single_submenu (int start, int end, int top_level_items)
{
  widget_value *wv, *prev_wv, *save_wv, *first_wv;
  int i;
  int submenu_depth = 0;
  widget_value **submenu_stack;
  int panes_seen = 0;

  submenu_stack
    = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
  wv = xmalloc_widget_value ();
  wv->name = "menu";
  wv->value = 0;
  wv->enabled = 1;
  wv->button_type = BUTTON_TYPE_NONE;
  wv->help = Qnil;
  first_wv = wv;
  save_wv = 0;
  prev_wv = 0;

  /* Loop over all panes and items made by the preceding call
     to parse_single_submenu and construct a tree of widget_value objects.
     Ignore the panes and items used by previous calls to
     digest_single_submenu, even though those are also in menu_items.  */
  i = start;
  while (i < end)
    {
      if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
	{
	  submenu_stack[submenu_depth++] = save_wv;
	  save_wv = prev_wv;
	  prev_wv = 0;
	  i++;
	}
      else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
	{
	  prev_wv = save_wv;
	  save_wv = submenu_stack[--submenu_depth];
	  i++;
	}
      else if (EQ (XVECTOR (menu_items)->contents[i], Qt)
	       && submenu_depth != 0)
	i += MENU_ITEMS_PANE_LENGTH;
      /* Ignore a nil in the item list.
	 It's meaningful only for dialog boxes.  */
      else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
	i += 1;
      else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
	{
	  /* Create a new pane.  */
	  Lisp_Object pane_name, prefix;
	  const char *pane_string;

	  panes_seen++;

	  pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
	  prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];

#ifdef HAVE_NTGUI
	  if (STRINGP (pane_name))
	    {
	      if (unicode_append_menu)
		/* Encode as UTF-8 for now.  */
		pane_name = ENCODE_UTF_8 (pane_name);
	      else if (STRING_MULTIBYTE (pane_name))
		pane_name = ENCODE_SYSTEM (pane_name);

	      ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
	    }
#elif defined (USE_LUCID) && defined (HAVE_XFT)
	  if (STRINGP (pane_name))
            {
              pane_name = ENCODE_UTF_8 (pane_name);
	      ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
            }
#elif !defined (HAVE_MULTILINGUAL_MENU)
	  if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
	    {
	      pane_name = ENCODE_MENU_STRING (pane_name);
	      ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
	    }
#endif

	  pane_string = (NILP (pane_name)
			 ? "" : (char *) SDATA (pane_name));
	  /* If there is just one top-level pane, put all its items directly
	     under the top-level menu.  */
	  if (menu_items_n_panes == 1)
	    pane_string = "";

	  /* If the pane has a meaningful name,
	     make the pane a top-level menu item
	     with its items as a submenu beneath it.  */
	  if (strcmp (pane_string, ""))
	    {
	      wv = xmalloc_widget_value ();
	      if (save_wv)
		save_wv->next = wv;
	      else
		first_wv->contents = wv;
	      wv->lname = pane_name;
              /* Set value to 1 so update_submenu_strings can handle '@'  */
	      wv->value = (char *)1;
	      wv->enabled = 1;
	      wv->button_type = BUTTON_TYPE_NONE;
	      wv->help = Qnil;
	      save_wv = wv;
	    }
	  else
	    save_wv = first_wv;

	  prev_wv = 0;
	  i += MENU_ITEMS_PANE_LENGTH;
	}
      else
	{
	  /* Create a new item within current pane.  */
	  Lisp_Object item_name, enable, descrip, def, type, selected;
	  Lisp_Object help;

	  /* All items should be contained in panes.  */
	  if (panes_seen == 0)
	    abort ();

	  item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
	  enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
	  descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
	  def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
	  type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE);
	  selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
	  help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);

#ifdef HAVE_NTGUI
	  if (STRINGP (item_name))
	    {
	      if (unicode_append_menu)
		item_name = ENCODE_UTF_8 (item_name);
	      else if (STRING_MULTIBYTE (item_name))
		item_name = ENCODE_SYSTEM (item_name);

	      ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
	    }

	  if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
	    {
	      descrip = ENCODE_SYSTEM (descrip);
	      ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
	    }
#elif USE_LUCID
	  if (STRINGP (item_name))
	    {
              item_name = ENCODE_UTF_8 (item_name);
	      ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
	    }

	  if (STRINGP (descrip))
	    {
	      descrip = ENCODE_UTF_8 (descrip);
	      ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
	    }
#elif !defined (HAVE_MULTILINGUAL_MENU)
          if (STRING_MULTIBYTE (item_name))
	    {
	      item_name = ENCODE_MENU_STRING (item_name);
	      ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
	    }

          if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
	    {
	      descrip = ENCODE_MENU_STRING (descrip);
	      ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
	    }
#endif

	  wv = xmalloc_widget_value ();
	  if (prev_wv)
	    prev_wv->next = wv;
	  else
	    save_wv->contents = wv;

	  wv->lname = item_name;
	  if (!NILP (descrip))
	    wv->lkey = descrip;
	  wv->value = 0;
	  /* The EMACS_INT cast avoids a warning.  There's no problem
	     as long as pointers have enough bits to hold small integers.  */
	  wv->call_data = (!NILP (def) ? (void *) (EMACS_INT) i : 0);
	  wv->enabled = !NILP (enable);

	  if (NILP (type))
	    wv->button_type = BUTTON_TYPE_NONE;
	  else if (EQ (type, QCradio))
	    wv->button_type = BUTTON_TYPE_RADIO;
	  else if (EQ (type, QCtoggle))
	    wv->button_type = BUTTON_TYPE_TOGGLE;
	  else
	    abort ();

	  wv->selected = !NILP (selected);
	  if (! STRINGP (help))
	    help = Qnil;

	  wv->help = help;

	  prev_wv = wv;

	  i += MENU_ITEMS_ITEM_LENGTH;
	}
    }

  /* If we have just one "menu item"
     that was originally a button, return it by itself.  */
  if (top_level_items && first_wv->contents && first_wv->contents->next == 0)
    {
      wv = first_wv->contents;
      free_widget_value (first_wv);
      return wv;
    }

  return first_wv;
}
Пример #10
0
static void
single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *skp_v)
{
  Lisp_Object map, item_string, enabled;
  struct gcpro gcpro1, gcpro2;
  int res;
  struct skp *skp = skp_v;

  /* Parse the menu item and leave the result in item_properties.  */
  GCPRO2 (key, item);
  res = parse_menu_item (item, 0);
  UNGCPRO;
  if (!res)
    return;			/* Not a menu item.  */

  map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];

  enabled = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE];
  item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];

  if (!NILP (map) && SREF (item_string, 0) == '@')
    {
      if (!NILP (enabled))
	/* An enabled separate pane. Remember this to handle it later.  */
	skp->pending_maps = Fcons (Fcons (map, Fcons (item_string, key)),
				   skp->pending_maps);
      return;
    }

#if defined(HAVE_X_WINDOWS) || defined(MSDOS)
#ifndef HAVE_BOXES
  /* Simulate radio buttons and toggle boxes by putting a prefix in
     front of them.  */
  {
    Lisp_Object prefix = Qnil;
    Lisp_Object type = XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE];
    if (!NILP (type))
      {
	Lisp_Object selected
	  = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED];

	if (skp->notbuttons)
	  /* The first button. Line up previous items in this menu.  */
	  {
	    int index = skp->notbuttons; /* Index for first item this menu.  */
	    int submenu = 0;
	    Lisp_Object tem;
	    while (index < menu_items_used)
	      {
		tem
		  = XVECTOR (menu_items)->contents[index + MENU_ITEMS_ITEM_NAME];
		if (NILP (tem))
		  {
		    index++;
		    submenu++;		/* Skip sub menu.  */
		  }
		else if (EQ (tem, Qlambda))
		  {
		    index++;
		    submenu--;		/* End sub menu.  */
		  }
		else if (EQ (tem, Qt))
		  index += 3;		/* Skip new pane marker. */
		else if (EQ (tem, Qquote))
		  index++;		/* Skip a left, right divider. */
		else
		  {
		    if (!submenu && SREF (tem, 0) != '\0'
			&& SREF (tem, 0) != '-')
		      XVECTOR (menu_items)->contents[index + MENU_ITEMS_ITEM_NAME]
			= concat2 (build_string ("    "), tem);
		    index += MENU_ITEMS_ITEM_LENGTH;
		  }
	      }
	    skp->notbuttons = 0;
	  }

	/* Calculate prefix, if any, for this item.  */
	if (EQ (type, QCtoggle))
	  prefix = build_string (NILP (selected) ? "[ ] " : "[X] ");
	else if (EQ (type, QCradio))
	  prefix = build_string (NILP (selected) ? "( ) " : "(*) ");
      }
    /* Not a button. If we have earlier buttons, then we need a prefix.  */
    else if (!skp->notbuttons && SREF (item_string, 0) != '\0'
	     && SREF (item_string, 0) != '-')
      prefix = build_string ("    ");

    if (!NILP (prefix))
      item_string = concat2 (prefix, item_string);
  }
#endif /* not HAVE_BOXES */

#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
  if (!NILP (map))
    /* Indicate visually that this is a submenu.  */
    item_string = concat2 (item_string, build_string (" >"));
#endif

#endif /* HAVE_X_WINDOWS || MSDOS */

  push_menu_item (item_string, enabled, key,
		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF],
		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ],
		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE],
		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
		  XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);

#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (HAVE_NTGUI)
  /* Display a submenu using the toolkit.  */
  if (! (NILP (map) || NILP (enabled)))
    {
      push_submenu_start ();
      single_keymap_panes (map, Qnil, key, skp->maxdepth - 1);
      push_submenu_end ();
    }
#endif
}
Пример #11
0
/* pattern is a list of strings:
	compiled_code, fastmap, syntax_fastmap, category_fastmap */
void
set_pattern (Lisp_Object pattern, struct re_pattern_buffer *bufp, char *translate)
{
  Lisp_Object temp;

  if (bufp->allocated != 0) {
/*
  Coming here means that this buffer was used to hold
  an old-style pattern.  Because new-style pattern is not
  self-destructive, we only have to set pointer.
  Instead, to avoid it being freed later,
  bufp->allocated should be set to 0.
*/
    free (bufp->buffer);
    bufp->allocated = 0;
  }
  temp = XVECTOR (pattern)->contents[0];
  bufp->buffer = (char *)XSTRING (temp)->data;
  bufp->used = XSTRING (temp)->size;
  bufp->translate = translate;
  /* 93.7.13 by K.Handa -- set fastmap */
  bufp->mc_flag = !NILP (current_buffer->mc_flag);
  {
    Lisp_Object fmap, syntax_fmap, category_fmap;
    char *fastmap = bufp->fastmap;
    int i;
    unsigned char ch;

    bufp->fastmap_accurate = 1;

    fmap = XVECTOR (pattern)->contents[1];
    if (NILP (fmap) && NILP (syntax_fmap) && NILP (category_fmap)) {
      bufp->can_be_null = 1;
    } else {
      bufp->can_be_null = 0;
      bzero (fastmap, 256);
      if (XTYPE (fmap) == Lisp_String) /* 93.7.19 by K.Handa */
	bcopy (XSTRING (fmap)->data, fastmap, XSTRING (fmap)->size);

      syntax_fmap = XVECTOR (pattern)->contents[2];
      if (XTYPE (syntax_fmap) == Lisp_String) {
	for (ch = 0; ch < 0x80; ch++)
	  if (!fastmap[ch]
	      && XSTRING (syntax_fmap)->data[syntax_code_spec[(char) SYNTAX (ch)]])
	    fastmap[ch] = 1;
	bufp->syntax_version = syntax_table_version;
      } else
	bufp->syntax_version = 0;

      category_fmap = XVECTOR (pattern)->contents[3];
      if (XTYPE (category_fmap) == Lisp_String) {
	char str[96], *p;
	int not_category_spec = 0;

	for (i = 32; i < 128; i++)
	  if (XSTRING (category_fmap)->data[i] == 2) {
	    not_category_spec = 1;
	    break;
	  }
	for (ch = 0; ch < 0x80; ch++) {
	  if (!fastmap[ch]) {
	    pack_mnemonic_string
	      (char_category (ch, current_buffer->category_table), str);
	    if (not_category_spec) {
	      for (p = str; *p; p++)
		if (XSTRING (category_fmap)->data[*p] != 2) {
		  fastmap[ch] = 1;
		  break;
		}
	    } else {
	      for (p = str; *p; p++)
		if (XSTRING (category_fmap)->data[*p] == 1) {
		  fastmap[ch] = 1;
		  break;
		}
	    }
	  }
	}
	bufp->category_version = category_table_version;
      } else
	bufp->category_version = 0;

      if (bufp->mc_flag
	  && (XTYPE (syntax_fmap) == Lisp_String
	      || XTYPE (category_fmap) == Lisp_String)) {
	for (ch = 0x80; ch < 0xA0; ch++)
	  fastmap[ch] = 1;
      }
    }
  }
/* 92.7.10 by T.Enami
   Force 're-compile-pattern' when compile_pattern is called next time. */
  last_regexp = Qnil;
}
Пример #12
0
double CompareFits(const char * i_lpszFileSource, const ES::Spectrum &i_cTarget, XDATASET & i_cOpacity_Map_A, XDATASET & i_cOpacity_Map_B, unsigned int i_uiIon, const double &i_dMin_WL, const double &i_dMax_WL, bool i_bChi2, double &o_dDay, double & o_dPS_Vel, double &o_dPS_Temp, double & o_dPS_Ion_Temp, double &o_dPS_Log_Tau, double & o_dHVF_Ion_Temp, double &o_dHVF_Log_Tau, ES::Spectrum &o_cOutput)
{
	// use the following define to set the numberr of dimensions to test - value should be # dim + 1 (e.g. 3-d = 4 points)
#define NUM_PARAMETERS 7
	unsigned int uiParameters = NUM_PARAMETERS;
	ES::Spectrum cOutput  = ES::Spectrum::create_from_range_and_size( i_cTarget.wl(0), i_cTarget.wl(i_cTarget.size() - 1), i_cTarget.size());

	double	dFit_Min = DBL_MAX;
	double	*lpdFit;
	// define tetrahedron spanning the search space
	XVECTOR *lpcTest_Points;
	XVECTOR cBounds[2] = {XVECTOR(NUM_PARAMETERS),XVECTOR(NUM_PARAMETERS)};
	XVECTOR cThreshold(NUM_PARAMETERS);
	XVECTOR cCentroid(NUM_PARAMETERS);
	XVECTOR cTestOuter(NUM_PARAMETERS);
	XVECTOR cTestInner(NUM_PARAMETERS);
	XVECTOR cTest(NUM_PARAMETERS);
	XVECTOR cDelta(NUM_PARAMETERS);
	XVECTOR cConvergence_Fault(NUM_PARAMETERS);
	double dTest_Fit = 0.0;
	unsigned int uiNum_Vertices;

	cBounds[0].Set(0,0.0); // time
	cBounds[0].Set(1,5.0); // PS velocity (kkm/s)
	cBounds[0].Set(2,5.0); // PS temp (kK)
	cBounds[0].Set(3,1.0); // PS ion temp (kK)
	cBounds[0].Set(4,-10.0); // PS ion log opacity scaling
	cBounds[0].Set(5,1.0); // HVF ion temp (kK)
	cBounds[0].Set(6,-10.0); // HVF ion log opacity scaling

	cBounds[1].Set(0,i_cOpacity_Map_A.GetNumColumns() - 2); // time
	cBounds[1].Set(1,40.0); // PS velocity (kkm/s)
	cBounds[1].Set(2,30.0); // PS temp (kK)
	cBounds[1].Set(3,30.0); // PS ion temp (kK)
	cBounds[1].Set(4,10.0); // PS ion log opacity scaling
	cBounds[1].Set(5,30.0); // HVF ion temp (kK)
	cBounds[1].Set(6,-8.0); // HVF ion log opacity scaling

	cThreshold.Set(0,1.0);
	cThreshold.Set(1,0.5);
	cThreshold.Set(2,0.25);
	cThreshold.Set(3,0.5);
	cThreshold.Set(4,0.1);
	cThreshold.Set(5,0.5);
	cThreshold.Set(6,0.1);
	cThreshold.Set(7,0.5);

	if (i_cOpacity_Map_B.GetNumElements() == 0)
		uiParameters = 6; // don't look for HVF component separately

	uiNum_Vertices = 1 << uiParameters;
	lpcTest_Points = new XVECTOR[uiNum_Vertices];
	lpdFit = new double[uiNum_Vertices];

	for (unsigned int uiI = 0; uiI < uiNum_Vertices; uiI++)
		lpcTest_Points[uiI].Set_Size(NUM_PARAMETERS);

	double	dFit_Sum = 0.0;
	if (!ReadPointsCache(i_lpszFileSource,lpcTest_Points,uiNum_Vertices,uiParameters,lpdFit))
	{
		// create a cuboid that spans the search space
		for (unsigned int uiI = 0; uiI < uiNum_Vertices; uiI++)
		{
			lpcTest_Points[uiI] = cBounds[0];
			for (unsigned int uiJ = 0; uiJ < uiParameters; uiJ++)
			{
				if (uiI & (1 << uiJ)) 
					lpcTest_Points[uiI].Set(uiJ,cBounds[1].Get(uiJ));
			}
		}
		for (unsigned int uiI = 0; uiI < uiNum_Vertices; uiI++)
		{
			cCentroid += lpcTest_Points[uiI];
			dFit_Sum ++;
		}
		cCentroid /= dFit_Sum;
//		printf("Centroid\n");
	//	cCentroid.Print();
	
		// Make sure the centroid produces a valid spectrum - if not, randomly generate a point within the search space to act as the centroid for the time being...
		// This centroid is going to be used to adjust edges of the cuboid to have a valid fit
		double dCentroid_Fit = 0.0;
		do
		{
			fprintf(stdout,".");
			fflush(stdout);
			if (isnan(dCentroid_Fit) || isinf(dCentroid_Fit)) // need a different point - try random point within the grid
			{
				cDelta = cBounds[1] - cBounds[0];
				for (unsigned int uiI = 0; uiI < NUM_PARAMETERS; uiI++)
				{
					cCentroid.Set(uiI,cBounds[0].Get(uiI) + xrand_d() * cDelta.Get(uiI));
				}
			}
			Generate_Synow_Spectra(i_cTarget,i_cOpacity_Map_A,i_cOpacity_Map_B,i_uiIon,cCentroid,cOutput);
			dCentroid_Fit = Fit(i_cTarget, cOutput, i_dMin_WL, i_dMax_WL, i_bChi2);
		}
		while (isnan(dCentroid_Fit) || isinf(dCentroid_Fit));
	
		for (unsigned int uiI = 0; uiI < uiNum_Vertices; uiI++)
		{
			fprintf(stdout,"-");
			fflush(stdout);
			Generate_Synow_Spectra(i_cTarget,i_cOpacity_Map_A,i_cOpacity_Map_B,i_uiIon,lpcTest_Points[uiI],cOutput);
			lpdFit[uiI] = Fit(i_cTarget, cOutput, i_dMin_WL, i_dMax_WL, i_bChi2);
			cTestOuter = lpcTest_Points[uiI];
			cTest = lpcTest_Points[uiI];
			while(isnan(lpdFit[uiI]) || isinf(lpdFit[uiI]))
			{
				fprintf(stdout,"_");
				fflush(stdout);
				XVECTOR cDelta = cTestOuter - cCentroid;
				cDelta *= 0.5;
				cTest = cCentroid + cDelta;
	//			cTest.Print();
				Generate_Synow_Spectra(i_cTarget,i_cOpacity_Map_A,i_cOpacity_Map_B,i_uiIon,cTest,cOutput);
				lpdFit[uiI] = Fit(i_cTarget, cOutput, i_dMin_WL, i_dMax_WL, i_bChi2);
				cTestOuter = cTest;
			}
			lpcTest_Points[uiI] = cTest;
		}

		SavePointsCache(i_lpszFileSource,lpcTest_Points,uiNum_Vertices,uiParameters,lpdFit);
	}
	unsigned int uiFit_Max_Point = uiNum_Vertices;
	unsigned int uiFit_Min_Point = uiNum_Vertices;
	
	while (!Convergence(lpcTest_Points, uiNum_Vertices , cThreshold, &cConvergence_Fault))
	{
		fprintf(stdout,"+");
		fflush(stdout);
//		fprintf(stdout,"F: %.1f %.1f %.1f %.1f %.1f %.1f %.1f\n",cConvergence_Fault.Get(0),cConvergence_Fault.Get(1),cConvergence_Fault.Get(2),cConvergence_Fault.Get(3),cConvergence_Fault.Get(4),cConvergence_Fault.Get(5),cConvergence_Fault.Get(6));

		// Find point with worst fit
		double	dFit_Max = 0.0;
		double	dFit_Near_Max = 0.0;
		double	dFit_Min = DBL_MAX;
		double	dFit_Variance = 0.0;
		double	dFit_Mean = 0.0;
		bool	bClose_Fit = true;
		uiFit_Max_Point = uiNum_Vertices;
		uiFit_Min_Point = uiNum_Vertices;
		for (unsigned int uiI = 0; uiI < uiNum_Vertices; uiI++)
		{
//			printf("%i : %.2e\n",uiI,lpdFit[uiI]);
			dFit_Variance += lpdFit[uiI] * lpdFit[uiI];
			dFit_Mean += lpdFit[uiI];
			if (lpdFit[uiI] > dFit_Max)
			{
				dFit_Max = lpdFit[uiI];
				uiFit_Max_Point = uiI;
			}
			if (lpdFit[uiI] < dFit_Min)
			{
				dFit_Min = lpdFit[uiI];
				uiFit_Min_Point = uiI;
			}
		}
		if (dFit_Min <= 0.5)
		{
			for (unsigned int uiI = 0; uiI < uiNum_Vertices; uiI++)
			{
				lpdFit[uiI] = lpdFit[uiFit_Min_Point];
				lpcTest_Points[uiI] = lpcTest_Points[uiFit_Min_Point];
			}
		}
		else
		{
			dFit_Variance /= uiNum_Vertices;
			dFit_Mean /= uiNum_Vertices;
			double dFit_Std_Dev = dFit_Variance - dFit_Mean * dFit_Mean;
//			for (unsigned int uiI = 0; uiI < uiNum_Vertices && bClose_Fit; uiI++)
//			{
//				bClose_Fit = (fabs(lpdFit[uiI] - dFit_Mean) < (2.0 * dFit_Std_Dev));
//			}
//			bClose_Fit |= (dFit_Std_Dev < 10.0);
			bClose_Fit &= (dFit_Std_Dev < 10.0);
			if (dFit_Near_Max == 0.0)
			{
				for (unsigned int uiI = 0; uiI < uiNum_Vertices; uiI++)
				{
					if (lpdFit[uiI] > dFit_Near_Max && uiI != uiFit_Max_Point)
						dFit_Near_Max = lpdFit[uiI];
				}
			}
	//		fprintf(stdout,"%i",uiFit_Max_Point);
	//		fprintf(stdout,"F: %.8e %.8e %.8e %.8e %.8e %.8e %.8e\n",dFit[0],dFit[1],dFit[2],dFit[3],dFit[4],dFit[5],dFit[6],dFit[7]);
	//		if (uiFit_Max_Point < uiNum_Vertices)
			{
				// Compute weighted centroid of remaining parameters
				for (unsigned int uiI = 0; uiI < cCentroid.Get_Size(); uiI++)
					cCentroid.Set(uiI,0.0);
				dFit_Sum = 0.0;
				for (unsigned int uiI = 0; uiI < uiNum_Vertices; uiI++)
				{
					if (uiI != uiFit_Max_Point)
					{
						XVECTOR cTemp = lpcTest_Points[uiI];
	//					lpcTest_Points[uiI].Print(NULL);
	//					cTemp.Print(NULL);
						if (lpdFit[uiI] > 1.0)
							cTemp *= lpdFit[uiI];
						cCentroid += cTemp;
	//					cCentroid.Print(NULL);
						if (lpdFit[uiI] > 1.0)
							dFit_Sum += lpdFit[uiI];
						else
							dFit_Sum += 1.0;
					}
				}
				cCentroid /= dFit_Sum;
	//			printf("Centroid\n");
	//			for (unsigned int uiI = 0; uiI < uiParameters; uiI++)
	//			{
	//				printf("%.1f\n",cCentroid.Get(uiI));
	//			}
				cTestOuter = lpcTest_Points[uiFit_Max_Point];
				cTestInner = cCentroid;
//				printf("\n");
//				cCentroid.Print();
				Generate_Synow_Spectra(i_cTarget,i_cOpacity_Map_A,i_cOpacity_Map_B,i_uiIon,cCentroid,cOutput);
				dTest_Fit = Fit(i_cTarget, cOutput, i_dMin_WL, i_dMax_WL, i_bChi2);
				if (bClose_Fit && !isnan(dTest_Fit) && !isinf(dTest_Fit))
				{
					for (unsigned int uiI = 0; uiI < uiNum_Vertices; uiI++)
					{
//						fprintf(stdout,"-%.0f\t%.2e\t%.0f\t%.0f\t%c\t%.1f\n",dTest_Fit,dFit_Min,dFit_Max,dFit_Near_Max,bClose_Fit ? 't' : 'f',dFit_Std_Dev);
						fprintf(stdout,"-");
						fflush(stdout);
						cDelta = cCentroid - lpcTest_Points[uiI];
						cDelta *= 0.5;
						lpcTest_Points[uiI] += cDelta;
						Generate_Synow_Spectra(i_cTarget,i_cOpacity_Map_A,i_cOpacity_Map_B,i_uiIon,lpcTest_Points[uiI],cOutput);
						lpdFit[uiI] = Fit(i_cTarget, cOutput, i_dMin_WL, i_dMax_WL, i_bChi2);
					}
				}
				else if (dTest_Fit > dFit_Near_Max)
				{
					cTestOuter = cCentroid;
					cTestInner = lpcTest_Points[uiFit_Min_Point];
					cTest = cTestInner;
					while (isnan(dTest_Fit) || isinf(dTest_Fit) || dTest_Fit > dFit_Near_Max)
					{
						//cCentroid.Print();
//						fprintf(stdout,"@%.0f\t%.2e\t%.0f\t%.0f\t%c\t%.1f\n",dTest_Fit,dFit_Min,dFit_Max,dFit_Near_Max,bClose_Fit ? 't' : 'f',dFit_Std_Dev);
						fprintf(stdout,"@");
						fflush(stdout);
						cDelta = cTestOuter - cTestInner;
						cDelta *= 0.5;
						cTest = cTestInner + cDelta;
//						cTest.Print();
						Generate_Synow_Spectra(i_cTarget,i_cOpacity_Map_A,i_cOpacity_Map_B,i_uiIon,cTest,cOutput);
						dTest_Fit = Fit(i_cTarget, cOutput, i_dMin_WL, i_dMax_WL, i_bChi2);
						cTestOuter = cTest;
/*						lpcTest_Points[uiFit_Max_Point] = cCentroid;
						lpdFit[uiFit_Max_Point] = dTest_Fit;
						for (unsigned int uiI = 0; uiI < cCentroid.Get_Size(); uiI++)
							cCentroid.Set(uiI,0.0);
						dFit_Sum = 0.0;
						for (unsigned int uiI = 0; uiI < uiNum_Vertices; uiI++)
						{
							XVECTOR cTemp = lpcTest_Points[uiI];
							if (lpdFit[uiI] > 1.0)
								cTemp *= lpdFit[uiI];
							cCentroid += cTemp;
							if (lpdFit[uiI] > 1.0)
								dFit_Sum += lpdFit[uiI];
							else
								dFit_Sum == 1.0;
						}
						cCentroid /= dFit_Sum;
						Generate_Synow_Spectra(i_cTarget,i_cOpacity_Map_A,i_cOpacity_Map_B,i_uiIon,cCentroid,cOutput);
						dTest_Fit = Fit(i_cTarget, cOutput, i_dMin_WL, i_dMax_WL, i_bChi2);
*/
					}
					lpcTest_Points[uiFit_Max_Point] = cTest;
					lpdFit[uiFit_Max_Point] = dTest_Fit;
				}
				else
				{
					cTest = lpcTest_Points[uiFit_Max_Point];
					double dTest_Fit = 0.0;
					while(isnan(dTest_Fit) || isinf(dTest_Fit) || (!bClose_Fit && dTest_Fit < dFit_Min))
					{
//						fprintf(stdout,"*%.0f\t%.2e\t%.0f\t%.0f\t%c\t%.1f\n",dTest_Fit,dFit_Min,dFit_Max,dFit_Near_Max,bClose_Fit ? 't' : 'f',dFit_Std_Dev);
						fprintf(stdout,"*");
						fflush(stdout);
						cDelta = cTestOuter - cTestInner;
						cDelta *= 0.5;
						cTest = cTestInner + cDelta;
//						cTest.Print();
						Generate_Synow_Spectra(i_cTarget,i_cOpacity_Map_A,i_cOpacity_Map_B,i_uiIon,cTest,cOutput);
						dTest_Fit = Fit(i_cTarget, cOutput, i_dMin_WL, i_dMax_WL, i_bChi2);
						cTestInner = cTest;
					}
					cTestOuter = cTest;
					cTestInner = cCentroid;
					while(isnan(dTest_Fit) || isinf(dTest_Fit) || dTest_Fit == 0.0 || dTest_Fit > dFit_Near_Max)
					{
//						fprintf(stdout,"%%%.0f\t%.2e\t%.0f\t%.0f\t%c\t%.1f\n",dTest_Fit,dFit_Min,dFit_Max,dFit_Near_Max,bClose_Fit ? 't' : 'f',dFit_Std_Dev);
						fprintf(stdout,"%%");
						fflush(stdout);
						cDelta = cTestOuter - cTestInner;
						cDelta *= 0.5;
						cTest = cTestInner + cDelta;
//						cTest.Print();
						Generate_Synow_Spectra(i_cTarget,i_cOpacity_Map_A,i_cOpacity_Map_B,i_uiIon,cTest,cOutput);
						dTest_Fit = Fit(i_cTarget, cOutput, i_dMin_WL, i_dMax_WL, i_bChi2);
						cTestOuter = cTest;
					}
					lpcTest_Points[uiFit_Max_Point] = cTest;
					lpdFit[uiFit_Max_Point] = dTest_Fit;
				}
			}
		}
		SavePointsCache(i_lpszFileSource,lpcTest_Points,uiNum_Vertices,uiParameters,lpdFit);
	}

//	printf("Convergence\n");
//	for (unsigned int uiI = 0; uiI < uiParameters; uiI++)
//	{
//		printf("%.1f\n",cConvergence_Fault.Get(uiI));
//	}
	for (unsigned int uiI = 0; uiI < cCentroid.Get_Size(); uiI++)
		cCentroid.Set(uiI,0.0);
	for (unsigned int uiI = 0; uiI < uiNum_Vertices; uiI++)
	{
		cCentroid += lpcTest_Points[uiI];
	}
	cCentroid /= (double)(uiNum_Vertices);

	int iT_ref = (int )(cCentroid.Get(0) + 0.5);
	if (iT_ref < 0)
		iT_ref = 0;
	if (iT_ref > (i_cOpacity_Map_A.GetNumColumns() - 2))
		iT_ref = i_cOpacity_Map_A.GetNumColumns() - 2;
	iT_ref++;

	o_dDay = i_cOpacity_Map_A.GetElement(iT_ref,0);
//	printf("%i %.2f\n",iT_ref,o_dDay);
	o_dPS_Vel = cCentroid.Get(1);
	o_dPS_Temp = cCentroid.Get(2);
	o_dPS_Ion_Temp = cCentroid.Get(3);
	o_dPS_Log_Tau = cCentroid.Get(4);
	o_dHVF_Ion_Temp = cCentroid.Get(5);
	o_dHVF_Log_Tau = cCentroid.Get(6);

	fprintf(stdout,"X");
	fflush(stdout);
	Generate_Synow_Spectra(i_cTarget,i_cOpacity_Map_A,i_cOpacity_Map_B,i_uiIon,cCentroid,cOutput);
	o_cOutput = cOutput; // not completely sure why this has to be done instead of passing o_cOutput as a parameter to Generate_Synow_Spectra, but if I do the latter it returns with flux set to zero...
//	system("rm spectrafit.cache");
	return Fit(i_cTarget, o_cOutput, i_dMin_WL, i_dMax_WL, i_bChi2);
}