Function: unintern

unintern is a function defined in lread.c.

Signature

(unintern NAME OBARRAY)

Documentation

Delete the symbol named NAME, if any, from OBARRAY.

The value is t if a symbol was found and deleted, nil otherwise. NAME may be a string or a symbol. If it is a symbol, that symbol is deleted, if it belongs to OBARRAY--no other symbol is deleted. OBARRAY, if nil, defaults to the value of the variable obarray.

Probably introduced at or before Emacs version 19.29.

Source Code

// Defined in /usr/src/emacs/src/lread.c
{
  register Lisp_Object tem;
  Lisp_Object string;
  size_t hash;

  if (NILP (obarray)) obarray = Vobarray;
  obarray = check_obarray (obarray);

  if (SYMBOLP (name))
    string = SYMBOL_NAME (name);
  else
    {
      CHECK_STRING (name);
      string = name;
    }

  char *longhand = NULL;
  ptrdiff_t longhand_chars = 0;
  ptrdiff_t longhand_bytes = 0;
  tem = oblookup_considering_shorthand (obarray, SSDATA (string),
					SCHARS (string), SBYTES (string),
					&longhand, &longhand_chars,
					&longhand_bytes);
  if (longhand)
    xfree(longhand);

  if (FIXNUMP (tem))
    return Qnil;
  /* If arg was a symbol, don't delete anything but that symbol itself.  */
  if (SYMBOLP (name) && !EQ (name, tem))
    return Qnil;

  /* There are plenty of other symbols which will screw up the Emacs
     session if we unintern them, as well as even more ways to use
     `setq' or `fset' or whatnot to make the Emacs session
     unusable.  Let's not go down this silly road.  --Stef  */
  /* if (NILP (tem) || EQ (tem, Qt))
       error ("Attempt to unintern t or nil"); */

  XSYMBOL (tem)->u.s.interned = SYMBOL_UNINTERNED;

  hash = oblookup_last_bucket_number;

  if (EQ (AREF (obarray, hash), tem))
    {
      if (XSYMBOL (tem)->u.s.next)
	{
	  Lisp_Object sym;
	  XSETSYMBOL (sym, XSYMBOL (tem)->u.s.next);
	  ASET (obarray, hash, sym);
	}
      else
	ASET (obarray, hash, make_fixnum (0));
    }
  else
    {
      Lisp_Object tail, following;

      for (tail = AREF (obarray, hash);
	   XSYMBOL (tail)->u.s.next;
	   tail = following)
	{
	  XSETSYMBOL (following, XSYMBOL (tail)->u.s.next);
	  if (EQ (following, tem))
	    {
	      set_symbol_next (tail, XSYMBOL (following)->u.s.next);
	      break;
	    }
	}
    }

  return Qt;
}