diff src/lisp.h @ 2367:ecf1ebac70d8

[xemacs-hg @ 2004-11-04 23:05:23 by ben] commit mega-patch configure.in: Turn off -Winline and -Wchar-subscripts. Use the right set of cflags when compiling modules. Rewrite ldap configuration to separate the inclusion of lber (needed in recent Cygwin) from the basic checks for the needed libraries. add a function for MAKE_JUNK_C; initially code was added to generate xemacs.def using this, but it will need to be rewritten. add an rm -f for junk.c to avoid weird Cygwin bug with cp -f onto an existing file. Sort list of auto-detected functions and eliminate unused checks for stpcpy, setlocale and getwd. Add autodetection of Cygwin scanf problems BETA: Rewrite section on configure to indicate what flags are important and what not. digest-doc.c, make-dump-id.c, profile.c, sorted-doc.c: Add proper decls for main(). make-msgfile.c: Document that this is old junk. Move proposal to text.c. make-msgfile.lex: Move proposal to text.c. make-mswin-unicode.pl: Convert error-generating code so that the entire message will be seen as a single unrecognized token. mule/mule-ccl.el: Update docs. lispref/mule.texi: Update CCL docs. ldap/eldap.c: Mule-ize. Use EXTERNAL_LIST_LOOP_2 instead of deleted EXTERNAL_LIST_LOOP. * XEmacs 21.5.18 "chestnut" is released. --------------------------------------------------------------- MULE-RELATED WORK: --------------------------------------------------------------- --------------------------- byte-char conversion --------------------------- buffer.c, buffer.h, insdel.c, text.c: Port FSF algorithm for byte-char conversion, replacing broken previous version. Track the char position of the gap. Add functions to do char-byte conversion downwards as well as upwards. Move comments about algorithm workings to internals manual. --------------------------- work on types --------------------------- alloc.c, console-x-impl.h, dump-data.c, dump-data.h, dumper.c, dialog-msw.c, dired-msw.c, doc.c, editfns.c, esd.c, event-gtk.h, event-msw.c, events.c, file-coding.c, file-coding.h, fns.c, glyphs-eimage.c, glyphs-gtk.c, glyphs-msw.c, glyphs-shared.c, glyphs-x.c, glyphs.c, glyphs.h, gui.c, hpplay.c, imgproc.c, intl-win32.c, lrecord.h, lstream.c, keymap.c, lisp.h, libsst.c, linuxplay.c, miscplay.c, miscplay.h, mule-coding.c, nas.c, nt.c, ntheap.c, ntplay.c, objects-msw.c, objects-tty.c, objects-x.c, print.c, process-nt.c, process.c, redisplay.h, select-common.h, select-gtk.c, select-x.c, sgiplay.c, sound.c, sound.h, sunplay.c, sysfile.h, sysdep.c, syswindows.h, text.c, unexnt.c, win32.c, xgccache.c: Further work on types. This creates a full set of types for all the basic semantics of `char' that I have so far identified, so that its semantics can always be identified for the purposes of proper Mule-safe code, and the raw use of `char' always avoided. (1) More type renaming, for consistency of naming. Char_ASCII -> Ascbyte UChar_ASCII -> UAscbyte Char_Binary -> CBinbyte UChar_Binary -> Binbyte SChar_Binary -> SBinbyte (2) Introduce Rawbyte, CRawbyte, Boolbyte, Chbyte, UChbyte, and Bitbyte and use them. (3) New types Itext, Wexttext and Textcount for separating out the concepts of bytes and textual units (different under UTF-16 and UTF-32, which are potential internal encodings). (4) qxestr*_c -> qxestr*_ascii. lisp.h: New; goes with other qxe() functions. #### Maybe goes in a different section. lisp.h: Group generic int-type defs together with EMACS_INT defs. lisp.h: * lisp.h (WEXTTEXT_IS_WIDE) New defns. lisp.h: New type to replace places where int occurs as a boolean. It's signed because occasionally people may want to use -1 as an error value, and because unsigned ints are viral -- see comments in the internals manual against using them. dynarr.c: int -> Bytecount. --------------------------- Mule-izing --------------------------- device-x.c: Partially Mule-ize. dumper.c, dumper.h: Mule-ize. Use Rawbyte. Use stderr_out not printf. Use wext_*(). sysdep.c, syswindows.h, text.c: New Wexttext API for manipulation of external text that may be Unicode (e.g. startup code under Windows). emacs.c: Mule-ize. Properly deal with argv in external encoding. Use wext_*() and Wexttext. Use Rawbyte. #if 0 some old junk on SCO that is unlikely to be correct. Rewrite allocation code in run-temacs. emacs.c, symsinit.h, win32.c: Rename win32 init function and call it even earlier, to initialize mswindows_9x_p even earlier, for use in startup code (XEUNICODE_P). process.c: Use _wenviron not environ under Windows, to get Unicode environment variables. event-Xt.c: Mule-ize drag-n-drop related stuff. dragdrop.c, dragdrop.h, frame-x.c: Mule-ize. text.h: Add some more stand-in defines for particular kinds of conversion; use in Mule-ization work in frame-x.c etc. --------------------------- Freshening --------------------------- intl-auto-encap-win32.c, intl-auto-encap-win32.h: Regenerate. --------------------------- Unicode-work --------------------------- intl-win32.c, syswindows.h: Factor out common options to MultiByteToWideChar and WideCharToMultiByte. Add convert_unicode_to_multibyte_malloc() and convert_unicode_to_multibyte_dynarr() and use. Add stuff for alloca() conversion of multibyte/unicode. alloc.c: Use dfc_external_data_len() in case of unicode coding system. alloc.c, mule-charset.c: Don't zero out and reinit charset Unicode tables. This fucks up dump-time loading. Anyway, either we load them at dump time or run time, never both. unicode.c: Dump the blank tables as well. --------------------------------------------------------------- DOCUMENTATION, MOSTLY MULE-RELATED: --------------------------------------------------------------- EmacsFrame.c, emodules.c, event-Xt.c, fileio.c, input-method-xlib.c, mule-wnnfns.c, redisplay-gtk.c, redisplay-tty.c, redisplay-x.c, regex.c, sysdep.c: Add comment about Mule work needed. text.h: Add more documentation describing why DFC routines were not written to return their value. Add some other DFC documentation. console-msw.c, console-msw.h: Add pointer to docs in win32.c. emacs.c: Add comments on sources of doc info. text.c, charset.h, unicode.c, intl-win32.c, intl-encap-win32.c, text.h, file-coding.c, mule-coding.c: Collect background comments and related to text matters and internationalization, and proposals for work to be done, in text.c or Internals manual, stuff related to specific textual API's in text.h, and stuff related to internal implementation of Unicode conversion in unicode.c. Put lots of pointers to the comments to make them easier to find. s/mingw32.h, s/win32-common.h, s/win32-native.h, s/windowsnt.h, win32.c: Add bunches of new documentation on the different kinds of builds and environments under Windows and how they work. Collect this info in win32.c. Add pointers to these docs in the relevant s/* files. emacs.c: Document places with long comments. Remove comment about exiting, move to internals manual, put in pointer. event-stream.c: Move docs about event queues and focus to internals manual, put in pointer. events.h: Move docs about event stream callbacks to internals manual, put in pointer. profile.c, redisplay.c, signal.c: Move documentation to the Internals manual. process-nt.c: Add pointer to comment in win32-native.el. lisp.h: Add comments about some comment conventions. lisp.h: Add comment about the second argument. device-msw.c, redisplay-msw.c: @@#### comments are out-of-date. --------------------------------------------------------------- PDUMP WORK (MOTIVATED BY UNICODE CHANGES) --------------------------------------------------------------- alloc.c, buffer.c, bytecode.c, console-impl.h, console.c, device.c, dumper.c, lrecord.h, elhash.c, emodules.h, events.c, extents.c, frame.c, glyphs.c, glyphs.h, mule-charset.c, mule-coding.c, objects.c, profile.c, rangetab.c, redisplay.c, specifier.c, specifier.h, window.c, lstream.c, file-coding.h, file-coding.c: PDUMP: Properly implement dump_add_root_block(), which never worked before, and is necessary for dumping Unicode tables. Pdump name changes for accuracy: XD_STRUCT_PTR -> XD_BLOCK_PTR. XD_STRUCT_ARRAY -> XD_BLOCK_ARRAY. XD_C_STRING -> XD_ASCII_STRING. *_structure_* -> *_block_*. lrecord.h: some comments added about dump_add_root_block() vs dump_add_root_block_ptr(). extents.c: remove incorrect comment about pdump problems with gap array. --------------------------------------------------------------- ALLOCATION --------------------------------------------------------------- abbrev.c, alloc.c, bytecode.c, casefiddle.c, device-msw.c, device-x.c, dired-msw.c, doc.c, doprnt.c, dragdrop.c, editfns.c, emodules.c, file-coding.c, fileio.c, filelock.c, fns.c, glyphs-eimage.c, glyphs-gtk.c, glyphs-msw.c, glyphs-x.c, gui-msw.c, gui-x.c, imgproc.c, intl-win32.c, lread.c, menubar-gtk.c, menubar.c, nt.c, objects-msw.c, objects-x.c, print.c, process-nt.c, process-unix.c, process.c, realpath.c, redisplay.c, search.c, select-common.c, symbols.c, sysdep.c, syswindows.h, text.c, text.h, ui-byhand.c: New macros {alloca,xnew}_{itext,{i,ext,raw,bin,asc}bytes} for more convenient allocation of these commonly requested items. Modify functions to use alloca_ibytes, alloca_array, alloca_extbytes, xnew_ibytes, etc. also XREALLOC_ARRAY, xnew. alloc.c: Rewrite the allocation functions to factor out repeated code. Add assertions for freeing dumped data. lisp.h: Moved down and consolidated with other allocation stuff. lisp.h, dynarr.c: New functions for allocation that's very efficient when mostly in LIFO order. lisp.h, text.c, text.h: Factor out some stuff for general use by alloca()-conversion funs. text.h, lisp.h: Fill out convenience routines for allocating various kinds of bytes and put them in lisp.h. Use them in place of xmalloc(), ALLOCA(). text.h: Fill out the convenience functions so the _MALLOC() kinds match the alloca() kinds. --------------------------------------------------------------- ERROR-CHECKING --------------------------------------------------------------- text.h: Create ASSERT_ASCTEXT_ASCII() and ASSERT_ASCTEXT_ASCII_LEN() from similar Eistring checkers and change the Eistring checkers to use them instead. --------------------------------------------------------------- MACROS IN LISP.H --------------------------------------------------------------- lisp.h: Redo GCPRO declarations. Create a "base" set of functions that can be used to generate any kind of gcpro sets -- regular, ngcpro, nngcpro, private ones used in GC_EXTERNAL_LIST_LOOP_2. buffer.c, callint.c, chartab.c, console-msw.c, device-x.c, dialog-msw.c, dired.c, extents.c, ui-gtk.c, rangetab.c, nt.c, mule-coding.c, minibuf.c, menubar-msw.c, menubar.c, menubar-gtk.c, lread.c, lisp.h, gutter.c, glyphs.c, glyphs-widget.c, fns.c, fileio.c, file-coding.c, specifier.c: Eliminate EXTERNAL_LIST_LOOP, which does not check for circularities. Use EXTERNAL_LIST_LOOP_2 instead or EXTERNAL_LIST_LOOP_3 or EXTERNAL_PROPERTY_LIST_LOOP_3 or GC_EXTERNAL_LIST_LOOP_2 (new macro). Removed/redid comments on EXTERNAL_LIST_LOOP. --------------------------------------------------------------- SPACING FIXES --------------------------------------------------------------- callint.c, hftctl.c, number-gmp.c, process-unix.c: Spacing fixes. --------------------------------------------------------------- FIX FOR GEOMETRY PROBLEM IN FIRST FRAME --------------------------------------------------------------- unicode.c: Add workaround for newlib bug in sscanf() [should be fixed by release 1.5.12 of Cygwin]. toolbar.c: bug fix for problem of initial frame being 77 chars wide on Windows. will be overridden by my other ws. --------------------------------------------------------------- FIX FOR LEAKING PROCESS HANDLES: --------------------------------------------------------------- process-nt.c: Fixes for leaking handles. Inspired by work done by Adrian Aichner <adrian@xemacs.org>. --------------------------------------------------------------- FIX FOR CYGWIN BUG (Unicode-related): --------------------------------------------------------------- unicode.c: Add workaround for newlib bug in sscanf() [should be fixed by release 1.5.12 of Cygwin]. --------------------------------------------------------------- WARNING FIXES: --------------------------------------------------------------- console-stream.c: `reinit' is unused. compiler.h, event-msw.c, frame-msw.c, intl-encap-win32.c, text.h: Add stuff to deal with ANSI-aliasing warnings I got. regex.c: Gather includes together to avoid warning. --------------------------------------------------------------- CHANGES TO INITIALIZATION ROUTINES: --------------------------------------------------------------- buffer.c, emacs.c, console.c, debug.c, device-x.c, device.c, dragdrop.c, emodules.c, eval.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, event-tty.c, events.c, extents.c, faces.c, file-coding.c, fileio.c, font-lock.c, frame-msw.c, glyphs-widget.c, glyphs.c, gui-x.c, insdel.c, lread.c, lstream.c, menubar-gtk.c, menubar-x.c, minibuf.c, mule-wnnfns.c, objects-msw.c, objects.c, print.c, scrollbar-x.c, search.c, select-x.c, text.c, undo.c, unicode.c, window.c, symsinit.h: Call reinit_*() functions directly from emacs.c, for clarity. Factor out some redundant init code. Move disallowed stuff that had crept into vars_of_glyphs() into complex_vars_of_glyphs(). Call init_eval_semi_early() from eval.c not in the middle of vars_of_() in emacs.c since there should be no order dependency in the latter calls. --------------------------------------------------------------- ARMAGEDDON: --------------------------------------------------------------- alloc.c, emacs.c, lisp.h, print.c: Rename inhibit_non_essential_printing_operations to inhibit_non_essential_conversion_operations. text.c: Assert on !inhibit_non_essential_conversion_operations. console-msw.c, print.c: Don't do conversion in SetConsoleTitle or FindWindow to avoid problems during armageddon. Put #errors for NON_ASCII_INTERNAL_FORMAT in places where problems would arise. --------------------------------------------------------------- CHANGES TO THE BUILD PROCEDURE: --------------------------------------------------------------- config.h.in, s/cxux.h, s/usg5-4-2.h, m/powerpc.h: Add comment about correct ordering of this file. Rearrange everything to follow this -- put all #undefs together and before the s&m files. Add undefs for HAVE_ALLOCA, C_ALLOCA, BROKEN_ALLOCA_IN_FUNCTION_CALLS, STACK_DIRECTION. Remove unused HAVE_STPCPY, HAVE_GETWD, HAVE_SETLOCALE. m/gec63.h: Deleted; totally broken, not used at all, not in FSF. m/7300.h, m/acorn.h, m/alliant-2800.h, m/alliant.h, m/altos.h, m/amdahl.h, m/apollo.h, m/att3b.h, m/aviion.h, m/celerity.h, m/clipper.h, m/cnvrgnt.h, m/convex.h, m/cydra5.h, m/delta.h, m/delta88k.h, m/dpx2.h, m/elxsi.h, m/ews4800r.h, m/gould.h, m/hp300bsd.h, m/hp800.h, m/hp9000s300.h, m/i860.h, m/ibmps2-aix.h, m/ibmrs6000.h, m/ibmrt-aix.h, m/ibmrt.h, m/intel386.h, m/iris4d.h, m/iris5d.h, m/iris6d.h, m/irist.h, m/isi-ov.h, m/luna88k.h, m/m68k.h, m/masscomp.h, m/mg1.h, m/mips-nec.h, m/mips-siemens.h, m/mips.h, m/news.h, m/nh3000.h, m/nh4000.h, m/ns32000.h, m/orion105.h, m/pfa50.h, m/plexus.h, m/pmax.h, m/powerpc.h, m/pyrmips.h, m/sequent-ptx.h, m/sequent.h, m/sgi-challenge.h, m/symmetry.h, m/tad68k.h, m/tahoe.h, m/targon31.h, m/tekxd88.h, m/template.h, m/tower32.h, m/tower32v3.h, m/ustation.h, m/vax.h, m/wicat.h, m/xps100.h: Delete C_ALLOCA, HAVE_ALLOCA, STACK_DIRECTION, BROKEN_ALLOCA_IN_FUNCTION_CALLS. All of this is auto-detected. When in doubt, I followed recent FSF sources, which also have these things deleted.
author ben
date Thu, 04 Nov 2004 23:08:28 +0000
parents 61855263cb07
children ab71ad6ff3dd
line wrap: on
line diff
--- a/src/lisp.h	Thu Nov 04 22:51:31 2004 +0000
+++ b/src/lisp.h	Thu Nov 04 23:08:28 2004 +0000
@@ -1,7 +1,7 @@
 /* Fundamental definitions for XEmacs Lisp interpreter.
    Copyright (C) 1985-1987, 1992-1995 Free Software Foundation, Inc.
    Copyright (C) 1993-1996 Richard Mlynarik.
-   Copyright (C) 1995, 1996, 2000, 2001, 2002, 2003 Ben Wing.
+   Copyright (C) 1995, 1996, 2000, 2001, 2002, 2003, 2004 Ben Wing.
 
 This file is part of XEmacs.
 
@@ -57,6 +57,40 @@
 /*			  general definitions				*/
 /************************************************************************/
 
+/* Conventions in comments:
+
+   "Mule-izing" is the process of going through a file and eliminating
+   assumptions that the internal format (Ibyte * text) is the same as the
+   external format used by library routines.  Mule-ization should also
+   include replacing *ALL* raw references to `char' or `unsigned char' with
+   one of the self-documenting types created below.  How exactly to do the
+   conversion, and how to write correctly Mule-ized code, is described in
+   the internals manual.  Files that say "This file is Mule-ized" have
+   been reviewed at some point; that's not to say that incorrect code hasn't
+   crept in, though.
+
+   "Unicode-splitting" is the process of fixing a file so that it will
+   handle external text in Unicode under Microsoft Windows, as appropriate.
+   ("splitting" because it needs to handle either Unicode or variable-width
+   multibyte depending on the OS -- NT or 9x).  See intl-win32.c.
+
+   #### is a way of marking problems of any sort.
+
+   !!#### marks places that are not properly Mule-ized.
+
+   &&#### marks places that need to be fixed in order for the "8-bit mule"
+   conversion to work correctly, i.e. in order to support multiple different
+   buffer formats under Mule, including a fixed 8-bit format.
+
+   ^^#### marks places that need to be fixed in order to eliminate the
+   assumption that Ibyte * text is composed of 1-byte units (e.g. UTF-16
+   is composed of 2-byte units and might be a possible format to consider
+   for Ibyte * text).
+
+   %%#### marks places that need work for KKCC (the new garbage collector).
+
+   */
+
 /* -------------------------- include files --------------------- */
 
 /* We include the following generally useful header files so that you
@@ -133,37 +167,11 @@
 #define trapping_problems_checking_assert_with_message(assertion, msg)
 #endif
 
-/* ------------------------ definition of EMACS_INT ------------------- */
-
-/* EMACS_INT is the underlying integral type into which a Lisp_Object must fit.
-   In particular, it must be large enough to contain a pointer.
-   config.h can override this, e.g. to use `long long' for bigger lisp ints.
-
-   #### In point of fact, it would NOT be a good idea for config.h to mess
-   with EMACS_INT.  A lot of code makes the basic assumption that EMACS_INT
-   is the size of a pointer. */
-
-#ifndef SIZEOF_EMACS_INT
-# define SIZEOF_EMACS_INT SIZEOF_VOID_P
-#endif
-
-#ifndef EMACS_INT
-# if   SIZEOF_EMACS_INT == SIZEOF_LONG
-#  define EMACS_INT long
-# elif SIZEOF_EMACS_INT == SIZEOF_INT
-#  define EMACS_INT int
-# elif SIZEOF_EMACS_INT == SIZEOF_LONG_LONG
-#  define EMACS_INT long long
-# else
-#  error Unable to determine suitable type for EMACS_INT
-# endif
-#endif
-
-#ifndef EMACS_UINT
-# define EMACS_UINT unsigned EMACS_INT
-#endif
-
-#define BITS_PER_EMACS_INT (SIZEOF_EMACS_INT * BITS_PER_CHAR)
+/************************************************************************/
+/**                     Definitions of basic types                     **/
+/************************************************************************/
+
+/* ------------- generic 8/16/32/64/128-bit integral types ------------ */
 
 #if SIZEOF_SHORT == 2
 #define INT_16_BIT short
@@ -223,23 +231,99 @@
 #define EFFICIENT_UINT_128_BIT UINT_128_BIT
 #endif
 
-/* ------------------------ basic char/int typedefs ------------------- */
-
-/* The definitions we put here use typedefs to attribute specific meaning
-   to types that by themselves are pretty general.  Stuff pointed to by a
-   char * or unsigned char * will nearly always be one of four types:
-   a) pointer to internally-formatted text; b) pointer to text in some
-   external format, which can be defined as all formats other than the
-   internal one; c) pure ASCII text; d) binary data that is not meant to
-   be interpreted as text. [A fifth possible type "e) a general pointer
-   to memory" should be replaced with void *.]  Using these more specific
-   types rather than the general ones helps avoid the confusions that
-   occur when the semantics of a char * argument being studied are unclear.
-
-   Note that these typedefs are purely for documentation purposes; from
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif defined (HAVE_INTPTR_T_IN_SYS_TYPES_H)
+/* included elsewhere */
+#elif SIZEOF_VOID_P == SIZEOF_INT
+typedef int intptr_t;
+typedef unsigned int uintptr_t;
+#elif SIZEOF_VOID_P == SIZEOF_LONG
+typedef long intptr_t;
+typedef unsigned long uintptr_t;
+#elif defined (SIZEOF_LONG_LONG) && SIZEOF_VOID_P == SIZEOF_LONG_LONG
+typedef long long intptr_t;
+typedef unsigned long long uintptr_t;
+#else
+/* Just pray. May break, may not. */
+typedef long intptr_t;
+typedef unsigned long uintptr_t;
+#endif
+
+/* ---------------------- definition of EMACS_INT --------------------- */
+
+/* EMACS_INT is the underlying integral type into which a Lisp_Object must fit.
+   In particular, it must be large enough to contain a pointer.
+   config.h can override this, e.g. to use `long long' for bigger lisp ints.
+
+   #### In point of fact, it would NOT be a good idea for config.h to mess
+   with EMACS_INT.  A lot of code makes the basic assumption that EMACS_INT
+   is the size of a pointer. */
+
+#ifndef SIZEOF_EMACS_INT
+# define SIZEOF_EMACS_INT SIZEOF_VOID_P
+#endif
+
+#ifndef EMACS_INT
+# if   SIZEOF_EMACS_INT == SIZEOF_LONG
+#  define EMACS_INT long
+# elif SIZEOF_EMACS_INT == SIZEOF_INT
+#  define EMACS_INT int
+# elif SIZEOF_EMACS_INT == SIZEOF_LONG_LONG
+#  define EMACS_INT long long
+# else
+#  error Unable to determine suitable type for EMACS_INT
+# endif
+#endif
+
+#ifndef EMACS_UINT
+# define EMACS_UINT unsigned EMACS_INT
+#endif
+
+#define BITS_PER_EMACS_INT (SIZEOF_EMACS_INT * BITS_PER_CHAR)
+
+/* -------------------------- basic byte typedefs --------------------- */
+
+/* The definitions we put here and in the next section use typedefs to
+   attribute specific meaning to types that by themselves are pretty
+   general.
+
+   REMEMBER!  These typedefs are purely for documentation purposes; from
    the C code's perspective, they are exactly equivalent to `char *',
    `unsigned char *', etc., so you can freely use them with library
-   functions declared as such. */
+   functions declared as such.
+
+   (See also "Byte/Character Types" in text.c)
+ 
+   The basic semantics for `char':
+
+   a) [Ibyte] pointer to internally-formatted text
+   b) [Extbyte] pointer to text in some external format, which can be
+                defined as all formats other than the internal one
+   c) [Ascbyte] pure ASCII text
+   d) [Binbyte] binary data that is not meant to be interpreted as text
+   e) [Rawbyte] general data in memory, where we don't care about whether
+                it's text or binary
+   f) [Boolbyte] a zero or a one
+   g) [Bitbyte] a byte used for bit fields
+   h) [Chbyte] null-semantics `char *'; used when casting an argument to
+               an external API where the the other types may not be
+               appropriate
+
+
+   Prefixing codes:
+
+   C = plain char, when the base type is unsigned
+   U = unsigned
+   S = signed
+
+   Ideally, XEmacs code should NEVER directly use `char' or any type
+   derived from it.  This is for Mule-cleanliness.  If you find yourself
+   wanting or needing to use `char' and one of the above six semantics does
+   not apply, add a new type of semantics; don't use `char' directly.
+
+   See text.c under "Byte Types", and following sections.
+*/
 
 /* The data representing the text in a buffer is logically a set
    of Ibytes, declared as follows. */
@@ -251,9 +335,10 @@
    are function arguments whose values are most commonly literal strings,
    or where you have to apply a stdlib string function to internal data.
 
-   In general, you should avoid this where possible and use Ibyte instead,
-   for consistency.  For example, the new Mule workspace contains
-   Ibyte versions of the stdlib string functions. */
+   In general, you should avoid this where possible and use Ascbyte if the
+   text is just ASCII (e.g. string literals) or otherwise Ibyte, for
+   consistency.  For example, the new Mule workspace contains Ibyte
+   versions of the stdlib string functions. */
 
 typedef char CIbyte;
 
@@ -266,16 +351,51 @@
 typedef char Extbyte;
 typedef unsigned char UExtbyte;
 
-/* A byte in a string in binary format: */
-typedef char Char_Binary;
-typedef signed char SChar_Binary;
-typedef unsigned char UChar_Binary;
+#define EXTTEXT_ZTERM_SIZE (sizeof (Extbyte))
 
 /* A byte in a string in entirely US-ASCII format: (Nothing outside
  the range 00 - 7F) */
 
-typedef char Char_ASCII;
-typedef unsigned char UChar_ASCII;
+typedef char Ascbyte;
+typedef unsigned char UAscbyte;
+
+/* A generic memory pointer, no text or binary semantics assumed.
+   In general, there should be no manipulation of the memory pointed to
+   by these pointers other than just copying it around. */
+
+typedef unsigned char Rawbyte;
+typedef char CRawbyte;
+
+/* A byte in a string in binary (not meant as text) format: */
+
+typedef unsigned char Binbyte;
+typedef char CBinbyte;
+typedef signed char SBinbyte;
+
+/* A byte used to represent a boolean value: 0 or 1.
+   Normally use plain Boolint, and only use Boolbyte to save space. */
+
+typedef char Boolbyte;
+
+/* A byte composed of bitfields.  Hardly ever used. */
+
+typedef unsigned char Bitbyte;
+
+/* A no-semantics `char'.  Used (pretty-much) ONLY for casting arguments to
+   functions accepting a `char *', `unsigned char *', etc. where the other
+   types don't exactly apply and what you are logically concerned with is
+   the type of the function's argument and not its semantics.
+
+   DO NOT DO NOT DO NOT DO NOT use this as a sloppy replacement for one of
+   the other types.  If you're not using this as part of casting an
+   argument to a function call, and you're not Ben Wing, you're using it
+   wrong.  Go find another one of the types. */
+
+typedef char Chbyte;
+typedef unsigned char UChbyte;
+typedef signed char SChbyte;
+
+/* ------------------------ other text-related typedefs ------------------- */
 
 /* To the user, a buffer is made up of characters.  In the non-Mule world,
    characters and Ibytes are equivalent, restricted to the range 0 - 255.
@@ -309,6 +429,39 @@
 
 typedef int Raw_Ichar;
 
+/* Internal text as a series of textual units (8-bit bytes in the old
+   "Mule" encoding -- still the standard internal encoding -- and in UTF-8,
+   but 16-bit bytes in UTF-16 and 32-bit bytes in UTF-32).  See text.c. */
+
+#ifdef UTF16_IBYTE_FORMAT
+#define NON_ASCII_INTERNAL_FORMAT
+typedef unsigned short Itext;
+#else
+typedef Ibyte Itext;
+#endif
+typedef EMACS_INT Textcount;
+
+#define ITEXT_SIZE (sizeof (Itext))
+/* Use this to emphasize that we are adding space for the zero-terminator */
+#define ITEXT_ZTERM_SIZE ITEXT_SIZE
+
+/* Wexttext is wchar_t on WIN32_NATIVE (and perhaps other systems that
+   support wchar_t's in library functions), and Extbyte otherwise.  This is
+   used whenever we have to do any sort of manipulation of
+   externally-encoded strings -- generally a very bad idea, and unsafe, but
+   in some cases we have no choice (especially at startup, and esp. prior
+   to pdump, where we haven't loaded the Unicode tables necessary for
+   conversion under Windows).  On platforms where the external encoding may
+   be Unicode (i.e. Windows), we always do our manipulations in Unicode,
+   converting to and from multibyte if necessary -- otherwise we'd have to
+   conditionalize on Unicode vs. multibyte all over the place, which is
+   just a nightmare. */
+#ifdef WIN32_NATIVE
+#define WEXTTEXT_IS_WIDE
+typedef wchar_t Wexttext;
+#else
+typedef Extbyte Wexttext;
+#endif
 
 #if !defined (__cplusplus) || !defined (CPLUSPLUS_INTEGRAL_CLASSES_NOT_YET)
 
@@ -797,25 +950,8 @@
 typedef EMACS_INT Elemcount;
 /* Hash codes */
 typedef unsigned long Hashcode;
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif defined(HAVE_INTPTR_T_IN_SYS_TYPES_H)
-/* included elsewhere */
-#elif SIZEOF_VOID_P == SIZEOF_INT
-typedef int intptr_t;
-typedef unsigned int uintptr_t;
-#elif SIZEOF_VOID_P == SIZEOF_LONG
-typedef long intptr_t;
-typedef unsigned long uintptr_t;
-#elif defined(SIZEOF_LONG_LONG) && SIZEOF_VOID_P == SIZEOF_LONG_LONG
-typedef long long intptr_t;
-typedef unsigned long long uintptr_t;
-#else
-/* Just pray. May break, may not. */
-typedef long intptr_t;
-typedef unsigned long uintptr_t;
-#endif
+/* Booleans */
+typedef int Boolint;
 
 /* ------------------------ basic compiler defines ------------------- */
 
@@ -907,7 +1043,7 @@
 #ifdef USE_ASSERTIONS
 /* Highly dubious kludge */
 /*   (thanks, Jamie, I feel better now -- ben) */
-MODULE_API void assert_failed (const char *, int, const char *);
+MODULE_API void assert_failed (const Ascbyte *, int, const Ascbyte *);
 # define abort() (assert_failed (__FILE__, __LINE__, "abort()"))
 # define assert(x) ((x) ? (void) 0 : assert_failed (__FILE__, __LINE__, #x))
 # define assert_with_message(x, msg) \
@@ -926,54 +1062,38 @@
 # endif
 #endif
 
-/* EMACS_INT is the underlying integral type into which a Lisp_Object must fit.
-   In particular, it must be large enough to contain a pointer.
-   config.h can override this, e.g. to use `long long' for bigger lisp ints.
-
-   #### In point of fact, it would NOT be a good idea for config.h to mess
-   with EMACS_INT.  A lot of code makes the basic assumption that EMACS_INT
-   is the size of a pointer. */
-
-#ifndef SIZEOF_EMACS_INT
-# define SIZEOF_EMACS_INT SIZEOF_VOID_P
-#endif
+/************************************************************************/
+/**                         Memory allocation                          **/
+/************************************************************************/
 
 /* ------------------------ simple memory allocation ------------------- */
 
-/* Memory allocation */
-void malloc_warning (const char *);
+/* Basic memory allocation and freeing functions */
+void malloc_warning (const Ascbyte *);
 MODULE_API void *xmalloc (Bytecount size) ATTRIBUTE_MALLOC;
 MODULE_API void *xmalloc_and_zero (Bytecount size) ATTRIBUTE_MALLOC;
 MODULE_API void *xrealloc (void *, Bytecount size) ATTRIBUTE_MALLOC;
-MODULE_API char *xstrdup (const char *) ATTRIBUTE_MALLOC;
-/* generally useful */
-#define countof(x) ((int) (sizeof(x)/sizeof((x)[0])))
-#define xnew(type) ((type *) xmalloc (sizeof (type)))
-#define xnew_array(type, len) ((type *) xmalloc ((len) * sizeof (type)))
-#define xnew_and_zero(type) ((type *) xmalloc_and_zero (sizeof (type)))
-#define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue)))
-#define xnew_array_and_zero(type, len) ((type *) xmalloc_and_zero ((len) * sizeof (type)))
-#define XREALLOC_ARRAY(ptr, type, len) ((void) (ptr = (type *) xrealloc (ptr, (len) * sizeof (type))))
-#define alloca_new(type) ((type *) ALLOCA (sizeof (type)))
-#define alloca_array(type, len) ((type *) ALLOCA ((len) * sizeof (type)))
-
-MODULE_API void *xemacs_c_alloca (unsigned int size) ATTRIBUTE_MALLOC;
-
-MODULE_API int record_unwind_protect_freeing (void *ptr);
-
-DECLARE_INLINE_HEADER (
-void *
-xmalloc_and_record_unwind (Bytecount size)
-)
-{
-  void *ptr = xmalloc (size);
-  record_unwind_protect_freeing (ptr);
-  return ptr;
-}
-
-/* Stack allocation.
-
-   Allocating excessively large blocks on the stack can cause crashes.
+MODULE_API Chbyte *xstrdup (const Chbyte *) ATTRIBUTE_MALLOC;
+
+/* Basic free function */
+
+MODULE_API void xfree_1 (void *);
+#ifdef ERROR_CHECK_MALLOC
+/* This used to use a temporary variable, which both avoided the multiple
+   evaluation and obviated the need for the TYPE argument.  But that triggered
+   complaints under strict aliasing. #### There should be a better way. */
+#define xfree(lvalue, type) do						\
+{									\
+  xfree_1 (lvalue);							\
+  VOIDP_CAST (lvalue) = (void *) 0xDEADBEEF;				\
+} while (0)
+#else
+#define xfree(lvalue,type) xfree_1 (lvalue)
+#endif /* ERROR_CHECK_MALLOC */
+
+/* ------------------------ stack allocation -------------------------- */
+
+/* Allocating excessively large blocks on the stack can cause crashes.
    We provide MALLOC_OR_ALLOCA() below for places where it's likely that
    large amounts will be allocated; it mallocs the block if it's too big.
    Unfortunately, that requires a call to unbind_to() at the end of the
@@ -1047,6 +1167,20 @@
 #define ALLOCA_FUNCALL_OK(size) ALLOCA (size)
 #endif
 
+MODULE_API void *xemacs_c_alloca (unsigned int size) ATTRIBUTE_MALLOC;
+
+MODULE_API int record_unwind_protect_freeing (void *ptr);
+
+DECLARE_INLINE_HEADER (
+void *
+xmalloc_and_record_unwind (Bytecount size)
+)
+{
+  void *ptr = xmalloc (size);
+  record_unwind_protect_freeing (ptr);
+  return ptr;
+}
+
 /* WARNING: If you use this, you must unbind_to() at the end of your
    function! */
 
@@ -1058,6 +1192,46 @@
    (need_to_check_c_alloca ? xemacs_c_alloca (0) : 0,	\
     alloca (__temp_alloca_size__)))
 
+/* -------------- convenience functions for memory allocation ------------- */
+
+#define countof(x) ((int) (sizeof(x)/sizeof((x)[0])))
+#define xnew(type) ((type *) xmalloc (sizeof (type)))
+#define xnew_array(type, len) ((type *) xmalloc ((len) * sizeof (type)))
+#define xnew_and_zero(type) ((type *) xmalloc_and_zero (sizeof (type)))
+#define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue)))
+#define xnew_array_and_zero(type, len) ((type *) xmalloc_and_zero ((len) * sizeof (type)))
+
+#define alloca_new(type) ((type *) ALLOCA (sizeof (type)))
+#define alloca_array(type, len) ((type *) ALLOCA ((len) * sizeof (type)))
+
+#define alloca_itexts(num) alloca_array (Itext, num)
+#define alloca_ibytes(num) alloca_array (Ibyte, num)
+#define alloca_extbytes(num) alloca_array (Extbyte, num)
+#define alloca_rawbytes(num) alloca_array (Rawbyte, num)
+#define alloca_binbytes(num) alloca_array (Binbyte, num)
+#define alloca_ascbytes(num) alloca_array (Ascbyte, num)
+#define xmalloc_itexts(num) xnew_array (Itext, num)
+#define xnew_ibytes(num) xnew_array (Ibyte, num)
+#define xnew_extbytes(num) xnew_array (Extbyte, num)
+#define xnew_rawbytes(num) xnew_array (Rawbyte, num)
+#define xnew_binbytes(num) xnew_array (Binbyte, num)
+#define xnew_ascbytes(num) xnew_array (Ascbyte, num)
+
+/* Make an alloca'd copy of a Ibyte * */
+#define IBYTE_STRING_TO_ALLOCA(p, lval)		\
+do {						\
+  Ibyte **_bsta_ = (Ibyte **) &(lval);		\
+  const Ibyte *_bsta_2 = (p);			\
+  Bytecount _bsta_3 = qxestrlen (_bsta_2);	\
+  *_bsta_ = alloca_ibytes (1 + _bsta_3);	\
+  memcpy (*_bsta_, _bsta_2, 1 + _bsta_3);	\
+} while (0)
+
+/* ----------------- convenience functions for reallocation --------------- */
+
+#define XREALLOC_ARRAY(ptr, type, len) \
+  ((void) (ptr = (type *) xrealloc (ptr, (len) * sizeof (type))))
+
 /* also generally useful if you want to avoid arbitrary size limits
    but don't need a full dynamic array.  Assumes that BASEVAR points
    to a malloced array of TYPE objects (or possibly a NULL pointer,
@@ -1078,17 +1252,6 @@
     }								\
 } while (0)
 
-MODULE_API void xfree_1 (void *);
-#ifdef ERROR_CHECK_MALLOC
-#define xfree(lvalue,type) do			\
-{						\
-  xfree_1 (lvalue);				\
-  lvalue = (type) 0xDEADBEEF;			\
-} while (0)
-#else
-#define xfree(lvalue,type) xfree_1 (lvalue)
-#endif /* ERROR_CHECK_MALLOC */
-
 /* ------------------------ dynamic arrays ------------------- */
 
 #ifdef ERROR_CHECK_STRUCTURES
@@ -1114,7 +1277,7 @@
 } Dynarr;
 
 MODULE_API void *Dynarr_newf (int elsize);
-MODULE_API void Dynarr_resize (void *dy, int size);
+MODULE_API void Dynarr_resize (void *dy, Elemcount size);
 MODULE_API void Dynarr_insert_many (void *d, const void *el, int len, int start);
 MODULE_API void Dynarr_delete_many (void *d, int start, int len);
 MODULE_API void Dynarr_free (void *d);
@@ -1131,7 +1294,7 @@
 #ifdef ERROR_CHECK_STRUCTURES
 DECLARE_INLINE_HEADER (
 Dynarr *
-Dynarr_verify_1 (void *d, const char *file, int line)
+Dynarr_verify_1 (void *d, const Ascbyte *file, int line)
 )
 {
   Dynarr *dy = (Dynarr *) d;
@@ -1142,7 +1305,7 @@
 
 DECLARE_INLINE_HEADER (
 Dynarr *
-Dynarr_verify_mod_1 (void *d, const char *file, int line)
+Dynarr_verify_mod_1 (void *d, const Ascbyte *file, int line)
 )
 {
   Dynarr *dy = (Dynarr *) d;
@@ -1216,7 +1379,12 @@
 Bytecount Dynarr_memory_usage (void *d, struct overhead_stats *stats);
 #endif
 
-/* Counts of bytes or chars */
+void *stack_like_malloc (Bytecount size);
+void stack_like_free (void *val);
+
+/************************************************************************/
+/**                 Definitions of more complex types                  **/
+/************************************************************************/
 
 /* Note that the simplest typedefs are near the top of this file. */
 
@@ -1671,22 +1839,13 @@
    macros will hit an assertion failure if the structure is ill-formed;
    the external-list macros will signal an error in this case, either a
    malformed-list error or a circular-list error.
-
-   Note also that the simplest external list iterator, EXTERNAL_LIST_LOOP,
-   does *NOT* check for circularities.  Therefore, make sure you call
-   QUIT each iteration or so.  However, it's probably easier just to use
-   EXTERNAL_LIST_LOOP_2, which is easier to use in any case.
 */
 
-/* LIST_LOOP and EXTERNAL_LIST_LOOP are the simplest macros.  They don't
-   require brace surrounding, and iterate through a list, which may or may
-   not known to be syntactically correct.  EXTERNAL_LIST_LOOP is for those
-   not known to be correct, and it detects and signals a malformed list
-   error when encountering a problem.  Circularities, however, are not
-   handled, and cause looping forever, so make sure to include a QUIT.
-   These functions also accept two args, TAIL (set progressively to each
-   cons starting with the first), and LIST, the list to iterate over.
-   TAIL needs to be defined by the program.
+/* LIST_LOOP is a simple, old-fashioned macro.  It doesn't require brace
+   surrounding, and iterates through a list, which may or may not known to
+   be syntactically correct.  It accepts two args, TAIL (set progressively
+   to each cons starting with the first), and LIST, the list to iterate
+   over.  TAIL needs to be defined by the caller.
 
    In each iteration, you can retrieve the current list item using XCAR
    (tail), or destructively modify the list using XSETCAR (tail,
@@ -1697,12 +1856,6 @@
        !NILP (tail);			\
        tail = XCDR (tail))
 
-#define EXTERNAL_LIST_LOOP(tail, list)			\
-  for (tail = list; !NILP (tail); tail = XCDR (tail))	\
-     if (!CONSP (tail))					\
-       signal_malformed_list_error (list);		\
-     else
-
 /* The following macros are the "core" macros for list traversal.
 
    *** ALL OF THESE MACROS MUST BE DECLARED INSIDE BRACES -- SEE ABOVE. ***
@@ -1757,6 +1910,22 @@
 PRIVATE_EXTERNAL_LIST_LOOP_6 (elt, list, len_##elt, hare_##elt,		\
 		      tortoise_##elt, CIRCULAR_LIST_SUSPICION_LENGTH)
 
+
+#define GC_EXTERNAL_LIST_LOOP_2(elt, list)				\
+do {									\
+  XGCDECL3 (elt);							\
+  Lisp_Object elt, hare_##elt, tortoise_##elt;				\
+  EMACS_INT len_##elt;							\
+  XGCPRO3 (elt, elt, hare_##elt, tortoise_##elt);			\
+  PRIVATE_EXTERNAL_LIST_LOOP_6 (elt, list, len_##elt, hare_##elt,	\
+				tortoise_##elt,				\
+				CIRCULAR_LIST_SUSPICION_LENGTH)
+
+#define END_GC_EXTERNAL_LIST_LOOP(elt)		\
+  XUNGCPRO (elt);				\
+}						\
+while (0)
+
 #define EXTERNAL_LIST_LOOP_3(elt, list, tail)				\
 Lisp_Object elt, tail, tortoise_##elt;					\
 EMACS_INT len_##elt;							\
@@ -2036,23 +2205,6 @@
 	    ((void) signal_circular_property_list_error (list)) :	\
 	    ((void) 0)))))
 
-/* For a property list (alternating keywords/values) that may not be
-   in valid list format -- will signal an error if the list is not in
-   valid format.  CONSVAR is used to keep track of the iterations
-   without modifying PLIST.
-
-   We have to be tricky to still keep the same C format.*/
-#define EXTERNAL_PROPERTY_LIST_LOOP(tail, key, value, plist)	\
-  for (tail = plist;						\
-       (CONSP (tail) && CONSP (XCDR (tail)) ?			\
-	(key = XCAR (tail), value = XCAR (XCDR (tail))) :	\
-	(key = Qunbound,    value = Qunbound)),			\
-       !NILP (tail);						\
-       tail = XCDR (XCDR (tail)))				\
-    if (UNBOUNDP (key))						\
-      Fsignal (Qmalformed_property_list, list1 (plist));	\
-    else
-
 #define PROPERTY_LIST_LOOP(tail, key, value, plist)	\
   for (tail = plist;					\
        NILP (tail) ? 0 :				\
@@ -2387,7 +2539,7 @@
 
 DECLARE_INLINE_HEADER (
 Ichar
-XCHAR_1 (Lisp_Object obj, const char *file, int line)
+XCHAR_1 (Lisp_Object obj, const Ascbyte *file, int line)
 )
 {
   assert_at_line (CHARP (obj), file, line);
@@ -2455,7 +2607,7 @@
 
 DECLARE_INLINE_HEADER (
 EMACS_INT
-XINT_1 (Lisp_Object obj, const char *file, int line)
+XINT_1 (Lisp_Object obj, const Ascbyte *file, int line)
 )
 {
   assert_at_line (INTP (obj), file, line);
@@ -2464,7 +2616,7 @@
 
 DECLARE_INLINE_HEADER (
 EMACS_INT
-XCHAR_OR_INT_1 (Lisp_Object obj, const char *file, int line)
+XCHAR_OR_INT_1 (Lisp_Object obj, const Ascbyte *file, int line)
 )
 {
   assert_at_line (INTP (obj) || CHARP (obj), file, line);
@@ -3095,114 +3247,93 @@
 
 BEGIN_C_DECLS
 
+#define XGCDECL1(x) struct gcpro x##cpro1
+#define XGCDECL2(x) struct gcpro x##cpro1, x##cpro2
+#define XGCDECL3(x) struct gcpro x##cpro1, x##cpro2, x##cpro3
+#define XGCDECL4(x) struct gcpro x##cpro1, x##cpro2, x##cpro3, x##cpro4
+#define XGCDECL5(x) struct gcpro x##cpro1, x##cpro2, x##cpro3, x##cpro4, x##cpro5
+
 #ifdef DEBUG_GCPRO
 
-MODULE_API void debug_gcpro1 (char *, int, struct gcpro *, Lisp_Object *);
-MODULE_API void debug_gcpro2 (char *, int, struct gcpro *, struct gcpro *,
+MODULE_API void debug_gcpro1 (Ascbyte *, int, struct gcpro *, Lisp_Object *);
+MODULE_API void debug_gcpro2 (Ascbyte *, int, struct gcpro *, struct gcpro *,
 			      Lisp_Object *, Lisp_Object *);
-MODULE_API void debug_gcpro3 (char *, int, struct gcpro *, struct gcpro *,
+MODULE_API void debug_gcpro3 (Ascbyte *, int, struct gcpro *, struct gcpro *,
 			      struct gcpro *, Lisp_Object *, Lisp_Object *,
 			      Lisp_Object *);
-MODULE_API void debug_gcpro4 (char *, int, struct gcpro *, struct gcpro *,
+MODULE_API void debug_gcpro4 (Ascbyte *, int, struct gcpro *, struct gcpro *,
 			      struct gcpro *, struct gcpro *, Lisp_Object *,
 			      Lisp_Object *, Lisp_Object *, Lisp_Object *);
-MODULE_API void debug_gcpro5 (char *, int, struct gcpro *, struct gcpro *,
+MODULE_API void debug_gcpro5 (Ascbyte *, int, struct gcpro *, struct gcpro *,
 			      struct gcpro *, struct gcpro *, struct gcpro *,
 			      Lisp_Object *, Lisp_Object *, Lisp_Object *,
 			      Lisp_Object *, Lisp_Object *);
-MODULE_API void debug_ungcpro(char *, int, struct gcpro *);
-
-#define GCPRO1(v) \
- debug_gcpro1 (__FILE__, __LINE__,&gcpro1,&v)
-#define GCPRO2(v1,v2) \
- debug_gcpro2 (__FILE__, __LINE__,&gcpro1,&gcpro2,&v1,&v2)
-#define GCPRO3(v1,v2,v3) \
- debug_gcpro3 (__FILE__, __LINE__,&gcpro1,&gcpro2,&gcpro3,&v1,&v2,&v3)
-#define GCPRO4(v1,v2,v3,v4) \
- debug_gcpro4 (__FILE__, __LINE__,&gcpro1,&gcpro2,&gcpro3,&gcpro4,\
+MODULE_API void debug_ungcpro(Ascbyte *, int, struct gcpro *);
+
+#define XGCPRO1(x,v)							\
+ debug_gcpro1 (__FILE__, __LINE__,&x##cpro1,&v)
+#define XGCPRO2(x,v1,v2)						\
+ debug_gcpro2 (__FILE__, __LINE__,&x##cpro1,&x##cpro2,&v1,&v2)
+#define XGCPRO3(x,v1,v2,v3)						\
+ debug_gcpro3 (__FILE__, __LINE__,&x##cpro1,&x##cpro2,&x##cpro3,	\
+	       &v1,&v2,&v3)
+#define XGCPRO4(x,v1,v2,v3,v4)						\
+ debug_gcpro4 (__FILE__, __LINE__,&x##cpro1,&x##cpro2,&x##cpro3,	\
+	       &x##cpro4,						\
 	       &v1,&v2,&v3,&v4)
-#define GCPRO5(v1,v2,v3,v4,v5) \
- debug_gcpro5 (__FILE__, __LINE__,&gcpro1,&gcpro2,&gcpro3,&gcpro4,&gcpro5,\
+#define XGCPRO5(x,v1,v2,v3,v4,v5)					\
+ debug_gcpro5 (__FILE__, __LINE__,&x##cpro1,&x##cpro2,&x##cpro3,	\
+	       &x##cpro4,&x##cpro5,					\
 	       &v1,&v2,&v3,&v4,&v5)
-#define UNGCPRO \
- debug_ungcpro(__FILE__, __LINE__,&gcpro1)
-
-#define NGCPRO1(v) \
- debug_gcpro1 (__FILE__, __LINE__,&ngcpro1,&v)
-#define NGCPRO2(v1,v2) \
- debug_gcpro2 (__FILE__, __LINE__,&ngcpro1,&ngcpro2,&v1,&v2)
-#define NGCPRO3(v1,v2,v3) \
- debug_gcpro3 (__FILE__, __LINE__,&ngcpro1,&ngcpro2,&ngcpro3,&v1,&v2,&v3)
-#define NGCPRO4(v1,v2,v3,v4) \
- debug_gcpro4 (__FILE__, __LINE__,&ngcpro1,&ngcpro2,&ngcpro3,&ngcpro4,\
-	       &v1,&v2,&v3,&v4)
-#define NGCPRO5(v1,v2,v3,v4,v5) \
- debug_gcpro5 (__FILE__, __LINE__,&ngcpro1,&ngcpro2,&ngcpro3,&ngcpro4,\
-	       &ngcpro5,&v1,&v2,&v3,&v4,&v5)
-#define NUNGCPRO \
- debug_ungcpro(__FILE__, __LINE__,&ngcpro1)
-
-#define NNGCPRO1(v) \
- debug_gcpro1 (__FILE__, __LINE__,&nngcpro1,&v)
-#define NNGCPRO2(v1,v2) \
- debug_gcpro2 (__FILE__, __LINE__,&nngcpro1,&nngcpro2,&v1,&v2)
-#define NNGCPRO3(v1,v2,v3) \
- debug_gcpro3 (__FILE__, __LINE__,&nngcpro1,&nngcpro2,&nngcpro3,&v1,&v2,&v3)
-#define NNGCPRO4(v1,v2,v3,v4) \
- debug_gcpro4 (__FILE__, __LINE__,&nngcpro1,&nngcpro2,&nngcpro3,&nngcpro4,\
-	       &v1,&v2,&v3,&v4)
-#define NNGCPRO5(v1,v2,v3,v4,v5) \
- debug_gcpro5 (__FILE__, __LINE__,&nngcpro1,&nngcpro2,&nngcpro3,&nngcpro4,\
-	       &nngcpro5,&v1,&v2,&v3,&v4,&v5)
-#define NNUNGCPRO \
- debug_ungcpro(__FILE__, __LINE__,&nngcpro1)
+#define XUNGCPRO(x) \
+ debug_ungcpro(__FILE__, __LINE__,&x##cpro1)
 
 #else /* ! DEBUG_GCPRO */
 
-#define GCPRO1(var1) ((void) (						\
-  gcpro1.next = gcprolist, gcpro1.var = &var1, gcpro1.nvars = 1,	\
-  gcprolist = &gcpro1 ))
-
-#define GCPRO2(var1, var2) ((void) (					\
-  gcpro1.next = gcprolist, gcpro1.var = &var1, gcpro1.nvars = 1,	\
-  gcpro2.next = &gcpro1,   gcpro2.var = &var2, gcpro2.nvars = 1,	\
-  gcprolist = &gcpro2 ))
-
-#define GCPRO3(var1, var2, var3) ((void) (				\
-  gcpro1.next = gcprolist, gcpro1.var = &var1, gcpro1.nvars = 1,	\
-  gcpro2.next = &gcpro1,   gcpro2.var = &var2, gcpro2.nvars = 1,	\
-  gcpro3.next = &gcpro2,   gcpro3.var = &var3, gcpro3.nvars = 1,	\
-  gcprolist = &gcpro3 ))
-
-#define GCPRO4(var1, var2, var3, var4) ((void) (			\
-  gcpro1.next = gcprolist, gcpro1.var = &var1, gcpro1.nvars = 1,	\
-  gcpro2.next = &gcpro1,   gcpro2.var = &var2, gcpro2.nvars = 1,	\
-  gcpro3.next = &gcpro2,   gcpro3.var = &var3, gcpro3.nvars = 1,	\
-  gcpro4.next = &gcpro3,   gcpro4.var = &var4, gcpro4.nvars = 1,	\
-  gcprolist = &gcpro4 ))
-
-#define GCPRO5(var1, var2, var3, var4, var5) ((void) (			\
-  gcpro1.next = gcprolist, gcpro1.var = &var1, gcpro1.nvars = 1,	\
-  gcpro2.next = &gcpro1,   gcpro2.var = &var2, gcpro2.nvars = 1,	\
-  gcpro3.next = &gcpro2,   gcpro3.var = &var3, gcpro3.nvars = 1,	\
-  gcpro4.next = &gcpro3,   gcpro4.var = &var4, gcpro4.nvars = 1,	\
-  gcpro5.next = &gcpro4,   gcpro5.var = &var5, gcpro5.nvars = 1,	\
-  gcprolist = &gcpro5 ))
-
-#define GCPRO1_ARRAY(array, n) ((void) (				\
-  gcpro1.next = gcprolist, gcpro1.var = array, gcpro1.nvars = n,	\
-  gcprolist = &gcpro1 ))
-
-#define GCPRO2_ARRAY(array1, n1, array2, n2) ((void) (			\
-  gcpro1.next = gcprolist, gcpro1.var = array1, gcpro1.nvars = n1,	\
-  gcpro2.next = &gcpro1,   gcpro2.var = array2, gcpro2.nvars = n2,	\
-  gcprolist = &gcpro2 ))
-
-#define GCPRO3_ARRAY(array1, n1, array2, n2, array3, n3) ((void) (	\
-  gcpro1.next = gcprolist, gcpro1.var = array1, gcpro1.nvars = n1,	\
-  gcpro2.next = &gcpro1,   gcpro2.var = array2, gcpro2.nvars = n2,	\
-  gcpro3.next = &gcpro2,   gcpro3.var = array3, gcpro3.nvars = n3,	\
-  gcprolist = &gcpro3 ))
+#define XGCPRO1(x, var1) ((void) (					\
+  x##cpro1.next = gcprolist, x##cpro1.var = &var1, x##cpro1.nvars = 1,	\
+  gcprolist = &x##cpro1 ))
+
+#define XGCPRO2(x, var1, var2) ((void) (				\
+  x##cpro1.next = gcprolist, x##cpro1.var = &var1, x##cpro1.nvars = 1,	\
+  x##cpro2.next = &x##cpro1, x##cpro2.var = &var2, x##cpro2.nvars = 1,	\
+  gcprolist = &x##cpro2 ))
+
+#define XGCPRO3(x, var1, var2, var3) ((void) (				\
+  x##cpro1.next = gcprolist, x##cpro1.var = &var1, x##cpro1.nvars = 1,	\
+  x##cpro2.next = &x##cpro1, x##cpro2.var = &var2, x##cpro2.nvars = 1,	\
+  x##cpro3.next = &x##cpro2, x##cpro3.var = &var3, x##cpro3.nvars = 1,	\
+  gcprolist = &x##cpro3 ))
+
+#define XGCPRO4(x, var1, var2, var3, var4) ((void) (			\
+  x##cpro1.next = gcprolist, x##cpro1.var = &var1, x##cpro1.nvars = 1,	\
+  x##cpro2.next = &x##cpro1, x##cpro2.var = &var2, x##cpro2.nvars = 1,	\
+  x##cpro3.next = &x##cpro2, x##cpro3.var = &var3, x##cpro3.nvars = 1,	\
+  x##cpro4.next = &x##cpro3, x##cpro4.var = &var4, x##cpro4.nvars = 1,	\
+  gcprolist = &x##cpro4 ))
+
+#define XGCPRO5(x, var1, var2, var3, var4, var5) ((void) (		\
+  x##cpro1.next = gcprolist, x##cpro1.var = &var1, x##cpro1.nvars = 1,	\
+  x##cpro2.next = &x##cpro1, x##cpro2.var = &var2, x##cpro2.nvars = 1,	\
+  x##cpro3.next = &x##cpro2, x##cpro3.var = &var3, x##cpro3.nvars = 1,	\
+  x##cpro4.next = &x##cpro3, x##cpro4.var = &var4, x##cpro4.nvars = 1,	\
+  x##cpro5.next = &x##cpro4, x##cpro5.var = &var5, x##cpro5.nvars = 1,	\
+  gcprolist = &x##cpro5 ))
+
+#define XGCPRO1_ARRAY(x, array, n) ((void) (				 \
+  x##cpro1.next = gcprolist,  x##cpro1.var = array,  x##cpro1.nvars = n, \
+  gcprolist = &x##cpro1 ))
+
+#define XGCPRO2_ARRAY(x, array1, n1, array2, n2) ((void) (		  \
+  x##cpro1.next = gcprolist,  x##cpro1.var = array1, x##cpro1.nvars = n1, \
+  x##cpro2.next = &x##cpro1, x##cpro2.var = array2, x##cpro2.nvars = n2,  \
+  gcprolist = &x##cpro2 ))
+
+#define XGCPRO3_ARRAY(x, array1, n1, array2, n2, array3, n3) ((void) (	  \
+  x##cpro1.next = gcprolist,  x##cpro1.var = array1, x##cpro1.nvars = n1, \
+  x##cpro2.next = &x##cpro1, x##cpro2.var = array2, x##cpro2.nvars = n2,  \
+  x##cpro3.next = &x##cpro2, x##cpro3.var = array3, x##cpro3.nvars = n3,  \
+  gcprolist = &x##cpro3 ))
 
 #if defined (__cplusplus) && defined (ERROR_CHECK_GC)
 /* We need to reset each gcpro to avoid triggering the assert() in
@@ -3226,106 +3357,64 @@
 #define UNWIND_GCPRO_TO(val) (gcprolist = (val))
 #endif /* defined (__cplusplus) && defined (ERROR_CHECK_GC) */
 
-#define UNGCPRO_1(gcpro1) UNWIND_GCPRO_TO (gcpro1.next)
-
-#define UNGCPRO UNGCPRO_1 (gcpro1)
-
-#define NGCPRO1(var1) ((void) (						\
-  ngcpro1.next = gcprolist, ngcpro1.var = &var1, ngcpro1.nvars = 1,	\
-  gcprolist = &ngcpro1 ))
-
-#define NGCPRO2(var1, var2) ((void) (					\
-  ngcpro1.next = gcprolist, ngcpro1.var = &var1, ngcpro1.nvars = 1,	\
-  ngcpro2.next = &ngcpro1,  ngcpro2.var = &var2, ngcpro2.nvars = 1,	\
-  gcprolist = &ngcpro2 ))
-
-#define NGCPRO3(var1, var2, var3) ((void) (				\
-  ngcpro1.next = gcprolist, ngcpro1.var = &var1, ngcpro1.nvars = 1,	\
-  ngcpro2.next = &ngcpro1,  ngcpro2.var = &var2, ngcpro2.nvars = 1,	\
-  ngcpro3.next = &ngcpro2,  ngcpro3.var = &var3, ngcpro3.nvars = 1,	\
-  gcprolist = &ngcpro3 ))
-
-#define NGCPRO4(var1, var2, var3, var4) ((void) (			\
-  ngcpro1.next = gcprolist, ngcpro1.var = &var1, ngcpro1.nvars = 1,	\
-  ngcpro2.next = &ngcpro1,  ngcpro2.var = &var2, ngcpro2.nvars = 1,	\
-  ngcpro3.next = &ngcpro2,  ngcpro3.var = &var3, ngcpro3.nvars = 1,	\
-  ngcpro4.next = &ngcpro3,  ngcpro4.var = &var4, ngcpro4.nvars = 1,	\
-  gcprolist = &ngcpro4 ))
-
-#define NGCPRO5(var1, var2, var3, var4, var5) ((void) (			\
-  ngcpro1.next = gcprolist, ngcpro1.var = &var1, ngcpro1.nvars = 1,	\
-  ngcpro2.next = &ngcpro1,  ngcpro2.var = &var2, ngcpro2.nvars = 1,	\
-  ngcpro3.next = &ngcpro2,  ngcpro3.var = &var3, ngcpro3.nvars = 1,	\
-  ngcpro4.next = &ngcpro3,  ngcpro4.var = &var4, ngcpro4.nvars = 1,	\
-  ngcpro5.next = &ngcpro4,  ngcpro5.var = &var5, ngcpro5.nvars = 1,	\
-  gcprolist = &ngcpro5 ))
-
-#define NGCPRO1_ARRAY(array, n) ((void) (				\
-  ngcpro1.next = gcprolist, ngcpro1.var = array, ngcpro1.nvars = n,	\
-  gcprolist = &ngcpro1 ))
-
-#define NGCPRO2_ARRAY(array1, n1, array2, n2) ((void) (			\
-  ngcpro1.next = gcprolist, ngcpro1.var = array1, ngcpro1.nvars = n1,	\
-  ngcpro2.next = &ngcpro1,  ngcpro2.var = array2, ngcpro2.nvars = n2,	\
-  gcprolist = &ngcpro2 ))
-
-#define NGCPRO3_ARRAY(array1, n1, array2, n2, array3, n3) ((void) (	\
-  ngcpro1.next = gcprolist, ngcpro1.var = array1, ngcpro1.nvars = n1,	\
-  ngcpro2.next = &ngcpro1,  ngcpro2.var = array2, ngcpro2.nvars = n2,	\
-  ngcpro3.next = &ngcpro2,  ngcpro3.var = array3, ngcpro3.nvars = n3,	\
-  gcprolist = &ngcpro3 ))
-
-#define NUNGCPRO UNGCPRO_1 (ngcpro1)
-
-#define NNGCPRO1(var1) ((void) (					\
-  nngcpro1.next = gcprolist, nngcpro1.var = &var1, nngcpro1.nvars = 1,	\
-  gcprolist = &nngcpro1 ))
-
-#define NNGCPRO2(var1, var2) ((void) (					\
-  nngcpro1.next = gcprolist, nngcpro1.var = &var1, nngcpro1.nvars = 1,	\
-  nngcpro2.next = &nngcpro1, nngcpro2.var = &var2, nngcpro2.nvars = 1,	\
-  gcprolist = &nngcpro2 ))
-
-#define NNGCPRO3(var1, var2, var3) ((void) (				\
-  nngcpro1.next = gcprolist, nngcpro1.var = &var1, nngcpro1.nvars = 1,	\
-  nngcpro2.next = &nngcpro1, nngcpro2.var = &var2, nngcpro2.nvars = 1,	\
-  nngcpro3.next = &nngcpro2, nngcpro3.var = &var3, nngcpro3.nvars = 1,	\
-  gcprolist = &nngcpro3 ))
-
-#define NNGCPRO4(var1, var2, var3, var4)  ((void) (			\
-  nngcpro1.next = gcprolist, nngcpro1.var = &var1, nngcpro1.nvars = 1,	\
-  nngcpro2.next = &nngcpro1, nngcpro2.var = &var2, nngcpro2.nvars = 1,	\
-  nngcpro3.next = &nngcpro2, nngcpro3.var = &var3, nngcpro3.nvars = 1,	\
-  nngcpro4.next = &nngcpro3, nngcpro4.var = &var4, nngcpro4.nvars = 1,	\
-  gcprolist = &nngcpro4 ))
-
-#define NNGCPRO5(var1, var2, var3, var4, var5) ((void) (		\
-  nngcpro1.next = gcprolist, nngcpro1.var = &var1, nngcpro1.nvars = 1,	\
-  nngcpro2.next = &nngcpro1, nngcpro2.var = &var2, nngcpro2.nvars = 1,	\
-  nngcpro3.next = &nngcpro2, nngcpro3.var = &var3, nngcpro3.nvars = 1,	\
-  nngcpro4.next = &nngcpro3, nngcpro4.var = &var4, nngcpro4.nvars = 1,	\
-  nngcpro5.next = &nngcpro4, nngcpro5.var = &var5, nngcpro5.nvars = 1,	\
-  gcprolist = &nngcpro5 ))
-
-#define NNGCPRO1_ARRAY(array, n) ((void) (				\
-  nngcpro1.next = gcprolist, nngcpro1.var = array, nngcpro1.nvars = n,	\
-  gcprolist = &nngcpro1 ))
-
-#define NNGCPRO2_ARRAY(array1, n1, array2, n2) ((void) (		  \
-  nngcpro1.next = gcprolist,  nngcpro1.var = array1, nngcpro1.nvars = n1, \
-  nngcpro2.next = &nngcpro1,  nngcpro2.var = array2, nngcpro2.nvars = n2, \
-  gcprolist = &nngcpro2 ))
-
-#define NNGCPRO3_ARRAY(array1, n1, array2, n2, array3, n3) ((void) (	  \
-  nngcpro1.next = gcprolist,  nngcpro1.var = array1, nngcpro1.nvars = n1, \
-  nngcpro2.next = &nngcpro1,  nngcpro2.var = array2, nngcpro2.nvars = n2, \
-  nngcpro3.next = &nngcpro2,  nngcpro3.var = array3, nngcpro3.nvars = n3, \
-  gcprolist = &nngcpro3 ))
-
-#define NNUNGCPRO UNGCPRO_1 (nngcpro1)
+#define XUNGCPRO(x) UNWIND_GCPRO_TO (x##cpro1.next)
 
 #endif /* ! DEBUG_GCPRO */
 
+#define GCDECL1 XGCDECL1 (g)
+#define GCDECL2 XGCDECL2 (g)
+#define GCDECL3 XGCDECL3 (g)
+#define GCDECL4 XGCDECL4 (g)
+#define GCDECL5 XGCDECL5 (g)
+
+#define GCPRO1(a) XGCPRO1 (g,a)
+#define GCPRO2(a,b) XGCPRO2 (g,a,b)
+#define GCPRO3(a,b,c) XGCPRO3 (g,a,b,c)
+#define GCPRO4(a,b,c,d) XGCPRO4 (g,a,b,c,d)
+#define GCPRO5(a,b,c,d,e) XGCPRO5 (g,a,b,c,d,e)
+
+#define GCPRO1_ARRAY(a1,n1) XGCPRO1_ARRAY(g,a1,n1)
+#define GCPRO2_ARRAY(a1,n1,a2,n2) XGCPRO2_ARRAY (g,a1,n1,a2,n2)
+#define GCPRO3_ARRAY(a1,n1,a2,n2,a3,n3) XGCPRO3_ARRAY (g,a1,n1,a2,n2,a3,n3)
+
+#define UNGCPRO XUNGCPRO (g)
+
+#define NGCDECL1 XGCDECL1 (ng)
+#define NGCDECL2 XGCDECL2 (ng)
+#define NGCDECL3 XGCDECL3 (ng)
+#define NGCDECL4 XGCDECL4 (ng)
+#define NGCDECL5 XGCDECL5 (ng)
+
+#define NGCPRO1(a) XGCPRO1 (ng,a)
+#define NGCPRO2(a,b) XGCPRO2 (ng,a,b)
+#define NGCPRO3(a,b,c) XGCPRO3 (ng,a,b,c)
+#define NGCPRO4(a,b,c,d) XGCPRO4 (ng,a,b,c,d)
+#define NGCPRO5(a,b,c,d,e) XGCPRO5 (ng,a,b,c,d,e)
+
+#define NGCPRO1_ARRAY(a1,n1) XGCPRO1_ARRAY(ng,a1,n1)
+#define NGCPRO2_ARRAY(a1,n1,a2,n2) XGCPRO2_ARRAY (ng,a1,n1,a2,n2)
+#define NGCPRO3_ARRAY(a1,n1,a2,n2,a3,n3) XGCPRO3_ARRAY (ng,a1,n1,a2,n2,a3,n3)
+
+#define NUNGCPRO XUNGCPRO (ng)
+
+#define NNGCDECL1 XGCDECL1 (nng)
+#define NNGCDECL2 XGCDECL2 (nng)
+#define NNGCDECL3 XGCDECL3 (nng)
+#define NNGCDECL4 XGCDECL4 (nng)
+#define NNGCDECL5 XGCDECL5 (nng)
+
+#define NNGCPRO1(a) XGCPRO1 (nng,a)
+#define NNGCPRO2(a,b) XGCPRO2 (nng,a,b)
+#define NNGCPRO3(a,b,c) XGCPRO3 (nng,a,b,c)
+#define NNGCPRO4(a,b,c,d) XGCPRO4 (nng,a,b,c,d)
+#define NNGCPRO5(a,b,c,d,e) XGCPRO5 (nng,a,b,c,d,e)
+
+#define NNGCPRO1_ARRAY(a1,n1) XGCPRO1_ARRAY(nng,a1,n1)
+#define NNGCPRO2_ARRAY(a1,n1,a2,n2) XGCPRO2_ARRAY (nng,a1,n1,a2,n2)
+#define NNGCPRO3_ARRAY(a1,n1,a2,n2,a3,n3) XGCPRO3_ARRAY (nng,a1,n1,a2,n2,a3,n3)
+
+#define NNUNGCPRO XUNGCPRO (nng)
+
 /* Evaluate expr, UNGCPRO, and then return the value of expr.  */
 #define RETURN_UNGCPRO(expr) do		\
 {					\
@@ -3360,13 +3449,13 @@
 
 /* Help debug crashes gc-marking a staticpro'ed object. */
 
-MODULE_API void staticpro_1 (Lisp_Object *, char *);
-MODULE_API void staticpro_nodump_1 (Lisp_Object *, char *);
+MODULE_API void staticpro_1 (Lisp_Object *, Ascbyte *);
+MODULE_API void staticpro_nodump_1 (Lisp_Object *, Ascbyte *);
 #define staticpro(ptr) staticpro_1 (ptr, #ptr)
 #define staticpro_nodump(ptr) staticpro_nodump_1 (ptr, #ptr)
 
 #ifdef HAVE_SHLIB
-MODULE_API void unstaticpro_nodump_1 (Lisp_Object *, char *);
+MODULE_API void unstaticpro_nodump_1 (Lisp_Object *, Ascbyte *);
 #define unstaticpro_nodump(ptr) unstaticpro_nodump_1 (ptr, #ptr)
 #endif
 
@@ -3747,15 +3836,15 @@
 EXFUN (Fforce_debugging_signal, 1);
 
 SIGTYPE fatal_error_signal (int);
-Lisp_Object make_arg_list (int, Extbyte **);
-void make_argc_argv (Lisp_Object, int *, Extbyte ***);
-void free_argc_argv (Extbyte **);
+Lisp_Object make_arg_list (int, Wexttext **);
+void make_argc_argv (Lisp_Object, int *, Wexttext ***);
+void free_argc_argv (Wexttext **);
 Lisp_Object split_external_path (const Extbyte *path);
 Lisp_Object split_env_path (const CIbyte *evarname, const Ibyte *default_);
 
 /* Nonzero means don't do interactive redisplay and don't change tty modes */
 extern int noninteractive, noninteractive1;
-extern int inhibit_non_essential_printing_operations;
+extern int inhibit_non_essential_conversion_operations;
 extern int preparing_for_armageddon;
 extern Fixnum emacs_priority;
 extern int suppress_early_error_handler_backtrace;
@@ -3998,32 +4087,32 @@
 					 Lisp_Object arg);
 int set_trapping_problems_flags (int flags);
 Lisp_Object call_trapping_problems (Lisp_Object warning_class,
-				    const char *warning_string,
+				    const Ascbyte *warning_string,
 				    int flags,
 				    struct call_trapping_problems_result
 				    *problem,
 				    Lisp_Object (*fun) (void *),
 				    void *arg);
 Lisp_Object va_call_trapping_problems (Lisp_Object warning_class,
-				       const char *warning_string,
+				       const Ascbyte *warning_string,
 				       int flags,
 				       struct call_trapping_problems_result
 				       *problem,
 				       lisp_fn_t fun, int nargs, ...);
-Lisp_Object call0_trapping_problems (const char *, Lisp_Object, int);
-Lisp_Object call1_trapping_problems (const char *, Lisp_Object, Lisp_Object,
+Lisp_Object call0_trapping_problems (const Ascbyte *, Lisp_Object, int);
+Lisp_Object call1_trapping_problems (const Ascbyte *, Lisp_Object, Lisp_Object,
 				   int);
-Lisp_Object call2_trapping_problems (const char *, Lisp_Object, Lisp_Object,
+Lisp_Object call2_trapping_problems (const Ascbyte *, Lisp_Object, Lisp_Object,
 				   Lisp_Object, int);
-Lisp_Object call3_trapping_problems (const char *, Lisp_Object, Lisp_Object,
+Lisp_Object call3_trapping_problems (const Ascbyte *, Lisp_Object, Lisp_Object,
 				   Lisp_Object, Lisp_Object, int);
-Lisp_Object call4_trapping_problems (const char *, Lisp_Object, Lisp_Object,
+Lisp_Object call4_trapping_problems (const Ascbyte *, Lisp_Object, Lisp_Object,
 				   Lisp_Object, Lisp_Object, Lisp_Object,
 				   int);
-Lisp_Object call5_trapping_problems (const char *, Lisp_Object, Lisp_Object,
+Lisp_Object call5_trapping_problems (const Ascbyte *, Lisp_Object, Lisp_Object,
 				   Lisp_Object, Lisp_Object, Lisp_Object,
 				   Lisp_Object, int);
-Lisp_Object eval_in_buffer_trapping_problems (const char *, struct buffer *,
+Lisp_Object eval_in_buffer_trapping_problems (const Ascbyte *, struct buffer *,
 					    Lisp_Object, int);
 Lisp_Object run_hook_trapping_problems (Lisp_Object, Lisp_Object, int);
 Lisp_Object safe_run_hook_trapping_problems (Lisp_Object, Lisp_Object, int);
@@ -4288,7 +4377,7 @@
 			 Lisp_Object, int, Error_Behavior);
 int external_remprop (Lisp_Object *, Lisp_Object, int, Error_Behavior);
 int internal_equal_trapping_problems (Lisp_Object warning_class,
-    				      const char *warning_string,
+    				      const Ascbyte *warning_string,
 				      int flags,
 				      struct call_trapping_problems_result *p,
 				      int retval,
@@ -4305,8 +4394,8 @@
 void check_losing_bytecode (const char *, Lisp_Object);
 
 Lisp_Object add_suffix_to_symbol (Lisp_Object symbol,
-				  const Char_ASCII *ascii_string);
-Lisp_Object add_prefix_to_symbol (const Char_ASCII *ascii_string,
+				  const Ascbyte *ascii_string);
+Lisp_Object add_prefix_to_symbol (const Ascbyte *ascii_string,
 				  Lisp_Object symbol);
 
 /* Defined in free-hook.c */
@@ -4327,9 +4416,9 @@
 extern Lisp_Object Q_resource_type, Q_resource_id;
 
 /* Defined in gui.c */
-DECLARE_DOESNT_RETURN (gui_error (const char *reason,
+DECLARE_DOESNT_RETURN (gui_error (const Ascbyte *reason,
 				  Lisp_Object frob));
-DECLARE_DOESNT_RETURN (gui_error_2 (const char *reason,
+DECLARE_DOESNT_RETURN (gui_error_2 (const Ascbyte *reason,
 				    Lisp_Object frob0, Lisp_Object frob1));
 /* Defined in indent.c */
 EXFUN (Findent_to, 3);
@@ -4555,7 +4644,7 @@
 EXFUN (Fding, 3);
 
 void init_device_sound (struct device *);
-DECLARE_DOESNT_RETURN (report_sound_error (const Char_ASCII *, Lisp_Object));
+DECLARE_DOESNT_RETURN (report_sound_error (const Ascbyte *, Lisp_Object));
 
 /* Defined in specifier.c */
 EXFUN (Fadd_spec_to_specifier, 5);
@@ -4758,12 +4847,12 @@
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrdup (const Ibyte *s))
 {
-  return (Ibyte *) xstrdup ((const char *) s);
+  return (Ibyte *) xstrdup ((const Chbyte *) s);
 }
 
 DECLARE_INLINE_HEADER (Bytecount qxestrlen (const Ibyte *s))
 {
-  return strlen ((const char *) s);
+  return strlen ((const Chbyte *) s);
 }
 
 DECLARE_INLINE_HEADER (Charcount qxestrcharlen (const Ibyte *s))
@@ -4774,177 +4863,186 @@
 DECLARE_INLINE_HEADER (int qxestrcmp (const Ibyte *s1,
 				      const Ibyte *s2))
 {
-  return strcmp ((const char *) s1, (const char *) s2);
+  return strcmp ((const Chbyte *) s1, (const Chbyte *) s2);
 }
 
-DECLARE_INLINE_HEADER (int qxestrcmp_c (const Ibyte *s1,
-					const char *s2))
+DECLARE_INLINE_HEADER (int qxestrcmp_ascii (const Ibyte *s1,
+					    const Ascbyte *s2))
 {
-  return strcmp ((const char *) s1, s2);
+  return strcmp ((const Chbyte *) s1, s2);
 }
 
 DECLARE_INLINE_HEADER (int qxestrncmp (const Ibyte *string1,
 				       const Ibyte *string2,
 				       Bytecount count))
 {
-  return strncmp ((const char *) string1, (const char *) string2,
+  return strncmp ((const Chbyte *) string1, (const Chbyte *) string2,
 		  (size_t) count);
 }
 
-DECLARE_INLINE_HEADER (int qxestrncmp_c (const Ibyte *string1,
-					 const char *string2,
-					 Bytecount count))
+DECLARE_INLINE_HEADER (int qxestrncmp_ascii (const Ibyte *string1,
+					     const Ascbyte *string2,
+					     Bytecount count))
 {
-  return strncmp ((const char *) string1, string2, (size_t) count);
+  return strncmp ((const Chbyte *) string1, string2, (size_t) count);
 }
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrcpy (Ibyte *strDest,
-					   const Ibyte *strSource))
+					 const Ibyte *strSource))
 {
-  return (Ibyte *) strcpy ((char *) strDest, (const char *) strSource);
+  return (Ibyte *) strcpy ((Chbyte *) strDest, (const Chbyte *) strSource);
 }
 
-DECLARE_INLINE_HEADER (Ibyte *qxestrcpy_c (Ibyte *strDest,
-					     const char *strSource))
+DECLARE_INLINE_HEADER (Ibyte *qxestrcpy_ascii (Ibyte *strDest,
+					       const Ascbyte *strSource))
 {
-  return (Ibyte *) strcpy ((char *) strDest, strSource);
+  return (Ibyte *) strcpy ((Chbyte *) strDest, strSource);
 }
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrncpy (Ibyte *strDest,
-					    const Ibyte *strSource,
-					    Bytecount count))
+					  const Ibyte *strSource,
+					  Bytecount count))
 {
-  return (Ibyte *) strncpy ((char *) strDest, (const char *) strSource,
+  return (Ibyte *) strncpy ((Chbyte *) strDest, (const Chbyte *) strSource,
 			      (size_t) count);
 }
 
-DECLARE_INLINE_HEADER (Ibyte *qxestrncpy_c (Ibyte *strDest,
-					      const char *strSource,
-					      Bytecount count))
+DECLARE_INLINE_HEADER (Ibyte *qxestrncpy_ascii (Ibyte *strDest,
+						const Ascbyte *strSource,
+						Bytecount count))
 {
-  return (Ibyte *) strncpy ((char *) strDest, strSource, (size_t) count);
+  return (Ibyte *) strncpy ((Chbyte *) strDest, strSource, (size_t) count);
 }
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrcat (Ibyte *strDest,
-					   const Ibyte *strSource))
+					 const Ibyte *strSource))
 {
-  return (Ibyte *) strcat ((char *) strDest, (const char *) strSource);
+  return (Ibyte *) strcat ((Chbyte *) strDest, (const Chbyte *) strSource);
 }
 
-DECLARE_INLINE_HEADER (Ibyte *qxestrcat_c (Ibyte *strDest,
-					     const char *strSource))
+DECLARE_INLINE_HEADER (Ibyte *qxestrcat_ascii (Ibyte *strDest,
+					       const Ascbyte *strSource))
 {
-  return (Ibyte *) strcat ((char *) strDest, strSource);
+  return (Ibyte *) strcat ((Chbyte *) strDest, strSource);
 }
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrncat (Ibyte *strDest,
-					    const Ibyte *strSource,
-					    Bytecount count))
+					  const Ibyte *strSource,
+					  Bytecount count))
 {
-  return (Ibyte *) strncat ((char *) strDest, (const char *) strSource,
+  return (Ibyte *) strncat ((Chbyte *) strDest, (const Chbyte *) strSource,
 			      (size_t) count);
 }
 
-DECLARE_INLINE_HEADER (Ibyte *qxestrncat_c (Ibyte *strDest,
-					      const char *strSource,
-					      Bytecount count))
+DECLARE_INLINE_HEADER (Ibyte *qxestrncat_ascii (Ibyte *strDest,
+						const Ascbyte *strSource,
+						Bytecount count))
 {
-  return (Ibyte *) strncat ((char *) strDest, strSource, (size_t) count);
+  return (Ibyte *) strncat ((Chbyte *) strDest, strSource, (size_t) count);
 }
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrchr (const Ibyte *s, Ichar c))
 {
   assert (c >= 0 && c <= 255);
-  return (Ibyte *) strchr ((const char *) s, c);
+  return (Ibyte *) strchr ((const Chbyte *) s, c);
 }
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrrchr (const Ibyte *s, Ichar c))
 {
   assert (c >= 0 && c <= 255);
-  return (Ibyte *) strrchr ((const char *) s, c);
+  return (Ibyte *) strrchr ((const Chbyte *) s, c);
 }
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrstr (const Ibyte *string1,
-					   const Ibyte *string2))
+					 const Ibyte *string2))
 {
-  return (Ibyte *) strstr ((const char *) string1, (const char *) string2);
+  return (Ibyte *) strstr ((const Chbyte *) string1, (const Chbyte *) string2);
 }
 
 DECLARE_INLINE_HEADER (Bytecount qxestrcspn (const Ibyte *string,
 					     const CIbyte *strCharSet))
 {
-  return (Bytecount) strcspn ((const char *) string, strCharSet);
+  return (Bytecount) strcspn ((const Chbyte *) string, strCharSet);
 }
 
 DECLARE_INLINE_HEADER (Bytecount qxestrspn (const Ibyte *string,
 					    const CIbyte *strCharSet))
 {
-  return (Bytecount) strspn ((const char *) string, strCharSet);
+  return (Bytecount) strspn ((const Chbyte *) string, strCharSet);
 }
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrpbrk (const Ibyte *string,
-					    const CIbyte *strCharSet))
+					  const CIbyte *strCharSet))
 {
-  return (Ibyte *) strpbrk ((const char *) string, strCharSet);
+  return (Ibyte *) strpbrk ((const Chbyte *) string, strCharSet);
 }
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrtok (Ibyte *strToken,
-					   const CIbyte *strDelimit))
+					 const CIbyte *strDelimit))
 {
-  return (Ibyte *) strtok ((char *) strToken, strDelimit);
+  return (Ibyte *) strtok ((Chbyte *) strToken, strDelimit);
 }
 
 DECLARE_INLINE_HEADER (double qxestrtod (const Ibyte *nptr,
 					 Ibyte **endptr))
 {
-  return strtod ((const char *) nptr, (char **) endptr);
+  return strtod ((const Chbyte *) nptr, (Chbyte **) endptr);
 }
 
 DECLARE_INLINE_HEADER (long qxestrtol (const Ibyte *nptr, Ibyte **endptr,
 				       int base))
 {
-  return strtol ((const char *) nptr, (char **) endptr, base);
+  return strtol ((const Chbyte *) nptr, (Chbyte **) endptr, base);
 }
 
 DECLARE_INLINE_HEADER (unsigned long qxestrtoul (const Ibyte *nptr,
 						 Ibyte **endptr,
 						 int base))
 {
-  return strtoul ((const char *) nptr, (char **) endptr, base);
+  return strtoul ((const Chbyte *) nptr, (Chbyte **) endptr, base);
 }
 
 DECLARE_INLINE_HEADER (int qxeatoi (const Ibyte *string))
 {
-  return atoi ((const char *) string);
+  return atoi ((const Chbyte *) string);
 }
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrupr (Ibyte *s))
 {
-  return (Ibyte *) strupr ((char *) s);
+  return (Ibyte *) strupr ((Chbyte *) s);
 }
 
 DECLARE_INLINE_HEADER (Ibyte *qxestrlwr (Ibyte *s))
 {
-  return (Ibyte *) strlwr ((char *) s);
+  return (Ibyte *) strlwr ((Chbyte *) s);
 }
 
 int qxesprintf (Ibyte *buffer, const CIbyte *format, ...)
      PRINTF_ARGS (2, 3);
 
+DECLARE_INLINE_HEADER (int qxesscanf_ascii_1 (Ibyte *buffer,
+					      const Ascbyte *format,
+					      void *ptr))
+{
+  /* #### DAMNIT! No vsscanf! */
+  return sscanf ((Chbyte *) buffer, format, ptr);
+}
+
 /* Do not use POSIX locale routines.  Not Mule-correct. */
 #define qxestrcoll DO NOT USE.
 #define qxestrxfrm DO NOT USE.
 
 int qxestrcasecmp (const Ibyte *s1, const Ibyte *s2);
-int qxestrcasecmp_c (const Ibyte *s1, const Char_ASCII *s2);
+int qxestrcasecmp_ascii (const Ibyte *s1, const Ascbyte *s2);
 int qxestrcasecmp_i18n (const Ibyte *s1, const Ibyte *s2);
-int ascii_strcasecmp (const Char_ASCII *s1, const Char_ASCII *s2);
+int ascii_strcasecmp (const Ascbyte *s1, const Ascbyte *s2);
 int lisp_strcasecmp (Lisp_Object s1, Lisp_Object s2);
 int lisp_strcasecmp_i18n (Lisp_Object s1, Lisp_Object s2);
 int qxestrncasecmp (const Ibyte *s1, const Ibyte *s2, Bytecount len);
-int qxestrncasecmp_c (const Ibyte *s1, const Char_ASCII *s2, Bytecount len);
+int qxestrncasecmp_ascii (const Ibyte *s1, const Ascbyte *s2,
+			  Bytecount len);
 int qxestrncasecmp_i18n (const Ibyte *s1, const Ibyte *s2, Bytecount len);
-int ascii_strncasecmp (const Char_ASCII *s1, const Char_ASCII *s2,
+int ascii_strncasecmp (const Ascbyte *s1, const Ascbyte *s2,
 		       Bytecount len);
 int qxememcmp (const Ibyte *s1, const Ibyte *s2, Bytecount len);
 int qxememcmp4 (const Ibyte *s1, Bytecount len1,
@@ -4970,6 +5068,23 @@
 					Charbpos end, Bytebpos byte_start,
 					Bytebpos byte_end);
 
+typedef struct
+{
+  const char *srctext;
+  void *dst;
+  Bytecount dst_size;
+} alloca_convert_vals;
+
+typedef struct
+{
+  Dynarr_declare (alloca_convert_vals);
+} alloca_convert_vals_dynarr;
+
+extern alloca_convert_vals_dynarr *active_alloca_convert;
+
+MODULE_API int find_pos_of_existing_active_alloca_convert (const char *
+							   srctext);
+
 /* Defined in unicode.c */
 extern const struct sized_memory_description to_unicode_description;
 extern const struct sized_memory_description from_unicode_description;