Function: documentation

documentation is a function defined in doc.c.

Signature

(documentation FUNCTION &optional RAW)

Documentation

Return the documentation string of FUNCTION.

Unless a non-nil second argument RAW is given, the string is passed through substitute-command-keys.

Probably introduced at or before Emacs version 1.1.

Source Code

// Defined in /usr/src/emacs/src/doc.c
{
  Lisp_Object doc;
  bool try_reload = true;

 documentation:

  doc = Qnil;

  if (SYMBOLP (function))
    {
      Lisp_Object tem = Fget (function, Qfunction_documentation);
      if (!NILP (tem))
	return Fdocumentation_property (function, Qfunction_documentation,
					raw);
    }

  Lisp_Object fun = Findirect_function (function, Qnil);
  if (NILP (fun))
    xsignal1 (Qvoid_function, function);
  if (CONSP (fun) && EQ (XCAR (fun), Qmacro))
    fun = XCDR (fun);
#ifdef HAVE_NATIVE_COMP
  if (!NILP (Fsubr_native_elisp_p (fun)))
    doc = native_function_doc (fun);
  else
#endif
  if (SUBRP (fun))
    doc = make_fixnum (XSUBR (fun)->doc);
#ifdef HAVE_MODULES
  else if (MODULE_FUNCTIONP (fun))
    doc = module_function_documentation (XMODULE_FUNCTION (fun));
#endif
  else if (COMPILEDP (fun))
    {
      if (PVSIZE (fun) <= COMPILED_DOC_STRING)
	return Qnil;
      else
	{
	  Lisp_Object tem = AREF (fun, COMPILED_DOC_STRING);
	  if (STRINGP (tem))
	    doc = tem;
	  else if (FIXNATP (tem) || CONSP (tem))
	    doc = tem;
	  else
	    return Qnil;
	}
    }
  else if (STRINGP (fun) || VECTORP (fun))
    {
      return build_string ("Keyboard macro.");
    }
  else if (CONSP (fun))
    {
      Lisp_Object funcar = XCAR (fun);
      if (!SYMBOLP (funcar))
	xsignal1 (Qinvalid_function, fun);
      else if (EQ (funcar, Qkeymap))
	return build_string ("Prefix command (definition is a keymap associating keystrokes with commands).");
      else if (EQ (funcar, Qlambda)
	       || (EQ (funcar, Qclosure) && (fun = XCDR (fun), 1))
	       || EQ (funcar, Qautoload))
	{
	  Lisp_Object tem1 = Fcdr (Fcdr (fun));
	  Lisp_Object tem = Fcar (tem1);
	  if (STRINGP (tem))
	    doc = tem;
	  /* Handle a doc reference--but these never come last
	     in the function body, so reject them if they are last.  */
	  else if ((FIXNATP (tem) || (CONSP (tem) && FIXNUMP (XCDR (tem))))
		   && !NILP (XCDR (tem1)))
	    doc = tem;
	  else
	    return Qnil;
	}
      else
	goto oops;
    }
  else
    {
    oops:
      xsignal1 (Qinvalid_function, fun);
    }

  /* If DOC is 0, it's typically because of a dumped file missing
     from the DOC file (bug in src/Makefile.in).  */
  if (EQ (doc, make_fixnum (0)))
    doc = Qnil;
  if (FIXNUMP (doc) || CONSP (doc))
    {
      Lisp_Object tem;
      tem = get_doc_string (doc, 0, 0);
      if (NILP (tem) && try_reload)
	{
	  /* The file is newer, we need to reset the pointers.  */
	  try_reload = reread_doc_file (Fcar_safe (doc));
	  if (try_reload)
	    {
	      try_reload = false;
	      goto documentation;
	    }
	}
      else
	doc = tem;
    }

  if (NILP (raw))
    doc = call1 (Qsubstitute_command_keys, doc);
  return doc;
}