Function: require

require is a function defined in fns.c.

Signature

(require FEATURE &optional FILENAME NOERROR)

Documentation

If FEATURE is not already loaded, load it from FILENAME.

If FEATURE is not a member of the list features, then the feature was not yet loaded; so load it from file FILENAME.

If FILENAME is omitted, the printname of FEATURE is used as the file name, and load is called to try to load the file by that name, after appending the suffix .elc, .el, or the system-dependent suffix for dynamic module files, in that order; but the function will not try to load the file without any suffix. See get-load-suffixes for the complete list of suffixes.

To find the file, this function searches the directories in load-path.

If the optional third argument NOERROR is non-nil, then, if the file is not found, the function returns nil instead of signaling an error. Normally the return value is FEATURE.

The normal messages issued by load at start and end of loading FILENAME are suppressed.

View in manual

Probably introduced at or before Emacs version 15.

Aliases

mh-require (obsolete since 29.1)

Source Code

// Defined in /usr/src/emacs/src/fns.c
{
  Lisp_Object tem;
  bool from_file = load_in_progress;

  CHECK_SYMBOL (feature);

  /* Record the presence of `require' in this file
     even if the feature specified is already loaded.
     But not more than once in any file,
     and not when we aren't loading or reading from a file.  */
  if (!from_file)
    {
      Lisp_Object tail = Vcurrent_load_list;
      FOR_EACH_TAIL_SAFE (tail)
	if (NILP (XCDR (tail)) && STRINGP (XCAR (tail)))
	  from_file = true;
    }

  if (from_file)
    {
      tem = Fcons (Qrequire, feature);
      if (NILP (Fmember (tem, Vcurrent_load_list)))
	LOADHIST_ATTACH (tem);
    }
  tem = Fmemq (feature, Vfeatures);

  if (NILP (tem))
    {
      specpdl_ref count = SPECPDL_INDEX ();
      int nesting = 0;

      /* This is to make sure that loadup.el gives a clear picture
	 of what files are preloaded and when.  */
      if (will_dump_p () && !will_bootstrap_p ())
	{
	  /* Avoid landing here recursively while outputting the
	     backtrace from the error.  */
	  gflags.will_dump_ = false;
	  error ("(require %s) while preparing to dump",
		 SDATA (SYMBOL_NAME (feature)));
	}

      /* A certain amount of recursive `require' is legitimate,
	 but if we require the same feature recursively 3 times,
	 signal an error.  */
      tem = require_nesting_list;
      while (! NILP (tem))
	{
	  if (! NILP (Fequal (feature, XCAR (tem))))
	    nesting++;
	  tem = XCDR (tem);
	}
      if (nesting > 3)
	error ("Recursive `require' for feature `%s'",
	       SDATA (SYMBOL_NAME (feature)));

      /* Update the list for any nested `require's that occur.  */
      record_unwind_protect (require_unwind, require_nesting_list);
      require_nesting_list = Fcons (feature, require_nesting_list);

      /* Load the file.  */
      tem = load_with_autoload_queue
	(NILP (filename) ? Fsymbol_name (feature) : filename,
	 noerror, Qt, Qnil, (NILP (filename) ? Qt : Qnil));

      /* If load failed entirely, return nil.  */
      if (NILP (tem))
	return unbind_to (count, Qnil);

      tem = Fmemq (feature, Vfeatures);
      if (NILP (tem))
        {
          unsigned char *tem2 = SDATA (SYMBOL_NAME (feature));
          Lisp_Object tem3 = Fcar (Fcar (Vload_history));

          if (NILP (tem3))
            error ("Required feature `%s' was not provided", tem2);
          else
            /* Cf autoload-do-load.  */
            error ("Loading file %s failed to provide feature `%s'",
                   SDATA (tem3), tem2);
        }

      feature = unbind_to (count, feature);
    }

  return feature;
}