Function: match-data

match-data is a function defined in search.c.

Signature

(match-data &optional INTEGERS REUSE RESEAT)

Documentation

Return a list describing what the last search matched.

Element 2N is (match-beginning N); element 2N + 1 is (match-end N). All the elements are markers or nil (nil if the Nth pair didn't match) if the last match was on a buffer; integers or nil if a string was matched. Use set-match-data to reinstate the data in this list.

If INTEGERS (the optional first argument) is non-nil, always use integers (rather than markers) to represent buffer positions. In this case, and if the last match was in a buffer, the buffer will get stored as one additional element at the end of the list.

If REUSE is a list, reuse it as part of the value. If REUSE is long enough to hold all the values, and if INTEGERS is non-nil, no consing is done.

If optional third arg RESEAT is non-nil, any previous markers on the REUSE list will be modified to point to nowhere.

Return value is undefined if the last search failed.

Probably introduced at or before Emacs version 22.1.

Source Code

// Defined in /usr/src/emacs/src/search.c
{
  Lisp_Object tail, prev;
  Lisp_Object *data;
  ptrdiff_t i, len;

  if (!NILP (reseat))
    for (tail = reuse; CONSP (tail); tail = XCDR (tail))
      if (MARKERP (XCAR (tail)))
	{
	  unchain_marker (XMARKER (XCAR (tail)));
	  XSETCAR (tail, Qnil);
	}

  if (NILP (last_thing_searched))
    return Qnil;

  prev = Qnil;

  USE_SAFE_ALLOCA;
  SAFE_NALLOCA (data, 1, 2 * search_regs.num_regs + 1);

  len = 0;
  for (i = 0; i < search_regs.num_regs; i++)
    {
      ptrdiff_t start = search_regs.start[i];
      if (start >= 0)
	{
	  if (EQ (last_thing_searched, Qt)
	      || ! NILP (integers))
	    {
	      XSETFASTINT (data[2 * i], start);
	      XSETFASTINT (data[2 * i + 1], search_regs.end[i]);
	    }
	  else if (BUFFERP (last_thing_searched))
	    {
	      data[2 * i] = Fmake_marker ();
	      Fset_marker (data[2 * i],
			   make_fixnum (start),
			   last_thing_searched);
	      data[2 * i + 1] = Fmake_marker ();
	      Fset_marker (data[2 * i + 1],
			   make_fixnum (search_regs.end[i]),
			   last_thing_searched);
	    }
	  else
	    /* last_thing_searched must always be Qt, a buffer, or Qnil.  */
	    emacs_abort ();

	  len = 2 * i + 2;
	}
      else
	data[2 * i] = data[2 * i + 1] = Qnil;
    }

  if (BUFFERP (last_thing_searched) && !NILP (integers))
    {
      data[len] = last_thing_searched;
      len++;
    }

  /* If REUSE is not usable, cons up the values and return them.  */
  if (! CONSP (reuse))
    reuse = Flist (len, data);
  else
    {
      /* If REUSE is a list, store as many value elements as will fit
	 into the elements of REUSE.  */
      for (i = 0, tail = reuse; CONSP (tail);
	   i++, tail = XCDR (tail))
	{
	  if (i < len)
	    XSETCAR (tail, data[i]);
	  else
	    XSETCAR (tail, Qnil);
	  prev = tail;
	}

      /* If we couldn't fit all value elements into REUSE,
	 cons up the rest of them and add them to the end of REUSE.  */
      if (i < len)
	XSETCDR (prev, Flist (len - i, data + i));
    }

  SAFE_FREE ();
  return reuse;
}