On Sun, Jul 18, 2010 at 7:53 AM, David Kastrup <d...@gnu.org> wrote:

<snip rant and anti-rant>

>    File: elisp,  Node: Writing Emacs Primitives,  Next: Object Internals,  
> Prev: Memory Usage,  Up: GNU Emacs Internals
>
>    E.5 Writing Emacs Primitives
>    ============================
>
>    Lisp primitives are Lisp functions implemented in C.  The details of
>    interfacing the C function so that Lisp can call it are handled by a few
>    C macros.  The only way to really understand how to write new C code is
>    to read the source, but we can explain some things here.
>
>       An example of a special form is the definition of `or', from
>    `eval.c'.  (An ordinary function would have the same general
>    appearance.)
>
>         DEFUN ("or", For, Sor, 0, UNEVALLED, 0,
>           doc: /* Eval args until one of them yields non-nil, then return that
>         value. The remaining args are not evalled at all.
>         If all args return nil, return nil.
>         usage: (or CONDITIONS ...)  */)
>           (Lisp_Object args)
>         {
>           register Lisp_Object val = Qnil;
>           struct gcpro gcpro1;
>
>           GCPRO1 (args);
>
>           while (CONSP (args))
>             {
>               val = Feval (XCAR (args));
>               if (!NILP (val))
>                 break;
>               args = XCDR (args);
>             }
>
>           UNGCPRO;
>           return val;
>         }
>
>       Let's start with a precise explanation of the arguments to the
>    `DEFUN' macro.  Here is a template for them:
>
>         DEFUN (LNAME, FNAME, SNAME, MIN, MAX, INTERACTIVE, DOC)
>
>    LNAME
>         This is the name of the Lisp symbol to define as the function
>         name; in the example above, it is `or'.
>
>    FNAME
>         This is the C function name for this function.  This is the name
>         that is used in C code for calling the function.  The name is, by
>         convention, `F' prepended to the Lisp name, with all dashes (`-')
>         in the Lisp name changed to underscores.  Thus, to call this
>         function from C code, call `For'.  Remember that the arguments must
>         be of type `Lisp_Object'; various macros and functions for creating
>         values of type `Lisp_Object' are declared in the file `lisp.h'.
>
>    SNAME
>         This is a C variable name to use for a structure that holds the
>         data for the subr object that represents the function in Lisp.
>         This structure conveys the Lisp symbol name to the initialization
>         routine that will create the symbol and store the subr object as
>         its definition.  By convention, this name is always FNAME with `F'
>         replaced with `S'.
>
>    MIN
>         This is the minimum number of arguments that the function
>         requires.  The function `or' allows a minimum of zero arguments.
>
>    MAX
>         This is the maximum number of arguments that the function accepts,
>         if there is a fixed maximum.  Alternatively, it can be `UNEVALLED',
>         indicating a special form that receives unevaluated arguments, or
>         `MANY', indicating an unlimited number of evaluated arguments (the
>         equivalent of `&rest').  Both `UNEVALLED' and `MANY' are macros.
>         If MAX is a number, it may not be less than MIN and it may not be
>         greater than eight.
>
>    INTERACTIVE
>         This is an interactive specification, a string such as might be
>         used as the argument of `interactive' in a Lisp function.  In the
>         case of `or', it is 0 (a null pointer), indicating that `or'
>         cannot be called interactively.  A value of `""' indicates a
>         function that should receive no arguments when called
>         interactively.  If the value begins with a `(', the string is
>         evaluated as a Lisp form.
>
>    DOC
>         This is the documentation string.  It uses C comment syntax rather
>         than C string syntax because comment syntax requires nothing
>         special to include multiple lines.  The `doc:' identifies the
>         comment that follows as the documentation string.  The `/*' and
>         `*/' delimiters that begin and end the comment are not part of the
>         documentation string.
>
>         If the last line of the documentation string begins with the
>         keyword `usage:', the rest of the line is treated as the argument
>         list for documentation purposes.  This way, you can use different
>         argument names in the documentation string from the ones used in
>         the C code.  `usage:' is required if the function has an unlimited
>         number of arguments.
>
>         All the usual rules for documentation strings in Lisp code (*note
>         Documentation Tips::) apply to C code documentation strings too.
>
>       After the call to the `DEFUN' macro, you must write the argument
>    list that every C function must have, including the types for the
>    arguments.  For a function with a fixed maximum number of arguments,
>    declare a C argument for each Lisp argument, and give them all type
>    `Lisp_Object'.  When a Lisp function has no upper limit on the number
>    of arguments, its implementation in C actually receives exactly two
>    arguments: the first is the number of Lisp arguments, and the second is
>    the address of a block containing their values.  They have types `int'
>    and `Lisp_Object *'.
>
>       Within the function `For' itself, note the use of the macros
>    `GCPRO1' and `UNGCPRO'.  `GCPRO1' is used to "protect" a variable from
>    garbage collection--to inform the garbage collector that it must look
>    in that variable and regard its contents as an accessible object.  GC
>    protection is necessary whenever you call `Feval' or anything that can
>    directly or indirectly call `Feval'.  At such a time, any Lisp object
>    that this function may refer to again must be protected somehow.
>
>       It suffices to ensure that at least one pointer to each object is
>    GC-protected; that way, the object cannot be recycled, so all pointers
>    to it remain valid.  Thus, a particular local variable can do without
>    protection if it is certain that the object it points to will be
>    preserved by some other pointer (such as another local variable which
>    has a `GCPRO')(1).  Otherwise, the local variable needs a `GCPRO'.
>
>       The macro `GCPRO1' protects just one local variable.  If you want to
>    protect two variables, use `GCPRO2' instead; repeating `GCPRO1' will
>    not work.  Macros `GCPRO3', `GCPRO4', `GCPRO5', and `GCPRO6' also
>    exist.  All these macros implicitly use local variables such as
>    `gcpro1'; you must declare these explicitly, with type `struct gcpro'.
>    Thus, if you use `GCPRO2', you must declare `gcpro1' and `gcpro2'.
>    Alas, we can't explain all the tricky details here.
>
>       `UNGCPRO' cancels the protection of the variables that are protected
>    in the current function.  It is necessary to do this explicitly.
>
>       Built-in functions that take a variable number of arguments actually
>    accept two arguments at the C level: the number of Lisp arguments, and
>    a `Lisp_Object *' pointer to a C vector containing those Lisp
>    arguments.  This C vector may be part of a Lisp vector, but it need not
>    be.  The responsibility for using `GCPRO' to protect the Lisp arguments
>    from GC if necessary rests with the caller in this case, since the
>    caller allocated or found the storage for them.
>
>       You must not use C initializers for static or global variables unless
>    the variables are never written once Emacs is dumped.  These variables
>    with initializers are allocated in an area of memory that becomes
>    read-only (on certain operating systems) as a result of dumping Emacs.
>    *Note Pure Storage::.
>
>       Do not use static variables within functions--place all static
>    variables at top level in the file.  This is necessary because Emacs on
>    some operating systems defines the keyword `static' as a null macro.
>    (This definition is used because those systems put all variables
>    declared static in a place that becomes read-only after dumping, whether
>    they have initializers or not.)
>
>       Defining the C function is not enough to make a Lisp primitive
>    available; you must also create the Lisp symbol for the primitive and
>    store a suitable subr object in its function cell.  The code looks like
>    this:
>
>         defsubr (&SUBR-STRUCTURE-NAME);
>
>    Here SUBR-STRUCTURE-NAME is the name you used as the third argument to
>    `DEFUN'.
>
>       If you add a new primitive to a file that already has Lisp primitives
>    defined in it, find the function (near the end of the file) named
>    `syms_of_SOMETHING', and add the call to `defsubr' there.  If the file
>    doesn't have this function, or if you create a new file, add to it a
>    `syms_of_FILENAME' (e.g., `syms_of_myfile').  Then find the spot in
>    `emacs.c' where all of these functions are called, and add a call to
>    `syms_of_FILENAME' there.
>
>       The function `syms_of_FILENAME' is also the place to define any C
>    variables that are to be visible as Lisp variables.  `DEFVAR_LISP'
>    makes a C variable of type `Lisp_Object' visible in Lisp.  `DEFVAR_INT'
>    makes a C variable of type `int' visible in Lisp with a value that is
>    always an integer.  `DEFVAR_BOOL' makes a C variable of type `int'
>    visible in Lisp with a value that is either `t' or `nil'.  Note that
>    variables defined with `DEFVAR_BOOL' are automatically added to the list
>    `byte-boolean-vars' used by the byte compiler.
>
>       If you define a file-scope C variable of type `Lisp_Object', you
>    must protect it from garbage-collection by calling `staticpro' in
>    `syms_of_FILENAME', like this:
>
>         staticpro (&VARIABLE);
>
>       Here is another example function, with more complicated arguments.
>    This comes from the code in `window.c', and it demonstrates the use of
>    macros and functions to manipulate Lisp objects.
>
>         DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p,
>           Scoordinates_in_window_p, 2, 2,
>           "xSpecify coordinate pair: \nXExpression which evals to window: ",
>           "Return non-nil if COORDINATES is in WINDOW.\n\
>         COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
>         ...
>         If they are on the border between WINDOW and its right sibling,\n\
>            `vertical-line' is returned.")
>           (coordinates, window)
>              register Lisp_Object coordinates, window;
>         {
>           int x, y;
>
>           CHECK_LIVE_WINDOW (window, 0);
>           CHECK_CONS (coordinates, 1);
>           x = XINT (Fcar (coordinates));
>           y = XINT (Fcdr (coordinates));
>
>           switch (coordinates_in_window (XWINDOW (window), &x, &y))
>             {
>             case 0:                     /* NOT in window at all. */
>               return Qnil;
>
>             case 1:                     /* In text part of window. */
>               return Fcons (make_number (x), make_number (y));
>
>             case 2:                     /* In mode line of window. */
>               return Qmode_line;
>
>             case 3:                     /* On right border of window.  */
>               return Qvertical_line;
>
>             default:
>               abort ();
>             }
>         }
>
>       Note that C code cannot call functions by name unless they are
>    defined in C.  The way to call a function written in Lisp is to use
>    `Ffuncall', which embodies the Lisp function `funcall'.  Since the Lisp
>    function `funcall' accepts an unlimited number of arguments, in C it
>    takes two: the number of Lisp-level arguments, and a one-dimensional
>    array containing their values.  The first Lisp-level argument is the
>    Lisp function to call, and the rest are the arguments to pass to it.
>    Since `Ffuncall' can call the evaluator, you must protect pointers from
>    garbage collection around the call to `Ffuncall'.
>
>       The C functions `call0', `call1', `call2', and so on, provide handy
>    ways to call a Lisp function conveniently with a fixed number of
>    arguments.  They work by calling `Ffuncall'.
>
>       `eval.c' is a very good file to look through for examples; `lisp.h'
>    contains the definitions for some important macros and functions.
>
>       If you define a function which is side-effect free, update the code
>    in `byte-opt.el' which binds `side-effect-free-fns' and
>    `side-effect-and-error-free-fns' so that the compiler optimizer knows
>    about it.
>
>       ---------- Footnotes ----------
>
>       (1) Formerly, strings were a special exception; in older Emacs
>    versions, every local variable that might point to a string needed a
>    `GCPRO'.
>

<moar snip>

To me, this is amazing documentation. I would love it if there were
something this explicit for the C API.

Geremy Condra
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to