(declaim (inline foo bar))
(eval-when (compile load eval) (proclaim '(inline foo bar)))
- (proclaim-inline foo bar) ; XEmacs only
- (defsubst foo (...) ...) ; instead of defun; Emacs 19 only
+ (proclaim-inline foo bar) ; XEmacs only
+ (defsubst foo (...) ...) ; instead of defun; Emacs 19 only
*Please note:* This declaration remains in effect after the
containing source file is done. It is correct to use it to
function. In Emacs Lisp, it works just as well to use a regular
quote:
- (loop for x in y by #'cddr collect (mapcar #'plusp x)) ; Common Lisp
- (loop for x in y by 'cddr collect (mapcar 'plusp x)) ; Emacs Lisp
+ (loop for x in y by #'cddr collect (mapcar #'plusp x)) ; Common Lisp
+ (loop for x in y by 'cddr collect (mapcar 'plusp x)) ; Emacs Lisp
When `#'' introduces a `lambda' form, it is best to write out
`(function ...)' longhand in Emacs Lisp. You can use a regular
Foundation instead of in the original English.
\1f
-File: internals.info, Node: Working With Character and Byte Positions, Next: Conversion to and from External Data, Prev: Character-Related Data Types, Up: Coding for Mule
-
-Working With Character and Byte Positions
------------------------------------------
-
- Now that we have defined the basic character-related types, we can
-look at the macros and functions designed for work with them and for
-conversion between them. Most of these macros are defined in
-`buffer.h', and we don't discuss all of them here, but only the most
-important ones. Examining the existing code is the best way to learn
-about them.
-
-`MAX_EMCHAR_LEN'
- This preprocessor constant is the maximum number of buffer bytes
- per Emacs character, i.e. the byte length of an `Emchar'. It is
- useful when allocating temporary strings to keep a known number of
- characters. For instance:
-
- {
- Charcount cclen;
- ...
- {
- /* Allocate place for CCLEN characters. */
- Bufbyte *buf = (Bufbyte *)alloca (cclen * MAX_EMCHAR_LEN);
- ...
-
- If you followed the previous section, you can guess that,
- logically, multiplying a `Charcount' value with `MAX_EMCHAR_LEN'
- produces a `Bytecount' value.
-
- In the current Mule implementation, `MAX_EMCHAR_LEN' equals 4.
- Without Mule, it is 1.
-
-`charptr_emchar'
-`set_charptr_emchar'
- The `charptr_emchar' macro takes a `Bufbyte' pointer and returns
- the `Emchar' stored at that position. If it were a function, its
- prototype would be:
-
- Emchar charptr_emchar (Bufbyte *p);
-
- `set_charptr_emchar' stores an `Emchar' to the specified byte
- position. It returns the number of bytes stored:
-
- Bytecount set_charptr_emchar (Bufbyte *p, Emchar c);
-
- It is important to note that `set_charptr_emchar' is safe only for
- appending a character at the end of a buffer, not for overwriting a
- character in the middle. This is because the width of characters
- varies, and `set_charptr_emchar' cannot resize the string if it
- writes, say, a two-byte character where a single-byte character
- used to reside.
-
- A typical use of `set_charptr_emchar' can be demonstrated by this
- example, which copies characters from buffer BUF to a temporary
- string of Bufbytes.
-
- {
- Bufpos pos;
- for (pos = beg; pos < end; pos++)
- {
- Emchar c = BUF_FETCH_CHAR (buf, pos);
- p += set_charptr_emchar (buf, c);
- }
- }
-
- Note how `set_charptr_emchar' is used to store the `Emchar' and
- increment the counter, at the same time.
-
-`INC_CHARPTR'
-`DEC_CHARPTR'
- These two macros increment and decrement a `Bufbyte' pointer,
- respectively. They will adjust the pointer by the appropriate
- number of bytes according to the byte length of the character
- stored there. Both macros assume that the memory address is
- located at the beginning of a valid character.
-
- Without Mule support, `INC_CHARPTR (p)' and `DEC_CHARPTR (p)'
- simply expand to `p++' and `p--', respectively.
-
-`bytecount_to_charcount'
- Given a pointer to a text string and a length in bytes, return the
- equivalent length in characters.
-
- Charcount bytecount_to_charcount (Bufbyte *p, Bytecount bc);
-
-`charcount_to_bytecount'
- Given a pointer to a text string and a length in characters,
- return the equivalent length in bytes.
-
- Bytecount charcount_to_bytecount (Bufbyte *p, Charcount cc);
-
-`charptr_n_addr'
- Return a pointer to the beginning of the character offset CC (in
- characters) from P.
-
- Bufbyte *charptr_n_addr (Bufbyte *p, Charcount cc);
-
-\1f
File: internals.info, Node: Conversion to and from External Data, Next: General Guidelines for Writing Mule-Aware Code, Prev: Working With Character and Byte Positions, Up: Coding for Mule
Conversion to and from External Data
The interface to conversion between the internal and external
representations of text are the numerous conversion macros defined in
-`buffer.h'. Before looking at them, we'll look at the external formats
-supported by these macros.
-
- Currently meaningful formats are `FORMAT_BINARY', `FORMAT_FILENAME',
-`FORMAT_OS', and `FORMAT_CTEXT'. Here is a description of these.
-
-`FORMAT_BINARY'
- Binary format. This is the simplest format and is what we use in
- the absence of a more appropriate format. This converts according
- to the `binary' coding system:
-
- a. On input, bytes 0-255 are converted into characters 0-255.
+`buffer.h'. There used to be a fixed set of external formats supported
+by these macros, but now any coding system can be used with these
+macros. The coding system alias mechanism is used to create the
+following logical coding systems, which replace the fixed external
+formats. The (dontusethis-set-symbol-value-handler) mechanism was
+enhanced to make this possible (more work on that is needed - like
+remove the `dontusethis-' prefix).
+
+`Qbinary'
+ This is the simplest format and is what we use in the absence of a
+ more appropriate format. This converts according to the `binary'
+ coding system:
+
+ a. On input, bytes 0-255 are converted into (implicitly Latin-1)
+ characters 0-255. A non-Mule xemacs doesn't really know about
+ different character sets and the fonts to display them, so
+ the bytes can be treated as text in different 1-byte
+ encodings by simply setting the appropriate fonts. So in a
+ sense, non-Mule xemacs is a multi-lingual editor if, for
+ example, different fonts are used to display text in
+ different buffers, faces, or windows. The specifier
+ mechanism gives the user complete control over this kind of
+ behavior.
b. On output, characters 0-255 are converted into bytes 0-255
- and other characters are converted into `X'.
+ and other characters are converted into `~'.
-`FORMAT_FILENAME'
- Format used for filenames. In the original Mule, this is
- user-definable with the `pathname-coding-system' variable. For
- the moment, we just use the `binary' coding system.
+`Qfile_name'
+ Format used for filenames. This is user-definable via either the
+ `file-name-coding-system' or `pathname-coding-system' (now
+ obsolete) variables.
-`FORMAT_OS'
+`Qnative'
Format used for the external Unix environment--`argv[]', stuff
from `getenv()', stuff from the `/etc/passwd' file, etc.
+ Currently this is the same as Qfile_name. The two should be
+ distinguished for clarity and possible future separation.
+
+`Qctext'
+ Compound-text format. This is the standard X11 format used for
+ data stored in properties, selections, and the like. This is an
+ 8-bit no-lock-shift ISO2022 coding system. This is a real coding
+ system, unlike Qfile_name, which is user-definable.
+
+ There are two fundamental macros to convert between external and
+internal format.
+
+ `TO_INTERNAL_FORMAT' converts external data to internal format, and
+`TO_EXTERNAL_FORMAT' converts the other way around. The arguments each
+of these receives are a source type, a source, a sink type, a sink, and
+a coding system (or a symbol naming a coding system).
+
+ A typical call looks like
+ TO_EXTERNAL_FORMAT (LISP_STRING, str, C_STRING_MALLOC, ptr, Qfile_name);
+
+ which means that the contents of the lisp string `str' are written
+to a malloc'ed memory area which will be pointed to by `ptr', after the
+function returns. The conversion will be done using the `file-name'
+coding system, which will be controlled by the user indirectly by
+setting or binding the variable `file-name-coding-system'.
+
+ Some sources and sinks require two C variables to specify. We use
+some preprocessor magic to allow different source and sink types, and
+even different numbers of arguments to specify different types of
+sources and sinks.
+
+ So we can have a call that looks like
+ TO_INTERNAL_FORMAT (DATA, (ptr, len),
+ MALLOC, (ptr, len),
+ coding_system);
+
+ The parenthesized argument pairs are required to make the
+preprocessor magic work.
+
+ Here are the different source and sink types:
+
+``DATA, (ptr, len),''
+ input data is a fixed buffer of size LEN at address PTR
+
+``ALLOCA, (ptr, len),''
+ output data is placed in an alloca()ed buffer of size LEN pointed
+ to by PTR
+
+``MALLOC, (ptr, len),''
+ output data is in a malloc()ed buffer of size LEN pointed to by PTR
+
+``C_STRING_ALLOCA, ptr,''
+ equivalent to `ALLOCA (ptr, len_ignored)' on output.
+
+``C_STRING_MALLOC, ptr,''
+ equivalent to `MALLOC (ptr, len_ignored)' on output
+
+``C_STRING, ptr,''
+ equivalent to `DATA, (ptr, strlen (ptr) + 1)' on input
- Perhaps should be the same as FORMAT_FILENAME.
-
-`FORMAT_CTEXT'
- Compound-text format. This is the standard X format used for data
- stored in properties, selections, and the like. This is an 8-bit
- no-lock-shift ISO2022 coding system.
-
- The macros to convert between these formats and the internal format,
-and vice versa, follow.
-
-`GET_CHARPTR_INT_DATA_ALLOCA'
-`GET_CHARPTR_EXT_DATA_ALLOCA'
- These two are the most basic conversion macros.
- `GET_CHARPTR_INT_DATA_ALLOCA' converts external data to internal
- format, and `GET_CHARPTR_EXT_DATA_ALLOCA' converts the other way
- around. The arguments each of these receives are PTR (pointer to
- the text in external format), LEN (length of texts in bytes), FMT
- (format of the external text), PTR_OUT (lvalue to which new text
- should be copied), and LEN_OUT (lvalue which will be assigned the
- length of the internal text in bytes). The resulting text is
- stored to a stack-allocated buffer. If the text doesn't need
- changing, these macros will do nothing, except for setting LEN_OUT.
-
- The macros above take many arguments which makes them unwieldy.
- For this reason, a number of convenience macros are defined with
- obvious functionality, but accepting less arguments. The general
- rule is that macros with `INT' in their name convert text to
- internal Emacs representation, whereas the `EXT' macros convert to
- external representation.
-
-`GET_C_CHARPTR_INT_DATA_ALLOCA'
-`GET_C_CHARPTR_EXT_DATA_ALLOCA'
- As their names imply, these macros work on C char pointers, which
- are zero-terminated, and thus do not need LEN or LEN_OUT
- parameters.
-
-`GET_STRING_EXT_DATA_ALLOCA'
-`GET_C_STRING_EXT_DATA_ALLOCA'
- These two macros convert a Lisp string into an external
- representation. The difference between them is that
- `GET_STRING_EXT_DATA_ALLOCA' stores its output to a generic
- string, providing LEN_OUT, the length of the resulting external
- string. On the other hand, `GET_C_STRING_EXT_DATA_ALLOCA' assumes
- that the caller will be satisfied with output string being
- zero-terminated.
-
- Note that for Lisp strings only one conversion direction makes
- sense.
-
-`GET_C_CHARPTR_EXT_BINARY_DATA_ALLOCA'
-`GET_CHARPTR_EXT_BINARY_DATA_ALLOCA'
-`GET_STRING_BINARY_DATA_ALLOCA'
-`GET_C_STRING_BINARY_DATA_ALLOCA'
-`GET_C_CHARPTR_EXT_FILENAME_DATA_ALLOCA'
-`...'
- These macros convert internal text to a specific external
- representation, with the external format being encoded into the
- name of the macro. Note that the `GET_STRING_...' and
- `GET_C_STRING...' macros lack the `EXT' tag, because they only
- make sense in that direction.
-
-`GET_C_CHARPTR_INT_BINARY_DATA_ALLOCA'
-`GET_CHARPTR_INT_BINARY_DATA_ALLOCA'
-`GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA'
-`...'
- These macros convert external text of a specific format to its
- internal representation, with the external format being incoded
- into the name of the macro.
+``LISP_STRING, string,''
+ input or output is a Lisp_Object of type string
+
+``LISP_BUFFER, buffer,''
+ output is written to `(point)' in lisp buffer BUFFER
+
+``LISP_LSTREAM, lstream,''
+ input or output is a Lisp_Object of type lstream
+
+``LISP_OPAQUE, object,''
+ input or output is a Lisp_Object of type opaque
+
+ Often, the data is being converted to a '\0'-byte-terminated string,
+which is the format required by many external system C APIs. For these
+purposes, a source type of `C_STRING' or a sink type of
+`C_STRING_ALLOCA' or `C_STRING_MALLOC' is appropriate. Otherwise, we
+should try to keep XEmacs '\0'-byte-clean, which means using (ptr, len)
+pairs.
+
+ The sinks to be specified must be lvalues, unless they are the lisp
+object types `LISP_LSTREAM' or `LISP_BUFFER'.
+
+ For the sink types `ALLOCA' and `C_STRING_ALLOCA', the resulting
+text is stored in a stack-allocated buffer, which is automatically
+freed on returning from the function. However, the sink types `MALLOC'
+and `C_STRING_MALLOC' return `xmalloc()'ed memory. The caller is
+responsible for freeing this memory using `xfree()'.
+
+ Note that it doesn't make sense for `LISP_STRING' to be a source for
+`TO_INTERNAL_FORMAT' or a sink for `TO_EXTERNAL_FORMAT'. You'll get an
+assertion failure if you try.
\1f
File: internals.info, Node: General Guidelines for Writing Mule-Aware Code, Next: An Example of Mule-Aware Code, Prev: Conversion to and from External Data, Up: Coding for Mule
internal buffers literally.
This means that when a system function, such as `readdir', returns
- a string, you need to convert it using one of the conversion macros
- described in the previous chapter, before passing it further to
- Lisp. In the case of `readdir', you would use the
- `GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA' macro.
+ a string, you may need to convert it using one of the conversion
+ macros described in the previous chapter, before passing it
+ further to Lisp.
+
+ Actually, most of the basic system functions that accept
+ '\0'-terminated string arguments, like `stat()' and `open()', have
+ been *encapsulated* so that they are they `always' do internal to
+ external conversion themselves. This means you must pass
+ internally encoded data, typically the `XSTRING_DATA' of a
+ Lisp_String to these functions. This is actually a design bug,
+ since it unexpectedly changes the semantics of the system
+ functions. A better design would be to provide separate versions
+ of these system functions that accepted Lisp_Objects which were
+ lisp strings in place of their current `char *' arguments.
+
+ int stat_lisp (Lisp_Object path, struct stat *buf); /* Implement me */
Also note that many internal functions, such as `make_string',
accept Bufbytes, which removes the need for them to convert the
An Example of Mule-Aware Code
-----------------------------
- As an example of Mule-aware code, we shall will analyze the `string'
+ As an example of Mule-aware code, we will analyze the `string'
function, which conses up a Lisp string from the character arguments it
receives. Here is the definition, pasted from `alloc.c':
<...>' syntax, not the `#include "..."' syntax. The generated
headers are:
- `config.h puresize-adjust.h sheap-adjust.h paths.h Emacs.ad.h'
+ `config.h sheap-adjust.h paths.h Emacs.ad.h'
The basic rule is that you should assume builds using `--srcdir'
and the `#include <...>' syntax needs to be used when the
* Did I mention that you should run the test suite?
make check
+ Here is a checklist of things to do when creating a new lisp object
+type named FOO:
+
+ 1. create FOO.h
+
+ 2. create FOO.c
+
+ 3. add definitions of syms_of_FOO, etc. to FOO.c
+
+ 4. add declarations of syms_of_FOO, etc. to symsinit.h
+
+ 5. add calls to syms_of_FOO, etc. to emacs.c(main_1)
+
+ 6. add definitions of macros like CHECK_FOO and FOOP to FOO.h
+
+ 7. add the new type index to enum lrecord_type
+
+ 8. add DEFINE_LRECORD_IMPLEMENTATION call to FOO.c
+
\1f
File: internals.info, Node: A Summary of the Various XEmacs Modules, Next: Allocation of Objects in XEmacs Lisp, Prev: Rules When Writing New C Code, Up: Top
All initialization functions are prototyped in `symsinit.h'.
alloc.c
- pure.c
- puresize.h
The large module `alloc.c' implements all of the basic allocation and
garbage collection for Lisp objects. The most commonly used Lisp
subtypes in the subsystem; this provides a great deal of robustness to
the XEmacs code.
- `pure.c' contains the declaration of the "purespace" array. Pure
-space is a hack used to place some constant Lisp data into the code
-segment of the XEmacs executable, even though the data needs to be
-initialized through function calls. (See above in section VIII for more
-info about this.) During startup, certain sorts of data is
-automatically copied into pure space, and other data is copied manually
-in some of the basic Lisp files by calling the function `purecopy',
-which copies the object if possible (this only works in temacs, of
-course) and returns the new object. In particular, while temacs is
-executing, the Lisp reader automatically copies all compiled-function
-objects that it reads into pure space. Since compiled-function objects
-are large, are never modified, and typically comprise the majority of
-the contents of a compiled-Lisp file, this works well. While XEmacs is
-running, any attempt to modify an object that resides in pure space
-causes an error. Objects in pure space are never garbage collected -
-almost all of the time, they're intended to be permanent, and in any
-case you can't write into pure space to set the mark bits.
-
- `puresize.h' contains the declaration of the size of the pure space
-array. This depends on the optional features that are compiled in, any
-extra purespace requested by the user at compile time, and certain other
-factors (e.g. 64-bit machines need more pure space because their Lisp
-objects are larger). The smallest size that suffices should be used, so
-that there's no wasted space. If there's not enough pure space, you
-will get an error during the build process, specifying how much more
-pure space is needed.
-
eval.c
backtrace.h
These files provide some miscellaneous TTY-output functions and
should probably be merged into `redisplay-tty.c'.
+\1f
+File: internals.info, Node: Modules for Interfacing with the File System, Next: Modules for Other Aspects of the Lisp Interpreter and Object System, Prev: Modules for the Redisplay Mechanism, Up: A Summary of the Various XEmacs Modules
+
+Modules for Interfacing with the File System
+============================================
+
+ lstream.c
+ lstream.h
+
+ These modules implement the "stream" Lisp object type. This is an
+internal-only Lisp object that implements a generic buffering stream.
+The idea is to provide a uniform interface onto all sources and sinks of
+data, including file descriptors, stdio streams, chunks of memory, Lisp
+buffers, Lisp strings, etc. That way, I/O functions can be written to
+the stream interface and can transparently handle all possible sources
+and sinks. (For example, the `read' function can read data from a
+file, a string, a buffer, or even a function that is called repeatedly
+to return data, without worrying about where the data is coming from or
+what-size chunks it is returned in.)
+
+ Note that in the C code, streams are called "lstreams" (for "Lisp
+streams") to distinguish them from other kinds of streams, e.g. stdio
+streams and C++ I/O streams.
+
+ Similar to other subsystems in XEmacs, lstreams are separated into
+generic functions and a set of methods for the different types of
+lstreams. `lstream.c' provides implementations of many different types
+of streams; others are provided, e.g., in `mule-coding.c'.
+
+ fileio.c
+
+ This implements the basic primitives for interfacing with the file
+system. This includes primitives for reading files into buffers,
+writing buffers into files, checking for the presence or accessibility
+of files, canonicalizing file names, etc. Note that these primitives
+are usually not invoked directly by the user: There is a great deal of
+higher-level Lisp code that implements the user commands such as
+`find-file' and `save-buffer'. This is similar to the distinction
+between the lower-level primitives in `editfns.c' and the higher-level
+user commands in `commands.c' and `simple.el'.
+
+ filelock.c
+
+ This file provides functions for detecting clashes between different
+processes (e.g. XEmacs and some external process, or two different
+XEmacs processes) modifying the same file. (XEmacs can optionally use
+the `lock/' subdirectory to provide a form of "locking" between
+different XEmacs processes.) This module is also used by the low-level
+functions in `insdel.c' to ensure that, if the first modification is
+being made to a buffer whose corresponding file has been externally
+modified, the user is made aware of this so that the buffer can be
+synched up with the external changes if necessary.
+
+ filemode.c
+
+ This file provides some miscellaneous functions that construct a
+`rwxr-xr-x'-type permissions string (as might appear in an `ls'-style
+directory listing) given the information returned by the `stat()'
+system call.
+
+ dired.c
+ ndir.h
+
+ These files implement the XEmacs interface to directory searching.
+This includes a number of primitives for determining the files in a
+directory and for doing filename completion. (Remember that generic
+completion is handled by a different mechanism, in `minibuf.c'.)
+
+ `ndir.h' is a header file used for the directory-searching emulation
+functions provided in `sysdep.c' (see section J below), for systems
+that don't provide any directory-searching functions. (On those
+systems, directories can be read directly as files, and parsed.)
+
+ realpath.c
+
+ This file provides an implementation of the `realpath()' function
+for expanding symbolic links, on systems that don't implement it or have
+a broken implementation.
+
Foundation instead of in the original English.
\1f
-File: internals.info, Node: Modules for Interfacing with the File System, Next: Modules for Other Aspects of the Lisp Interpreter and Object System, Prev: Modules for the Redisplay Mechanism, Up: A Summary of the Various XEmacs Modules
-
-Modules for Interfacing with the File System
-============================================
-
- lstream.c
- lstream.h
-
- These modules implement the "stream" Lisp object type. This is an
-internal-only Lisp object that implements a generic buffering stream.
-The idea is to provide a uniform interface onto all sources and sinks of
-data, including file descriptors, stdio streams, chunks of memory, Lisp
-buffers, Lisp strings, etc. That way, I/O functions can be written to
-the stream interface and can transparently handle all possible sources
-and sinks. (For example, the `read' function can read data from a
-file, a string, a buffer, or even a function that is called repeatedly
-to return data, without worrying about where the data is coming from or
-what-size chunks it is returned in.)
-
- Note that in the C code, streams are called "lstreams" (for "Lisp
-streams") to distinguish them from other kinds of streams, e.g. stdio
-streams and C++ I/O streams.
-
- Similar to other subsystems in XEmacs, lstreams are separated into
-generic functions and a set of methods for the different types of
-lstreams. `lstream.c' provides implementations of many different types
-of streams; others are provided, e.g., in `mule-coding.c'.
-
- fileio.c
-
- This implements the basic primitives for interfacing with the file
-system. This includes primitives for reading files into buffers,
-writing buffers into files, checking for the presence or accessibility
-of files, canonicalizing file names, etc. Note that these primitives
-are usually not invoked directly by the user: There is a great deal of
-higher-level Lisp code that implements the user commands such as
-`find-file' and `save-buffer'. This is similar to the distinction
-between the lower-level primitives in `editfns.c' and the higher-level
-user commands in `commands.c' and `simple.el'.
-
- filelock.c
-
- This file provides functions for detecting clashes between different
-processes (e.g. XEmacs and some external process, or two different
-XEmacs processes) modifying the same file. (XEmacs can optionally use
-the `lock/' subdirectory to provide a form of "locking" between
-different XEmacs processes.) This module is also used by the low-level
-functions in `insdel.c' to ensure that, if the first modification is
-being made to a buffer whose corresponding file has been externally
-modified, the user is made aware of this so that the buffer can be
-synched up with the external changes if necessary.
-
- filemode.c
-
- This file provides some miscellaneous functions that construct a
-`rwxr-xr-x'-type permissions string (as might appear in an `ls'-style
-directory listing) given the information returned by the `stat()'
-system call.
-
- dired.c
- ndir.h
-
- These files implement the XEmacs interface to directory searching.
-This includes a number of primitives for determining the files in a
-directory and for doing filename completion. (Remember that generic
-completion is handled by a different mechanism, in `minibuf.c'.)
-
- `ndir.h' is a header file used for the directory-searching emulation
-functions provided in `sysdep.c' (see section J below), for systems
-that don't provide any directory-searching functions. (On those
-systems, directories can be read directly as files, and parsed.)
-
- realpath.c
-
- This file provides an implementation of the `realpath()' function
-for expanding symbolic links, on systems that don't implement it or have
-a broken implementation.
-
-\1f
File: internals.info, Node: Modules for Other Aspects of the Lisp Interpreter and Object System, Next: Modules for Interfacing with the Operating System, Prev: Modules for Interfacing with the File System, Up: A Summary of the Various XEmacs Modules
Modules for Other Aspects of the Lisp Interpreter and Object System
* Allocation from Frob Blocks::
* lrecords::
* Low-level allocation::
-* Pure Space::
* Cons::
* Vector::
* Bit Vector::
one C primitive for creating it.
Recall from section (VII) that a Lisp object, as stored in a 32-bit
-or 64-bit word, has a mark bit, a few tag bits, and a "value" that
-occupies the remainder of the bits. We can separate the different Lisp
-object types into four broad categories:
+or 64-bit word, has a few tag bits, and a "value" that occupies the
+remainder of the bits. We can separate the different Lisp object types
+into three broad categories:
* (a) Those for whom the value directly represents the contents of
the Lisp object. Only two types are in this category: integers and
necessary for such objects. Lisp objects of these types do not
need to be `GCPRO'ed.
- In the remaining three categories, the value is a pointer to a
-structure.
-
- * (b) Those for whom the tag directly specifies the type. Recall
- that there are only three tag bits; this means that at most five
- types can be specified this way. The most commonly-used types are
- stored in this format; this includes conses, strings, vectors, and
- sometimes symbols. With the exception of vectors, objects in this
- category are allocated in "frob blocks", i.e. large blocks of
- memory that are subdivided into individual objects. This saves a
- lot on malloc overhead, since there are typically quite a lot of
- these objects around, and the objects are small. (A cons, for
- example, occupies 8 bytes on 32-bit machines--4 bytes for each of
- the two objects it contains.) Vectors are individually
- `malloc()'ed since they are of variable size. (It would be
- possible, and desirable, to allocate vectors of certain small
- sizes out of frob blocks, but it isn't currently done.) Strings
- are handled specially: Each string is allocated in two parts, a
- fixed size structure containing a length and a data pointer, and
- the actual data of the string. The former structure is allocated
- in frob blocks as usual, and the latter data is stored in "string
- chars blocks" and is relocated during garbage collection to
- eliminate holes.
-
In the remaining two categories, the type is stored in the object
itself. The tag for all such objects is the generic "lrecord"
-(Lisp_Record) tag. The first four bytes (or eight, for 64-bit machines)
-of the object's structure are a pointer to a structure that describes
-the object's type, which includes method pointers and a pointer to a
-string naming the type. Note that it's possible to save some space by
-using a one- or two-byte tag, rather than a four- or eight-byte pointer
-to store the type, but it's not clear it's worth making the change.
-
- * (c) Those lrecords that are allocated in frob blocks (see above).
+(Lisp_Type_Record) tag. The first bytes of the object's structure are
+an integer (actually a char) characterising the object's type and some
+flags, in particular the mark bit used for garbage collection. A
+structure describing the type is accessible thru the
+lrecord_implementation_table indexed with said integer. This structure
+includes the method pointers and a pointer to a string naming the type.
+
+ * (b) Those lrecords that are allocated in frob blocks (see above).
This includes the objects that are most common and relatively
- small, and includes floats, compiled functions, symbols (when not
- in category (b)), extents, events, and markers. With the cleanup
- of frob blocks done in 19.12, it's not terribly hard to add more
- objects to this category, but it's a bit trickier than adding an
- object type to type (d) (esp. if the object needs a finalization
- method), and is not likely to save much space unless the object is
- small and there are many of them. (In fact, if there are very few
- of them, it might actually waste space.)
-
- * (d) Those lrecords that are individually `malloc()'ed. These are
+ small, and includes conses, strings, subrs, floats, compiled
+ functions, symbols, extents, events, and markers. With the
+ cleanup of frob blocks done in 19.12, it's not terribly hard to
+ add more objects to this category, but it's a bit trickier than
+ adding an object type to type (c) (esp. if the object needs a
+ finalization method), and is not likely to save much space unless
+ the object is small and there are many of them. (In fact, if there
+ are very few of them, it might actually waste space.)
+
+ * (c) Those lrecords that are individually `malloc()'ed. These are
called "lcrecords". All other types are in this category. Adding
a new type to this category is comparatively easy, and all types
added since 19.8 (when the current allocation scheme was devised,
have been in this category.
Note that bit vectors are a bit of a special case. They are simple
-lrecords as in category (c), but are individually `malloc()'ed like
+lrecords as in category (b), but are individually `malloc()'ed like
vectors. You can basically view them as exactly like vectors except
that their type is stored in lrecord fashion rather than in
directly-tagged fashion.
- Note that FSF Emacs redesigned their object system in 19.29 to follow
-a similar scheme. However, given RMS's expressed dislike for data
-abstraction, the FSF scheme is not nearly as clean or as easy to
-extend. (FSF calls items of type (c) `Lisp_Misc' and items of type (d)
-`Lisp_Vectorlike', with separate tags for each, although
-`Lisp_Vectorlike' is also used for vectors.)
-
\1f
File: internals.info, Node: Garbage Collection, Next: GCPROing, Prev: Introduction to Allocation, Up: Allocation of Objects in XEmacs Lisp
frob blocks, all vectors (which are chained in one big list), and all
lcrecords (which are likewise chained).
- Note that, when an object is marked, the mark has to occur inside of
-the object's structure, rather than in the 32-bit `Lisp_Object' holding
-the object's pointer; i.e. you can't just set the pointer's mark bit.
-This is because there may be many pointers to the same object. This
-means that the method of marking an object can differ depending on the
-type. The different marking methods are approximately as follows:
-
- 1. For conses, the mark bit of the car is set.
-
- 2. For strings, the mark bit of the string's plist is set.
-
- 3. For symbols when not lrecords, the mark bit of the symbol's plist
- is set.
-
- 4. For vectors, the length is negated after adding 1.
-
- 5. For lrecords, the pointer to the structure describing the type is
- changed (see below).
-
- 6. Integers and characters do not need to be marked, since no
- allocation occurs for them.
-
- The details of this are in the `mark_object()' function.
-
- Note that any code that operates during garbage collection has to be
-especially careful because of the fact that some objects may be marked
-and as such may not look like they normally do. In particular:
-
- Some object pointers may have their mark bit set. This will make
- `FOOBARP()' predicates fail. Use `GC_FOOBARP()' to deal with this.
-
- * Even if you clear the mark bit, `FOOBARP()' will still fail for
- lrecords because the implementation pointer has been changed (see
- below). `GC_FOOBARP()' will correctly deal with this.
-
- * Vectors have their size field munged, so anything that looks at
- this field will fail.
-
- * Note that `XFOOBAR()' macros _will_ work correctly on object
- pointers with their mark bit set, because the logical shift
- operations that remove the tag also remove the mark bit.
-
- Finally, note that garbage collection can be invoked explicitly by
-calling `garbage-collect' but is also called automatically by `eval',
-once a certain amount of memory has been allocated since the last
-garbage collection (according to `gc-cons-threshold').
+ Garbage collection can be invoked explicitly by calling
+`garbage-collect' but is also called automatically by `eval', once a
+certain amount of memory has been allocated since the last garbage
+collection (according to `gc-cons-threshold').
\1f
File: internals.info, Node: GCPROing, Next: Garbage Collection - Step by Step, Prev: Garbage Collection, Up: Allocation of Objects in XEmacs Lisp
all in-use objects must be reachable somehow or other from one of the
roots of accessibility. The roots of accessibility are:
- 1. All objects that have been `staticpro()'d. This is used for any
- global C variables that hold Lisp objects. A call to
- `staticpro()' happens implicitly as a result of any symbols
- declared with `defsymbol()' and any variables declared with
- `DEFVAR_FOO()'. You need to explicitly call `staticpro()' (in the
- `vars_of_foo()' method of a module) for other global C variables
- holding Lisp objects. (This typically includes internal lists and
- such things.)
+ 1. All objects that have been `staticpro()'d or
+ `staticpro_nodump()'ed. This is used for any global C variables
+ that hold Lisp objects. A call to `staticpro()' happens implicitly
+ as a result of any symbols declared with `defsymbol()' and any
+ variables declared with `DEFVAR_FOO()'. You need to explicitly
+ call `staticpro()' (in the `vars_of_foo()' method of a module) for
+ other global C variables holding Lisp objects. (This typically
+ includes internal lists and such things.). Use
+ `staticpro_nodump()' only in the rare cases when you do not want
+ the pointed variable to be saved at dump time but rather recompute
+ it at startup.
Note that `obarray' is one of the `staticpro()'d things.
Therefore, all functions and variables get marked through this.
The upshot is that garbage collection can basically occur everywhere
`Feval', respectively `Ffuncall', is used - either directly or through
another function. Since calls to these two functions are hidden in
-various other functions, many calls to `garabge_collect_1' are not
+various other functions, many calls to `garbage_collect_1' are not
obviously foreseeable, and therefore unexpected. Instances where they
are used that are worth remembering are various elisp commands, as for
example `or', `and', `if', `cond', `while', `setq', etc., miscellaneous
signals, as for example the ones raised by every `QUITE'-macro
triggered after pressing Ctrl-g.
+\1f
+File: internals.info, Node: garbage_collect_1, Next: mark_object, Prev: Invocation, Up: Garbage Collection - Step by Step
+
+`garbage_collect_1'
+-------------------
+
+ We can now describe exactly what happens after the invocation takes
+place.
+ 1. There are several cases in which the garbage collector is left
+ immediately: when we are already garbage collecting
+ (`gc_in_progress'), when the garbage collection is somehow
+ forbidden (`gc_currently_forbidden'), when we are currently
+ displaying something (`in_display') or when we are preparing for
+ the armageddon of the whole system (`preparing_for_armageddon').
+
+ 2. Next the correct frame in which to put all the output occurring
+ during garbage collecting is determined. In order to be able to
+ restore the old display's state after displaying the message, some
+ data about the current cursor position has to be saved. The
+ variables `pre_gc_cursor' and `cursor_changed' take care of that.
+
+ 3. The state of `gc_currently_forbidden' must be restored after the
+ garbage collection, no matter what happens during the process. We
+ accomplish this by `record_unwind_protect'ing the suitable function
+ `restore_gc_inhibit' together with the current value of
+ `gc_currently_forbidden'.
+
+ 4. If we are concurrently running an interactive xemacs session, the
+ next step is simply to show the garbage collector's cursor/message.
+
+ 5. The following steps are the intrinsic steps of the garbage
+ collector, therefore `gc_in_progress' is set.
+
+ 6. For debugging purposes, it is possible to copy the current C stack
+ frame. However, this seems to be a currently unused feature.
+
+ 7. Before actually starting to go over all live objects, references to
+ objects that are no longer used are pruned. We only have to do
+ this for events (`clear_event_resource') and for specifiers
+ (`cleanup_specifiers').
+
+ 8. Now the mark phase begins and marks all accessible elements. In
+ order to start from all slots that serve as roots of
+ accessibility, the function `mark_object' is called for each root
+ individually to go out from there to mark all reachable objects.
+ All roots that are traversed are shown in their processed order:
+ * all constant symbols and static variables that are registered
+ via `staticpro' in the array `staticvec'. *Note Adding
+ Global Lisp Variables::.
+
+ * all Lisp objects that are created in C functions and that
+ must be protected from freeing them. They are registered in
+ the global list `gcprolist'. *Note GCPROing::.
+
+ * all local variables (i.e. their name fields `symbol' and old
+ values `old_values') that are bound during the evaluation by
+ the Lisp engine. They are stored in `specbinding' structs
+ pushed on a stack called `specpdl'. *Note Dynamic Binding;
+ The specbinding Stack; Unwind-Protects::.
+
+ * all catch blocks that the Lisp engine encounters during the
+ evaluation cause the creation of structs `catchtag' inserted
+ in the list `catchlist'. Their tag (`tag') and value (`val'
+ fields are freshly created objects and therefore have to be
+ marked. *Note Catch and Throw::.
+
+ * every function application pushes new structs `backtrace' on
+ the call stack of the Lisp engine (`backtrace_list'). The
+ unique parts that have to be marked are the fields for each
+ function (`function') and all their arguments (`args').
+ *Note Evaluation::.
+
+ * all objects that are used by the redisplay engine that must
+ not be freed are marked by a special function called
+ `mark_redisplay' (in `redisplay.c').
+
+ * all objects created for profiling purposes are allocated by C
+ functions instead of using the lisp allocation mechanisms. In
+ order to receive the right ones during the sweep phase, they
+ also have to be marked manually. That is done by the function
+ `mark_profiling_info'
+
+ 9. Hash tables in XEmacs belong to a kind of special objects that
+ make use of a concept often called 'weak pointers'. To make a
+ long story short, these kind of pointers are not followed during
+ the estimation of the live objects during garbage collection. Any
+ object referenced only by weak pointers is collected anyway, and
+ the reference to it is cleared. In hash tables there are different
+ usage patterns of them, manifesting in different types of hash
+ tables, namely 'non-weak', 'weak', 'key-weak' and 'value-weak'
+ (internally also 'key-car-weak' and 'value-car-weak') hash tables,
+ each clearing entries depending on different conditions. More
+ information can be found in the documentation to the function
+ `make-hash-table'.
+
+ Because there are complicated dependency rules about when and what
+ to mark while processing weak hash tables, the standard `marker'
+ method is only active if it is marking non-weak hash tables. As
+ soon as a weak component is in the table, the hash table entries
+ are ignored while marking. Instead their marking is done each
+ separately by the function `finish_marking_weak_hash_tables'. This
+ function iterates over each hash table entry `hentries' for each
+ weak hash table in `Vall_weak_hash_tables'. Depending on the type
+ of a table, the appropriate action is performed. If a table is
+ acting as `HASH_TABLE_KEY_WEAK', and a key already marked,
+ everything reachable from the `value' component is marked. If it is
+ acting as a `HASH_TABLE_VALUE_WEAK' and the value component is
+ already marked, the marking starts beginning only from the `key'
+ component. If it is a `HASH_TABLE_KEY_CAR_WEAK' and the car of
+ the key entry is already marked, we mark both the `key' and
+ `value' components. Finally, if the table is of the type
+ `HASH_TABLE_VALUE_CAR_WEAK' and the car of the value components is
+ already marked, again both the `key' and the `value' components
+ get marked.
+
+ Again, there are lists with comparable properties called weak
+ lists. There exist different peculiarities of their types called
+ `simple', `assoc', `key-assoc' and `value-assoc'. You can find
+ further details about them in the description to the function
+ `make-weak-list'. The scheme of their marking is similar: all weak
+ lists are listed in `Qall_weak_lists', therefore we iterate over
+ them. The marking is advanced until we hit an already marked pair.
+ Then we know that during a former run all the rest has been marked
+ completely. Again, depending on the special type of the weak list,
+ our jobs differ. If it is a `WEAK_LIST_SIMPLE' and the elem is
+ marked, we mark the `cons' part. If it is a `WEAK_LIST_ASSOC' and
+ not a pair or a pair with both marked car and cdr, we mark the
+ `cons' and the `elem'. If it is a `WEAK_LIST_KEY_ASSOC' and not a
+ pair or a pair with a marked car of the elem, we mark the `cons'
+ and the `elem'. Finally, if it is a `WEAK_LIST_VALUE_ASSOC' and
+ not a pair or a pair with a marked cdr of the elem, we mark both
+ the `cons' and the `elem'.
+
+ Since, by marking objects in reach from weak hash tables and weak
+ lists, other objects could get marked, this perhaps implies
+ further marking of other weak objects, both finishing functions
+ are redone as long as yet unmarked objects get freshly marked.
+
+ 10. After completing the special marking for the weak hash tables and
+ for the weak lists, all entries that point to objects that are
+ going to be swept in the further process are useless, and
+ therefore have to be removed from the table or the list.
+
+ The function `prune_weak_hash_tables' does the job for weak hash
+ tables. Totally unmarked hash tables are removed from the list
+ `Vall_weak_hash_tables'. The other ones are treated more carefully
+ by scanning over all entries and removing one as soon as one of
+ the components `key' and `value' is unmarked.
+
+ The same idea applies to the weak lists. It is accomplished by
+ `prune_weak_lists': An unmarked list is pruned from
+ `Vall_weak_lists' immediately. A marked list is treated more
+ carefully by going over it and removing just the unmarked pairs.
+
+ 11. The function `prune_specifiers' checks all listed specifiers held
+ in `Vall_specifiers' and removes the ones from the lists that are
+ unmarked.
+
+ 12. All syntax tables are stored in a list called
+ `Vall_syntax_tables'. The function `prune_syntax_tables' walks
+ through it and unlinks the tables that are unmarked.
+
+ 13. Next, we will attack the complete sweeping - the function
+ `gc_sweep' which holds the predominance.
+
+ 14. First, all the variables with respect to garbage collection are
+ reset. `consing_since_gc' - the counter of the created cells since
+ the last garbage collection - is set back to 0, and
+ `gc_in_progress' is not `true' anymore.
+
+ 15. In case the session is interactive, the displayed cursor and
+ message are removed again.
+
+ 16. The state of `gc_inhibit' is restored to the former value by
+ unwinding the stack.
+
+ 17. A small memory reserve is always held back that can be reached by
+ `breathing_space'. If nothing more is left, we create a new reserve
+ and exit.
+
+\1f
+File: internals.info, Node: mark_object, Next: gc_sweep, Prev: garbage_collect_1, Up: Garbage Collection - Step by Step
+
+`mark_object'
+-------------
+
+ The first thing that is checked while marking an object is whether
+the object is a real Lisp object `Lisp_Type_Record' or just an integer
+or a character. Integers and characters are the only two types that are
+stored directly - without another level of indirection, and therefore
+they don't have to be marked and collected. *Note How Lisp Objects Are
+Represented in C::.
+
+ The second case is the one we have to handle. It is the one when we
+are dealing with a pointer to a Lisp object. But, there exist also three
+possibilities, that prevent us from doing anything while marking: The
+object is read only which prevents it from being garbage collected,
+i.e. marked (`C_READONLY_RECORD_HEADER'). The object in question is
+already marked, and need not be marked for the second time (checked by
+`MARKED_RECORD_HEADER_P'). If it is a special, unmarkable object
+(`UNMARKABLE_RECORD_HEADER_P', apparently, these are objects that sit
+in some const space, and can therefore not be marked, see
+`this_one_is_unmarkable' in `alloc.c').
+
+ Now, the actual marking is feasible. We do so by once using the macro
+`MARK_RECORD_HEADER' to mark the object itself (actually the special
+flag in the lrecord header), and calling its special marker "method"
+`marker' if available. The marker method marks every other object that
+is in reach from our current object. Note, that these marker methods
+should not call `mark_object' recursively, but instead should return
+the next object from where further marking has to be performed.
+
+ In case another object was returned, as mentioned before, we
+reiterate the whole `mark_object' process beginning with this next
+object.
+
Foundation instead of in the original English.
\1f
-File: internals.info, Node: garbage_collect_1, Next: mark_object, Prev: Invocation, Up: Garbage Collection - Step by Step
-
-`garbage_collect_1'
--------------------
-
- We can now describe exactly what happens after the invocation takes
-place.
- 1. There are several cases in which the garbage collector is left
- immediately: when we are already garbage collecting
- (`gc_in_progress'), when the garbage collection is somehow
- forbidden (`gc_currently_forbidden'), when we are currently
- displaying something (`in_display') or when we are preparing for
- the armageddon of the whole system (`preparing_for_armageddon').
-
- 2. Next the correct frame in which to put all the output occurring
- during garbage collecting is determined. In order to be able to
- restore the old display's state after displaying the message, some
- data about the current cursor position has to be saved. The
- variables `pre_gc_curser' and `cursor_changed' take care of that.
-
- 3. The state of `gc_currently_forbidden' must be restored after the
- garbage collection, no matter what happens during the process. We
- accomplish this by `record_unwind_protect'ing the suitable function
- `restore_gc_inhibit' together with the current value of
- `gc_currently_forbidden'.
-
- 4. If we are concurrently running an interactive xemacs session, the
- next step is simply to show the garbage collector's cursor/message.
-
- 5. The following steps are the intrinsic steps of the garbage
- collector, therefore `gc_in_progress' is set.
-
- 6. For debugging purposes, it is possible to copy the current C stack
- frame. However, this seems to be a currently unused feature.
-
- 7. Before actually starting to go over all live objects, references to
- objects that are no longer used are pruned. We only have to do
- this for events (`clear_event_resource') and for specifiers
- (`cleanup_specifiers').
-
- 8. Now the mark phase begins and marks all accessible elements. In
- order to start from all slots that serve as roots of
- accessibility, the function `mark_object' is called for each root
- individually to go out from there to mark all reachable objects.
- All roots that are traversed are shown in their processed order:
- * all constant symbols and static variables that are registered
- via `staticpro' in the array `staticvec'. *Note Adding
- Global Lisp Variables::.
-
- * all Lisp objects that are created in C functions and that
- must be protected from freeing them. They are registered in
- the global list `gcprolist'. *Note GCPROing::.
-
- * all local variables (i.e. their name fields `symbol' and old
- values `old_values') that are bound during the evaluation by
- the Lisp engine. They are stored in `specbinding' structs
- pushed on a stack called `specpdl'. *Note Dynamic Binding;
- The specbinding Stack; Unwind-Protects::.
-
- * all catch blocks that the Lisp engine encounters during the
- evaluation cause the creation of structs `catchtag' inserted
- in the list `catchlist'. Their tag (`tag') and value (`val'
- fields are freshly created objects and therefore have to be
- marked. *Note Catch and Throw::.
-
- * every function application pushes new structs `backtrace' on
- the call stack of the Lisp engine (`backtrace_list'). The
- unique parts that have to be marked are the fields for each
- function (`function') and all their arguments (`args').
- *Note Evaluation::.
-
- * all objects that are used by the redisplay engine that must
- not be freed are marked by a special function called
- `mark_redisplay' (in `redisplay.c').
-
- * all objects created for profiling purposes are allocated by C
- functions instead of using the lisp allocation mechanisms. In
- order to receive the right ones during the sweep phase, they
- also have to be marked manually. That is done by the function
- `mark_profiling_info'
-
- 9. Hash tables in XEmacs belong to a kind of special objects that
- make use of a concept often called 'weak pointers'. To make a
- long story short, these kind of pointers are not followed during
- the estimation of the live objects during garbage collection. Any
- object referenced only by weak pointers is collected anyway, and
- the reference to it is cleared. In hash tables there are different
- usage patterns of them, manifesting in different types of hash
- tables, namely 'non-weak', 'weak', 'key-weak' and 'value-weak'
- (internally also 'key-car-weak' and 'value-car-weak') hash tables,
- each clearing entries depending on different conditions. More
- information can be found in the documentation to the function
- `make-hash-table'.
-
- Because there are complicated dependency rules about when and what
- to mark while processing weak hash tables, the standard `marker'
- method is only active if it is marking non-weak hash tables. As
- soon as a weak component is in the table, the hash table entries
- are ignored while marking. Instead their marking is done each
- separately by the function `finish_marking_weak_hash_tables'. This
- function iterates over each hash table entry `hentries' for each
- weak hash table in `Vall_weak_hash_tables'. Depending on the type
- of a table, the appropriate action is performed. If a table is
- acting as `HASH_TABLE_KEY_WEAK', and a key already marked,
- everything reachable from the `value' component is marked. If it is
- acting as a `HASH_TABLE_VALUE_WEAK' and the value component is
- already marked, the marking starts beginning only from the `key'
- component. If it is a `HASH_TABLE_KEY_CAR_WEAK' and the car of
- the key entry is already marked, we mark both the `key' and
- `value' components. Finally, if the table is of the type
- `HASH_TABLE_VALUE_CAR_WEAK' and the car of the value components is
- already marked, again both the `key' and the `value' components
- get marked.
-
- Again, there are lists with comparable properties called weak
- lists. There exist different peculiarities of their types called
- `simple', `assoc', `key-assoc' and `value-assoc'. You can find
- further details about them in the description to the function
- `make-weak-list'. The scheme of their marking is similar: all weak
- lists are listed in `Qall_weak_lists', therefore we iterate over
- them. The marking is advanced until we hit an already marked pair.
- Then we know that during a former run all the rest has been marked
- completely. Again, depending on the special type of the weak list,
- our jobs differ. If it is a `WEAK_LIST_SIMPLE' and the elem is
- marked, we mark the `cons' part. If it is a `WEAK_LIST_ASSOC' and
- not a pair or a pair with both marked car and cdr, we mark the
- `cons' and the `elem'. If it is a `WEAK_LIST_KEY_ASSOC' and not a
- pair or a pair with a marked car of the elem, we mark the `cons'
- and the `elem'. Finally, if it is a `WEAK_LIST_VALUE_ASSOC' and
- not a pair or a pair with a marked cdr of the elem, we mark both
- the `cons' and the `elem'.
-
- Since, by marking objects in reach from weak hash tables and weak
- lists, other objects could get marked, this perhaps implies
- further marking of other weak objects, both finishing functions
- are redone as long as yet unmarked objects get freshly marked.
-
- 10. After completing the special marking for the weak hash tables and
- for the weak lists, all entries that point to objects that are
- going to be swept in the further process are useless, and
- therefore have to be removed from the table or the list.
-
- The function `prune_weak_hash_tables' does the job for weak hash
- tables. Totally unmarked hash tables are removed from the list
- `Vall_weak_hash_tables'. The other ones are treated more carefully
- by scanning over all entries and removing one as soon as one of
- the components `key' and `value' is unmarked.
-
- The same idea applies to the weak lists. It is accomplished by
- `prune_weak_lists': An unmarked list is pruned from
- `Vall_weak_lists' immediately. A marked list is treated more
- carefully by going over it and removing just the unmarked pairs.
-
- 11. The function `prune_specifiers' checks all listed specifiers held
- in `Vall_speficiers' and removes the ones from the lists that are
- unmarked.
-
- 12. All syntax tables are stored in a list called
- `Vall_syntax_tables'. The function `prune_syntax_tables' walks
- through it and unlinks the tables that are unmarked.
-
- 13. Next, we will attack the complete sweeping - the function
- `gc_sweep' which holds the predominance.
-
- 14. First, all the variables with respect to garbage collection are
- reset. `consing_since_gc' - the counter of the created cells since
- the last garbage collection - is set back to 0, and
- `gc_in_progress' is not `true' anymore.
-
- 15. In case the session is interactive, the displayed cursor and
- message are removed again.
-
- 16. The state of `gc_inhibit' is restored to the former value by
- unwinding the stack.
-
- 17. A small memory reserve is always held back that can be reached by
- `breathing_space'. If nothing more is left, we create a new reserve
- and exit.
-
-\1f
-File: internals.info, Node: mark_object, Next: gc_sweep, Prev: garbage_collect_1, Up: Garbage Collection - Step by Step
-
-`mark_object'
--------------
-
- The first thing that is checked while marking an object is whether
-the object is a real Lisp object `Lisp_Type_Record' or just an integer
-or a character. Integers and characters are the only two types that are
-stored directly - without another level of indirection, and therefore
-they don't have to be marked and collected. *Note How Lisp Objects Are
-Represented in C::.
-
- The second case is the one we have to handle. It is the one when we
-are dealing with a pointer to a Lisp object. But, there exist also three
-possibilities, that prevent us from doing anything while marking: The
-object is read only which prevents it from being garbage collected,
-i.e. marked (`C_READONLY_RECORD_HEADER'). The object in question is
-already marked, and need not be marked for the second time (checked by
-`MARKED_RECORD_HEADER_P'). If it is a special, unmarkable object
-(`UNMARKABLE_RECORD_HEADER_P', apparently, these are objects that sit
-in some const space, and can therefore not be marked, see
-`this_one_is_unmarkable' in `alloc.c').
-
- Now, the actual marking is feasible. We do so by once using the macro
-`MARK_RECORD_HEADER' to mark the object itself (actually the special
-flag in the lrecord header), and calling its special marker "method"
-`marker' if available. The marker method marks every other object that
-is in reach from our current object. Note, that these marker methods
-should not call `mark_object' recursively, but instead should return
-the next object from where further marking has to be performed.
-
- In case another object was returned, as mentioned before, we
-reiterate the whole `mark_object' process beginning with this next
-object.
-
-\1f
File: internals.info, Node: gc_sweep, Next: sweep_lcrecords_1, Prev: mark_object, Up: Garbage Collection - Step by Step
`gc_sweep'
[see `lrecord.h']
All lrecords have at the beginning of their structure a `struct
-lrecord_header'. This just contains a pointer to a `struct
+lrecord_header'. This just contains a type number and some flags,
+including the mark bit. The type number, thru the
+`lrecord_implementation_table', gives access to a `struct
lrecord_implementation', which is a structure containing method pointers
and such. There is one of these for each type, and it is a global,
constant, statically-declared structure that is declared in the
-`DEFINE_LRECORD_IMPLEMENTATION()' macro. (This macro actually declares
-an array of two `struct lrecord_implementation' structures. The first
-one contains all the standard method pointers, and is used in all
-normal circumstances. During garbage collection, however, the lrecord
-is "marked" by bumping its implementation pointer by one, so that it
-points to the second structure in the array. This structure contains a
-special indication in it that it's a "marked-object" structure: the
-finalize method is the special function `this_marks_a_marked_record()',
-and all other methods are null pointers. At the end of garbage
-collection, all lrecords will either be reclaimed or unmarked by
-decrementing their implementation pointers, so this second structure
-pointer will never remain past garbage collection.
-
- Simple lrecords (of type (c) above) just have a `struct
+`DEFINE_LRECORD_IMPLEMENTATION()' macro.
+
+ Simple lrecords (of type (b) above) just have a `struct
lrecord_header' at their beginning. lcrecords, however, actually have a
`struct lcrecord_header'. This, in turn, has a `struct lrecord_header'
at its beginning, so sanity is preserved; but it also has a pointer
configurations and opaques.
\1f
-File: internals.info, Node: Low-level allocation, Next: Pure Space, Prev: lrecords, Up: Allocation of Objects in XEmacs Lisp
+File: internals.info, Node: Low-level allocation, Next: Cons, Prev: lrecords, Up: Allocation of Objects in XEmacs Lisp
Low-level allocation
====================
is reached.
\1f
-File: internals.info, Node: Pure Space, Next: Cons, Prev: Low-level allocation, Up: Allocation of Objects in XEmacs Lisp
-
-Pure Space
-==========
-
- Not yet documented.
-
-\1f
-File: internals.info, Node: Cons, Next: Vector, Prev: Pure Space, Up: Allocation of Objects in XEmacs Lisp
+File: internals.info, Node: Cons, Next: Vector, Prev: Low-level allocation, Up: Allocation of Objects in XEmacs Lisp
Cons
====
Symbol
======
- Symbols are also allocated in frob blocks. Note that the code
-exists for symbols to be either lrecords (category (c) above) or simple
-types (category (b) above), and are lrecords by default (I think),
-although there is no good reason for this.
-
- Note that symbols in the awful horrible obarray structure are
-chained through their `next' field.
+ Symbols are also allocated in frob blocks. Symbols in the awful
+horrible obarray structure are chained through their `next' field.
Remember that `intern' looks up a symbol in an obarray, creating one
if necessary.
starting address if needed, and reinitialize all pointers to this
data. Also, rebuild all the quickly rebuildable data.
+\1f
+File: internals.info, Node: Data descriptions, Next: Dumping phase, Prev: Overview, Up: Dumping
+
+Data descriptions
+=================
+
+ The more complex task of the dumper is to be able to write lisp
+objects (lrecords) and C structs to disk and reload them at a different
+address, updating all the pointers they include in the process. This
+is done by using external data descriptions that give information about
+the layout of the structures in memory.
+
+ The specification of these descriptions is in lrecord.h. A
+description of an lrecord is an array of struct lrecord_description.
+Each of these structs include a type, an offset in the structure and
+some optional parameters depending on the type. For instance, here is
+the string description:
+
+ static const struct lrecord_description string_description[] = {
+ { XD_BYTECOUNT, offsetof (Lisp_String, size) },
+ { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String, data), XD_INDIRECT(0, 1) },
+ { XD_LISP_OBJECT, offsetof (Lisp_String, plist) },
+ { XD_END }
+ };
+
+ The first line indicates a member of type Bytecount, which is used by
+the next, indirect directive. The second means "there is a pointer to
+some opaque data in the field `data'". The length of said data is
+given by the expression `XD_INDIRECT(0, 1)', which means "the value in
+the 0th line of the description (welcome to C) plus one". The third
+line means "there is a Lisp_Object member `plist' in the Lisp_String
+structure". `XD_END' then ends the description.
+
+ This gives us all the information we need to move around what is
+pointed to by a structure (C or lrecord) and, by transitivity,
+everything that it points to. The only missing information for dumping
+is the size of the structure. For lrecords, this is part of the
+lrecord_implementation, so we don't need to duplicate it. For C
+structures we use a struct struct_description, which includes a size
+field and a pointer to an associated array of lrecord_description.
+
+\1f
+File: internals.info, Node: Dumping phase, Next: Reloading phase, Prev: Data descriptions, Up: Dumping
+
+Dumping phase
+=============
+
+ Dumping is done by calling the function pdump() (in alloc.c) which is
+invoked from Fdump_emacs (in emacs.c). This function performs a number
+of tasks.
+
+* Menu:
+
+* Object inventory::
+* Address allocation::
+* The header::
+* Data dumping::
+* Pointers dumping::
+
+\1f
+File: internals.info, Node: Object inventory, Next: Address allocation, Prev: Dumping phase, Up: Dumping phase
+
+Object inventory
+----------------
+
+ The first task is to build the list of the objects to dump. This
+includes:
+
+ * lisp objects
+
+ * C structures
+
+ We end up with one `pdump_entry_list_elmt' per object group (arrays
+of C structs are kept together) which includes a pointer to the first
+object of the group, the per-object size and the count of objects in the
+group, along with some other information which is initialized later.
+
+ These entries are linked together in `pdump_entry_list' structures
+and can be enumerated thru either:
+
+ 1. the `pdump_object_table', an array of `pdump_entry_list', one per
+ lrecord type, indexed by type number.
+
+ 2. the `pdump_opaque_data_list', used for the opaque data which does
+ not include pointers, and hence does not need descriptions.
+
+ 3. the `pdump_struct_table', which is a vector of
+ `struct_description'/`pdump_entry_list' pairs, used for non-opaque
+ C structures.
+
+ This uses a marking strategy similar to the garbage collector. Some
+differences though:
+
+ 1. We do not use the mark bit (which does not exist for C structures
+ anyway), we use a big hash table instead.
+
+ 2. We do not use the mark function of lrecords but instead rely on the
+ external descriptions. This happens essentially because we need to
+ follow pointers to C structures and opaque data in addition to
+ Lisp_Object members.
+
+ This is done by `pdump_register_object', which handles Lisp_Object
+variables, and pdump_register_struct which handles C structures, which
+both delegate the description management to pdump_register_sub.
+
+ The hash table doubles as a map object to pdump_entry_list_elmt (i.e.
+allows us to look up a pdump_entry_list_elmt with the object it points
+to). Entries are added with `pdump_add_entry()' and looked up with
+`pdump_get_entry()'. There is no need for entry removal. The hash
+value is computed quite basically from the object pointer by
+`pdump_make_hash()'.
+
+ The roots for the marking are:
+
+ 1. the `staticpro''ed variables (there is a special
+ `staticpro_nodump()' call for protected variables we do not want
+ to dump).
+
+ 2. the `pdump_wire''d variables (`staticpro' is equivalent to
+ `staticpro_nodump()' + `pdump_wire()').
+
+ 3. the `dumpstruct''ed variables, which points to C structures.
+
+ This does not include the GCPRO'ed variables, the specbinds, the
+catchtags, the backlist, the redisplay or the profiling info, since we
+do not want to rebuild the actual chain of lisp calls which end up to
+the dump-emacs call, only the global variables.
+
+ Weak lists and weak hash tables are dumped as if they were their
+non-weak equivalent (without changing their type, of course). This has
+not yet been a problem.
+
+\1f
+File: internals.info, Node: Address allocation, Next: The header, Prev: Object inventory, Up: Dumping phase
+
+Address allocation
+------------------
+
+ The next step is to allocate the offsets of each of the objects in
+the final dump file. This is done by `pdump_allocate_offset()' which
+is called indirectly by `pdump_scan_by_alignment()'.
+
+ The strategy to deal with alignment problems uses these facts:
+
+ 1. real world alignment requirements are powers of two.
+
+ 2. the C compiler is required to adjust the size of a struct so that
+ you can have an array of them next to each other. This means you
+ can have a upper bound of the alignment requirements of a given
+ structure by looking at which power of two its size is a multiple.
+
+ 3. the non-variant part of variable size lrecords has an alignment
+ requirement of 4.
+
+ Hence, for each lrecord type, C struct type or opaque data block the
+alignment requirement is computed as a power of two, with a minimum of
+2^2 for lrecords. `pdump_scan_by_alignment()' then scans all the
+`pdump_entry_list_elmt''s, the ones with the highest requirements
+first. This ensures the best packing.
+
+ The maximum alignment requirement we take into account is 2^8.
+
+ `pdump_allocate_offset()' only has to do a linear allocation,
+starting at offset 256 (this leaves room for the header and keep the
+alignments happy).
+
+\1f
+File: internals.info, Node: The header, Next: Data dumping, Prev: Address allocation, Up: Dumping phase
+
+The header
+----------
+
+ The next step creates the file and writes a header with a signature
+and some random informations in it (number of staticpro, number of
+assigned lrecord types, etc...). The reloc_address field, which
+indicates at which address the file should be loaded if we want to
+avoid post-reload relocation, is set to 0. It then seeks to offset 256
+(base offset for the objects).
+
+\1f
+File: internals.info, Node: Data dumping, Next: Pointers dumping, Prev: The header, Up: Dumping phase
+
+Data dumping
+------------
+
+ The data is dumped in the same order as the addresses were allocated
+by `pdump_dump_data()', called from `pdump_scan_by_alignment()'. This
+function copies the data to a temporary buffer, relocates all pointers
+in the object to the addresses allocated in step Address Allocation,
+and writes it to the file. Using the same order means that, if we are
+careful with lrecords whose size is not a multiple of 4, we are ensured
+that the object is always written at the offset in the file allocated
+in step Address Allocation.
+
+\1f
+File: internals.info, Node: Pointers dumping, Prev: Data dumping, Up: Dumping phase
+
+Pointers dumping
+----------------
+
+ A bunch of tables needed to reassign properly the global pointers are
+then written. They are:
+
+ 1. the staticpro array
+
+ 2. the dumpstruct array
+
+ 3. the lrecord_implementation_table array
+
+ 4. a vector of all the offsets to the objects in the file that
+ include a description (for faster relocation at reload time)
+
+ 5. the pdump_wired and pdump_wired_list arrays
+
+ For each of the arrays we write both the pointer to the variables and
+the relocated offset of the object they point to. Since these variables
+are global, the pointers are still valid when restarting the program and
+are used to regenerate the global pointers.
+
+ The `pdump_wired_list' array is a special case. The variables it
+points to are the head of weak linked lists of lisp objects of the same
+type. Not all objects of this list are dumped so the relocated pointer
+we associate with them points to the first dumped object of the list, or
+Qnil if none is available. This is also the reason why they are not
+used as roots for the purpose of object enumeration.
+
+ This is the end of the dumping part.
+
+\1f
+File: internals.info, Node: Reloading phase, Next: Remaining issues, Prev: Dumping phase, Up: Dumping
+
+Reloading phase
+===============
+
+File loading
+------------
+
+ The file is mmap'ed in memory (which ensures a PAGESIZE alignment, at
+least 4096), or if mmap is unavailable or fails, a 256-bytes aligned
+malloc is done and the file is loaded.
+
+ Some variables are reinitialized from the values found in the header.
+
+ The difference between the actual loading address and the
+reloc_address is computed and will be used for all the relocations.
+
+Putting back the staticvec
+--------------------------
+
+ The staticvec array is memcpy'd from the file and the variables it
+points to are reset to the relocated objects addresses.
+
+Putting back the dumpstructed variables
+---------------------------------------
+
+ The variables pointed to by dumpstruct in the dump phase are reset to
+the right relocated object addresses.
+
+lrecord_implementations_table
+-----------------------------
+
+ The lrecord_implementations_table is reset to its dump time state and
+the right lrecord_type_index values are put in.
+
+Object relocation
+-----------------
+
+ All the objects are relocated using their description and their
+offset by `pdump_reloc_one'. This step is unnecessary if the
+reloc_address is equal to the file loading address.
+
+Putting back the pdump_wire and pdump_wire_list variables
+---------------------------------------------------------
+
+ Same as Putting back the dumpstructed variables.
+
+Reorganize the hash tables
+--------------------------
+
+ Since some of the hash values in the lisp hash tables are
+address-dependent, their layout is now wrong. So we go through each of
+them and have them resorted by calling `pdump_reorganize_hash_table'.
+
+\1f
+File: internals.info, Node: Remaining issues, Prev: Reloading phase, Up: Dumping
+
+Remaining issues
+================
+
+ The build process will have to start a post-dump xemacs, ask it the
+loading address (which will, hopefully, be always the same between
+different xemacs invocations) and relocate the file to the new address.
+This way the object relocation phase will not have to be done, which
+means no writes in the objects and that, because of the use of mmap, the
+dumped data will be shared between all the xemacs running on the
+computer.
+
+ Some executable signature will be necessary to ensure that a given
+dump file is really associated with a given executable, or random
+crashes will occur. Maybe a random number set at compile or configure
+time thru a define. This will also allow for having
+differently-compiled xemacsen on the same system (mule and no-mule
+comes to mind).
+
+ The DOC file contents should probably end up in the dump file.
+
+\1f
+File: internals.info, Node: Events and the Event Loop, Next: Evaluation; Stack Frames; Bindings, Prev: Dumping, Up: Top
+
+Events and the Event Loop
+*************************
+
+* Menu:
+
+* Introduction to Events::
+* Main Loop::
+* Specifics of the Event Gathering Mechanism::
+* Specifics About the Emacs Event::
+* The Event Stream Callback Routines::
+* Other Event Loop Functions::
+* Converting Events::
+* Dispatching Events; The Command Builder::
+
Foundation instead of in the original English.
\1f
-File: internals.info, Node: Data descriptions, Next: Dumping phase, Prev: Overview, Up: Dumping
-
-Data descriptions
-=================
-
- The more complex task of the dumper is to be able to write lisp
-objects (lrecords) and C structs to disk and reload them at a different
-address, updating all the pointers they include in the process. This
-is done by using external data descriptions that give information about
-the layout of the structures in memory.
-
- The specification of these descriptions is in lrecord.h. A
-description of an lrecord is an array of struct lrecord_description.
-Each of these structs include a type, an offset in the structure and
-some optional parameters depending on the type. For instance, here is
-the string description:
-
- static const struct lrecord_description string_description[] = {
- { XD_BYTECOUNT, offsetof (Lisp_String, size) },
- { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String, data), XD_INDIRECT(0, 1) },
- { XD_LISP_OBJECT, offsetof (Lisp_String, plist) },
- { XD_END }
- };
-
- The first line indicates a member of type Bytecount, which is used by
-the next, indirect directive. The second means "there is a pointer to
-some opaque data in the field `data'". The length of said data is
-given by the expression `XD_INDIRECT(0, 1)', which means "the value in
-the 0th line of the description (welcome to C) plus one". The third
-line means "there is a Lisp_Object member `plist' in the Lisp_String
-structure". `XD_END' then ends the description.
-
- This gives us all the information we need to move around what is
-pointed to by a structure (C or lrecord) and, by transitivity,
-everything that it points to. The only missing information for dumping
-is the size of the structure. For lrecords, this is part of the
-lrecord_implementation, so we don't need to duplicate it. For C
-structures we use a struct struct_description, which includes a size
-field and a pointer to an associated array of lrecord_description.
-
-\1f
-File: internals.info, Node: Dumping phase, Next: Reloading phase, Prev: Data descriptions, Up: Dumping
-
-Dumping phase
-=============
-
- Dumping is done by calling the function pdump() (in alloc.c) which is
-invoked from Fdump_emacs (in emacs.c). This function performs a number
-of tasks.
-
-* Menu:
-
-* Object inventory::
-* Address allocation::
-* The header::
-* Data dumping::
-* Pointers dumping::
-
-\1f
-File: internals.info, Node: Object inventory, Next: Address allocation, Prev: Dumping phase, Up: Dumping phase
-
-Object inventory
-----------------
-
- The first task is to build the list of the objects to dump. This
-includes:
-
- * lisp objects
-
- * C structures
-
- We end up with one `pdump_entry_list_elmt' per object group (arrays
-of C structs are kept together) which includes a pointer to the first
-object of the group, the per-object size and the count of objects in the
-group, along with some other information which is initialized later.
-
- These entries are linked together in `pdump_entry_list' structures
-and can be enumerated thru either:
-
- 1. the `pdump_object_table', an array of `pdump_entry_list', one per
- lrecord type, indexed by type number.
-
- 2. the `pdump_opaque_data_list', used for the opaque data which does
- not include pointers, and hence does not need descriptions.
-
- 3. the `pdump_struct_table', which is a vector of
- `struct_description'/`pdump_entry_list' pairs, used for non-opaque
- C structures.
-
- This uses a marking strategy similar to the garbage collector. Some
-differences though:
-
- 1. We do not use the mark bit (which does not exist for C structures
- anyway), we use a big hash table instead.
-
- 2. We do not use the mark function of lrecords but instead rely on the
- external descriptions. This happens essentially because we need to
- follow pointers to C structures and opaque data in addition to
- Lisp_Object members.
-
- This is done by `pdump_register_object', which handles Lisp_Object
-variables, and pdump_register_struct which handles C structures, which
-both delegate the description management to pdump_register_sub.
-
- The hash table doubles as a map object to pdump_entry_list_elmt (i.e.
-allows us to look up a pdump_entry_list_elmt with the object it points
-to). Entries are added with `pdump_add_entry()' and looked up with
-`pdump_get_entry()'. There is no need for entry removal. The hash
-value is computed quite basically from the object pointer by
-`pdump_make_hash()'.
-
- The roots for the marking are:
-
- 1. the `staticpro''ed variables (there is a special
- `staticpro_nodump()' call for protected variables we do not want
- to dump).
-
- 2. the `pdump_wire''d variables (`staticpro' is equivalent to
- `staticpro_nodump()' + `pdump_wire()').
-
- 3. the `dumpstruct''ed variables, which points to C structures.
-
- This does not include the GCPRO'ed variables, the specbinds, the
-catchtags, the backlist, the redisplay or the profiling info, since we
-do not want to rebuild the actual chain of lisp calls which end up to
-the dump-emacs call, only the global variables.
-
- Weak lists and weak hash tables are dumped as if they were their
-non-weak equivalent (without changing their type, of course). This has
-not yet been a problem.
-
-\1f
-File: internals.info, Node: Address allocation, Next: The header, Prev: Object inventory, Up: Dumping phase
-
-Address allocation
-------------------
-
- The next step is to allocate the offsets of each of the objects in
-the final dump file. This is done by `pdump_allocate_offset()' which
-is called indirectly by `pdump_scan_by_alignment()'.
-
- The strategy to deal with alignment problems uses these facts:
-
- 1. real world alignment requirements are powers of two.
-
- 2. the C compiler is required to adjust the size of a struct so that
- you can have an array of them next to each other. This means you
- can have a upper bound of the alignment requirements of a given
- structure by looking at which power of two its size is a multiple.
-
- 3. the non-variant part of variable size lrecords has an alignment
- requirement of 4.
-
- Hence, for each lrecord type, C struct type or opaque data block the
-alignment requirement is computed as a power of two, with a minimum of
-2^2 for lrecords. `pdump_scan_by_alignment()' then scans all the
-`pdump_entry_list_elmt''s, the ones with the highest requirements
-first. This ensures the best packing.
-
- The maximum alignment requirement we take into account is 2^8.
-
- `pdump_allocate_offset()' only has to do a linear allocation,
-starting at offset 256 (this leaves room for the header and keep the
-alignments happy).
-
-\1f
-File: internals.info, Node: The header, Next: Data dumping, Prev: Address allocation, Up: Dumping phase
-
-The header
-----------
-
- The next step creates the file and writes a header with a signature
-and some random informations in it (number of staticpro, number of
-assigned lrecord types, etc...). The reloc_address field, which
-indicates at which address the file should be loaded if we want to
-avoid post-reload relocation, is set to 0. It then seeks to offset 256
-(base offset for the objects).
-
-\1f
-File: internals.info, Node: Data dumping, Next: Pointers dumping, Prev: The header, Up: Dumping phase
-
-Data dumping
-------------
-
- The data is dumped in the same order as the addresses were allocated
-by `pdump_dump_data()', called from `pdump_scan_by_alignment()'. This
-function copies the data to a temporary buffer, relocates all pointers
-in the object to the addresses allocated in step Address Allocation,
-and writes it to the file. Using the same order means that, if we are
-careful with lrecords whose size is not a multiple of 4, we are ensured
-that the object is always written at the offset in the file allocated
-in step Address Allocation.
-
-\1f
-File: internals.info, Node: Pointers dumping, Prev: Data dumping, Up: Dumping phase
-
-Pointers dumping
-----------------
-
- A bunch of tables needed to reassign properly the global pointers are
-then written. They are:
-
- 1. the staticpro array
-
- 2. the dumpstruct array
-
- 3. the lrecord_implementation_table array
-
- 4. a vector of all the offsets to the objects in the file that
- include a description (for faster relocation at reload time)
-
- 5. the pdump_wired and pdump_wired_list arrays
-
- For each of the arrays we write both the pointer to the variables and
-the relocated offset of the object they point to. Since these variables
-are global, the pointers are still valid when restarting the program and
-are used to regenerate the global pointers.
-
- The `pdump_wired_list' array is a special case. The variables it
-points to are the head of weak linked lists of lisp objects of the same
-type. Not all objects of this list are dumped so the relocated pointer
-we associate with them points to the first dumped object of the list, or
-Qnil if none is available. This is also the reason why they are not
-used as roots for the purpose of object enumeration.
-
- This is the end of the dumping part.
-
-\1f
-File: internals.info, Node: Reloading phase, Next: Remaining issues, Prev: Dumping phase, Up: Dumping
-
-Reloading phase
-===============
-
-File loading
-------------
-
- The file is mmap'ed in memory (which ensures a PAGESIZE alignment, at
-least 4096), or if mmap is unavailable or fails, a 256-bytes aligned
-malloc is done and the file is loaded.
-
- Some variables are reinitialized from the values found in the header.
-
- The difference between the actual loading address and the
-reloc_address is computed and will be used for all the relocations.
-
-Putting back the staticvec
---------------------------
-
- The staticvec array is memcpy'd from the file and the variables it
-points to are reset to the relocated objects addresses.
-
-Putting back the dumpstructed variables
----------------------------------------
-
- The variables pointed to by dumpstruct in the dump phase are reset to
-the right relocated object addresses.
-
-lrecord_implementations_table
------------------------------
-
- The lrecord_implementations_table is reset to its dump time state and
-the right lrecord_type_index values are put in.
-
-Object relocation
------------------
-
- All the objects are relocated using their description and their
-offset by `pdump_reloc_one'. This step is unnecessary if the
-reloc_address is equal to the file loading address.
-
-Putting back the pdump_wire and pdump_wire_list variables
----------------------------------------------------------
-
- Same as Putting back the dumpstructed variables.
-
-Reorganize the hash tables
---------------------------
-
- Since some of the hash values in the lisp hash tables are
-address-dependent, their layout is now wrong. So we go through each of
-them and have them resorted by calling `pdump_reorganize_hash_table'.
-
-\1f
-File: internals.info, Node: Remaining issues, Prev: Reloading phase, Up: Dumping
-
-Remaining issues
-================
-
- The build process will have to start a post-dump xemacs, ask it the
-loading address (which will, hopefully, be always the same between
-different xemacs invocations) and relocate the file to the new address.
-This way the object relocation phase will not have to be done, which
-means no writes in the objects and that, because of the use of mmap, the
-dumped data will be shared between all the xemacs running on the
-computer.
-
- Some executable signature will be necessary to ensure that a given
-dump file is really associated with a given executable, or random
-crashes will occur. Maybe a random number set at compile or configure
-time thru a define. This will also allow for having
-differently-compiled xemacsen on the same system (mule and no-mule
-comes to mind).
-
- The DOC file contents should probably end up in the dump file.
-
-\1f
-File: internals.info, Node: Events and the Event Loop, Next: Evaluation; Stack Frames; Bindings, Prev: Dumping, Up: Top
-
-Events and the Event Loop
-*************************
-
-* Menu:
-
-* Introduction to Events::
-* Main Loop::
-* Specifics of the Event Gathering Mechanism::
-* Specifics About the Emacs Event::
-* The Event Stream Callback Routines::
-* Other Event Loop Functions::
-* Converting Events::
-* Dispatching Events; The Command Builder::
-
-\1f
File: internals.info, Node: Introduction to Events, Next: Main Loop, Prev: Events and the Event Loop, Up: Events and the Event Loop
Introduction to Events
converted into an internal form for faster execution.
When a compiled function is executed for the first time by
-`funcall_compiled_function()', or when it is `Fpurecopy()'ed during the
-dump phase of building XEmacs, the byte-code instructions are converted
-from a `Lisp_String' (which is inefficient to access, especially in the
-presence of MULE) into a `Lisp_Opaque' object containing an array of
-unsigned char, which can be directly executed by the byte-code
-interpreter. At this time the byte code is also analyzed for validity
-and transformed into a more optimized form, so that
-`execute_optimized_program()' can really fly.
+`funcall_compiled_function()', or during the dump phase of building
+XEmacs, the byte-code instructions are converted from a `Lisp_String'
+(which is inefficient to access, especially in the presence of MULE)
+into a `Lisp_Opaque' object containing an array of unsigned char, which
+can be directly executed by the byte-code interpreter. At this time
+the byte code is also analyzed for validity and transformed into a more
+optimized form, so that `execute_optimized_program()' can really fly.
Here are some of the optimizations performed by the internal
byte-code transformer:
`nil', or `keywordp') symbols, so that the byte interpreter
doesn't have to.
- 3. The maxiumum number of variable bindings in the byte-code is
+ 3. The maximum number of variable bindings in the byte-code is
pre-computed, so that space on the `specpdl' stack can be
pre-reserved once for the whole function execution.
`specbind()' to create bindings and `unbind_to()' to undo the bindings
when finished.
- Note that, with the exeption of `Fprogn', these functions are
+ Note that, with the exception of `Fprogn', these functions are
typically called in real life only in interpreted code, since the byte
compiler knows how to convert calls to these functions directly into
byte code.
additional values with particular names, and once again the namespace is
independent of the function and variable namespaces.
+\1f
+File: internals.info, Node: Obarrays, Next: Symbol Values, Prev: Introduction to Symbols, Up: Symbols and Variables
+
+Obarrays
+========
+
+ The identity of symbols with their names is accomplished through a
+structure called an obarray, which is just a poorly-implemented hash
+table mapping from strings to symbols whose name is that string. (I say
+"poorly implemented" because an obarray appears in Lisp as a vector
+with some hidden fields rather than as its own opaque type. This is an
+Emacs Lisp artifact that should be fixed.)
+
+ Obarrays are implemented as a vector of some fixed size (which should
+be a prime for best results), where each "bucket" of the vector
+contains one or more symbols, threaded through a hidden `next' field in
+the symbol. Lookup of a symbol in an obarray, and adding a symbol to
+an obarray, is accomplished through standard hash-table techniques.
+
+ The standard Lisp function for working with symbols and obarrays is
+`intern'. This looks up a symbol in an obarray given its name; if it's
+not found, a new symbol is automatically created with the specified
+name, added to the obarray, and returned. This is what happens when the
+Lisp reader encounters a symbol (or more precisely, encounters the name
+of a symbol) in some text that it is reading. There is a standard
+obarray called `obarray' that is used for this purpose, although the
+Lisp programmer is free to create his own obarrays and `intern' symbols
+in them.
+
+ Note that, once a symbol is in an obarray, it stays there until
+something is done about it, and the standard obarray `obarray' always
+stays around, so once you use any particular variable name, a
+corresponding symbol will stay around in `obarray' until you exit
+XEmacs.
+
+ Note that `obarray' itself is a variable, and as such there is a
+symbol in `obarray' whose name is `"obarray"' and which contains
+`obarray' as its value.
+
+ Note also that this call to `intern' occurs only when in the Lisp
+reader, not when the code is executed (at which point the symbol is
+already around, stored as such in the definition of the function).
+
+ You can create your own obarray using `make-vector' (this is
+horrible but is an artifact) and intern symbols into that obarray.
+Doing that will result in two or more symbols with the same name.
+However, at most one of these symbols is in the standard `obarray': You
+cannot have two symbols of the same name in any particular obarray.
+Note that you cannot add a symbol to an obarray in any fashion other
+than using `intern': i.e. you can't take an existing symbol and put it
+in an existing obarray. Nor can you change the name of an existing
+symbol. (Since obarrays are vectors, you can violate the consistency of
+things by storing directly into the vector, but let's ignore that
+possibility.)
+
+ Usually symbols are created by `intern', but if you really want, you
+can explicitly create a symbol using `make-symbol', giving it some
+name. The resulting symbol is not in any obarray (i.e. it is
+"uninterned"), and you can't add it to any obarray. Therefore its
+primary purpose is as a symbol to use in macros to avoid namespace
+pollution. It can also be used as a carrier of information, but cons
+cells could probably be used just as well.
+
+ You can also use `intern-soft' to look up a symbol but not create a
+new one, and `unintern' to remove a symbol from an obarray. This
+returns the removed symbol. (Remember: You can't put the symbol back
+into any obarray.) Finally, `mapatoms' maps over all of the symbols in
+an obarray.
+
+\1f
+File: internals.info, Node: Symbol Values, Prev: Obarrays, Up: Symbols and Variables
+
+Symbol Values
+=============
+
+ The value field of a symbol normally contains a Lisp object.
+However, a symbol can be "unbound", meaning that it logically has no
+value. This is internally indicated by storing a special Lisp object,
+called "the unbound marker" and stored in the global variable
+`Qunbound'. The unbound marker is of a special Lisp object type called
+"symbol-value-magic". It is impossible for the Lisp programmer to
+directly create or access any object of this type.
+
+ *You must not let any "symbol-value-magic" object escape to the Lisp
+level.* Printing any of these objects will cause the message `INTERNAL
+EMACS BUG' to appear as part of the print representation. (You may see
+this normally when you call `debug_print()' from the debugger on a Lisp
+object.) If you let one of these objects escape to the Lisp level, you
+will violate a number of assumptions contained in the C code and make
+the unbound marker not function right.
+
+ When a symbol is created, its value field (and function field) are
+set to `Qunbound'. The Lisp programmer can restore these conditions
+later using `makunbound' or `fmakunbound', and can query to see whether
+the value of function fields are "bound" (i.e. have a value other than
+`Qunbound') using `boundp' and `fboundp'. The fields are set to a
+normal Lisp object using `set' (or `setq') and `fset'.
+
+ Other symbol-value-magic objects are used as special markers to
+indicate variables that have non-normal properties. This includes any
+variables that are tied into C variables (setting the variable magically
+sets some global variable in the C code, and likewise for retrieving the
+variable's value), variables that magically tie into slots in the
+current buffer, variables that are buffer-local, etc. The
+symbol-value-magic object is stored in the value cell in place of a
+normal object, and the code to retrieve a symbol's value (i.e.
+`symbol-value') knows how to do special things with them. This means
+that you should not just fetch the value cell directly if you want a
+symbol's value.
+
+ The exact workings of this are rather complex and involved and are
+well-documented in comments in `buffer.c', `symbols.c', and `lisp.h'.
+
+\1f
+File: internals.info, Node: Buffers and Textual Representation, Next: MULE Character Sets and Encodings, Prev: Symbols and Variables, Up: Top
+
+Buffers and Textual Representation
+**********************************
+
+* Menu:
+
+* Introduction to Buffers:: A buffer holds a block of text such as a file.
+* The Text in a Buffer:: Representation of the text in a buffer.
+* Buffer Lists:: Keeping track of all buffers.
+* Markers and Extents:: Tagging locations within a buffer.
+* Bufbytes and Emchars:: Representation of individual characters.
+* The Buffer Object:: The Lisp object corresponding to a buffer.
+
+\1f
+File: internals.info, Node: Introduction to Buffers, Next: The Text in a Buffer, Prev: Buffers and Textual Representation, Up: Buffers and Textual Representation
+
+Introduction to Buffers
+=======================
+
+ A buffer is logically just a Lisp object that holds some text. In
+this, it is like a string, but a buffer is optimized for frequent
+insertion and deletion, while a string is not. Furthermore:
+
+ 1. Buffers are "permanent" objects, i.e. once you create them, they
+ remain around, and need to be explicitly deleted before they go
+ away.
+
+ 2. Each buffer has a unique name, which is a string. Buffers are
+ normally referred to by name. In this respect, they are like
+ symbols.
+
+ 3. Buffers have a default insertion position, called "point".
+ Inserting text (unless you explicitly give a position) goes at
+ point, and moves point forward past the text. This is what is
+ going on when you type text into Emacs.
+
+ 4. Buffers have lots of extra properties associated with them.
+
+ 5. Buffers can be "displayed". What this means is that there exist a
+ number of "windows", which are objects that correspond to some
+ visible section of your display, and each window has an associated
+ buffer, and the current contents of the buffer are shown in that
+ section of the display. The redisplay mechanism (which takes care
+ of doing this) knows how to look at the text of a buffer and come
+ up with some reasonable way of displaying this. Many of the
+ properties of a buffer control how the buffer's text is displayed.
+
+ 6. One buffer is distinguished and called the "current buffer". It is
+ stored in the variable `current_buffer'. Buffer operations operate
+ on this buffer by default. When you are typing text into a
+ buffer, the buffer you are typing into is always `current_buffer'.
+ Switching to a different window changes the current buffer. Note
+ that Lisp code can temporarily change the current buffer using
+ `set-buffer' (often enclosed in a `save-excursion' so that the
+ former current buffer gets restored when the code is finished).
+ However, calling `set-buffer' will NOT cause a permanent change in
+ the current buffer. The reason for this is that the top-level
+ event loop sets `current_buffer' to the buffer of the selected
+ window, each time it finishes executing a user command.
+
+ Make sure you understand the distinction between "current buffer"
+and "buffer of the selected window", and the distinction between
+"point" of the current buffer and "window-point" of the selected
+window. (This latter distinction is explained in detail in the section
+on windows.)
+
Foundation instead of in the original English.
\1f
-File: internals.info, Node: Obarrays, Next: Symbol Values, Prev: Introduction to Symbols, Up: Symbols and Variables
-
-Obarrays
-========
-
- The identity of symbols with their names is accomplished through a
-structure called an obarray, which is just a poorly-implemented hash
-table mapping from strings to symbols whose name is that string. (I say
-"poorly implemented" because an obarray appears in Lisp as a vector
-with some hidden fields rather than as its own opaque type. This is an
-Emacs Lisp artifact that should be fixed.)
-
- Obarrays are implemented as a vector of some fixed size (which should
-be a prime for best results), where each "bucket" of the vector
-contains one or more symbols, threaded through a hidden `next' field in
-the symbol. Lookup of a symbol in an obarray, and adding a symbol to
-an obarray, is accomplished through standard hash-table techniques.
-
- The standard Lisp function for working with symbols and obarrays is
-`intern'. This looks up a symbol in an obarray given its name; if it's
-not found, a new symbol is automatically created with the specified
-name, added to the obarray, and returned. This is what happens when the
-Lisp reader encounters a symbol (or more precisely, encounters the name
-of a symbol) in some text that it is reading. There is a standard
-obarray called `obarray' that is used for this purpose, although the
-Lisp programmer is free to create his own obarrays and `intern' symbols
-in them.
-
- Note that, once a symbol is in an obarray, it stays there until
-something is done about it, and the standard obarray `obarray' always
-stays around, so once you use any particular variable name, a
-corresponding symbol will stay around in `obarray' until you exit
-XEmacs.
-
- Note that `obarray' itself is a variable, and as such there is a
-symbol in `obarray' whose name is `"obarray"' and which contains
-`obarray' as its value.
-
- Note also that this call to `intern' occurs only when in the Lisp
-reader, not when the code is executed (at which point the symbol is
-already around, stored as such in the definition of the function).
-
- You can create your own obarray using `make-vector' (this is
-horrible but is an artifact) and intern symbols into that obarray.
-Doing that will result in two or more symbols with the same name.
-However, at most one of these symbols is in the standard `obarray': You
-cannot have two symbols of the same name in any particular obarray.
-Note that you cannot add a symbol to an obarray in any fashion other
-than using `intern': i.e. you can't take an existing symbol and put it
-in an existing obarray. Nor can you change the name of an existing
-symbol. (Since obarrays are vectors, you can violate the consistency of
-things by storing directly into the vector, but let's ignore that
-possibility.)
-
- Usually symbols are created by `intern', but if you really want, you
-can explicitly create a symbol using `make-symbol', giving it some
-name. The resulting symbol is not in any obarray (i.e. it is
-"uninterned"), and you can't add it to any obarray. Therefore its
-primary purpose is as a symbol to use in macros to avoid namespace
-pollution. It can also be used as a carrier of information, but cons
-cells could probably be used just as well.
-
- You can also use `intern-soft' to look up a symbol but not create a
-new one, and `unintern' to remove a symbol from an obarray. This
-returns the removed symbol. (Remember: You can't put the symbol back
-into any obarray.) Finally, `mapatoms' maps over all of the symbols in
-an obarray.
-
-\1f
-File: internals.info, Node: Symbol Values, Prev: Obarrays, Up: Symbols and Variables
-
-Symbol Values
-=============
-
- The value field of a symbol normally contains a Lisp object.
-However, a symbol can be "unbound", meaning that it logically has no
-value. This is internally indicated by storing a special Lisp object,
-called "the unbound marker" and stored in the global variable
-`Qunbound'. The unbound marker is of a special Lisp object type called
-"symbol-value-magic". It is impossible for the Lisp programmer to
-directly create or access any object of this type.
-
- *You must not let any "symbol-value-magic" object escape to the Lisp
-level.* Printing any of these objects will cause the message `INTERNAL
-EMACS BUG' to appear as part of the print representation. (You may see
-this normally when you call `debug_print()' from the debugger on a Lisp
-object.) If you let one of these objects escape to the Lisp level, you
-will violate a number of assumptions contained in the C code and make
-the unbound marker not function right.
-
- When a symbol is created, its value field (and function field) are
-set to `Qunbound'. The Lisp programmer can restore these conditions
-later using `makunbound' or `fmakunbound', and can query to see whether
-the value of function fields are "bound" (i.e. have a value other than
-`Qunbound') using `boundp' and `fboundp'. The fields are set to a
-normal Lisp object using `set' (or `setq') and `fset'.
-
- Other symbol-value-magic objects are used as special markers to
-indicate variables that have non-normal properties. This includes any
-variables that are tied into C variables (setting the variable magically
-sets some global variable in the C code, and likewise for retrieving the
-variable's value), variables that magically tie into slots in the
-current buffer, variables that are buffer-local, etc. The
-symbol-value-magic object is stored in the value cell in place of a
-normal object, and the code to retrieve a symbol's value (i.e.
-`symbol-value') knows how to do special things with them. This means
-that you should not just fetch the value cell directly if you want a
-symbol's value.
-
- The exact workings of this are rather complex and involved and are
-well-documented in comments in `buffer.c', `symbols.c', and `lisp.h'.
-
-\1f
-File: internals.info, Node: Buffers and Textual Representation, Next: MULE Character Sets and Encodings, Prev: Symbols and Variables, Up: Top
-
-Buffers and Textual Representation
-**********************************
-
-* Menu:
-
-* Introduction to Buffers:: A buffer holds a block of text such as a file.
-* The Text in a Buffer:: Representation of the text in a buffer.
-* Buffer Lists:: Keeping track of all buffers.
-* Markers and Extents:: Tagging locations within a buffer.
-* Bufbytes and Emchars:: Representation of individual characters.
-* The Buffer Object:: The Lisp object corresponding to a buffer.
-
-\1f
-File: internals.info, Node: Introduction to Buffers, Next: The Text in a Buffer, Prev: Buffers and Textual Representation, Up: Buffers and Textual Representation
-
-Introduction to Buffers
-=======================
-
- A buffer is logically just a Lisp object that holds some text. In
-this, it is like a string, but a buffer is optimized for frequent
-insertion and deletion, while a string is not. Furthermore:
-
- 1. Buffers are "permanent" objects, i.e. once you create them, they
- remain around, and need to be explicitly deleted before they go
- away.
-
- 2. Each buffer has a unique name, which is a string. Buffers are
- normally referred to by name. In this respect, they are like
- symbols.
-
- 3. Buffers have a default insertion position, called "point".
- Inserting text (unless you explicitly give a position) goes at
- point, and moves point forward past the text. This is what is
- going on when you type text into Emacs.
-
- 4. Buffers have lots of extra properties associated with them.
-
- 5. Buffers can be "displayed". What this means is that there exist a
- number of "windows", which are objects that correspond to some
- visible section of your display, and each window has an associated
- buffer, and the current contents of the buffer are shown in that
- section of the display. The redisplay mechanism (which takes care
- of doing this) knows how to look at the text of a buffer and come
- up with some reasonable way of displaying this. Many of the
- properties of a buffer control how the buffer's text is displayed.
-
- 6. One buffer is distinguished and called the "current buffer". It is
- stored in the variable `current_buffer'. Buffer operations operate
- on this buffer by default. When you are typing text into a
- buffer, the buffer you are typing into is always `current_buffer'.
- Switching to a different window changes the current buffer. Note
- that Lisp code can temporarily change the current buffer using
- `set-buffer' (often enclosed in a `save-excursion' so that the
- former current buffer gets restored when the code is finished).
- However, calling `set-buffer' will NOT cause a permanent change in
- the current buffer. The reason for this is that the top-level
- event loop sets `current_buffer' to the buffer of the selected
- window, each time it finishes executing a user command.
-
- Make sure you understand the distinction between "current buffer"
-and "buffer of the selected window", and the distinction between
-"point" of the current buffer and "window-point" of the selected
-window. (This latter distinction is explained in detail in the section
-on windows.)
-
-\1f
File: internals.info, Node: The Text in a Buffer, Next: Buffer Lists, Prev: Introduction to Buffers, Up: Buffers and Textual Representation
The Text in a Buffer
decoding
encoding
+\1f
+File: internals.info, Node: Lstream Functions, Next: Lstream Methods, Prev: Lstream Types, Up: Lstreams
+
+Lstream Functions
+=================
+
+ - Function: Lstream * Lstream_new (Lstream_implementation *IMP, const
+ char *MODE)
+ Allocate and return a new Lstream. This function is not really
+ meant to be called directly; rather, each stream type should
+ provide its own stream creation function, which creates the stream
+ and does any other necessary creation stuff (e.g. opening a file).
+
+ - Function: void Lstream_set_buffering (Lstream *LSTR,
+ Lstream_buffering BUFFERING, int BUFFERING_SIZE)
+ Change the buffering of a stream. See `lstream.h'. By default the
+ buffering is `STREAM_BLOCK_BUFFERED'.
+
+ - Function: int Lstream_flush (Lstream *LSTR)
+ Flush out any pending unwritten data in the stream. Clear any
+ buffered input data. Returns 0 on success, -1 on error.
+
+ - Macro: int Lstream_putc (Lstream *STREAM, int C)
+ Write out one byte to the stream. This is a macro and so it is
+ very efficient. The C argument is only evaluated once but the
+ STREAM argument is evaluated more than once. Returns 0 on
+ success, -1 on error.
+
+ - Macro: int Lstream_getc (Lstream *STREAM)
+ Read one byte from the stream. This is a macro and so it is very
+ efficient. The STREAM argument is evaluated more than once.
+ Return value is -1 for EOF or error.
+
+ - Macro: void Lstream_ungetc (Lstream *STREAM, int C)
+ Push one byte back onto the input queue. This will be the next
+ byte read from the stream. Any number of bytes can be pushed back
+ and will be read in the reverse order they were pushed back--most
+ recent first. (This is necessary for consistency--if there are a
+ number of bytes that have been unread and I read and unread a
+ byte, it needs to be the first to be read again.) This is a macro
+ and so it is very efficient. The C argument is only evaluated
+ once but the STREAM argument is evaluated more than once.
+
+ - Function: int Lstream_fputc (Lstream *STREAM, int C)
+ - Function: int Lstream_fgetc (Lstream *STREAM)
+ - Function: void Lstream_fungetc (Lstream *STREAM, int C)
+ Function equivalents of the above macros.
+
+ - Function: ssize_t Lstream_read (Lstream *STREAM, void *DATA, size_t
+ SIZE)
+ Read SIZE bytes of DATA from the stream. Return the number of
+ bytes read. 0 means EOF. -1 means an error occurred and no bytes
+ were read.
+
+ - Function: ssize_t Lstream_write (Lstream *STREAM, void *DATA, size_t
+ SIZE)
+ Write SIZE bytes of DATA to the stream. Return the number of
+ bytes written. -1 means an error occurred and no bytes were
+ written.
+
+ - Function: void Lstream_unread (Lstream *STREAM, void *DATA, size_t
+ SIZE)
+ Push back SIZE bytes of DATA onto the input queue. The next call
+ to `Lstream_read()' with the same size will read the same bytes
+ back. Note that this will be the case even if there is other
+ pending unread data.
+
+ - Function: int Lstream_close (Lstream *STREAM)
+ Close the stream. All data will be flushed out.
+
+ - Function: void Lstream_reopen (Lstream *STREAM)
+ Reopen a closed stream. This enables I/O on it again. This is not
+ meant to be called except from a wrapper routine that reinitializes
+ variables and such--the close routine may well have freed some
+ necessary storage structures, for example.
+
+ - Function: void Lstream_rewind (Lstream *STREAM)
+ Rewind the stream to the beginning.
+
+\1f
+File: internals.info, Node: Lstream Methods, Prev: Lstream Functions, Up: Lstreams
+
+Lstream Methods
+===============
+
+ - Lstream Method: ssize_t reader (Lstream *STREAM, unsigned char
+ *DATA, size_t SIZE)
+ Read some data from the stream's end and store it into DATA, which
+ can hold SIZE bytes. Return the number of bytes read. A return
+ value of 0 means no bytes can be read at this time. This may be
+ because of an EOF, or because there is a granularity greater than
+ one byte that the stream imposes on the returned data, and SIZE is
+ less than this granularity. (This will happen frequently for
+ streams that need to return whole characters, because
+ `Lstream_read()' calls the reader function repeatedly until it has
+ the number of bytes it wants or until 0 is returned.) The lstream
+ functions do not treat a 0 return as EOF or do anything special;
+ however, the calling function will interpret any 0 it gets back as
+ EOF. This will normally not happen unless the caller calls
+ `Lstream_read()' with a very small size.
+
+ This function can be `NULL' if the stream is output-only.
+
+ - Lstream Method: ssize_t writer (Lstream *STREAM, const unsigned char
+ *DATA, size_t SIZE)
+ Send some data to the stream's end. Data to be sent is in DATA
+ and is SIZE bytes. Return the number of bytes sent. This
+ function can send and return fewer bytes than is passed in; in that
+ case, the function will just be called again until there is no
+ data left or 0 is returned. A return value of 0 means that no
+ more data can be currently stored, but there is no error; the data
+ will be squirreled away until the writer can accept data. (This is
+ useful, e.g., if you're dealing with a non-blocking file
+ descriptor and are getting `EWOULDBLOCK' errors.) This function
+ can be `NULL' if the stream is input-only.
+
+ - Lstream Method: int rewinder (Lstream *STREAM)
+ Rewind the stream. If this is `NULL', the stream is not seekable.
+
+ - Lstream Method: int seekable_p (Lstream *STREAM)
+ Indicate whether this stream is seekable--i.e. it can be rewound.
+ This method is ignored if the stream does not have a rewind
+ method. If this method is not present, the result is determined
+ by whether a rewind method is present.
+
+ - Lstream Method: int flusher (Lstream *STREAM)
+ Perform any additional operations necessary to flush the data in
+ this stream.
+
+ - Lstream Method: int pseudo_closer (Lstream *STREAM)
+
+ - Lstream Method: int closer (Lstream *STREAM)
+ Perform any additional operations necessary to close this stream
+ down. May be `NULL'. This function is called when
+ `Lstream_close()' is called or when the stream is
+ garbage-collected. When this function is called, all pending data
+ in the stream will already have been written out.
+
+ - Lstream Method: Lisp_Object marker (Lisp_Object LSTREAM, void
+ (*MARKFUN) (Lisp_Object))
+ Mark this object for garbage collection. Same semantics as a
+ standard `Lisp_Object' marker. This function can be `NULL'.
+
+\1f
+File: internals.info, Node: Consoles; Devices; Frames; Windows, Next: The Redisplay Mechanism, Prev: Lstreams, Up: Top
+
+Consoles; Devices; Frames; Windows
+**********************************
+
+* Menu:
+
+* Introduction to Consoles; Devices; Frames; Windows::
+* Point::
+* Window Hierarchy::
+* The Window Object::
+
+\1f
+File: internals.info, Node: Introduction to Consoles; Devices; Frames; Windows, Next: Point, Prev: Consoles; Devices; Frames; Windows, Up: Consoles; Devices; Frames; Windows
+
+Introduction to Consoles; Devices; Frames; Windows
+==================================================
+
+ A window-system window that you see on the screen is called a
+"frame" in Emacs terminology. Each frame is subdivided into one or
+more non-overlapping panes, called (confusingly) "windows". Each
+window displays the text of a buffer in it. (See above on Buffers.) Note
+that buffers and windows are independent entities: Two or more windows
+can be displaying the same buffer (potentially in different locations),
+and a buffer can be displayed in no windows.
+
+ A single display screen that contains one or more frames is called a
+"display". Under most circumstances, there is only one display.
+However, more than one display can exist, for example if you have a
+"multi-headed" console, i.e. one with a single keyboard but multiple
+displays. (Typically in such a situation, the various displays act like
+one large display, in that the mouse is only in one of them at a time,
+and moving the mouse off of one moves it into another.) In some cases,
+the different displays will have different characteristics, e.g. one
+color and one mono.
+
+ XEmacs can display frames on multiple displays. It can even deal
+simultaneously with frames on multiple keyboards (called "consoles" in
+XEmacs terminology). Here is one case where this might be useful: You
+are using XEmacs on your workstation at work, and leave it running.
+Then you go home and dial in on a TTY line, and you can use the
+already-running XEmacs process to display another frame on your local
+TTY.
+
+ Thus, there is a hierarchy console -> display -> frame -> window.
+There is a separate Lisp object type for each of these four concepts.
+Furthermore, there is logically a "selected console", "selected
+display", "selected frame", and "selected window". Each of these
+objects is distinguished in various ways, such as being the default
+object for various functions that act on objects of that type. Note
+that every containing object remembers the "selected" object among the
+objects that it contains: e.g. not only is there a selected window, but
+every frame remembers the last window in it that was selected, and
+changing the selected frame causes the remembered window within it to
+become the selected window. Similar relationships apply for consoles
+to devices and devices to frames.
+
+\1f
+File: internals.info, Node: Point, Next: Window Hierarchy, Prev: Introduction to Consoles; Devices; Frames; Windows, Up: Consoles; Devices; Frames; Windows
+
+Point
+=====
+
+ Recall that every buffer has a current insertion position, called
+"point". Now, two or more windows may be displaying the same buffer,
+and the text cursor in the two windows (i.e. `point') can be in two
+different places. You may ask, how can that be, since each buffer has
+only one value of `point'? The answer is that each window also has a
+value of `point' that is squirreled away in it. There is only one
+selected window, and the value of "point" in that buffer corresponds to
+that window. When the selected window is changed from one window to
+another displaying the same buffer, the old value of `point' is stored
+into the old window's "point" and the value of `point' from the new
+window is retrieved and made the value of `point' in the buffer. This
+means that `window-point' for the selected window is potentially
+inaccurate, and if you want to retrieve the correct value of `point'
+for a window, you must special-case on the selected window and retrieve
+the buffer's point instead. This is related to why
+`save-window-excursion' does not save the selected window's value of
+`point'.
+
Foundation instead of in the original English.
\1f
-File: internals.info, Node: Lstream Functions, Next: Lstream Methods, Prev: Lstream Types, Up: Lstreams
-
-Lstream Functions
-=================
-
- - Function: Lstream * Lstream_new (Lstream_implementation *IMP, const
- char *MODE)
- Allocate and return a new Lstream. This function is not really
- meant to be called directly; rather, each stream type should
- provide its own stream creation function, which creates the stream
- and does any other necessary creation stuff (e.g. opening a file).
-
- - Function: void Lstream_set_buffering (Lstream *LSTR,
- Lstream_buffering BUFFERING, int BUFFERING_SIZE)
- Change the buffering of a stream. See `lstream.h'. By default the
- buffering is `STREAM_BLOCK_BUFFERED'.
-
- - Function: int Lstream_flush (Lstream *LSTR)
- Flush out any pending unwritten data in the stream. Clear any
- buffered input data. Returns 0 on success, -1 on error.
-
- - Macro: int Lstream_putc (Lstream *STREAM, int C)
- Write out one byte to the stream. This is a macro and so it is
- very efficient. The C argument is only evaluated once but the
- STREAM argument is evaluated more than once. Returns 0 on
- success, -1 on error.
-
- - Macro: int Lstream_getc (Lstream *STREAM)
- Read one byte from the stream. This is a macro and so it is very
- efficient. The STREAM argument is evaluated more than once.
- Return value is -1 for EOF or error.
-
- - Macro: void Lstream_ungetc (Lstream *STREAM, int C)
- Push one byte back onto the input queue. This will be the next
- byte read from the stream. Any number of bytes can be pushed back
- and will be read in the reverse order they were pushed back--most
- recent first. (This is necessary for consistency--if there are a
- number of bytes that have been unread and I read and unread a
- byte, it needs to be the first to be read again.) This is a macro
- and so it is very efficient. The C argument is only evaluated
- once but the STREAM argument is evaluated more than once.
-
- - Function: int Lstream_fputc (Lstream *STREAM, int C)
- - Function: int Lstream_fgetc (Lstream *STREAM)
- - Function: void Lstream_fungetc (Lstream *STREAM, int C)
- Function equivalents of the above macros.
-
- - Function: ssize_t Lstream_read (Lstream *STREAM, void *DATA, size_t
- SIZE)
- Read SIZE bytes of DATA from the stream. Return the number of
- bytes read. 0 means EOF. -1 means an error occurred and no bytes
- were read.
-
- - Function: ssize_t Lstream_write (Lstream *STREAM, void *DATA, size_t
- SIZE)
- Write SIZE bytes of DATA to the stream. Return the number of
- bytes written. -1 means an error occurred and no bytes were
- written.
-
- - Function: void Lstream_unread (Lstream *STREAM, void *DATA, size_t
- SIZE)
- Push back SIZE bytes of DATA onto the input queue. The next call
- to `Lstream_read()' with the same size will read the same bytes
- back. Note that this will be the case even if there is other
- pending unread data.
-
- - Function: int Lstream_close (Lstream *STREAM)
- Close the stream. All data will be flushed out.
-
- - Function: void Lstream_reopen (Lstream *STREAM)
- Reopen a closed stream. This enables I/O on it again. This is not
- meant to be called except from a wrapper routine that reinitializes
- variables and such--the close routine may well have freed some
- necessary storage structures, for example.
-
- - Function: void Lstream_rewind (Lstream *STREAM)
- Rewind the stream to the beginning.
-
-\1f
-File: internals.info, Node: Lstream Methods, Prev: Lstream Functions, Up: Lstreams
-
-Lstream Methods
-===============
-
- - Lstream Method: ssize_t reader (Lstream *STREAM, unsigned char
- *DATA, size_t SIZE)
- Read some data from the stream's end and store it into DATA, which
- can hold SIZE bytes. Return the number of bytes read. A return
- value of 0 means no bytes can be read at this time. This may be
- because of an EOF, or because there is a granularity greater than
- one byte that the stream imposes on the returned data, and SIZE is
- less than this granularity. (This will happen frequently for
- streams that need to return whole characters, because
- `Lstream_read()' calls the reader function repeatedly until it has
- the number of bytes it wants or until 0 is returned.) The lstream
- functions do not treat a 0 return as EOF or do anything special;
- however, the calling function will interpret any 0 it gets back as
- EOF. This will normally not happen unless the caller calls
- `Lstream_read()' with a very small size.
-
- This function can be `NULL' if the stream is output-only.
-
- - Lstream Method: ssize_t writer (Lstream *STREAM, const unsigned char
- *DATA, size_t SIZE)
- Send some data to the stream's end. Data to be sent is in DATA
- and is SIZE bytes. Return the number of bytes sent. This
- function can send and return fewer bytes than is passed in; in that
- case, the function will just be called again until there is no
- data left or 0 is returned. A return value of 0 means that no
- more data can be currently stored, but there is no error; the data
- will be squirreled away until the writer can accept data. (This is
- useful, e.g., if you're dealing with a non-blocking file
- descriptor and are getting `EWOULDBLOCK' errors.) This function
- can be `NULL' if the stream is input-only.
-
- - Lstream Method: int rewinder (Lstream *STREAM)
- Rewind the stream. If this is `NULL', the stream is not seekable.
-
- - Lstream Method: int seekable_p (Lstream *STREAM)
- Indicate whether this stream is seekable--i.e. it can be rewound.
- This method is ignored if the stream does not have a rewind
- method. If this method is not present, the result is determined
- by whether a rewind method is present.
-
- - Lstream Method: int flusher (Lstream *STREAM)
- Perform any additional operations necessary to flush the data in
- this stream.
-
- - Lstream Method: int pseudo_closer (Lstream *STREAM)
-
- - Lstream Method: int closer (Lstream *STREAM)
- Perform any additional operations necessary to close this stream
- down. May be `NULL'. This function is called when
- `Lstream_close()' is called or when the stream is
- garbage-collected. When this function is called, all pending data
- in the stream will already have been written out.
-
- - Lstream Method: Lisp_Object marker (Lisp_Object LSTREAM, void
- (*MARKFUN) (Lisp_Object))
- Mark this object for garbage collection. Same semantics as a
- standard `Lisp_Object' marker. This function can be `NULL'.
-
-\1f
-File: internals.info, Node: Consoles; Devices; Frames; Windows, Next: The Redisplay Mechanism, Prev: Lstreams, Up: Top
-
-Consoles; Devices; Frames; Windows
-**********************************
-
-* Menu:
-
-* Introduction to Consoles; Devices; Frames; Windows::
-* Point::
-* Window Hierarchy::
-* The Window Object::
-
-\1f
-File: internals.info, Node: Introduction to Consoles; Devices; Frames; Windows, Next: Point, Prev: Consoles; Devices; Frames; Windows, Up: Consoles; Devices; Frames; Windows
-
-Introduction to Consoles; Devices; Frames; Windows
-==================================================
-
- A window-system window that you see on the screen is called a
-"frame" in Emacs terminology. Each frame is subdivided into one or
-more non-overlapping panes, called (confusingly) "windows". Each
-window displays the text of a buffer in it. (See above on Buffers.) Note
-that buffers and windows are independent entities: Two or more windows
-can be displaying the same buffer (potentially in different locations),
-and a buffer can be displayed in no windows.
-
- A single display screen that contains one or more frames is called a
-"display". Under most circumstances, there is only one display.
-However, more than one display can exist, for example if you have a
-"multi-headed" console, i.e. one with a single keyboard but multiple
-displays. (Typically in such a situation, the various displays act like
-one large display, in that the mouse is only in one of them at a time,
-and moving the mouse off of one moves it into another.) In some cases,
-the different displays will have different characteristics, e.g. one
-color and one mono.
-
- XEmacs can display frames on multiple displays. It can even deal
-simultaneously with frames on multiple keyboards (called "consoles" in
-XEmacs terminology). Here is one case where this might be useful: You
-are using XEmacs on your workstation at work, and leave it running.
-Then you go home and dial in on a TTY line, and you can use the
-already-running XEmacs process to display another frame on your local
-TTY.
-
- Thus, there is a hierarchy console -> display -> frame -> window.
-There is a separate Lisp object type for each of these four concepts.
-Furthermore, there is logically a "selected console", "selected
-display", "selected frame", and "selected window". Each of these
-objects is distinguished in various ways, such as being the default
-object for various functions that act on objects of that type. Note
-that every containing object rememembers the "selected" object among
-the objects that it contains: e.g. not only is there a selected window,
-but every frame remembers the last window in it that was selected, and
-changing the selected frame causes the remembered window within it to
-become the selected window. Similar relationships apply for consoles
-to devices and devices to frames.
-
-\1f
-File: internals.info, Node: Point, Next: Window Hierarchy, Prev: Introduction to Consoles; Devices; Frames; Windows, Up: Consoles; Devices; Frames; Windows
-
-Point
-=====
-
- Recall that every buffer has a current insertion position, called
-"point". Now, two or more windows may be displaying the same buffer,
-and the text cursor in the two windows (i.e. `point') can be in two
-different places. You may ask, how can that be, since each buffer has
-only one value of `point'? The answer is that each window also has a
-value of `point' that is squirreled away in it. There is only one
-selected window, and the value of "point" in that buffer corresponds to
-that window. When the selected window is changed from one window to
-another displaying the same buffer, the old value of `point' is stored
-into the old window's "point" and the value of `point' from the new
-window is retrieved and made the value of `point' in the buffer. This
-means that `window-point' for the selected window is potentially
-inaccurate, and if you want to retrieve the correct value of `point'
-for a window, you must special-case on the selected window and retrieve
-the buffer's point instead. This is related to why
-`save-window-excursion' does not save the selected window's value of
-`point'.
-
-\1f
File: internals.info, Node: Window Hierarchy, Next: The Window Object, Prev: Point, Up: Consoles; Devices; Frames; Windows
Window Hierarchy
3. Output changes Implemented by `redisplay-output.c',
`redisplay-x.c', `redisplay-msw.c' and `redisplay-tty.c'
- Steps 1 and 2 are device-independant and relatively complex. Step 3
+ Steps 1 and 2 are device-independent and relatively complex. Step 3
is mostly device-dependent.
Determining the desired display
`display_line''s are held by each window representing the current
display and the desired display.
- The `display_line' structures are tighly tied to buffers which
+ The `display_line' structures are tightly tied to buffers which
presents a problem for redisplay as this connection is bogus for the
modeline. Hence the `display_line' generation routines are duplicated
for generating the modeline. This means that the modeline display code
if we create a Pixmap, we can actually display this on multiple windows
- even though we only need a single Pixmap instance to do this. If
caching wasn't done then it would be necessary to create
-image-instances for every displayable occurrance of a glyph - and every
+image-instances for every displayable occurrence of a glyph - and every
usage - and this would be extremely memory and cpu intensive.
Widget-glyphs (a.k.a native widgets) are not cached in this way.
This has desirable properties such as lw_modify_all_widgets which is
called from glyphs-x.c and updates all the properties of a widget
without having to know what the widget is or what toolkit it is from.
-Unfortunately this also has hairy properrties such as making the lwlib
+Unfortunately this also has hairy properties such as making the lwlib
code quite complex. And of course lwlib has to know at some level what
the widget is and how to set its properties.
Not yet documented.
+\1f
+File: internals.info, Node: Index, Prev: Interface to X Windows, Up: Top
+
+Index
+*****
+
+* Menu:
+
+* Amdahl Corporation: XEmacs.
+* Andreessen, Marc: XEmacs.
+* asynchronous subprocesses: Modules for Interfacing with the Operating System.
+* Baur, Steve: XEmacs.
+* Benson, Eric: Lucid Emacs.
+* bridge, playing: XEmacs From the Outside.
+* Buchholz, Martin: XEmacs.
+* Bufbyte: Character-Related Data Types.
+* Bufpos: Character-Related Data Types.
+* Bytecount: Character-Related Data Types.
+* bytecount_to_charcount: Working With Character and Byte Positions.
+* Bytind: Character-Related Data Types.
+* C vs. Lisp: The Lisp Language.
+* caller-protects (GCPRO rule): Writing Lisp Primitives.
+* case table: Modules for Other Aspects of the Lisp Interpreter and Object System.
+* Charcount: Character-Related Data Types.
+* charcount_to_bytecount: Working With Character and Byte Positions.
+* charptr_emchar: Working With Character and Byte Positions.
+* charptr_n_addr: Working With Character and Byte Positions.
+* closer: Lstream Methods.
+* closure: The XEmacs Object System (Abstractly Speaking).
+* Coding for Mule: Coding for Mule.
+* Common Lisp: The Lisp Language.
+* compact_string_chars: compact_string_chars.
+* conservative garbage collection: GCPROing.
+* copy-on-write: General Coding Rules.
+* critical redisplay sections: Critical Redisplay Sections.
+* DEC_CHARPTR: Working With Character and Byte Positions.
+* Devin, Matthieu: Lucid Emacs.
+* display order of extents: Mathematics of Extent Ordering.
+* dynamic array: Low-Level Modules.
+* dynamic scoping: The Lisp Language.
+* dynamic types: The Lisp Language.
+* Emchar: Character-Related Data Types.
+* Energize: Lucid Emacs.
+* Epoch <1>: XEmacs.
+* Epoch: Lucid Emacs.
+* Extbyte: Character-Related Data Types.
+* Extcount: Character-Related Data Types.
+* extent fragment: Extent Fragments.
+* extent mathematics: Mathematics of Extent Ordering.
+* extent ordering: Mathematics of Extent Ordering.
+* extents, display order: Mathematics of Extent Ordering.
+* external widget: Modules for Interfacing with X Windows.
+* flusher: Lstream Methods.
+* Free Software Foundation: A History of Emacs.
+* FSF: A History of Emacs.
+* FSF Emacs <1>: GNU Emacs 20.
+* FSF Emacs: GNU Emacs 19.
+* garbage collection: Garbage Collection.
+* garbage collection protection: Writing Lisp Primitives.
+* garbage collection step by step: Garbage Collection - Step by Step.
+* garbage collection, conservative: GCPROing.
+* garbage collection, invocation: Invocation.
+* garbage_collect_1: garbage_collect_1.
+* gc_sweep: gc_sweep.
+* GNU Emacs 19: GNU Emacs 19.
+* GNU Emacs 20: GNU Emacs 20.
+* Gosling, James <1>: The Lisp Language.
+* Gosling, James: Through Version 18.
+* Great Usenet Renaming: Through Version 18.
+* Hackers (Steven Levy): A History of Emacs.
+* hierarchy of windows: Window Hierarchy.
+* history of Emacs: A History of Emacs.
+* Illinois, University of: XEmacs.
+* INC_CHARPTR: Working With Character and Byte Positions.
+* interactive: Modules for Standard Editing Operations.
+* interning: The XEmacs Object System (Abstractly Speaking).
+* ITS (Incompatible Timesharing System): A History of Emacs.
+* Java: The Lisp Language.
+* Java vs. Lisp: The Lisp Language.
+* Jones, Kyle: XEmacs.
+* Kaplan, Simon: XEmacs.
+* Levy, Steven: A History of Emacs.
+* line start cache: Line Start Cache.
+* Lisp vs. C: The Lisp Language.
+* Lisp vs. Java: The Lisp Language.
+* lstream: Modules for Interfacing with the File System.
+* Lstream_close: Lstream Functions.
+* Lstream_fgetc: Lstream Functions.
+* Lstream_flush: Lstream Functions.
+* Lstream_fputc: Lstream Functions.
+* Lstream_fungetc: Lstream Functions.
+* Lstream_getc: Lstream Functions.
+* Lstream_new: Lstream Functions.
+* Lstream_putc: Lstream Functions.
+* Lstream_read: Lstream Functions.
+* Lstream_reopen: Lstream Functions.
+* Lstream_rewind: Lstream Functions.
+* Lstream_set_buffering: Lstream Functions.
+* Lstream_ungetc: Lstream Functions.
+* Lstream_unread: Lstream Functions.
+* Lstream_write: Lstream Functions.
+* Lucid Emacs: Lucid Emacs.
+* Lucid Inc.: Lucid Emacs.
+* mark and sweep: Garbage Collection.
+* mark method <1>: lrecords.
+* mark method: Modules for Other Aspects of the Lisp Interpreter and Object System.
+* mark_object: mark_object.
+* marker: Lstream Methods.
+* mathematics of extents: Mathematics of Extent Ordering.
+* MAX_EMCHAR_LEN: Working With Character and Byte Positions.
+* merging attempts: XEmacs.
+* MIT: A History of Emacs.
+* Mlynarik, Richard: GNU Emacs 19.
+* MULE merged XEmacs appears: XEmacs.
+* NAS: Modules for Interfacing with the Operating System.
+* native sound: Modules for Interfacing with the Operating System.
+* network connections: Modules for Interfacing with the Operating System.
+* network sound: Modules for Interfacing with the Operating System.
+* Niksic, Hrvoje: XEmacs.
+* pane: Modules for the Basic Displayable Lisp Objects.
+* permanent objects: The XEmacs Object System (Abstractly Speaking).
+* pi, calculating: XEmacs From the Outside.
+* pseudo_closer: Lstream Methods.
+* read syntax: The XEmacs Object System (Abstractly Speaking).
+* read-eval-print: XEmacs From the Outside.
+* reader: Lstream Methods.
+* Redisplay Piece by Piece: Redisplay Piece by Piece.
+* relocating allocator: Low-Level Modules.
+* rename to XEmacs: XEmacs.
+* rewinder: Lstream Methods.
+* RMS: A History of Emacs.
+* scanner: Modules for Other Aspects of the Lisp Interpreter and Object System.
+* scoping, dynamic: The Lisp Language.
+* seekable_p: Lstream Methods.
+* selections: Modules for Interfacing with X Windows.
+* set_charptr_emchar: Working With Character and Byte Positions.
+* Sexton, Harlan: Lucid Emacs.
+* sound, native: Modules for Interfacing with the Operating System.
+* sound, network: Modules for Interfacing with the Operating System.
+* SPARCWorks: XEmacs.
+* Stallman, Richard: A History of Emacs.
+* subprocesses, asynchronous: Modules for Interfacing with the Operating System.
+* subprocesses, synchronous: Modules for Interfacing with the Operating System.
+* Sun Microsystems: XEmacs.
+* sweep_bit_vectors_1: sweep_bit_vectors_1.
+* sweep_lcrecords_1: sweep_lcrecords_1.
+* sweep_strings: sweep_strings.
+* synchronous subprocesses: Modules for Interfacing with the Operating System.
+* taxes, doing: XEmacs From the Outside.
+* TECO: A History of Emacs.
+* temporary objects: The XEmacs Object System (Abstractly Speaking).
+* Thompson, Chuck: XEmacs.
+* types, dynamic: The Lisp Language.
+* University of Illinois: XEmacs.
+* Win-Emacs: XEmacs.
+* window (in Emacs): Modules for the Basic Displayable Lisp Objects.
+* window hierarchy: Window Hierarchy.
+* window point internals: The Window Object.
+* Wing, Ben: XEmacs.
+* writer: Lstream Methods.
+* XEmacs: XEmacs.
+* XEmacs goes it alone: XEmacs.
+* Zawinski, Jamie: Lucid Emacs.
+
+
(*note Backup Names::) is responsible for determining which backup
versions to delete, but does not delete them itself.
- - User Option: trim-versions-without-asking
+ - User Option: delete-old-versions
If this variable is non-`nil', then saving a file deletes excess
backup versions silently. Otherwise, it asks the user whether to
delete them.
* delete-horizontal-space: User-Level Deletion.
* delete-indentation: User-Level Deletion.
* delete-menu-item: Modifying Menus.
+* delete-old-versions: Numbered Backups.
* delete-other-windows: Deleting Windows.
* delete-process: Deleting Processes.
* delete-region: Deletion.
* translate-region: Substitution.
* translating input events: Translating Input.
* transpose-regions: Transposition.
-* trim-versions-without-asking: Numbered Backups.
* true: nil and t.
* truename (of file): Truenames.
* truncate: Numeric Conversions.
* default-input-method: Select Input Method.
* default-major-mode: Choosing Modes.
* delete-auto-save-files: Auto Save Files.
+* delete-old-versions: Backup Deletion.
* describe-function-show-arglist: Help.
* diary-date-forms: Diary Customizing.
* diary-display-hook: Fancy Diary Display.
* today-invisible-calendar-hook: Calendar Customizing.
* today-visible-calendar-hook: Calendar Customizing.
* track-eol: Basic.
-* trim-versions-without-asking: Backup Deletion.
* truncate-lines: Continuation Lines.
* truncate-partial-width-windows: Split Window.
* vc-command-messages: Variables for Check-in/out.
new backup version is made; that newly made backup is included in the
count in `kept-new-versions'. By default, both variables are 2.
- If `trim-versions-without-asking' is non-`nil', excess middle
-versions are deleted without notification. If it is `nil', the
-default, you are asked whether the excess middle versions should really
-be deleted.
+ If `delete-old-versions' is non-`nil', excess middle versions are
+deleted without notification. If it is `nil', the default, you are
+asked whether the excess middle versions should really be deleted.
You can also use Dired's `.' (Period) command to delete old versions.
*Note Dired::.