XEmacs 21.2.29 "Hestia".
authortomo <tomo>
Tue, 2 May 2000 12:32:34 +0000 (12:32 +0000)
committertomo <tomo>
Tue, 2 May 2000 12:32:34 +0000 (12:32 +0000)
info/cl.info-3
info/cl.info-6
info/internals.info-3
info/internals.info-4
info/internals.info-5
info/internals.info-6
info/internals.info-7
info/internals.info-8
info/lispref.info-44

index 1783ddb..6d81217 100644 (file)
@@ -831,7 +831,7 @@ from Emacs Lisp.
 
 * Menu:
 
-* Property Lists::       `remprop', `getf', `remf'
+* Property Lists::       `getf', `remf'
 * Creating Symbols::     `gensym', `gentemp'
 
 \1f
@@ -841,19 +841,9 @@ Property Lists
 ==============
 
 These functions augment the standard Emacs Lisp functions `get' and
-`put' for operating on properties attached to symbols.  There are also
+`put' for operating on properties attached to objects.  There are also
 functions for working with property lists as first-class data
-structures not attached to particular symbols.
-
- - Function: remprop symbol property
-     This function removes the entry for PROPERTY from the property
-     list of SYMBOL.  It returns a true value if the property was
-     indeed found and removed, or `nil' if there was no such property.
-     (This function was probably omitted from Emacs originally because,
-     since `get' did not allow a DEFAULT, it was very difficult to
-     distinguish between a missing property and a property whose value
-     was `nil'; thus, setting a property to `nil' was close enough to
-     `remprop' for most purposes.)
+structures not attached to particular objects.
 
  - Function: getf place property &optional default
      This function scans the list PLACE as if it were a property list,
index a3d0e27..b4d07ac 100644 (file)
@@ -186,7 +186,6 @@ Function Index
 * remove-duplicates:                     Sequence Functions.
 * remove-if:                             Sequence Functions.
 * remove-if-not:                         Sequence Functions.
-* remprop:                               Property Lists.
 * remq:                                  Sequence Functions.
 * replace:                               Sequence Functions.
 * rest:                                  List Functions.
index c6ed97c..7a87402 100644 (file)
@@ -446,7 +446,7 @@ A Summary of the Various XEmacs Modules
 * Modules for Internationalization::
 
 \1f
-File: internals.info,  Node: Low-Level Modules,  Next: Basic Lisp Modules,  Up: A Summary of the Various XEmacs Modules
+File: internals.info,  Node: Low-Level Modules,  Next: Basic Lisp Modules,  Prev: A Summary of the Various XEmacs Modules,  Up: A Summary of the Various XEmacs Modules
 
 Low-Level Modules
 =================
index af2f27c..98c7705 100644 (file)
@@ -597,7 +597,7 @@ method.  None of this code is currently working.
 Asian-language support, and is not currently used.
 
 \1f
-File: internals.info,  Node: Allocation of Objects in XEmacs Lisp,  Next: Events and the Event Loop,  Prev: A Summary of the Various XEmacs Modules,  Up: Top
+File: internals.info,  Node: Allocation of Objects in XEmacs Lisp,  Next: Dumping,  Prev: A Summary of the Various XEmacs Modules,  Up: Top
 
 Allocation of Objects in XEmacs Lisp
 ************************************
@@ -622,7 +622,7 @@ Allocation of Objects in XEmacs Lisp
 * Compiled Function::
 
 \1f
-File: internals.info,  Node: Introduction to Allocation,  Next: Garbage Collection,  Up: Allocation of Objects in XEmacs Lisp
+File: internals.info,  Node: Introduction to Allocation,  Next: Garbage Collection,  Prev: Allocation of Objects in XEmacs Lisp,  Up: Allocation of Objects in XEmacs Lisp
 
 Introduction to Allocation
 ==========================
@@ -937,7 +937,7 @@ Garbage Collection - Step by Step
 * sweep_bit_vectors_1::
 
 \1f
-File: internals.info,  Node: Invocation,  Next: garbage_collect_1,  Up: Garbage Collection - Step by Step
+File: internals.info,  Node: Invocation,  Next: garbage_collect_1,  Prev: Garbage Collection - Step by Step,  Up: Garbage Collection - Step by Step
 
 Invocation
 ----------
index 163f1c5..f25698f 100644 (file)
@@ -238,7 +238,7 @@ 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
+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
@@ -949,58 +949,68 @@ Compiled Function
    Not yet documented.
 
 \1f
-File: internals.info,  Node: Events and the Event Loop,  Next: Evaluation; Stack Frames; Bindings,  Prev: Allocation of Objects in XEmacs Lisp,  Up: Top
-
-Events and the Event Loop
-*************************
+File: internals.info,  Node: Dumping,  Next: Events and the Event Loop,  Prev: Allocation of Objects in XEmacs Lisp,  Up: Top
+
+Dumping
+*******
+
+What is dumping and its justification
+=====================================
+
+   The C code of XEmacs is just a Lisp engine with a lot of built-in
+primitives useful for writing an editor.  The editor itself is written
+mostly in Lisp, and represents around 100K lines of code.  Loading and
+executing the initialization of all this code takes a bit a time (five
+to ten times the usual startup time of current xemacs) and requires
+having all the lisp source files around.  Having to reload them each
+time the editor is started would not be acceptable.
+
+   The traditional solution to this problem is called dumping: the build
+process first creates the lisp engine under the name `temacs', then
+runs it until it has finished loading and initializing all the lisp
+code, and eventually creates a new executable called `xemacs' including
+both the object code in `temacs' and all the contents of the memory
+after the initialization.
+
+   This solution, while working, has a huge problem: the creation of the
+new executable from the actual contents of memory is an extremely
+system-specific process, quite error-prone, and which interferes with a
+lot of system libraries (like malloc).  It is even getting worse
+nowadays with libraries using constructors which are automatically
+called when the program is started (even before main()) which tend to
+crash when they are called multiple times, once before dumping and once
+after (IRIX 6.x libz.so pulls in some C++ image libraries thru
+dependencies which have this problem).  Writing the dumper is also one
+of the most difficult parts of porting XEmacs to a new operating system.
+Basically, `dumping' is an operation that is just not officially
+supported on many operating systems.
+
+   The aim of the portable dumper is to solve the same problem as the
+system-specific dumper, that is to be able to reload quickly, using only
+a small number of files, the fully initialized lisp part of the editor,
+without any system-specific hacks.
 
 * 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::
+* Overview::
+* Data descriptions::
+* Dumping phase::
+* Reloading phase::
+* Remaining issues::
 
 \1f
-File: internals.info,  Node: Introduction to Events,  Next: Main Loop,  Up: Events and the Event Loop
-
-Introduction to Events
-======================
-
-   An event is an object that encapsulates information about an
-interesting occurrence in the operating system.  Events are generated
-either by user action, direct (e.g. typing on the keyboard or moving
-the mouse) or indirect (moving another window, thereby generating an
-expose event on an Emacs frame), or as a result of some other typically
-asynchronous action happening, such as output from a subprocess being
-ready or a timer expiring.  Events come into the system in an
-asynchronous fashion (typically through a callback being called) and
-are converted into a synchronous event queue (first-in, first-out) in a
-process that we will call "collection".
-
-   Note that each application has its own event queue. (It is
-immaterial whether the collection process directly puts the events in
-the proper application's queue, or puts them into a single system
-queue, which is later split up.)
-
-   The most basic level of event collection is done by the operating
-system or window system.  Typically, XEmacs does its own event
-collection as well.  Often there are multiple layers of collection in
-XEmacs, with events from various sources being collected into a queue,
-which is then combined with other sources to go into another queue
-(i.e. a second level of collection), with perhaps another level on top
-of this, etc.
-
-   XEmacs has its own types of events (called "Emacs events"), which
-provides an abstract layer on top of the system-dependent nature of the
-most basic events that are received.  Part of the complex nature of the
-XEmacs event collection process involves converting from the
-operating-system events into the proper Emacs events--there may not be
-a one-to-one correspondence.
-
-   Emacs events are documented in `events.h'; I'll discuss them later.
+File: internals.info,  Node: Overview,  Next: Data descriptions,  Prev: Dumping,  Up: Dumping
+
+Overview
+========
+
+   The portable dumping system has to:
+
+  1. At dump time, write all initialized, non-quickly-rebuildable data
+     to a file [Note: currently named `xemacs.dmp', but the name will
+     change], along with all informations needed for the reloading.
+
+  2. When starting xemacs, reload the dump file, relocate it to its new
+     starting address if needed, and reinitialize all pointers to this
+     data.  Also, rebuild all the quickly rebuildable data.
 
index 66d9da0..cef86b7 100644 (file)
@@ -38,6 +38,368 @@ may be included in a translation approved by the Free Software
 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
+======================
+
+   An event is an object that encapsulates information about an
+interesting occurrence in the operating system.  Events are generated
+either by user action, direct (e.g. typing on the keyboard or moving
+the mouse) or indirect (moving another window, thereby generating an
+expose event on an Emacs frame), or as a result of some other typically
+asynchronous action happening, such as output from a subprocess being
+ready or a timer expiring.  Events come into the system in an
+asynchronous fashion (typically through a callback being called) and
+are converted into a synchronous event queue (first-in, first-out) in a
+process that we will call "collection".
+
+   Note that each application has its own event queue. (It is
+immaterial whether the collection process directly puts the events in
+the proper application's queue, or puts them into a single system
+queue, which is later split up.)
+
+   The most basic level of event collection is done by the operating
+system or window system.  Typically, XEmacs does its own event
+collection as well.  Often there are multiple layers of collection in
+XEmacs, with events from various sources being collected into a queue,
+which is then combined with other sources to go into another queue
+(i.e. a second level of collection), with perhaps another level on top
+of this, etc.
+
+   XEmacs has its own types of events (called "Emacs events"), which
+provides an abstract layer on top of the system-dependent nature of the
+most basic events that are received.  Part of the complex nature of the
+XEmacs event collection process involves converting from the
+operating-system events into the proper Emacs events--there may not be
+a one-to-one correspondence.
+
+   Emacs events are documented in `events.h'; I'll discuss them later.
+
+\1f
 File: internals.info,  Node: Main Loop,  Next: Specifics of the Event Gathering Mechanism,  Prev: Introduction to Events,  Up: Events and the Event Loop
 
 Main Loop
@@ -412,7 +774,7 @@ Evaluation; Stack Frames; Bindings
 * Catch and Throw::
 
 \1f
-File: internals.info,  Node: Evaluation,  Next: Dynamic Binding; The specbinding Stack; Unwind-Protects,  Up: Evaluation; Stack Frames; Bindings
+File: internals.info,  Node: Evaluation,  Next: Dynamic Binding; The specbinding Stack; Unwind-Protects,  Prev: Evaluation; Stack Frames; Bindings,  Up: Evaluation; Stack Frames; Bindings
 
 Evaluation
 ==========
@@ -679,7 +1041,7 @@ Symbols and Variables
 * Symbol Values::
 
 \1f
-File: internals.info,  Node: Introduction to Symbols,  Next: Obarrays,  Up: Symbols and Variables
+File: internals.info,  Node: Introduction to Symbols,  Next: Obarrays,  Prev: Symbols and Variables,  Up: Symbols and Variables
 
 Introduction to Symbols
 =======================
@@ -698,322 +1060,3 @@ property list is used as a more general mechanism of associating
 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,  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
-====================
-
-   The text in a buffer consists of a sequence of zero or more
-characters.  A "character" is an integer that logically represents a
-letter, number, space, or other unit of text.  Most of the characters
-that you will typically encounter belong to the ASCII set of characters,
-but there are also characters for various sorts of accented letters,
-special symbols, Chinese and Japanese ideograms (i.e. Kanji, Katakana,
-etc.), Cyrillic and Greek letters, etc.  The actual number of possible
-characters is quite large.
-
-   For now, we can view a character as some non-negative integer that
-has some shape that defines how it typically appears (e.g. as an
-uppercase A). (The exact way in which a character appears depends on the
-font used to display the character.) The internal type of characters in
-the C code is an `Emchar'; this is just an `int', but using a symbolic
-type makes the code clearer.
-
-   Between every character in a buffer is a "buffer position" or
-"character position".  We can speak of the character before or after a
-particular buffer position, and when you insert a character at a
-particular position, all characters after that position end up at new
-positions.  When we speak of the character "at" a position, we really
-mean the character after the position.  (This schizophrenia between a
-buffer position being "between" a character and "on" a character is
-rampant in Emacs.)
-
-   Buffer positions are numbered starting at 1.  This means that
-position 1 is before the first character, and position 0 is not valid.
-If there are N characters in a buffer, then buffer position N+1 is
-after the last one, and position N+2 is not valid.
-
-   The internal makeup of the Emchar integer varies depending on whether
-we have compiled with MULE support.  If not, the Emchar integer is an
-8-bit integer with possible values from 0 - 255.  0 - 127 are the
-standard ASCII characters, while 128 - 255 are the characters from the
-ISO-8859-1 character set.  If we have compiled with MULE support, an
-Emchar is a 19-bit integer, with the various bits having meanings
-according to a complex scheme that will be detailed later.  The
-characters numbered 0 - 255 still have the same meanings as for the
-non-MULE case, though.
-
-   Internally, the text in a buffer is represented in a fairly simple
-fashion: as a contiguous array of bytes, with a "gap" of some size in
-the middle.  Although the gap is of some substantial size in bytes,
-there is no text contained within it: From the perspective of the text
-in the buffer, it does not exist.  The gap logically sits at some buffer
-position, between two characters (or possibly at the beginning or end of
-the buffer).  Insertion of text in a buffer at a particular position is
-always accomplished by first moving the gap to that position (i.e.
-through some block moving of text), then writing the text into the
-beginning of the gap, thereby shrinking the gap.  If the gap shrinks
-down to nothing, a new gap is created. (What actually happens is that a
-new gap is "created" at the end of the buffer's text, which requires
-nothing more than changing a couple of indices; then the gap is "moved"
-to the position where the insertion needs to take place by moving up in
-memory all the text after that position.)  Similarly, deletion occurs
-by moving the gap to the place where the text is to be deleted, and
-then simply expanding the gap to include the deleted text.
-("Expanding" and "shrinking" the gap as just described means just that
-the internal indices that keep track of where the gap is located are
-changed.)
-
-   Note that the total amount of memory allocated for a buffer text
-never decreases while the buffer is live.  Therefore, if you load up a
-20-megabyte file and then delete all but one character, there will be a
-20-megabyte gap, which won't get any smaller (except by inserting
-characters back again).  Once the buffer is killed, the memory allocated
-for the buffer text will be freed, but it will still be sitting on the
-heap, taking up virtual memory, and will not be released back to the
-operating system. (However, if you have compiled XEmacs with rel-alloc,
-the situation is different.  In this case, the space _will_ be released
-back to the operating system.  However, this tends to result in a
-noticeable speed penalty.)
-
-   Astute readers may notice that the text in a buffer is represented as
-an array of _bytes_, while (at least in the MULE case) an Emchar is a
-19-bit integer, which clearly cannot fit in a byte.  This means (of
-course) that the text in a buffer uses a different representation from
-an Emchar: specifically, the 19-bit Emchar becomes a series of one to
-four bytes.  The conversion between these two representations is complex
-and will be described later.
-
-   In the non-MULE case, everything is very simple: An Emchar is an
-8-bit value, which fits neatly into one byte.
-
-   If we are given a buffer position and want to retrieve the character
-at that position, we need to follow these steps:
-
-  1. Pretend there's no gap, and convert the buffer position into a
-     "byte index" that indexes to the appropriate byte in the buffer's
-     stream of textual bytes.  By convention, byte indices begin at 1,
-     just like buffer positions.  In the non-MULE case, byte indices
-     and buffer positions are identical, since one character equals one
-     byte.
-
-  2. Convert the byte index into a "memory index", which takes the gap
-     into account.  The memory index is a direct index into the block of
-     memory that stores the text of a buffer.  This basically just
-     involves checking to see if the byte index is past the gap, and if
-     so, adding the size of the gap to it.  By convention, memory
-     indices begin at 1, just like buffer positions and byte indices,
-     and when referring to the position that is "at" the gap, we always
-     use the memory position at the _beginning_, not at the end, of the
-     gap.
-
-  3. Fetch the appropriate bytes at the determined memory position.
-
-  4. Convert these bytes into an Emchar.
-
-   In the non-Mule case, (3) and (4) boil down to a simple one-byte
-memory access.
-
-   Note that we have defined three types of positions in a buffer:
-
-  1. "buffer positions" or "character positions", typedef `Bufpos'
-
-  2. "byte indices", typedef `Bytind'
-
-  3. "memory indices", typedef `Memind'
-
-   All three typedefs are just `int's, but defining them this way makes
-things a lot clearer.
-
-   Most code works with buffer positions.  In particular, all Lisp code
-that refers to text in a buffer uses buffer positions.  Lisp code does
-not know that byte indices or memory indices exist.
-
-   Finally, we have a typedef for the bytes in a buffer.  This is a
-`Bufbyte', which is an unsigned char.  Referring to them as Bufbytes
-underscores the fact that we are working with a string of bytes in the
-internal Emacs buffer representation rather than in one of a number of
-possible alternative representations (e.g. EUC-encoded text, etc.).
-
index 2562605..e8f9206 100644 (file)
@@ -38,6 +38,325 @@ may be included in a translation approved by the Free Software
 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
+====================
+
+   The text in a buffer consists of a sequence of zero or more
+characters.  A "character" is an integer that logically represents a
+letter, number, space, or other unit of text.  Most of the characters
+that you will typically encounter belong to the ASCII set of characters,
+but there are also characters for various sorts of accented letters,
+special symbols, Chinese and Japanese ideograms (i.e. Kanji, Katakana,
+etc.), Cyrillic and Greek letters, etc.  The actual number of possible
+characters is quite large.
+
+   For now, we can view a character as some non-negative integer that
+has some shape that defines how it typically appears (e.g. as an
+uppercase A). (The exact way in which a character appears depends on the
+font used to display the character.) The internal type of characters in
+the C code is an `Emchar'; this is just an `int', but using a symbolic
+type makes the code clearer.
+
+   Between every character in a buffer is a "buffer position" or
+"character position".  We can speak of the character before or after a
+particular buffer position, and when you insert a character at a
+particular position, all characters after that position end up at new
+positions.  When we speak of the character "at" a position, we really
+mean the character after the position.  (This schizophrenia between a
+buffer position being "between" a character and "on" a character is
+rampant in Emacs.)
+
+   Buffer positions are numbered starting at 1.  This means that
+position 1 is before the first character, and position 0 is not valid.
+If there are N characters in a buffer, then buffer position N+1 is
+after the last one, and position N+2 is not valid.
+
+   The internal makeup of the Emchar integer varies depending on whether
+we have compiled with MULE support.  If not, the Emchar integer is an
+8-bit integer with possible values from 0 - 255.  0 - 127 are the
+standard ASCII characters, while 128 - 255 are the characters from the
+ISO-8859-1 character set.  If we have compiled with MULE support, an
+Emchar is a 19-bit integer, with the various bits having meanings
+according to a complex scheme that will be detailed later.  The
+characters numbered 0 - 255 still have the same meanings as for the
+non-MULE case, though.
+
+   Internally, the text in a buffer is represented in a fairly simple
+fashion: as a contiguous array of bytes, with a "gap" of some size in
+the middle.  Although the gap is of some substantial size in bytes,
+there is no text contained within it: From the perspective of the text
+in the buffer, it does not exist.  The gap logically sits at some buffer
+position, between two characters (or possibly at the beginning or end of
+the buffer).  Insertion of text in a buffer at a particular position is
+always accomplished by first moving the gap to that position (i.e.
+through some block moving of text), then writing the text into the
+beginning of the gap, thereby shrinking the gap.  If the gap shrinks
+down to nothing, a new gap is created. (What actually happens is that a
+new gap is "created" at the end of the buffer's text, which requires
+nothing more than changing a couple of indices; then the gap is "moved"
+to the position where the insertion needs to take place by moving up in
+memory all the text after that position.)  Similarly, deletion occurs
+by moving the gap to the place where the text is to be deleted, and
+then simply expanding the gap to include the deleted text.
+("Expanding" and "shrinking" the gap as just described means just that
+the internal indices that keep track of where the gap is located are
+changed.)
+
+   Note that the total amount of memory allocated for a buffer text
+never decreases while the buffer is live.  Therefore, if you load up a
+20-megabyte file and then delete all but one character, there will be a
+20-megabyte gap, which won't get any smaller (except by inserting
+characters back again).  Once the buffer is killed, the memory allocated
+for the buffer text will be freed, but it will still be sitting on the
+heap, taking up virtual memory, and will not be released back to the
+operating system. (However, if you have compiled XEmacs with rel-alloc,
+the situation is different.  In this case, the space _will_ be released
+back to the operating system.  However, this tends to result in a
+noticeable speed penalty.)
+
+   Astute readers may notice that the text in a buffer is represented as
+an array of _bytes_, while (at least in the MULE case) an Emchar is a
+19-bit integer, which clearly cannot fit in a byte.  This means (of
+course) that the text in a buffer uses a different representation from
+an Emchar: specifically, the 19-bit Emchar becomes a series of one to
+four bytes.  The conversion between these two representations is complex
+and will be described later.
+
+   In the non-MULE case, everything is very simple: An Emchar is an
+8-bit value, which fits neatly into one byte.
+
+   If we are given a buffer position and want to retrieve the character
+at that position, we need to follow these steps:
+
+  1. Pretend there's no gap, and convert the buffer position into a
+     "byte index" that indexes to the appropriate byte in the buffer's
+     stream of textual bytes.  By convention, byte indices begin at 1,
+     just like buffer positions.  In the non-MULE case, byte indices
+     and buffer positions are identical, since one character equals one
+     byte.
+
+  2. Convert the byte index into a "memory index", which takes the gap
+     into account.  The memory index is a direct index into the block of
+     memory that stores the text of a buffer.  This basically just
+     involves checking to see if the byte index is past the gap, and if
+     so, adding the size of the gap to it.  By convention, memory
+     indices begin at 1, just like buffer positions and byte indices,
+     and when referring to the position that is "at" the gap, we always
+     use the memory position at the _beginning_, not at the end, of the
+     gap.
+
+  3. Fetch the appropriate bytes at the determined memory position.
+
+  4. Convert these bytes into an Emchar.
+
+   In the non-Mule case, (3) and (4) boil down to a simple one-byte
+memory access.
+
+   Note that we have defined three types of positions in a buffer:
+
+  1. "buffer positions" or "character positions", typedef `Bufpos'
+
+  2. "byte indices", typedef `Bytind'
+
+  3. "memory indices", typedef `Memind'
+
+   All three typedefs are just `int's, but defining them this way makes
+things a lot clearer.
+
+   Most code works with buffer positions.  In particular, all Lisp code
+that refers to text in a buffer uses buffer positions.  Lisp code does
+not know that byte indices or memory indices exist.
+
+   Finally, we have a typedef for the bytes in a buffer.  This is a
+`Bufbyte', which is an unsigned char.  Referring to them as Bufbytes
+underscores the fact that we are working with a string of bytes in the
+internal Emacs buffer representation rather than in one of a number of
+possible alternative representations (e.g. EUC-encoded text, etc.).
+
+\1f
 File: internals.info,  Node: Buffer Lists,  Next: Markers and Extents,  Prev: The Text in a Buffer,  Up: Buffers and Textual Representation
 
 Buffer Lists
@@ -248,7 +567,7 @@ representation is that it's compact and is compatible with ASCII.
 * CCL::
 
 \1f
-File: internals.info,  Node: Character Sets,  Next: Encodings,  Up: MULE Character Sets and Encodings
+File: internals.info,  Node: Character Sets,  Next: Encodings,  Prev: MULE Character Sets and Encodings,  Up: MULE Character Sets and Encodings
 
 Character Sets
 ==============
@@ -355,7 +674,7 @@ common usage of "byte").
 * JIS7::
 
 \1f
-File: internals.info,  Node: Japanese EUC (Extended Unix Code),  Next: JIS7,  Up: Encodings
+File: internals.info,  Node: Japanese EUC (Extended Unix Code),  Next: JIS7,  Prev: Encodings,  Up: Encodings
 
 Japanese EUC (Extended Unix Code)
 ---------------------------------
@@ -459,7 +778,7 @@ followed later by the exact details.)
 * Internal Character Encoding::
 
 \1f
-File: internals.info,  Node: Internal String Encoding,  Next: Internal Character Encoding,  Up: Internal Mule Encodings
+File: internals.info,  Node: Internal String Encoding,  Next: Internal Character Encoding,  Prev: Internal Mule Encodings,  Up: Internal Mule Encodings
 
 Internal String Encoding
 ------------------------
@@ -738,7 +1057,7 @@ blocking data together in order to achieve efficiency.
 * Lstream Methods::             Creating new lstream types.
 
 \1f
-File: internals.info,  Node: Creating an Lstream,  Next: Lstream Types,  Up: Lstreams
+File: internals.info,  Node: Creating an Lstream,  Next: Lstream Types,  Prev: Lstreams,  Up: Lstreams
 
 Creating an Lstream
 ===================
@@ -797,421 +1116,3 @@ print
 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,  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
-================
-
-   If a frame contains multiple windows (panes), they are always created
-by splitting an existing window along the horizontal or vertical axis.
-Terminology is a bit confusing here: to "split a window horizontally"
-means to create two side-by-side windows, i.e. to make a _vertical_ cut
-in a window.  Likewise, to "split a window vertically" means to create
-two windows, one above the other, by making a _horizontal_ cut.
-
-   If you split a window and then split again along the same axis, you
-will end up with a number of panes all arranged along the same axis.
-The precise way in which the splits were made should not be important,
-and this is reflected internally.  Internally, all windows are arranged
-in a tree, consisting of two types of windows, "combination" windows
-(which have children, and are covered completely by those children) and
-"leaf" windows, which have no children and are visible.  Every
-combination window has two or more children, all arranged along the same
-axis.  There are (logically) two subtypes of windows, depending on
-whether their children are horizontally or vertically arrayed.  There is
-always one root window, which is either a leaf window (if the frame
-contains only one window) or a combination window (if the frame contains
-more than one window).  In the latter case, the root window will have
-two or more children, either horizontally or vertically arrayed, and
-each of those children will be either a leaf window or another
-combination window.
-
-   Here are some rules:
-
-  1. Horizontal combination windows can never have children that are
-     horizontal combination windows; same for vertical.
-
-  2. Only leaf windows can be split (obviously) and this splitting does
-     one of two things: (a) turns the leaf window into a combination
-     window and creates two new leaf children, or (b) turns the leaf
-     window into one of the two new leaves and creates the other leaf.
-     Rule (1) dictates which of these two outcomes happens.
-
-  3. Every combination window must have at least two children.
-
-  4. Leaf windows can never become combination windows.  They can be
-     deleted, however.  If this results in a violation of (3), the
-     parent combination window also gets deleted.
-
-  5. All functions that accept windows must be prepared to accept
-     combination windows, and do something sane (e.g. signal an error
-     if so).  Combination windows _do_ escape to the Lisp level.
-
-  6. All windows have three fields governing their contents: these are
-     "hchild" (a list of horizontally-arrayed children), "vchild" (a
-     list of vertically-arrayed children), and "buffer" (the buffer
-     contained in a leaf window).  Exactly one of these will be
-     non-nil.  Remember that "horizontally-arrayed" means
-     "side-by-side" and "vertically-arrayed" means "one above the
-     other".
-
-  7. Leaf windows also have markers in their `start' (the first buffer
-     position displayed in the window) and `pointm' (the window's
-     stashed value of `point'--see above) fields, while combination
-     windows have nil in these fields.
-
-  8. The list of children for a window is threaded through the `next'
-     and `prev' fields of each child window.
-
-  9. *Deleted windows can be undeleted*.  This happens as a result of
-     restoring a window configuration, and is unlike frames, displays,
-     and consoles, which, once deleted, can never be restored.
-     Deleting a window does nothing except set a special `dead' bit to
-     1 and clear out the `next', `prev', `hchild', and `vchild' fields,
-     for GC purposes.
-
- 10. Most frames actually have two top-level windows--one for the
-     minibuffer and one (the "root") for everything else.  The modeline
-     (if present) separates these two.  The `next' field of the root
-     points to the minibuffer, and the `prev' field of the minibuffer
-     points to the root.  The other `next' and `prev' fields are `nil',
-     and the frame points to both of these windows.  Minibuffer-less
-     frames have no minibuffer window, and the `next' and `prev' of the
-     root window are `nil'.  Minibuffer-only frames have no root
-     window, and the `next' of the minibuffer window is `nil' but the
-     `prev' points to itself. (#### This is an artifact that should be
-     fixed.)
-
-\1f
-File: internals.info,  Node: The Window Object,  Prev: Window Hierarchy,  Up: Consoles; Devices; Frames; Windows
-
-The Window Object
-=================
-
-   Windows have the following accessible fields:
-
-`frame'
-     The frame that this window is on.
-
-`mini_p'
-     Non-`nil' if this window is a minibuffer window.
-
-`buffer'
-     The buffer that the window is displaying.  This may change often
-     during the life of the window.
-
-`dedicated'
-     Non-`nil' if this window is dedicated to its buffer.
-
-`pointm'
-     This is the value of point in the current buffer when this window
-     is selected; when it is not selected, it retains its previous
-     value.
-
-`start'
-     The position in the buffer that is the first character to be
-     displayed in the window.
-
-`force_start'
-     If this flag is non-`nil', it says that the window has been
-     scrolled explicitly by the Lisp program.  This affects what the
-     next redisplay does if point is off the screen: instead of
-     scrolling the window to show the text around point, it moves point
-     to a location that is on the screen.
-
-`last_modified'
-     The `modified' field of the window's buffer, as of the last time a
-     redisplay completed in this window.
-
-`last_point'
-     The buffer's value of point, as of the last time a redisplay
-     completed in this window.
-
-`left'
-     This is the left-hand edge of the window, measured in columns.
-     (The leftmost column on the screen is column 0.)
-
-`top'
-     This is the top edge of the window, measured in lines.  (The top
-     line on the screen is line 0.)
-
-`height'
-     The height of the window, measured in lines.
-
-`width'
-     The width of the window, measured in columns.
-
-`next'
-     This is the window that is the next in the chain of siblings.  It
-     is `nil' in a window that is the rightmost or bottommost of a
-     group of siblings.
-
-`prev'
-     This is the window that is the previous in the chain of siblings.
-     It is `nil' in a window that is the leftmost or topmost of a group
-     of siblings.
-
-`parent'
-     Internally, XEmacs arranges windows in a tree; each group of
-     siblings has a parent window whose area includes all the siblings.
-     This field points to a window's parent.
-
-     Parent windows do not display buffers, and play little role in
-     display except to shape their child windows.  Emacs Lisp programs
-     usually have no access to the parent windows; they operate on the
-     windows at the leaves of the tree, which actually display buffers.
-
-`hscroll'
-     This is the number of columns that the display in the window is
-     scrolled horizontally to the left.  Normally, this is 0.
-
-`use_time'
-     This is the last time that the window was selected.  The function
-     `get-lru-window' uses this field.
-
-`display_table'
-     The window's display table, or `nil' if none is specified for it.
-
-`update_mode_line'
-     Non-`nil' means this window's mode line needs to be updated.
-
-`base_line_number'
-     The line number of a certain position in the buffer, or `nil'.
-     This is used for displaying the line number of point in the mode
-     line.
-
-`base_line_pos'
-     The position in the buffer for which the line number is known, or
-     `nil' meaning none is known.
-
-`region_showing'
-     If the region (or part of it) is highlighted in this window, this
-     field holds the mark position that made one end of that region.
-     Otherwise, this field is `nil'.
-
index b0c7fbd..dc5125e 100644 (file)
@@ -38,6 +38,424 @@ may be included in a translation approved by the Free Software
 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
+================
+
+   If a frame contains multiple windows (panes), they are always created
+by splitting an existing window along the horizontal or vertical axis.
+Terminology is a bit confusing here: to "split a window horizontally"
+means to create two side-by-side windows, i.e. to make a _vertical_ cut
+in a window.  Likewise, to "split a window vertically" means to create
+two windows, one above the other, by making a _horizontal_ cut.
+
+   If you split a window and then split again along the same axis, you
+will end up with a number of panes all arranged along the same axis.
+The precise way in which the splits were made should not be important,
+and this is reflected internally.  Internally, all windows are arranged
+in a tree, consisting of two types of windows, "combination" windows
+(which have children, and are covered completely by those children) and
+"leaf" windows, which have no children and are visible.  Every
+combination window has two or more children, all arranged along the same
+axis.  There are (logically) two subtypes of windows, depending on
+whether their children are horizontally or vertically arrayed.  There is
+always one root window, which is either a leaf window (if the frame
+contains only one window) or a combination window (if the frame contains
+more than one window).  In the latter case, the root window will have
+two or more children, either horizontally or vertically arrayed, and
+each of those children will be either a leaf window or another
+combination window.
+
+   Here are some rules:
+
+  1. Horizontal combination windows can never have children that are
+     horizontal combination windows; same for vertical.
+
+  2. Only leaf windows can be split (obviously) and this splitting does
+     one of two things: (a) turns the leaf window into a combination
+     window and creates two new leaf children, or (b) turns the leaf
+     window into one of the two new leaves and creates the other leaf.
+     Rule (1) dictates which of these two outcomes happens.
+
+  3. Every combination window must have at least two children.
+
+  4. Leaf windows can never become combination windows.  They can be
+     deleted, however.  If this results in a violation of (3), the
+     parent combination window also gets deleted.
+
+  5. All functions that accept windows must be prepared to accept
+     combination windows, and do something sane (e.g. signal an error
+     if so).  Combination windows _do_ escape to the Lisp level.
+
+  6. All windows have three fields governing their contents: these are
+     "hchild" (a list of horizontally-arrayed children), "vchild" (a
+     list of vertically-arrayed children), and "buffer" (the buffer
+     contained in a leaf window).  Exactly one of these will be
+     non-nil.  Remember that "horizontally-arrayed" means
+     "side-by-side" and "vertically-arrayed" means "one above the
+     other".
+
+  7. Leaf windows also have markers in their `start' (the first buffer
+     position displayed in the window) and `pointm' (the window's
+     stashed value of `point'--see above) fields, while combination
+     windows have nil in these fields.
+
+  8. The list of children for a window is threaded through the `next'
+     and `prev' fields of each child window.
+
+  9. *Deleted windows can be undeleted*.  This happens as a result of
+     restoring a window configuration, and is unlike frames, displays,
+     and consoles, which, once deleted, can never be restored.
+     Deleting a window does nothing except set a special `dead' bit to
+     1 and clear out the `next', `prev', `hchild', and `vchild' fields,
+     for GC purposes.
+
+ 10. Most frames actually have two top-level windows--one for the
+     minibuffer and one (the "root") for everything else.  The modeline
+     (if present) separates these two.  The `next' field of the root
+     points to the minibuffer, and the `prev' field of the minibuffer
+     points to the root.  The other `next' and `prev' fields are `nil',
+     and the frame points to both of these windows.  Minibuffer-less
+     frames have no minibuffer window, and the `next' and `prev' of the
+     root window are `nil'.  Minibuffer-only frames have no root
+     window, and the `next' of the minibuffer window is `nil' but the
+     `prev' points to itself. (#### This is an artifact that should be
+     fixed.)
+
+\1f
+File: internals.info,  Node: The Window Object,  Prev: Window Hierarchy,  Up: Consoles; Devices; Frames; Windows
+
+The Window Object
+=================
+
+   Windows have the following accessible fields:
+
+`frame'
+     The frame that this window is on.
+
+`mini_p'
+     Non-`nil' if this window is a minibuffer window.
+
+`buffer'
+     The buffer that the window is displaying.  This may change often
+     during the life of the window.
+
+`dedicated'
+     Non-`nil' if this window is dedicated to its buffer.
+
+`pointm'
+     This is the value of point in the current buffer when this window
+     is selected; when it is not selected, it retains its previous
+     value.
+
+`start'
+     The position in the buffer that is the first character to be
+     displayed in the window.
+
+`force_start'
+     If this flag is non-`nil', it says that the window has been
+     scrolled explicitly by the Lisp program.  This affects what the
+     next redisplay does if point is off the screen: instead of
+     scrolling the window to show the text around point, it moves point
+     to a location that is on the screen.
+
+`last_modified'
+     The `modified' field of the window's buffer, as of the last time a
+     redisplay completed in this window.
+
+`last_point'
+     The buffer's value of point, as of the last time a redisplay
+     completed in this window.
+
+`left'
+     This is the left-hand edge of the window, measured in columns.
+     (The leftmost column on the screen is column 0.)
+
+`top'
+     This is the top edge of the window, measured in lines.  (The top
+     line on the screen is line 0.)
+
+`height'
+     The height of the window, measured in lines.
+
+`width'
+     The width of the window, measured in columns.
+
+`next'
+     This is the window that is the next in the chain of siblings.  It
+     is `nil' in a window that is the rightmost or bottommost of a
+     group of siblings.
+
+`prev'
+     This is the window that is the previous in the chain of siblings.
+     It is `nil' in a window that is the leftmost or topmost of a group
+     of siblings.
+
+`parent'
+     Internally, XEmacs arranges windows in a tree; each group of
+     siblings has a parent window whose area includes all the siblings.
+     This field points to a window's parent.
+
+     Parent windows do not display buffers, and play little role in
+     display except to shape their child windows.  Emacs Lisp programs
+     usually have no access to the parent windows; they operate on the
+     windows at the leaves of the tree, which actually display buffers.
+
+`hscroll'
+     This is the number of columns that the display in the window is
+     scrolled horizontally to the left.  Normally, this is 0.
+
+`use_time'
+     This is the last time that the window was selected.  The function
+     `get-lru-window' uses this field.
+
+`display_table'
+     The window's display table, or `nil' if none is specified for it.
+
+`update_mode_line'
+     Non-`nil' means this window's mode line needs to be updated.
+
+`base_line_number'
+     The line number of a certain position in the buffer, or `nil'.
+     This is used for displaying the line number of point in the mode
+     line.
+
+`base_line_pos'
+     The position in the buffer for which the line number is known, or
+     `nil' meaning none is known.
+
+`region_showing'
+     If the region (or part of it) is highlighted in this window, this
+     field holds the mark position that made one end of that region.
+     Otherwise, this field is `nil'.
+
+\1f
 File: internals.info,  Node: The Redisplay Mechanism,  Next: Extents,  Prev: Consoles; Devices; Frames; Windows,  Up: Top
 
 The Redisplay Mechanism
@@ -65,7 +483,7 @@ of Redisplay:
 * Redisplay Piece by Piece::
 
 \1f
-File: internals.info,  Node: Critical Redisplay Sections,  Next: Line Start Cache,  Up: The Redisplay Mechanism
+File: internals.info,  Node: Critical Redisplay Sections,  Next: Line Start Cache,  Prev: The Redisplay Mechanism,  Up: The Redisplay Mechanism
 
 Critical Redisplay Sections
 ===========================
@@ -218,11 +636,11 @@ Extents
 * Extent Ordering::             How extents are ordered internally.
 * Format of the Extent Info::   The extent information in a buffer or string.
 * Zero-Length Extents::         A weird special case.
-* Mathematics of Extent Ordering::      A rigorous foundation.
+* Mathematics of Extent Ordering::  A rigorous foundation.
 * Extent Fragments::            Cached information useful for redisplay.
 
 \1f
-File: internals.info,  Node: Introduction to Extents,  Next: Extent Ordering,  Up: Extents
+File: internals.info,  Node: Introduction to Extents,  Next: Extent Ordering,  Prev: Extents,  Up: Extents
 
 Introduction to Extents
 =======================
@@ -701,171 +1119,3 @@ Interface to X Windows
 
    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.
-* frob block:                            Introduction to Allocation.
-* 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.
-* pure space:                            Basic Lisp Modules.
-* read syntax:                           The XEmacs Object System (Abstractly Speaking).
-* read-eval-print:                       XEmacs From the Outside.
-* reader:                                Lstream Methods.
-* record type:                           How Lisp Objects Are Represented in C.
-* 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.
-
-
index e2e76dc..4fae459 100644 (file)
@@ -1514,7 +1514,7 @@ Index
 * generate-new-buffer:                   Creating Buffers.
 * generate-new-buffer-name:              Buffer Names.
 * generic-specifier-p:                   Specifier Types.
-* get:                                   Symbol Plists.
+* get:                                   Object Plists.
 * get-buffer:                            Buffer Names.
 * get-buffer-create:                     Creating Buffers.
 * get-buffer-process:                    Process Buffers.
@@ -2247,6 +2247,7 @@ Index
 * objc-mode-map:                         Standard Keymaps.
 * object:                                Lisp Data Types.
 * object to string:                      Output Functions.
+* object-plist:                          Object Plists.
 * oblique:                               Font Instance Characteristics.
 * obsolete buffer:                       Modification Time.
 * occur-mode-map:                        Standard Keymaps.
@@ -2472,7 +2473,7 @@ Index
 * purecopy:                              Pure Storage.
 * purify-flag:                           Pure Storage.
 * push-mark:                             The Mark.
-* put:                                   Symbol Plists.
+* put:                                   Object Plists.
 * put-char-table:                        Working With Char Tables.
 * put-database:                          Working With a Database.
 * put-range-table:                       Working With Range Tables.
@@ -2587,6 +2588,7 @@ Index
 * remove-range-table:                    Working With Range Tables.
 * remove-specifier:                      Other Specification Functions.
 * remove-text-properties:                Changing Properties.
+* remprop:                               Object Plists.
 * remrassoc:                             Association Lists.
 * remrassq:                              Association Lists.
 * rename-auto-save-file:                 Auto-Saving.
@@ -2795,7 +2797,7 @@ Index
 * setcar:                                Setcar.
 * setcdr:                                Setcdr.
 * setenv:                                System Environment.
-* setplist:                              Symbol Plists.
+* setplist:                              Object Plists.
 * setprv:                                System Environment.
 * setq:                                  Setting Variables.
 * setq-default:                          Default Value.
@@ -2974,7 +2976,7 @@ Index
 * symbol name hashing:                   Creating Symbols.
 * symbol-function:                       Function Cells.
 * symbol-name:                           Creating Symbols.
-* symbol-plist:                          Symbol Plists.
+* symbol-plist:                          Object Plists.
 * symbol-value:                          Accessing Variables.
 * symbolp:                               Symbols.
 * symbol constituent:                    Syntax Class Table.