diff src/lisp.h @ 814:a634e3b7acc8

[xemacs-hg @ 2002-04-14 12:41:59 by ben] latest changes TODO.ben-mule-21-5: Update. make-docfile.c: Add basic support for handling ISO 2022 doc strings -- we parse the basic charset designation sequences so we know whether we're in ASCII and have to pay attention to end quotes and such. Reformat code according to coding standards. abbrev.el: Add `global-abbrev-mode', which turns on or off abbrev-mode in all buffers. Added `defining-abbrev-turns-on-abbrev-mode' -- if non-nil, defining an abbrev through an interactive function will automatically turn on abbrev-mode, either globally or locally depending on the command. This is the "what you'd expect" behavior. indent.el: general function for indenting a balanced expression in a mode-correct way. Works similar to indent-region in that a mode can specify a specific command to do the whole operation; if not, figure out the region using forward-sexp and indent each line using indent-according-to-mode. keydefs.el: Removed. Modify M-C-backslash to do indent-region-or-balanced-expression. Make S-Tab just insert a TAB char, like it's meant to do. make-docfile.el: Now that we're using the call-process-in-lisp, we need to load an extra file win32-native.el because we're running a bare temacs. menubar-items.el: Totally redo the Cmds menu so that most used commands appear directly on the menu and less used commands appear in submenus. The old way may have been very pretty, but rather impractical. process.el: Under Windows, don't ever use old-call-process-internal, even in batch mode. We can do processes in batch mode. subr.el: Someone recoded truncate-string-to-width, saying "the FSF version is too complicated and does lots of hard-to-understand stuff" but the resulting recoded version was *totally* wrong! it misunderstood the basic point of this function, which is work in *columns* not chars. i dumped ours and copied the version from FSF 21.1. Also added truncate-string-with-continuation-dots, since this idiom is used often. config.inc.samp, xemacs.mak: Separate out debug and optimize flags. Remove all vestiges of USE_MINIMAL_TAGBITS, USE_INDEXED_LRECORD_IMPLEMENTATION, and GUNG_HO, since those ifdefs have long been removed. Make error-checking support actually work. Some rearrangement of config.inc.samp to make it more logical. Remove callproc.c and ntproc.c from xemacs.mak, no longer used. Make pdump the default. lisp.h: Add support for strong type-checking of Bytecount, Bytebpos, Charcount, Charbpos, and others, by making them classes, overloading the operators to provide integer-like operation and carefully controlling what operations are allowed. Not currently enabled in C++ builds because there are still a number of compile errors, and it won't really work till we merge in my "8-bit-Mule" workspace, in which I make use of the new types Charxpos, Bytexpos, Memxpos, representing a "position" either in a buffer or a string. (This is especially important in the extent code.) abbrev.c, alloc.c, eval.c, buffer.c, buffer.h, editfns.c, fns.c, text.h: Warning fixes, some of them related to new C++ strict type checking of Bytecount, Charbpos, etc. dired.c: Caught an actual error due to strong type checking -- char len being passed when should be byte len. alloc.c, backtrace.h, bytecode.c, bytecode.h, eval.c, sysdep.c: Further optimize Ffuncall: -- process arg list at compiled-function creation time, converting into an array for extra-quick access at funcall time. -- rewrite funcall_compiled_function to use it, and inline this function. -- change the order of check for magic stuff in SPECBIND_FAST_UNSAFE to be faster. -- move the check for need to garbage collect into the allocation code, so only a single flag needs to be checked in funcall. buffer.c, symbols.c: add debug funs to check on mule optimization info in buffers and strings. eval.c, emacs.c, text.c, regex.c, scrollbar-msw.c, search.c: Fix evil crashes due to eistrings not properly reinitialized under pdump. Redo a bit some of the init routines; convert some complex_vars_of() into simple vars_of(), because they didn't need complex processing. callproc.c, emacs.c, event-stream.c, nt.c, process.c, process.h, sysdep.c, sysdep.h, syssignal.h, syswindows.h, ntproc.c: Delete. Hallelujah, praise the Lord, there is no god but Allah!!! fix so that processes can be invoked in bare temacs -- thereby eliminating any need for callproc.c. (currently only eliminated under NT.) remove all crufty and unnecessary old process code in ntproc.c and elsewhere. move non-callproc-specific stuff (mostly environment) into process.c, so callproc.c can be left out under NT. console-tty.c, doc.c, file-coding.c, file-coding.h, lstream.c, lstream.h: fix doc string handling so it works with Japanese, etc docs. change handling of "character mode" so callers don't have to manually set it (quite error-prone). event-msw.c: spacing fixes. lread.c: eliminate unused crufty vintage-19 "FSF defun hack" code. lrecord.h: improve pdump description docs. buffer.c, ntheap.c, unexnt.c, win32.c, emacs.c: Mule-ize some unexec and startup code. It was pseudo-Mule-ized before by simply always calling the ...A versions of functions, but that won't cut it -- eventually we want to be able to run properly even if XEmacs has been installed in a Japanese directory. (The current problem is the timing of the loading of the Unicode tables; this will eventually be fixed.) Go through and fix various other places where the code was not Mule-clean. Provide a function mswindows_get_module_file_name() to get our own name without resort to PATH_MAX and such. Add a big comment in main() about the problem with Unicode table load timing that I just alluded to. emacs.c: When error-checking is enabled (interpreted as "user is developing XEmacs"), don't ask user to "pause to read messages" when a fatal error has occurred, because it will wedge if we are in an inner modal loop (typically when a menu is popped up) and make us unable to get a useful stack trace in the debugger. text.c: Correct update_entirely_ascii_p_flag to actually work. lisp.h, symsinit.h: declarations for above changes.
author ben
date Sun, 14 Apr 2002 12:43:31 +0000
parents 19dfb459d51a
children 6504113e7c2d
line wrap: on
line diff
--- a/src/lisp.h	Sat Apr 13 20:44:53 2002 +0000
+++ b/src/lisp.h	Sun Apr 14 12:43:31 2002 +0000
@@ -146,6 +146,7 @@
    buffer.h (where they rightfully belong) to avoid syntax errors
    in function prototypes. */
 
+#if !defined (__cplusplus) || !defined (CPLUSPLUS_INTEGRAL_CLASSES_NOT_YET)
 
 typedef EMACS_INT Charbpos;
 typedef EMACS_INT Bytebpos;
@@ -154,6 +155,460 @@
 /* Counts of bytes or chars */
 typedef EMACS_INT Bytecount;
 typedef EMACS_INT Charcount;
+
+/* Not yet used */
+typedef EMACS_INT Charxpos;
+typedef EMACS_INT Bytexpos;
+typedef EMACS_INT Memxpos;
+
+#else /* __cplusplus */
+
+/* Implement strong type-checking of the above integral types by declaring
+   them to be classes and using operator overloading.  Unfortunately this
+   is a huge pain in the ass because C++ doesn't strongly distinguish
+   "bool" and "size_t" from int.  The problem is especially bad with "bool"
+   -- if you want to be able to say 'if (len--)' where len is e.g. a
+   Bytecount, you need to declare a conversion operator to bool(); and
+   since bool is just an alias for int, you suddenly get tons and tons of
+   ambiguities, which need to be resolved by lots of laborious declarations
+   for every single possible type combination.  Hence the multitude of
+   declarations in DECLARE_INTCLASS_ARITH_COMPARE().  The bool/int
+   equivalence also means that we have to forcibly block the combinations
+   we don't want by creating overloaded versions of them and declaring them
+   private. */
+   
+#undef class
+#undef this
+
+class Bytecount;
+class Bytebpos;
+class Bytexpos;
+class Charcount;
+class Charbpos;
+class Charxpos;
+class Membpos;
+class Memxpos;
+
+/* Declare the arithmetic and comparison operations for an integral class,
+   i.e. one of the above classes.  If this is a "position" class, where the
+   difference between two positions is a different class (a "count" class),
+   then use POSCL for the position class and COUNTCL for the count class.
+   If this is a simple class, where all operations yield the same class,
+   substitute the same class for POSCL and COUNTCL. */
+
+#define DECLARE_INTCLASS_ARITH_COMPARE(poscl, countcl)			      \
+  poscl operator += (const countcl& l) { data += l.data; return *this; }      \
+  poscl operator -= (const countcl& l) { data -= l.data; return *this; }      \
+  poscl operator + (const countcl& l) const { return poscl (data + l.data); } \
+  poscl operator - (const countcl& l) const { return poscl (data - l.data); } \
+  poscl operator += (const int& l) { data += l; return *this; }		      \
+  poscl operator -= (const int& l) { data -= l; return *this; }		      \
+  poscl operator + (const int& l) const { return poscl (data + l); }	      \
+  poscl operator - (const int& l) const { return poscl (data - l); }	      \
+  poscl operator += (const unsigned int& l) { data += l; return *this; }      \
+  poscl operator -= (const unsigned int& l) { data -= l; return *this; }      \
+  poscl operator + (const unsigned int& l) const			      \
+    { return poscl (data + l); }					      \
+  poscl operator - (const unsigned int& l) const			      \
+    { return poscl (data - l); }					      \
+  poscl operator += (const long& l) { data += l; return *this; }	      \
+  poscl operator -= (const long& l) { data -= l; return *this; }	      \
+  poscl operator + (const long& l) const { return poscl (data + l); }	      \
+  poscl operator - (const long& l) const { return poscl (data - l); }	      \
+  poscl operator += (const unsigned long& l) { data += l; return *this; }     \
+  poscl operator -= (const unsigned long& l) { data -= l; return *this; }     \
+  poscl operator + (const unsigned long& l) const			      \
+    { return poscl (data + l); }					      \
+  poscl operator - (const unsigned long& l) const			      \
+    { return poscl (data - l); }					      \
+  poscl operator += (const short& l) { data += l; return *this; }	      \
+  poscl operator -= (const short& l) { data -= l; return *this; }	      \
+  poscl operator + (const short& l) const { return poscl (data + l); }	      \
+  poscl operator - (const short& l) const { return poscl (data - l); }	      \
+  poscl operator += (const unsigned short& l) { data += l; return *this; }    \
+  poscl operator -= (const unsigned short& l) { data -= l; return *this; }    \
+  poscl operator + (const unsigned short& l) const			      \
+    { return poscl (data + l); }					      \
+  poscl operator - (const unsigned short& l) const			      \
+    { return poscl (data - l); }					      \
+									      \
+  poscl operator *= (const countcl& l) { data *= l.data; return *this; }      \
+  poscl operator /= (const countcl& l) { data /= l.data; return *this; }      \
+  poscl operator * (const countcl& l) const { return poscl (data * l.data); } \
+  poscl operator / (const countcl& l) const { return poscl (data / l.data); } \
+  poscl operator *= (const int& l) { data *= l; return *this; }		      \
+  poscl operator /= (const int& l) { data /= l; return *this; }		      \
+  poscl operator * (const int& l) const { return poscl (data * l); }	      \
+  poscl operator / (const int& l) const { return poscl (data / l); }	      \
+  poscl operator *= (const unsigned int& l) { data *= l; return *this; }      \
+  poscl operator /= (const unsigned int& l) { data /= l; return *this; }      \
+  poscl operator * (const unsigned int& l) const { return poscl (data * l); } \
+  poscl operator / (const unsigned int& l) const { return poscl (data / l); } \
+  poscl operator *= (const long& l) { data *= l; return *this; }	      \
+  poscl operator /= (const long& l) { data /= l; return *this; }	      \
+  poscl operator * (const long& l) const { return poscl (data * l); }	      \
+  poscl operator / (const long& l) const { return poscl (data / l); }	      \
+  poscl operator *= (const unsigned long& l) { data *= l; return *this; }     \
+  poscl operator /= (const unsigned long& l) { data /= l; return *this; }     \
+  poscl operator * (const unsigned long& l) const			      \
+    { return poscl (data * l); }					      \
+  poscl operator / (const unsigned long& l) const			      \
+    { return poscl (data / l); }					      \
+  poscl operator *= (const short& l) { data *= l; return *this; }	      \
+  poscl operator /= (const short& l) { data /= l; return *this; }	      \
+  poscl operator * (const short& l) const { return poscl (data * l); }	      \
+  poscl operator / (const short& l) const { return poscl (data / l); }	      \
+  poscl operator *= (const unsigned short& l) { data *= l; return *this; }    \
+  poscl operator /= (const unsigned short& l) { data /= l; return *this; }    \
+  poscl operator * (const unsigned short& l) const			      \
+    { return poscl (data * l); }					      \
+  poscl operator / (const unsigned short& l) const			      \
+    { return poscl (data / l); }					      \
+									      \
+  poscl operator &= (const countcl& l) { data &= l.data; return *this; }      \
+  poscl operator |= (const countcl& l) { data |= l.data; return *this; }      \
+  poscl operator & (const countcl& l) const { return poscl (data & l.data); } \
+  poscl operator | (const countcl& l) const { return poscl (data | l.data); } \
+  poscl operator &= (const int& l) { data &= l; return *this; }		      \
+  poscl operator |= (const int& l) { data |= l; return *this; }		      \
+  poscl operator & (const int& l) const { return poscl (data & l); }	      \
+  poscl operator | (const int& l) const { return poscl (data | l); }	      \
+  poscl operator &= (const unsigned int& l) { data &= l; return *this; }      \
+  poscl operator |= (const unsigned int& l) { data |= l; return *this; }      \
+  poscl operator & (const unsigned int& l) const { return poscl (data & l); } \
+  poscl operator | (const unsigned int& l) const { return poscl (data | l); } \
+  poscl operator &= (const long& l) { data &= l; return *this; }	      \
+  poscl operator |= (const long& l) { data |= l; return *this; }	      \
+  poscl operator & (const long& l) const { return poscl (data & l); }	      \
+  poscl operator | (const long& l) const { return poscl (data | l); }	      \
+  poscl operator &= (const unsigned long& l) { data &= l; return *this; }     \
+  poscl operator |= (const unsigned long& l) { data |= l; return *this; }     \
+  poscl operator & (const unsigned long& l) const			      \
+    { return poscl (data & l); }					      \
+  poscl operator | (const unsigned long& l) const			      \
+    { return poscl (data | l); }					      \
+  poscl operator &= (const short& l) { data &= l; return *this; }	      \
+  poscl operator |= (const short& l) { data |= l; return *this; }	      \
+  poscl operator & (const short& l) const { return poscl (data & l); }	      \
+  poscl operator | (const short& l) const { return poscl (data | l); }	      \
+  poscl operator &= (const unsigned short& l) { data &= l; return *this; }    \
+  poscl operator |= (const unsigned short& l) { data |= l; return *this; }    \
+  poscl operator & (const unsigned short& l) const			      \
+    { return poscl (data & l); }					      \
+  poscl operator | (const unsigned short& l) const			      \
+    { return poscl (data | l); }					      \
+									      \
+  poscl operator - ()           { return poscl (-data); }		      \
+  poscl operator-- ()           { data--; return *this; }		      \
+  poscl operator-- (int)	     { data--; return poscl (data + 1); }     \
+  poscl operator++ ()           { data++; return *this; }		      \
+  poscl operator++ (int)        { data++; return poscl (data - 1); }	      \
+									      \
+  bool operator < (const poscl& l) const { return data < l.data; }	      \
+  bool operator <= (const poscl& l) const { return data <= l.data; }	      \
+  bool operator > (const poscl& l) const { return data > l.data; }	      \
+  bool operator >= (const poscl& l) const { return data >= l.data; }	      \
+  bool operator == (const poscl& l) const { return data == l.data; }	      \
+  bool operator != (const poscl& l) const { return data != l.data; }	      \
+  bool operator < (const int& l) const { return data < (EMACS_INT) l; }	      \
+  bool operator <= (const int& l) const { return data <= (EMACS_INT) l; }     \
+  bool operator > (const int& l) const { return data > (EMACS_INT) l; }	      \
+  bool operator >= (const int& l) const { return data >= (EMACS_INT) l; }     \
+  bool operator == (const int& l) const { return data == (EMACS_INT) l; }     \
+  bool operator != (const int& l) const { return data != (EMACS_INT) l; }     \
+  bool operator < (const unsigned int& l) const				      \
+    { return data < (EMACS_INT) l; }					      \
+  bool operator <= (const unsigned int& l) const			      \
+    { return data <= (EMACS_INT) l; }					      \
+  bool operator > (const unsigned int& l) const				      \
+    { return data > (EMACS_INT) l; }					      \
+  bool operator >= (const unsigned int& l) const			      \
+    { return data >= (EMACS_INT) l; }					      \
+  bool operator == (const unsigned int& l) const			      \
+    { return data == (EMACS_INT) l; }					      \
+  bool operator != (const unsigned int& l) const			      \
+    { return data != (EMACS_INT) l; }					      \
+  bool operator < (const long& l) const { return data < (EMACS_INT) l; }      \
+  bool operator <= (const long& l) const { return data <= (EMACS_INT) l; }    \
+  bool operator > (const long& l) const { return data > (EMACS_INT) l; }      \
+  bool operator >= (const long& l) const { return data >= (EMACS_INT) l; }    \
+  bool operator == (const long& l) const { return data == (EMACS_INT) l; }    \
+  bool operator != (const long& l) const { return data != (EMACS_INT) l; }    \
+  bool operator < (const unsigned long& l) const			      \
+    { return data < (EMACS_INT) l; }					      \
+  bool operator <= (const unsigned long& l) const			      \
+    { return data <= (EMACS_INT) l; }					      \
+  bool operator > (const unsigned long& l) const			      \
+    { return data > (EMACS_INT) l; }					      \
+  bool operator >= (const unsigned long& l) const			      \
+    { return data >= (EMACS_INT) l; }					      \
+  bool operator == (const unsigned long& l) const			      \
+    { return data == (EMACS_INT) l; }					      \
+  bool operator != (const unsigned long& l) const			      \
+    { return data != (EMACS_INT) l; }					      \
+  bool operator < (const short& l) const { return data < (EMACS_INT) l; }     \
+  bool operator <= (const short& l) const { return data <= (EMACS_INT) l; }   \
+  bool operator > (const short& l) const { return data > (EMACS_INT) l; }     \
+  bool operator >= (const short& l) const { return data >= (EMACS_INT) l; }   \
+  bool operator == (const short& l) const { return data == (EMACS_INT) l; }   \
+  bool operator != (const short& l) const { return data != (EMACS_INT) l; }   \
+  bool operator < (const unsigned short& l) const			      \
+    { return data < (EMACS_INT) l; }					      \
+  bool operator <= (const unsigned short& l) const			      \
+    { return data <= (EMACS_INT) l; }					      \
+  bool operator > (const unsigned short& l) const			      \
+    { return data > (EMACS_INT) l; }					      \
+  bool operator >= (const unsigned short& l) const			      \
+    { return data >= (EMACS_INT) l; }					      \
+  bool operator == (const unsigned short& l) const			      \
+    { return data == (EMACS_INT) l; }					      \
+  bool operator != (const unsigned short& l) const			      \
+    { return data != (EMACS_INT) l; }					      \
+  bool operator ! () const { return !data; }
+
+/* Declare the "bad" or disallowed arithmetic and comparion operations
+   between class GOOD and class BAD.  Meant to go inside the private
+   section of class GOOD. */
+
+#define DECLARE_BAD_INTCLASS_ARITH_COMPARE(good, bad)	\
+  good operator += (const bad& l) { return badret; }	\
+  good operator -= (const bad& l) { return badret; }	\
+  good operator *= (const bad& l) { return badret; }	\
+  good operator /= (const bad& l) { return badret; }	\
+  good operator + (const bad& l) { return badret; }	\
+  good operator - (const bad& l) { return badret; }	\
+  good operator * (const bad& l) { return badret; }	\
+  good operator / (const bad& l) { return badret; }	\
+							\
+  bool operator < (const bad& l)  { return 0; }		\
+  bool operator <= (const bad& l) { return 0; }		\
+  bool operator > (const bad& l)  { return 0; }		\
+  bool operator >= (const bad& l) { return 0; }		\
+  bool operator == (const bad& l) { return 0; }		\
+  bool operator != (const bad& l) { return 0; }
+
+/* Declare the "bad" or disallowed arithmetic operations between class GOOD
+   and another of the same class, for a position class.  Meant to go inside
+   the private section of class GOOD. */
+
+#define DECLARE_BAD_POS_CLASS_ARITH(good)		\
+  good operator += (const good& l) { return badret; }	\
+  good operator -= (const good& l) { return badret; }	\
+  good operator *= (const good& l) { return badret; }	\
+  good operator /= (const good& l) { return badret; }	\
+  good operator + (const good& l) { return badret; }	\
+  good operator * (const good& l) { return badret; }	\
+  good operator / (const good& l) { return badret; }
+
+/* Basic declaration at the top of all integral classes.  Don't call
+   directly, use one of the more specific versions below. */
+
+#define DECLARE_INTCLASS(cl)			\
+ public:					\
+  EMACS_INT data;				\
+  cl () { data = 0xCDCDCDCD; }			\
+  cl (int i) { data = i; }			\
+  cl (unsigned int i) { data = i; }		\
+  cl (long i) { data = i; }			\
+  cl (unsigned long i) { data = i; }		\
+  cl (short i) { data = i; }			\
+  cl (unsigned short i) { data = i; }		\
+  operator EMACS_INT ()  const { return data; }
+
+/* Basic declaration at the top of all count classes. */
+
+#define DECLARE_COUNT_CLASS(cl)				\
+  DECLARE_INTCLASS (cl)					\
+  DECLARE_INTCLASS_ARITH_COMPARE (cl, cl)		\
+ private:						\
+  static cl badret;
+
+/* Basic declaration at the bottom of the prelude of all position classes.
+   Don't call directly. */
+
+#define DECLARE_POS_CLASS_SECOND_HALF(cl, countcl)			     \
+  DECLARE_INTCLASS_ARITH_COMPARE (cl, countcl)				     \
+  countcl operator - (const cl& l) const { return countcl (data - l.data); } \
+ private:								     \
+  static cl badret;							     \
+  DECLARE_BAD_POS_INTCLASS_ARITH (cl)
+
+/* Basic declaration at the top of all buffer position classes. */
+
+#define DECLARE_BPOS_CLASS(cl, countcl)		\
+  DECLARE_INTCLASS (cl)				\
+  DECLARE_POS_CLASS_SECOND_HALF (cl, countcl)
+
+/* Basic declaration at the top of all X-position classes (that can refer
+   to buffers or strings).  CL1 and CL2 are the equivalent more specific
+   classes referring only to buffers or strings, respefitvely. */
+
+#define DECLARE_XPOS_CLASS(cl, countcl, cl1, cl2)	\
+  DECLARE_INTCLASS (cl)					\
+  cl (const cl1& x) { data = x.data; }			\
+  cl (const cl2& x) { data = x.data; }			\
+  operator cl1 () const { return cl1 (data); }		\
+  operator cl2 () const { return cl2 (data); }		\
+  DECLARE_POS_CLASS_SECOND_HALF (cl, countcl)
+
+/* Declare the "bad" or disallowed arithmetic and comparion operations
+   between class CHARCL (a character class) and various non-character
+   classes.  Meant to go inside the private section of class GOOD. */
+
+#define DECLARE_BAD_CHAR_INTCLASS_ARITH_COMPARE(charcl)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (charcl, Bytecount)	\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (charcl, Bytebpos)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (charcl, Bytexpos)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (charcl, Membpos)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (charcl, Memxpos)
+
+/* Declare the "bad" or disallowed arithmetic and comparion operations
+   between class BYTECL (a byte class) and various non-byte classes.
+   Meant to go inside the private section of class GOOD. */
+
+#define DECLARE_BAD_BYTE_INTCLASS_ARITH_COMPARE(bytecl)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (bytecl, Charcount)	\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (bytecl, Charbpos)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (bytecl, Charxpos)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (bytecl, Membpos)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (bytecl, Memxpos)
+
+/* Declare the "bad" or disallowed arithmetic and comparion operations
+   between class BYTECL (a mem class) and various non-mem classes.
+   Meant to go inside the private section of class GOOD. */
+
+#define DECLARE_BAD_MEM_INTCLASS_ARITH_COMPARE(bytecl)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (bytecl, Charcount)	\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (bytecl, Charbpos)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (bytecl, Charxpos)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (bytecl, Bytebpos)		\
+  DECLARE_BAD_INTCLASS_ARITH_COMPARE (bytecl, Bytexpos)
+
+class Charcount
+{
+  DECLARE_COUNT_CLASS (Charcount)
+  DECLARE_BAD_CHAR_INTCLASS_ARITH_COMPARE (Charcount)
+};
+
+class Charbpos
+{
+  DECLARE_BPOS_CLASS (Charbpos, Charcount)
+  DECLARE_BAD_CHAR_INTCLASS_ARITH_COMPARE (Charbpos)
+};
+
+class Charxpos
+{
+  DECLARE_XPOS_CLASS (Charxpos, Charcount, Charbpos, Charcount)
+  DECLARE_BAD_CHAR_INTCLASS_ARITH_COMPARE (Charxpos)
+};
+
+class Bytecount
+{
+  DECLARE_COUNT_CLASS (Bytecount)
+  DECLARE_BAD_BYTE_INTCLASS_ARITH_COMPARE (Bytecount)
+};
+
+class Bytebpos
+{
+  DECLARE_BPOS_CLASS (Bytebpos, Bytecount)
+  DECLARE_BAD_BYTE_INTCLASS_ARITH_COMPARE (Bytebpos)
+};
+
+class Bytexpos
+{
+  DECLARE_XPOS_CLASS (Bytexpos, Bytecount, Bytebpos, Bytecount)
+  DECLARE_BAD_BYTE_INTCLASS_ARITH_COMPARE (Bytexpos)
+};
+
+class Membpos
+{
+  DECLARE_BPOS_CLASS (Membpos, Bytecount)
+  DECLARE_BAD_MEM_INTCLASS_ARITH_COMPARE (Membpos)
+};
+
+class Memxpos
+{
+  DECLARE_XPOS_CLASS (Memxpos, Bytecount, Membpos, Bytecount)
+  DECLARE_BAD_MEM_INTCLASS_ARITH_COMPARE (Memxpos)
+};
+
+#define DECLARE_POINTER_TYPE_ARITH_COUNT(pointer, countcl)	\
+inline pointer operator += (pointer & x, const countcl& y)	\
+{ x += y.data; return x; }					\
+inline pointer operator -= (pointer & x, const countcl& y)	\
+{ x -= y.data; return x; }					\
+inline pointer operator + (pointer x, const countcl& y)		\
+{ return x + y.data; }						\
+inline pointer operator - (pointer x, const countcl& y)		\
+{ return x - y.data; }
+
+#define DECLARE_INTEGRAL_TYPE_ARITH_COUNT(integral, countcl)	\
+inline integral operator += (integral & x, const countcl& y)	\
+{ x += y.data; return x; }					\
+inline integral operator -= (integral & x, const countcl& y)	\
+{ x -= y.data; return x; }					\
+inline countcl operator + (integral x, const countcl& y)	\
+{ return countcl (x + y.data); }				\
+inline countcl operator - (integral x, const countcl& y)	\
+{ return countcl (x - y.data); }
+
+#define DECLARE_INTEGRAL_TYPE_COMPARE(integral, cl)	\
+inline bool operator < (integral x, const cl& y)	\
+  { return (EMACS_INT) x < y.data; }			\
+inline bool operator <= (integral x, const cl& y)	\
+  { return (EMACS_INT) x <= y.data; }			\
+inline bool operator > (integral x, const cl& y)	\
+  { return (EMACS_INT) x > y.data; }			\
+inline bool operator >= (integral x, const cl& y)	\
+  { return (EMACS_INT) x >= y.data; }			\
+inline bool operator == (integral x, const cl& y)	\
+  { return (EMACS_INT) x == y.data; }			\
+inline bool operator != (integral x, const cl& y)	\
+  { return (EMACS_INT) x != y.data; }
+
+#if 0
+/* Unfortunately C++ doesn't let you overload the ?: operator, so we have
+   to manually deal with ambiguities using casting */
+#define DECLARE_INTEGRAL_TYPE_TRISTATE(integral, cl)	\
+inline cl operator ?: (bool b, integral x, const cl& y)	\
+  { return b ? cl (x) : y; }				\
+inline cl operator ?: (bool b, const cl& x, integral y)	\
+  { return b ? x : cl (y); }
+#endif /* 0 */
+
+DECLARE_POINTER_TYPE_ARITH_COUNT (const Intbyte *, Bytecount);
+DECLARE_POINTER_TYPE_ARITH_COUNT (const Extbyte *, Bytecount);
+DECLARE_POINTER_TYPE_ARITH_COUNT (Intbyte *, Bytecount);
+DECLARE_POINTER_TYPE_ARITH_COUNT (Extbyte *, Bytecount);
+
+DECLARE_INTEGRAL_TYPE_ARITH_COUNT (int, Bytecount);
+DECLARE_INTEGRAL_TYPE_ARITH_COUNT (int, Charcount);
+DECLARE_INTEGRAL_TYPE_ARITH_COUNT (unsigned int, Bytecount);
+DECLARE_INTEGRAL_TYPE_ARITH_COUNT (unsigned int, Charcount);
+DECLARE_INTEGRAL_TYPE_ARITH_COUNT (long, Bytecount);
+DECLARE_INTEGRAL_TYPE_ARITH_COUNT (long, Charcount);
+DECLARE_INTEGRAL_TYPE_ARITH_COUNT (unsigned long, Bytecount);
+DECLARE_INTEGRAL_TYPE_ARITH_COUNT (unsigned long, Charcount);
+
+DECLARE_INTEGRAL_TYPE_COMPARE (int, Bytecount);
+DECLARE_INTEGRAL_TYPE_COMPARE (int, Charcount);
+DECLARE_INTEGRAL_TYPE_COMPARE (unsigned int, Bytecount);
+DECLARE_INTEGRAL_TYPE_COMPARE (unsigned int, Charcount);
+DECLARE_INTEGRAL_TYPE_COMPARE (long, Bytecount);
+DECLARE_INTEGRAL_TYPE_COMPARE (long, Charcount);
+DECLARE_INTEGRAL_TYPE_COMPARE (unsigned long, Bytecount);
+DECLARE_INTEGRAL_TYPE_COMPARE (unsigned long, Charcount);
+
+#if 0 /* doesn't work */
+inline Bytecount operator - (const Intbyte *x, const Intbyte *y)	\
+  { return Bytecount (x - y); }
+#endif
+
+#define class c_class
+#define this c_this
+
+#endif /* __cplusplus */
+
 /* Counts of elements */
 typedef EMACS_INT Elemcount;
 /* Hash codes */
@@ -1453,7 +1908,7 @@
 {
   Charcount retval;
   if (idx <= (Bytecount) XSTRING_ASCII_BEGIN (s))
-    retval = idx;
+    retval = (Charcount) idx;
   else
     retval = (XSTRING_ASCII_BEGIN (s) +
 	      bytecount_to_charcount (XSTRING_DATA (s) +
@@ -1473,7 +1928,7 @@
 {
   Bytecount retval;
   if (idx <= (Charcount) XSTRING_ASCII_BEGIN (s))
-    retval = idx;
+    retval = (Bytecount) idx;
   else
     retval = (XSTRING_ASCII_BEGIN (s) +
 	      charcount_to_bytecount (XSTRING_DATA (s) +
@@ -1494,10 +1949,10 @@
 {
   Charcount retval;
   if (off + len <= (Bytecount) XSTRING_ASCII_BEGIN (s))
-    retval = len;
+    retval = (Charcount) len;
   else if (off < (Bytecount) XSTRING_ASCII_BEGIN (s))
     retval =
-      XSTRING_ASCII_BEGIN (s) - off +
+      XSTRING_ASCII_BEGIN (s) - (Charcount) off +
 	bytecount_to_charcount (XSTRING_DATA (s) + XSTRING_ASCII_BEGIN (s),
 				len - (XSTRING_ASCII_BEGIN (s) - off));
   else
@@ -1516,13 +1971,16 @@
 )
 {
   Bytecount retval;
-  if (off + len <= (Bytecount) XSTRING_ASCII_BEGIN (s))
-    retval = len;
+  /* casts to avoid errors from combining Bytecount/Charcount and warnings
+     from signed/unsigned comparisons */
+  if (off + (Bytecount) len <= (Bytecount) XSTRING_ASCII_BEGIN (s))
+    retval = (Bytecount) len;
   else if (off < (Bytecount) XSTRING_ASCII_BEGIN (s))
     retval =
       XSTRING_ASCII_BEGIN (s) - off +
 	charcount_to_bytecount (XSTRING_DATA (s) + XSTRING_ASCII_BEGIN (s),
-				len - (XSTRING_ASCII_BEGIN (s) - off));
+				len - (XSTRING_ASCII_BEGIN (s) -
+				       (Charcount) off));
   else
     retval = charcount_to_bytecount (XSTRING_DATA (s) + off, len);
 #ifdef SLEDGEHAMMER_CHECK_ASCII_BEGIN
@@ -1532,7 +1990,7 @@
 }
 
 DECLARE_INLINE_HEADER (
-Intbyte *
+const Intbyte *
 string_char_addr (Lisp_Object s, Charcount idx)
 )
 {
@@ -2699,7 +3157,7 @@
 int object_dead_p (Lisp_Object);
 void mark_object (Lisp_Object obj);
 int marked_p (Lisp_Object obj);
-int need_to_garbage_collect (void);
+extern int need_to_garbage_collect;
 
 #ifdef MEMORY_USAGE_STATS
 Bytecount malloced_storage_size (void *, Bytecount, struct overhead_stats *);
@@ -2811,7 +3269,10 @@
 Lisp_Object wasteful_word_to_lisp (unsigned int);
 
 /* Defined in doc.c */
-Lisp_Object unparesseuxify_doc_string (int, EMACS_INT, Intbyte *, Lisp_Object);
+Lisp_Object unparesseuxify_doc_string (int fd, EMACS_INT position,
+				       Intbyte *name_nonreloc,
+				       Lisp_Object name_reloc,
+				       int standard_doc_file);
 Lisp_Object read_doc_string (Lisp_Object);
 
 /* Defined in doprnt.c */
@@ -3397,6 +3858,7 @@
 /* Defined in process.c */
 DECLARE_DOESNT_RETURN (report_process_error (const char *, Lisp_Object));
 DECLARE_DOESNT_RETURN (report_network_error (const char *, Lisp_Object));
+extern Lisp_Object Vlisp_EXEC_SUFFIXES;
 
 /* Defined in profile.c */
 void mark_profiling_info (void);
@@ -3451,6 +3913,7 @@
 unsigned int hash_string (const Intbyte *, Bytecount);
 Lisp_Object intern_int (const Intbyte *str);
 Lisp_Object intern (const CIntbyte *str);
+Lisp_Object intern_converting_underscores_to_dashes (const CIntbyte *str);
 Lisp_Object oblookup (Lisp_Object, const Intbyte *, Bytecount);
 void map_obarray (Lisp_Object, int (*) (Lisp_Object, void *), void *);
 Lisp_Object indirect_function (Lisp_Object, int);
@@ -3810,7 +4273,11 @@
 void record_change (struct buffer *, Charbpos, Charcount);
 
 /* Defined in unex*.c */
-int unexec (char *, char *, uintptr_t, uintptr_t, uintptr_t);
+#ifdef WIN32_NATIVE
+int unexec (Intbyte *, Intbyte *, uintptr_t, uintptr_t, uintptr_t);
+#else
+int unexec (Extbyte *, Extbyte *, uintptr_t, uintptr_t, uintptr_t);
+#endif
 #ifdef RUN_TIME_REMAP
 int run_time_remap (char *);
 #endif
@@ -4109,15 +4576,16 @@
 
 */
 
-extern Lisp_Object Qactivate_menubar_hook, Qarith_error, Qarrayp, Qautoload;
-extern Lisp_Object Qbackground, Qbackground_pixmap, Qbeginning_of_buffer;
-extern Lisp_Object Qbitp, Qblinking, Qbuffer_glyph_p, Qbuffer_live_p;
-extern Lisp_Object Qbuffer_read_only, Qbyte_code, Qcall_interactively;
-extern Lisp_Object Qcategory_designator_p, Qcategory_table_value_p, Qcdr;
-extern Lisp_Object Qchar_or_string_p, Qcharacterp, Qcircular_list;
-extern Lisp_Object Qcircular_property_list, Qcolor_pixmap_image_instance_p;
-extern Lisp_Object Qcommandp, Qcompletion_ignore_case, Qconsole_live_p;
-extern Lisp_Object Qconst_specifier, Qconversion_error, Qcurrent_menubar;
+extern Lisp_Object Qactivate_menubar_hook, Qand_optional, Qand_rest;
+extern Lisp_Object Qarith_error, Qarrayp, Qautoload, Qbackground;
+extern Lisp_Object Qbackground_pixmap, Qbeginning_of_buffer, Qbitp, Qblinking;
+extern Lisp_Object Qbuffer_glyph_p, Qbuffer_live_p, Qbuffer_read_only;
+extern Lisp_Object Qbyte_code, Qcall_interactively, Qcategory_designator_p;
+extern Lisp_Object Qcategory_table_value_p, Qcdr, Qchar_or_string_p;
+extern Lisp_Object Qcharacterp, Qcircular_list, Qcircular_property_list;
+extern Lisp_Object Qcolor_pixmap_image_instance_p, Qcommandp;
+extern Lisp_Object Qcompletion_ignore_case, Qconsole_live_p, Qconst_specifier;
+extern Lisp_Object Qconversion_error, Qcurrent_menubar;
 extern Lisp_Object Qcyclic_variable_indirection, Qdefun, Qdevice_live_p, Qdim;
 extern Lisp_Object Qdirection, Qdisabled, Qdisabled_command_hook;
 extern Lisp_Object Qdisplay_table, Qdomain_error, Qediting_error;