This commit was generated by cvs2svn to compensate for changes in r1817,
authorkazuhiko <kazuhiko>
Wed, 6 Dec 2000 02:33:44 +0000 (02:33 +0000)
committerkazuhiko <kazuhiko>
Wed, 6 Dec 2000 02:33:44 +0000 (02:33 +0000)
which included commits to RCS files with non-trunk default branches.

86 files changed:
lib-src/ChangeLog
lib-src/Makefile.in.in
lisp/abbrev.el
lisp/buff-menu.el
lisp/byte-optimize.el
lisp/cl-extra.el
lisp/cl-macs.el
lisp/cl.el
lisp/faces.el
lisp/glyphs.el
lisp/indent.el
lisp/info.el
lisp/itimer.el
lisp/lisp-mode.el
lisp/lisp.el
lisp/menubar.el
lisp/mouse.el
lisp/page.el
lisp/paragraphs.el
lisp/picture.el
lisp/rect.el
lisp/simple.el
lisp/term/bg-mouse.el
lisp/view-less.el
lisp/wid-edit.el
lisp/x-mouse.el
lwlib/ChangeLog
lwlib/lwlib-Xlw.c
lwlib/lwlib-Xm.c
lwlib/xlwmenu.c
man/ChangeLog
man/cl.texi
man/info.texi
man/internals/internals.texi
man/lispref/abbrevs.texi
man/lispref/backups.texi
man/lispref/compile.texi
man/lispref/display.texi
man/lispref/help.texi
man/lispref/keymaps.texi
man/lispref/lispref.texi
man/lispref/locals.texi
man/lispref/modes.texi
man/lispref/positions.texi
man/lispref/searching.texi
man/lispref/symbols.texi
man/lispref/syntax.texi
man/lispref/text.texi
man/lispref/tips.texi
man/texinfo.texi
man/xemacs-faq.texi
man/xemacs/calendar.texi
man/xemacs/cmdargs.texi
man/xemacs/frame.texi
man/xemacs/packages.texi
nt/ChangeLog
src/callproc.c
src/device-msw.c
src/dired-msw.c
src/dired.c
src/doc.c
src/editfns.c
src/eldap.c
src/event-Xt.c
src/event-msw.c
src/event-stream.c
src/fileio.c
src/filelock.c
src/free-hook.c
src/glyphs-x.c
src/gpmevent.c
src/inline.c
src/keymap.c
src/menubar-x.c
src/print.c
src/realpath.c
src/regex.h
src/s/cygwin32.h
src/symeval.h
src/unexcw.c
src/unexelf.c
src/unexelfsgi.c
tests/ChangeLog
tests/automated/lisp-tests.el
tests/automated/test-harness.el
version.sh

index da7bcf0..5fa22ce 100644 (file)
@@ -1,3 +1,11 @@
+2000-12-05  Martin Buchholz <martin@xemacs.org>
+
+       * XEmacs 21.2.38 is released.
+
+2000-11-13  Yoshiki Hayashi  <yoshiki@xemacs.org>
+
+       * Makefile.in.in: Define emacs iff it's necessary.
+
 2000-11-14  Martin Buchholz <martin@xemacs.org>
 
        * XEmacs 21.2.37 is released.
index 2a64d1d..33dd10c 100644 (file)
@@ -160,7 +160,7 @@ ld_libs_general=@ld_libs_general@
 ## Where will the generated files like config.h be included from?
 ## This is also why you _must_ use <...> instead of "..." 
 ## when #include'ing generated files.
-cppflags = -Demacs -I. -I../src -I$(srcdir) -I$(top_srcdir)/src $(CPPFLAGS)
+cppflags = -I. -I../src -I$(srcdir) -I$(top_srcdir)/src $(CPPFLAGS)
 cflags   = $(CFLAGS) $(cppflags) $(c_switch_general)
 ldflags  = $(LDFLAGS) $(ld_switch_general) $(ld_libs_general)
 
@@ -281,7 +281,7 @@ alloca.o: ${top_srcdir}/src/alloca.c
        ${CC} -c $(cflags) ${srcdir}/../src/alloca.c
 
 regex.o: ${srcdir}/../src/regex.c ${top_srcdir}/src/regex.h
-       $(CC) -c `echo $(cflags) | sed 's/-Demacs/ /'` \
+       $(CC) -c $(cflags) \
        -DINHIBIT_STRING_HEADER ${top_srcdir}/src/regex.c
 
 etags_args = $(cflags) -DVERSION='"${version}"' ${srcdir}/etags.c \
@@ -319,7 +319,7 @@ make-docfile: ${srcdir}/make-docfile.c
        $(CC) $(cflags) ${srcdir}/make-docfile.c $(ldflags) -o $@
 
 digest-doc: ${srcdir}/digest-doc.c
-       $(CC) $(cflags) ${srcdir}/digest-doc.c $(ldflags) -o $@
+       $(CC) -Demacs $(cflags) ${srcdir}/digest-doc.c $(ldflags) -o $@
 
 sorted-doc: ${srcdir}/sorted-doc.c
        $(CC) $(cflags) ${srcdir}/sorted-doc.c $(ldflags) -o $@
@@ -378,7 +378,7 @@ mmencode : ${srcdir}/mmencode.c
 ## because XEmacs provides built-in timer facilities.
 
 make-path: ${srcdir}/make-path.c ../src/config.h
-       $(CC) $(cflags) ${srcdir}/make-path.c -o $@
+       $(CC) -Demacs $(cflags) ${srcdir}/make-path.c -o $@
 
 ## These are NOT included in INSTALLABLES or UTILITIES.
 ## See ../src/Makefile.in.in.
index eaf3c8b..75ce53b 100644 (file)
@@ -88,15 +88,9 @@ of the form (ABBREVNAME EXPANSION HOOK USECOUNT)."
   "Define an abbrev in TABLE named NAME, to expand to EXPANSION or call HOOK.
 NAME and EXPANSION are strings.  Hook is a function or `nil'.
 To undefine an abbrev, define it with an expansion of `nil'."
-  (unless (or (null expansion) (stringp expansion))
-    (setq expansion (wrong-type-argument 'stringp expansion)))
-
-  (unless (or (null count) (integerp count))
-    (setq count (wrong-type-argument 'fixnump count)))
-
-  (unless (vectorp table)
-    (setq table (wrong-type-argument 'vectorp table)))
-
+  (check-type expansion (or null string))
+  (check-type count (or null integer))
+  (check-type table vector)
   (let* ((sym (intern name table))
          (oexp (and (boundp sym) (symbol-value sym)))
          (ohook (and (fboundp sym) (symbol-function sym))))
@@ -426,7 +420,7 @@ ARG is the argument to `add-global-abbrev' or `add-mode-abbrev'."
        (buffer-substring
        (point)
        (if (= arg 0) (mark)
-         (save-excursion (forward-word (- arg)) (point))))))
+         (save-excursion (backward-word arg) (point))))))
 
 (defun add-mode-abbrev (arg)
   "Define mode-specific abbrev for last word(s) before point.
@@ -484,7 +478,7 @@ the user declines to confirm redefining an existing abbrev."
 ARG is the argument to `inverse-add-global-abbrev' or
 `inverse-add-mode-abbrev'."
   (save-excursion
-    (forward-word (- arg))
+    (backward-word arg)
     (buffer-substring (point) (progn (forward-word 1) (point)))))
 
 (defun inverse-add-mode-abbrev (arg)
@@ -511,7 +505,7 @@ Expands the abbreviation after defining it."
 (defun inverse-add-abbrev (table type arg)
   (let (name nameloc exp)
     (save-excursion
-     (forward-word (- arg))
+     (backward-word arg)
      (setq name (buffer-substring (point) (progn (forward-word 1)
                                               (setq nameloc (point))))))
     (set-text-properties 0 (length name) nil name)
@@ -554,7 +548,7 @@ If called from a Lisp program, arguments are START END &optional NOQUERY."
        (if (abbrev-expansion
             (setq string
                   (buffer-substring
-                   (save-excursion (forward-word -1) (point))
+                   (save-excursion (backward-word) (point))
                    pnt)))
            (if (or noquery (y-or-n-p (format "Expand `%s'? " string)))
                (expand-abbrev)))))))
index 5e62c34..482dcc7 100644 (file)
@@ -303,7 +303,7 @@ and then move up one line.  Prefix arg means move that many lines."
     (let ((buff-menu-buffer (current-buffer))
          (buffer-read-only nil))
       (while (search-forward "\nD" nil t)
-       (forward-char -1)
+       (backward-char 1)
        (let ((buf (Buffer-menu-buffer nil)))
          (or (eq buf nil)
              (eq buf buff-menu-buffer)
@@ -312,7 +312,7 @@ and then move up one line.  Prefix arg means move that many lines."
            (progn (delete-char 1)
                   (insert ? ))
          (delete-region (point) (progn (forward-line 1) (point)))
-         (forward-char -1))))))
+         (backward-char 1))))))
 
 (defun Buffer-menu-select ()
   "Select this line's buffer; also display buffers marked with `>'.
index 6f9f8f4..b6c1daa 100644 (file)
@@ -2,8 +2,9 @@
 
 ;;; Copyright (c) 1991, 1994 Free Software Foundation, Inc.
 
-;; Author: Jamie Zawinski <jwz@jwz.org>
-;;     Hallvard Furuseth <hbf@ulrik.uio.no>
+;; Authors: Jamie Zawinski <jwz@jwz.org>
+;;          Hallvard Furuseth <hbf@ulrik.uio.no>
+;;          Martin Buchholz <martin@xemacs.org>
 ;; Keywords: internal
 
 ;; This file is part of XEmacs.
        (progn
 ;;       (if (equal form new) (error "bogus optimizer -- %s" opt))
          (byte-compile-log "  %s\t==>\t%s" form new)
-         (setq new (byte-optimize-form new for-effect))
-         new)
+         (byte-optimize-form new for-effect))
       form)))
 
 
                                (list (apply fun (nreverse constants)))))))))
     form))
 
+;;; It is not safe to optimize calls to arithmetic ops with one arg
+;;; away entirely (actually, it would be safe if we know the sole arg
+;;; is not a marker or if it appears in other arithmetic).
+
+;;; But this degree of paranoia is normally unjustified, so optimize unless
+;;; the user has done (declaim (safety 3)).  Implemented in bytecomp.el.
+
 (defun byte-optimize-plus (form)
-  (setq form (byte-optimize-delay-constants-math form 1 '+))
-  (if (memq 0 form) (setq form (delq 0 (copy-sequence form))))
-  ;;(setq form (byte-optimize-associative-two-args-math form))
-
-  (case (length (cdr form))
-    ((0)                               ; (+)
-     (condition-case ()
-        (eval form)
-       (error form)))
-
-    ;; It is not safe to delete the function entirely
-    ;; (actually, it would be safe if we knew the sole arg
-    ;; is not a marker).
-    ;; ((1)
-    ;;  (nth 1 form))
-
-    ((2)                               ; (+ x y)
-     (byte-optimize-predicate
-      (cond
-       ;; `add1' and `sub1' are a marginally fewer instructions
-       ;; than `plus' and `minus', so use them when possible.
-       ((eq (nth 1 form)  1) `(1+ ,(nth 2 form))) ; (+ 1 x)   -->  (1+ x)
-       ((eq (nth 2 form)  1) `(1+ ,(nth 1 form))) ; (+ x 1)   -->  (1+ x)
-       ((eq (nth 1 form) -1) `(1- ,(nth 2 form))) ; (+ -1 x)  -->  (1- x)
-       ((eq (nth 2 form) -1) `(1- ,(nth 1 form))) ; (+ x -1)  -->  (1- x)
-       (t form))))
+  (byte-optimize-predicate (byte-optimize-delay-constants-math form 1 '+)))
+
+(defun byte-optimize-multiply (form)
+  (setq form (byte-optimize-delay-constants-math form 1 '*))
+  ;; If there is a constant integer in FORM, it is now the last element.
 
+  (case (car (last form))
+    ;; (* x y 0) --> (progn x y 0)
+    (0 (cons 'progn (cdr form)))
     (t (byte-optimize-predicate form))))
 
 (defun byte-optimize-minus (form)
-  ;; Put constants at the end, except the last constant.
+  ;; Put constants at the end, except the first arg.
   (setq form (byte-optimize-delay-constants-math form 2 '+))
-  ;; Now only first and last element can be an integer.
-  (let ((last (last (nthcdr 3 form))))
-    (cond ((eq 0 last)
-          ;; (- x y ... 0)  --> (- x y ...)
-          (setq form (copy-sequence form))
-          (setcdr (cdr (cdr form)) (delq 0 (nthcdr 3 form))))
-         ;; If form is (- CONST foo... CONST), merge first and last.
-         ((and (numberp (nth 1 form))
-               (numberp last))
-          (setq form (nconc (list '- (- (nth 1 form) last) (nth 2 form))
-                            (delq last (copy-sequence (nthcdr 3 form))))))))
-
-  (case (length (cdr form))
-    ((0)                               ; (-)
-     (condition-case ()
-        (eval form)
-       (error form)))
-
-    ;; It is not safe to delete the function entirely
-    ;; (actually, it would be safe if we knew the sole arg
-    ;; is not a marker).
-    ;; ((1)
-    ;;  (nth 1 form)
-
-    ((2)                               ; (+ x y)
-     (byte-optimize-predicate
-      (cond
-       ;; `add1' and `sub1' are a marginally fewer instructions than `plus'
-       ;; and `minus', so use them when possible.
-       ((eq (nth 2 form)  1) `(1- ,(nth 1 form))) ; (- x 1)  --> (1- x)
-       ((eq (nth 2 form) -1) `(1+ ,(nth 1 form))) ; (- x -1) --> (1+ x)
-       ((eq (nth 1 form)  0) `(-  ,(nth 2 form))) ; (- 0 x)  --> (- x)
-       (t form))))
+  ;; Now only the first and last args can be integers.
+  (let ((last (car (last (nthcdr 3 form)))))
+    (cond
+     ;; If form is (- CONST foo... CONST), merge first and last.
+     ((and (numberp (nth 1 form)) (numberp last))
+      (decf (nth 1 form) last)
+      (butlast form))
 
-    (t (byte-optimize-predicate form))))
+     ;; (- 0 x ...)  -->  (- (- x) ...)
+     ((and (eq 0 (nth 1 form)) (>= (length form) 3))
+      `(- (- ,(nth 2 form)) ,@(nthcdr 3 form)))
 
-(defun byte-optimize-multiply (form)
-  (setq form (byte-optimize-delay-constants-math form 1 '*))
-  ;; If there is a constant integer in FORM, it is now the last element.
-  (cond ((null (cdr form)) 1)
-;;; It is not safe to delete the function entirely
-;;; (actually, it would be safe if we know the sole arg
-;;; is not a marker or if it appears in other arithmetic).
-;;;    ((null (cdr (cdr form))) (nth 1 form))
-       ((let ((last (last form)))
-          (byte-optimize-predicate
-           (cond ((eq 0 last)  (cons 'progn (cdr form)))
-                 ((eq 1 last)  (delq 1 (copy-sequence form)))
-                 ((eq -1 last) (list '- (delq -1 (copy-sequence form))))
-                 ((and (eq 2 last)
-                       (memq t (mapcar 'symbolp (cdr form))))
-                  (prog1 (setq form (delq 2 (copy-sequence form)))
-                    (while (not (symbolp (car (setq form (cdr form))))))
-                    (setcar form (list '+ (car form) (car form)))))
-                 (form)))))))
+     (t (byte-optimize-predicate form)))))
 
 (defun byte-optimize-divide (form)
+  ;; Put constants at the end, except the first arg.
   (setq form (byte-optimize-delay-constants-math form 2 '*))
-  ;; If there is a constant integer in FORM, it is now the last element.
-  (let ((last (last (cdr (cdr form)))))
-    (if (numberp last)
-       (cond ((= (length form) 3)
-              (if (and (numberp (nth 1 form))
-                       (not (zerop last))
-                       (condition-case nil
-                           (/ (nth 1 form) last)
-                         (error nil)))
-                  (setq form (list 'progn (/ (nth 1 form) last)))))
-             ((= last 1)
-              (setq form (butlast form)))
-             ((numberp (nth 1 form))
-              (setq form (cons (car form)
-                               (cons (/ (nth 1 form) last)
-                                     (butlast (cdr (cdr form)))))
-                    last nil))))
+  ;; Now only the first and last args can be integers.
+  (let ((last (car (last (nthcdr 3 form)))))
     (cond
-;;;      ((null (cdr (cdr form)))
-;;;       (nth 1 form))
+     ;; If form is (/ CONST foo... CONST), merge first and last.
+     ((and (numberp (nth 1 form)) (numberp last))
+      (condition-case nil
+         (cons (nth 0 form)
+               (cons (/ (nth 1 form) last)
+                     (butlast (cdr (cdr form)))))
+       (error form)))
+
+     ;; (/ 0 x y) --> (progn x y 0)
      ((eq (nth 1 form) 0)
       (append '(progn) (cdr (cdr form)) '(0)))
-     ((eq last -1)
-      (list '- (if (nthcdr 3 form)
-                  (butlast form)
-                (nth 1 form))))
-     (form))))
+
+     ;; We don't have to check for divide-by-zero because `/' does.
+     (t (byte-optimize-predicate form)))))
 
 (defun byte-optimize-logmumble (form)
   (setq form (byte-optimize-delay-constants-math form 1 (car form)))
       (setq ok (byte-compile-constp (car rest))
            rest (cdr rest)))
     (if ok
-       (condition-case ()
+       (condition-case err
            (list 'quote (eval form))
-         (error form))
+         (error
+          (byte-compile-warn "evaluating %s: %s" form err)
+          form))
        form)))
 
 (defun byte-optimize-identity (form)
 (put '*   'byte-optimizer 'byte-optimize-multiply)
 (put '-   'byte-optimizer 'byte-optimize-minus)
 (put '/   'byte-optimizer 'byte-optimize-divide)
+(put '%   'byte-optimizer 'byte-optimize-predicate)
 (put 'max 'byte-optimizer 'byte-optimize-associative-math)
 (put 'min 'byte-optimizer 'byte-optimize-associative-math)
 
 (put 'if    'byte-optimizer 'byte-optimize-if)
 (put 'while 'byte-optimizer 'byte-optimize-while)
 
-;; Remove any reason for avoiding `char-before'.
-(defun byte-optimize-char-before (form)
-  `(char-after (1- ,(or (nth 1 form) '(point))) ,@(cdr (cdr form))))
+;; The supply of bytecodes is small and constrained by backward compatibility.
+;; Several functions have byte-coded versions and hence are very efficient.
+;; Related functions which can be expressed in terms of the byte-coded
+;; ones should be transformed into bytecoded calls for efficiency.
+;; This is especially the case for functions with a backward- and
+;; forward- version, but with a bytecode only for the forward one.
 
-(put 'char-before 'byte-optimizer 'byte-optimize-char-before)
+;; Some programmers have hand-optimized calls like (backward-char)
+;; into the call (forward-char -1).
+;; But it's so much nicer for the byte-compiler to do this automatically!
+
+;; (char-before) ==> (char-after (1- (point)))
+(put 'char-before   'byte-optimizer 'byte-optimize-char-before)
+(defun byte-optimize-char-before (form)
+  `(char-after
+    ,(cond
+      ((null (nth 1 form))
+       '(1- (point)))
+      ((equal '(point) (nth 1 form))
+       '(1- (point)))
+      (t `(1- (or ,(nth 1 form) (point)))))
+    ,@(cdr (cdr form))))
+
+;; (backward-char n) ==> (forward-char (- n))
+(put 'backward-char 'byte-optimizer 'byte-optimize-backward-char)
+(defun byte-optimize-backward-char (form)
+  `(forward-char
+    ,(typecase (nth 1 form)
+       (null -1)
+       (integer (- (nth 1 form)))
+       (t `(- (or ,(nth 1 form) 1))))
+    ,@(cdr (cdr form))))
+
+;; (backward-word n) ==> (forward-word (- n))
+(put 'backward-word 'byte-optimizer 'byte-optimize-backward-word)
+(defun byte-optimize-backward-word (form)
+  `(forward-word
+    ,(typecase (nth 1 form)
+       (null -1)
+       (integer (- (nth 1 form)))
+       (t `(- (or ,(nth 1 form) 1))))
+    ,@(cdr (cdr form))))
+
+;; The following would be a valid optimization of the above kind, but
+;; the gain in performance is very small, since the saved funcall is
+;; counterbalanced by the necessity of adding a bytecode for (point).
+;;
+;; Also, users are more likely to have modified the behavior of
+;; delete-char via advice or some similar mechanism.  This is much
+;; less of a problem for the previous functions because it wouldn't
+;; make sense to modify the behaviour of `backward-char' without also
+;; modifying `forward-char', for example.
+
+;; (delete-char n) ==> (delete-region (point) (+ (point) n))
+;; (put 'delete-char 'byte-optimizer 'byte-optimize-delete-char)
+;; (defun byte-optimize-delete-char (form)
+;;   (case (length (cdr form))
+;;     (0 `(delete-region (point) (1+ (point))))
+;;     (1 `(delete-region (point) (+ (point) ,(nth 1 form))))
+;;     (t form)))
 
 ;; byte-compile-negation-optimizer lives in bytecomp.el
 ;(put '/= 'byte-optimizer 'byte-compile-negation-optimizer)
 (put 'atom 'byte-optimizer 'byte-compile-negation-optimizer)
 (put 'nlistp 'byte-optimizer 'byte-compile-negation-optimizer)
 
-
 (defun byte-optimize-funcall (form)
   ;; (funcall '(lambda ...) ...) ==> ((lambda ...) ...)
   ;; (funcall 'foo ...) ==> (foo ...)
 
 (defun byte-compile-splice-in-already-compiled-code (form)
   ;; form is (byte-code "..." [...] n)
-  (if (not (memq byte-optimize '(t lap)))
+  (if (not (memq byte-optimize '(t byte)))
       (byte-compile-normal-call form)
     (byte-inline-lapcode
      (byte-decompile-bytecode-1 (nth 1 form) (nth 2 form) t))
index 97ca310..2acba6a 100644 (file)
@@ -76,8 +76,8 @@ TYPE is a Common Lisp type specifier."
        ((eq type 'array) (if (arrayp x) x (vconcat x)))
        ((and (eq type 'character) (stringp x) (= (length x) 1)) (aref x 0))
        ((and (eq type 'character) (symbolp x)) (coerce (symbol-name x) type))
-       ((and (eq type 'character) (numberp x) (char-or-char-int-p x)
-             (int-char x)))
+       ((and (eq type 'character) (char-int-p x)) (int-char x))
+       ((and (eq type 'integer) (characterp x)) (char-int x))
        ((eq type 'float) (float x))
        ((eq type 'bit-vector) (if (bit-vector-p x) x
                                 (apply 'bit-vector (append x nil))))
index 6eddb94..5a9ab08 100644 (file)
@@ -1434,13 +1434,15 @@ values.  For compatibility, (values A B C) is a synonym for (list A B C)."
 
        ((eq (car-safe spec) 'optimize)
         (let ((speed (assq (nth 1 (assq 'speed (cdr spec)))
-                           '((0 nil) (1 t) (2 t) (3 t))))
+                           '((0 . nil) (1 . t) (2 . t) (3 . t))))
               (safety (assq (nth 1 (assq 'safety (cdr spec)))
-                            '((0 t) (1 t) (2 t) (3 nil)))))
-          (if speed (setq cl-optimize-speed (car speed)
-                          byte-optimize (nth 1 speed)))
-          (if safety (setq cl-optimize-safety (car safety)
-                           byte-compile-delete-errors (nth 1 safety)))))
+                            '((0 . t) (1 . t) (2 . t) (3 . nil)))))
+          (when speed
+            (setq cl-optimize-speed (car speed)
+                  byte-optimize (cdr speed)))
+          (when safety
+            (setq cl-optimize-safety (car safety)
+                  byte-compile-delete-errors (cdr safety)))))
 
        ((and (eq (car-safe spec) 'warn) (boundp 'byte-compile-warnings))
         (if (eq byte-compile-warnings t)
@@ -2440,18 +2442,26 @@ TYPE is a Common Lisp-style type specifier."
   (eval (cl-make-type-test 'object type)))
 
 ;;;###autoload
-(defmacro check-type (form type &optional string)
-  "Verify that FORM is of type TYPE; signal an error if not.
+(defmacro check-type (place type &optional string)
+  "Verify that PLACE is of type TYPE; signal a continuable error if not.
 STRING is an optional description of the desired type."
-  (and (or (not (cl-compiling-file))
-          (< cl-optimize-speed 3) (= cl-optimize-safety 3))
-       (let* ((temp (if (cl-simple-expr-p form 3) form (gensym)))
-             (body (list 'or (cl-make-type-test temp type)
-                         (list 'signal '(quote wrong-type-argument)
-                               (list 'list (or string (list 'quote type))
-                                     temp (list 'quote form))))))
-        (if (eq temp form) (list 'progn body nil)
-          (list 'let (list (list temp form)) body nil)))))
+  (when (or (not (cl-compiling-file))
+           (< cl-optimize-speed 3)
+           (= cl-optimize-safety 3))
+    (let* ((temp (if (cl-simple-expr-p place 3) place (gensym)))
+          (test (cl-make-type-test temp type))
+          (signal-error `(signal 'wrong-type-argument
+                                 ,(list 'list (or string (list 'quote type))
+                                        temp (list 'quote place))))
+          (body
+           (condition-case nil
+               `(while (not ,test)
+                  ,(macroexpand `(setf ,place ,signal-error)))
+             (error
+              `(if ,test (progn ,signal-error nil))))))
+      (if (eq temp place)
+         body
+       `(let ((,temp ,place)) ,body)))))
 
 ;;;###autoload
 (defmacro assert (form &optional show-args string &rest args)
@@ -2750,6 +2760,8 @@ surrounded by (block NAME ...)."
    (fifth 'nth 4 x) (sixth 'nth 5 x) (seventh 'nth 6 x)
    (eighth 'nth 7 x) (ninth 'nth 8 x) (tenth 'nth 9 x)
    (rest 'cdr x) (endp 'null x) (plusp '> x 0) (minusp '< x 0)
+   (oddp  'eq (list 'logand x 1) 1)
+   (evenp 'eq (list 'logand x 1) 0)
    (caar car car) (cadr car cdr) (cdar cdr car) (cddr cdr cdr)
    (caaar car caar) (caadr car cadr) (cadar car cdar)
    (caddr car cddr) (cdaar cdr caar) (cdadr cdr cadr)
@@ -2764,7 +2776,6 @@ surrounded by (block NAME ...)."
 (proclaim '(inline floatp-safe acons map concatenate notany notevery
 ;; XEmacs change
                   cl-set-elt revappend nreconc
-                  plusp minusp oddp evenp
                   ))
 
 ;;; Things that are side-effect-free.  Moved to byte-optimize.el
index 03cfdf1..33c554c 100644 (file)
@@ -337,34 +337,29 @@ The name is made by appending a number to PREFIX, default \"G\"."
 
 ;;; Numbers.
 
-(defun floatp-safe (x)
-  "Return t if OBJECT is a floating point number.
-On Emacs versions that lack floating-point support, this function
-always returns nil."
-  ;;(and (numberp x) (not (integerp x)))
-  ;; XEmacs: use floatp.  XEmacs is always compiled with
-  ;; floating-point, anyway.
-  (floatp x))
-
-(defun plusp (x)
+(defun floatp-safe (object)
+  "Return t if OBJECT is a floating point number."
+  (floatp object))
+
+(defun plusp (number)
   "Return t if NUMBER is positive."
-  (> x 0))
+  (> number 0))
 
-(defun minusp (x)
+(defun minusp (number)
   "Return t if NUMBER is negative."
-  (< x 0))
+  (< number 0))
 
-(defun oddp (x)
+(defun oddp (integer)
   "Return t if INTEGER is odd."
-  (eq (logand x 1) 1))
+  (eq (logand integer 1) 1))
 
-(defun evenp (x)
+(defun evenp (integer)
   "Return t if INTEGER is even."
-  (eq (logand x 1) 0))
+  (eq (logand integer 1) 0))
 
-(defun cl-abs (x)
-  "Return the absolute value of ARG."
-  (if (>= x 0) x (- x)))
+(defun cl-abs (number)
+  "Return the absolute value of NUMBER."
+  (if (>= number 0) number (- number)))
 (or (fboundp 'abs) (defalias 'abs 'cl-abs))   ; This is built-in to Emacs 19
 
 (defvar *random-state* (vector 'cl-random-state-tag -1 30 (cl-random-time)))
index 953025b..d14b45b 100644 (file)
@@ -1636,7 +1636,7 @@ expected in this case, other types of image data will not work.
 If the optional FRAME argument is provided, change only
 in that frame; otherwise change each frame."
   (while (not (find-face face))
-    (setq face (signal 'wrong-type-argument (list 'facep face))))
+    (setq face (wrong-type-argument 'facep face)))
   (let ((bitmap-path (ecase (console-type)
                       (x         x-bitmap-file-path)
                       (mswindows mswindows-bitmap-file-path)))
@@ -1661,8 +1661,7 @@ in that frame; otherwise change each frame."
                   (and (listp pixmap) (= (length pixmap) 3)))))
        (setq pixmap (signal 'wrong-type-argument
                             (list 'stipple-pixmap-p pixmap)))))
-    (while (and frame (not (framep frame)))
-      (setq frame (signal 'wrong-type-argument (list 'framep frame))))
+    (check-type frame (or null frame))
     (set-face-background-pixmap face instantiator frame)))
 
 \f
index 4e31321..c150670 100644 (file)
@@ -1023,7 +1023,8 @@ If unspecified in a particular domain, `nontext-pointer-glyph' is used.")
                                 [jpeg :data nil] 2)))
        ,@(if (featurep 'png) '(("\\.png\\'" [png :file nil] 2)))
        ,@(if (featurep 'png) '(("\\`\211PNG" [png :data nil] 2)))
-       ("" [autodetect :data nil] 2))))
+       ("" [string :data nil] 2)
+       ("" [nothing]))))
   ;; #### this should really be formatted-string, not string but we
   ;; don't have it implemented yet
   ;;
index 5c642cf..8208126 100644 (file)
@@ -470,7 +470,7 @@ Use \\[edit-tab-stops] to edit them interactively."
                (let ((tabend (* (/ (current-column) tab-width) tab-width)))
                  (while (and (> (current-column) tabend)
                              (eq (char-before (point)) ?\ ))
-                   (forward-char -1))
+                   (backward-char 1))
                  (delete-region (point) before))))))))
 
 ;(define-key global-map "\t" 'indent-for-tab-command)
index bc8f765..3186cdb 100644 (file)
@@ -2008,7 +2008,7 @@ NAME may be an abbreviation of the reference name."
            ;; Kludge.
            ;; Allow dots in node name not followed by whitespace.
            (re-search-forward
-            (concat "\\(([^)]+)[^."
+            (concat "\\(([^)]+)[^.,"
                     (if multi-line "" "\n")
                     "]*\\|\\([^.,\t"
                     (if multi-line "" "\n")
@@ -3103,7 +3103,7 @@ The locations are of the format used in Info-history, i.e.
            (forward-char 1)
            (insert "\n")
            (just-one-space)
-           (backward-delete-char 1)
+           (delete-backward-char 1)
            (setq p (point)
                  len 0))))
       (toggle-read-only 1)
index 5199917..705df24 100644 (file)
@@ -167,7 +167,7 @@ This is a macro."
 (defun itimer-live-p (object)
   "Return non-nil if OBJECT is an itimer and is active.
 ``Active'' means Emacs will run it when it expires.
-`activate-timer' must be called on an itimer to make it active.
+`activate-itimer' must be called on an itimer to make it active.
 Itimers started with `start-itimer' are automatically active."
   (and (itimerp object) (memq object itimer-list)))
 
index d0278b1..8fcec45 100644 (file)
@@ -545,7 +545,7 @@ rigidly along with this one."
       (if (and (looking-at "\\s<") (not (looking-at "\\s<\\s<")))
          ;; Single-semicolon comment lines should be indented
          ;; as comment lines, not as code.
-         (progn (indent-for-comment) (forward-char -1))
+         (progn (indent-for-comment) (backward-char 1))
        (if (listp indent) (setq indent (car indent)))
        (setq shift-amt (- indent (current-column)))
        (if (zerop shift-amt)
index 4226730..c0db1a2 100644 (file)
@@ -206,7 +206,7 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
                          (end-of-line 1)
                          (beginning-of-defun-raw 1)))
                    nil
-                 (or (bobp) (forward-char -1))
+                 (or (bobp) (backward-char 1))
                  (beginning-of-defun-raw -1))
                (setq first nil)
                (forward-list 1)
@@ -279,7 +279,7 @@ before and after, depending on the surrounding characters."
   "Move past next `)', delete indentation before it, then indent after it."
   (interactive)
   (up-list 1)
-  (forward-char -1)
+  (backward-char 1)
   (while (save-excursion               ; this is my contribution
           (let ((before-paren (point)))
             (back-to-indentation)
index a971530..44c5b6a 100644 (file)
@@ -361,8 +361,7 @@ the menu hierarchy.  (\"File\" \"Save\") means the menu item called \"Save\"
 under the toplevel \"File\" menu.  (\"Menu\" \"Foo\" \"Item\") means the
 menu item called \"Item\" under the \"Foo\" submenu of \"Menu\".
 NEW-NAME is the string that the menu item will be printed as from now on."
-  (or (stringp new-name)
-      (setq new-name (wrong-type-argument 'stringp new-name)))
+  (check-type new-name string)
   (let* ((menubar current-menubar)
          (pair (find-menu-item menubar path))
          (item (car pair))
index 67bea91..0c76138 100644 (file)
@@ -748,7 +748,7 @@ at the initial click position."
       (let* ((edges (window-pixel-edges window))
             (row (event-y-pixel event))
             (text-start (nth 1 edges))
-            (text-end (+ (nth 3 edges))))
+            (text-end (nth 3 edges)))
        (if (or (< row text-start)
                (> row text-end))
            nil ;; Scroll
index 196a30a..77502b9 100644 (file)
@@ -53,7 +53,7 @@ A page boundary is any line whose beginning matches the regexp
     (and (save-excursion (re-search-backward page-delimiter nil t))
         (= (match-end 0) (point))
         (goto-char (match-beginning 0)))
-    (forward-char -1)
+    (backward-char 1)
     (if (re-search-backward page-delimiter nil t)
        ;; We found one--move to the end of it.
        (goto-char (match-end 0))
index 0d209a9..f26eb42 100644 (file)
@@ -188,7 +188,7 @@ to which the end of the previous line belongs, or the end of the buffer."
          nil
        (setq start (point))
        ;; Move back over paragraph-separating lines.
-       (forward-char -1) (beginning-of-line)
+       (backward-char 1) (beginning-of-line)
        (while (and (not (bobp))
                    (progn (move-to-left-margin)
                           (looking-at paragraph-separate)))
@@ -335,7 +335,7 @@ negative arg -N means kill forward to Nth end of paragraph."
 (defun end-of-paragraph-text ()
   (let ((opoint (point)))
     (forward-paragraph 1)
-    (if (eq (char-before (point)) ?\n) (forward-char -1))
+    (if (eq (char-before (point)) ?\n) (backward-char 1))
     (if (<= (point) opoint)
        (progn
          (forward-char 1)
index a2b3a21..c618b7a 100644 (file)
@@ -90,7 +90,7 @@ With argument, move that many columns."
     ;; but we might as well let the user move across them.
     (and (< arg 0)
         (> (current-column) target-column)
-        (forward-char -1))))
+        (backward-char 1))))
 
 (defun picture-backward-column (arg)
   "Move cursor left, making whitespace if necessary.
@@ -207,7 +207,7 @@ Do \\[command-apropos] `picture-movement' to see those commands."
     (delete-char -1)
     ;; FSF changes the following to last-command-event.
     (insert last-command-char)
-    (forward-char -1)
+    (backward-char 1)
     (picture-move)
     ;; XEmacs addition:
     (setq zmacs-region-stays nil)))
index 75ba30c..6f42ee4 100644 (file)
@@ -201,7 +201,7 @@ deleted."
     (goto-char start)
     (while (search-forward "\t" end t)
       (let ((width (- (current-column)
-                     (save-excursion (forward-char -1)
+                     (save-excursion (backward-char 1)
                                      (current-column)))))
        (setq line (concat (substring line 0 (- (point) end 1))
                           (spaces-string width)
index eb9ebee..51cc77d 100644 (file)
@@ -305,7 +305,7 @@ Leave one space or none, according to the context."
   (save-excursion
     (delete-horizontal-space)
     (if (or (looking-at "^\\|\\s)")
-           (save-excursion (forward-char -1)
+           (save-excursion (backward-char 1)
                            (looking-at "$\\|\\s(\\|\\s'")))
        nil
       (insert ?\ ))))
@@ -422,11 +422,11 @@ and KILLP is t if a prefix arg was specified."
       (while (and (> count 0) (not (bobp)))
        (if (eq (char-before (point)) ?\t) ; XEmacs
            (let ((col (current-column)))
-             (forward-char -1)
+             (backward-char 1)
              (setq col (- col (current-column)))
              (insert-char ?\ col)
              (delete-char 1)))
-       (forward-char -1)
+       (backward-char 1)
        (setq count (1- count)))))
   (delete-backward-char arg killp)
   ;; XEmacs: In overwrite mode, back over columns while clearing them out,
@@ -440,11 +440,11 @@ If nil, the DEL key will erase one character backwards."
   :type 'boolean
   :group 'editing-basics)
 
-(defcustom backward-delete-function 'backward-delete-char
+(defcustom backward-delete-function 'delete-backward-char
   "*Function called to delete backwards on a delete keypress.
 If `delete-key-deletes-forward' is nil, `backward-or-forward-delete-char'
 calls this function to erase one character backwards.  Default value
-is 'backward-delete-char, with 'backward-delete-char-untabify being a
+is `delete-backward-char', with `backward-delete-char-untabify' being a
 popular alternate setting."
   :type 'function
   :group 'editing-basics)
@@ -2346,7 +2346,7 @@ With prefix arg ARG, effect is to take character before point
 and drag it forward past ARG other characters (backward if ARG negative).
 If no argument and at end of line, the previous two chars are exchanged."
   (interactive "*P")
-  (and (null arg) (eolp) (forward-char -1))
+  (and (null arg) (eolp) (backward-char 1))
   (transpose-subr 'forward-char (prefix-numeric-value arg)))
 
 ;;; A very old implementation of transpose-chars from the old days ...
@@ -2356,7 +2356,7 @@ With prefix arg ARG, effect is to take character before point
 and drag it forward past ARG other characters (backward if ARG negative).
 If no argument and not at start of line, the previous two chars are exchanged."
   (interactive "*P")
-  (and (null arg) (not (bolp)) (forward-char -1))
+  (and (null arg) (not (bolp)) (backward-char 1))
   (transpose-subr 'forward-char (prefix-numeric-value arg)))
 
 
@@ -2731,31 +2731,32 @@ not end the comment.  Blank lines do not get comments."
          (forward-char 1)))))
 
 \f
-;; XEmacs - extra parameter
-(defun backward-word (arg &optional buffer)
-  "Move backward until encountering the end of a word.
-With argument, do this that many times.
-In programs, it is faster to call `forward-word' with negative arg."
-  (interactive "_p") ; XEmacs
-  (forward-word (- arg) buffer))
-
-(defun mark-word (arg)
-  "Set mark arg words away from point."
+(defun backward-word (&optional count buffer)
+  "Move point backward COUNT words (forward if COUNT is negative).
+Normally t is returned, but if an edge of the buffer is reached,
+point is left there and nil is returned.
+
+COUNT defaults to 1, and BUFFER defaults to the current buffer."
+  (interactive "_p")
+  (forward-word (- (or count 1)) buffer))
+
+(defun mark-word (&optional count)
+  "Mark the text from point until encountering the end of a word.
+With optional argument COUNT, mark COUNT words."
   (interactive "p")
-  (mark-something 'mark-word 'forward-word arg))
+  (mark-something 'mark-word 'forward-word count))
 
-;; XEmacs modified
-(defun kill-word (arg)
+(defun kill-word (&optional count)
   "Kill characters forward until encountering the end of a word.
-With argument, do this that many times."
+With optional argument COUNT, do this that many times."
   (interactive "*p")
-  (kill-region (point) (save-excursion (forward-word arg) (point))))
+  (kill-region (point) (save-excursion (forward-word count) (point))))
 
-(defun backward-kill-word (arg)
+(defun backward-kill-word (&optional count)
   "Kill characters backward until encountering the end of a word.
 With argument, do this that many times."
-  (interactive "*p") ; XEmacs
-  (kill-word (- arg)))
+  (interactive "*p")
+  (kill-word (- (or count 1))))
 
 (defun current-word (&optional strict)
   "Return the word point is on (or a nearby word) as a string.
@@ -2852,7 +2853,7 @@ indicating whether soft newlines should be inserted.")
                                (and (not (bobp))
                                     (not bounce)
                                     sentence-end-double-space
-                                    (save-excursion (forward-char -1)
+                                    (save-excursion (backward-char 1)
                                                     (and (looking-at "\\. ")
                                                          (not (looking-at "\\.  "))))))
                       (setq first nil)
@@ -2977,7 +2978,7 @@ indicating whether soft newlines should be inserted.")
 ;                            (and (not (bobp))
 ;                                 (not bounce)
 ;                                 sentence-end-double-space
-;                                 (save-excursion (forward-char -1)
+;                                 (save-excursion (backward-char 1)
 ;                                                 (and (looking-at "\\. ")
 ;                                                      (not (looking-at "\\.  "))))))
 ;                   (setq first nil)
@@ -3143,7 +3144,7 @@ unless optional argument SOFT is non-nil."
            (and comment-end (not (equal comment-end ""))
   ;           (if (not comment-multi-line)
                     (progn
-                      (forward-char -1)
+                      (backward-char 1)
                       (insert comment-end)
                       (forward-char 1))
   ;             (setq comment-column (+ comment-column (length comment-start))
@@ -3153,7 +3154,7 @@ unless optional argument SOFT is non-nil."
            (if (not (eolp))
                (setq comment-end ""))
            (insert ?\n)
-           (forward-char -1)
+           (backward-char 1)
            (indent-for-comment)
            (save-excursion
              ;; Make sure we delete the newline inserted above.
@@ -3318,7 +3319,7 @@ when it is off screen."
        ;; Verify an even number of quoting characters precede the close.
        (= 1 (logand 1 (- (point)
                         (save-excursion
-                          (forward-char -1)
+                          (backward-char 1)
                           (skip-syntax-backward "/\\")
                           (point)))))
        (let* ((oldpos (point))
index e75f35e..cc4291a 100644 (file)
@@ -201,7 +201,7 @@ Sexp is inserted into the buffer at point (where the text cursor is)."
       (indent-according-to-mode))
      ;; In Lisp assume double-quote is closing; in Text assume opening.
      ;; Why?  Because it does the right thing most often.
-     ((save-excursion (forward-char -1)
+     ((save-excursion (backward-char 1)
                      (and (not (looking-at "\\s\""))
                           (looking-at "[`'\"\\]\\|\\s(")))
       nil)
index bc41a17..7dd3e30 100644 (file)
@@ -289,7 +289,7 @@ turned into (+)."
     (while (= (following-char) ?\C-h)
       (delete-char 1))
     (while (search-forward "\C-h" nil t)
-      (forward-char -2)
+      (backward-char 2)
       (cond ((looking-at "_\C-h\\|\\(.\\)\C-h\\1\\||\C-h\\^")
             (delete-char 2))
            ((looking-at ".\C-h_\\|\\^\C-h|")
index 3f22c46..dfcdbe4 100644 (file)
@@ -1350,7 +1350,7 @@ With optional ARG, move across that many fields."
          (t
           (when (and (null arg)
                      (= last-non-space (point)))
-            (forward-char -1))
+            (backward-char 1))
           (transpose-chars arg)))))
 
 (defcustom widget-complete-field (lookup-key global-map "\M-\t")
index 3db5e6c..ca38faa 100644 (file)
@@ -101,39 +101,41 @@ to the cut buffer."
       nil
     (set-glyph-image text-pointer-glyph
          (or (x-get-resource "textPointer" "Cursor" 'string device nil 'warn)
-             "xterm"))
+             [cursor-font :data "xterm"]))
     (set-glyph-image selection-pointer-glyph
          (or (x-get-resource "selectionPointer" "Cursor" 'string device
                              nil 'warn)
-             "top_left_arrow"))
+             [cursor-font :data "top_left_arrow"]))
     (set-glyph-image nontext-pointer-glyph
          (or (x-get-resource "spacePointer" "Cursor" 'string device nil 'warn)
-             "xterm")) ; was "crosshair"
+             [cursor-font :data "xterm"])) ; was "crosshair"
     (set-glyph-image modeline-pointer-glyph
          (or (x-get-resource "modeLinePointer" "Cursor" 'string device
                              nil 'warn)
 ;;           "fleur"))
-             "sb_v_double_arrow"))
+             [cursor-font :data "sb_v_double_arrow"]))
     (set-glyph-image gc-pointer-glyph
          (or (x-get-resource "gcPointer" "Cursor" 'string device nil 'warn)
-             "watch"))
+             [cursor-font :data "watch"]))
     (when (featurep 'scrollbar)
       (set-glyph-image
        scrollbar-pointer-glyph
        (or (x-get-resource "scrollbarPointer" "Cursor" 'string device
                           nil 'warn)
-          "top_left_arrow")))
+          ;; bizarrely if we don't specify the specific locale (x) this
+          ;; gets instantiated on the stream device. Bad puppy.
+          [cursor-font :data "top_left_arrow"]) 'global '(default x)))
     (set-glyph-image busy-pointer-glyph
          (or (x-get-resource "busyPointer" "Cursor" 'string device nil 'warn)
-             "watch"))
+             [cursor-font :data "watch"]))
     (set-glyph-image toolbar-pointer-glyph
          (or (x-get-resource "toolBarPointer" "Cursor" 'string device
                              nil 'warn)
-             "left_ptr"))
+             [cursor-font :data "left_ptr"]))
     (set-glyph-image divider-pointer-glyph
          (or (x-get-resource "dividerPointer" "Cursor" 'string device
                              nil 'warn)
-             "sb_h_double_arrow"))
+             [cursor-font :data "sb_h_double_arrow"]))
     (let ((fg
           (x-get-resource "pointerColor" "Foreground" 'string device
                           nil 'warn)))
index 776a3b8..07d6f5d 100644 (file)
@@ -1,3 +1,49 @@
+2000-12-05  Martin Buchholz <martin@xemacs.org>
+
+       * XEmacs 21.2.38 is released.
+
+2000-11-30  Andy Piper  <andy@xemacs.org>
+
+       * lwlib-Xm.c (xm_update_label): Hack to stop %_ labels until
+       someone fixes it properly.
+
+2000-11-24  Andy Piper  <andy@xemacs.org>
+
+       * xlwtabsP.h: add visible flag, realRows and remove displayChildren.
+
+       * xlwtabs.c (TabVisible): new macro. Consults visible flag.
+       (TabsInit): remove displayChildren, add realRows.
+       (TabsConstraintInitialize): ditto.
+       (TabsResize): ditto.
+       (TabsGeometryManager): ditto.
+       (TabsChangeManaged): ditto.
+       (TabsSelect): ditto.
+       (TabsPage): ditto.
+       (TabsHighlight): ditto.
+       (DrawTabs): ditto.
+       (TabLayout): Caclulate rows for all children and whether they
+       should be visible or not..
+       (TabsShuffleRows): shuffle rows based on both real and displayed
+       rows. Adjust visibility of all children.
+       (PreferredSize): ditto.
+
+2000-11-19  Martin Buchholz  <martin@xemacs.org>
+
+       * xlwtabs.c (TabsResize): Don't delete `tab', mark unused instead.
+
+2000-11-18  Martin Buchholz  <martin@xemacs.org>
+
+       * xlwmenu.c (make_windows_if_needed): 
+       (XlwMenuRealize): 
+       The proper type for `mask' is `unsigned long', not `int'.
+
+2000-11-18  Martin Buchholz  <martin@xemacs.org>
+
+       * xlwtabs.c (defaultAccelerators): Add #### to unused var.
+       (TabsResize): Remove unused var.
+       * xlwmenu.c (XlwMenuInitialize): Remove unused vars.
+       * lwlib-Xlw.c (xlw_update_one_widget): Add #### for probable bug.
+
 2000-11-14  Martin Buchholz <martin@xemacs.org>
 
        * XEmacs 21.2.37 is released.
index 71b4959..bfb2dfa 100644 (file)
@@ -549,7 +549,7 @@ xlw_update_one_widget (widget_instance* instance, Widget widget,
       else
        mw = (XlwMenuWidget)widget;
       XtSetArg (al [0], XtNmenu, val);
-      XtSetValues (widget, al, 1);
+      XtSetValues (widget, al, 1); /* #### mw unused! */
     }
 #endif
 #ifdef LWLIB_SCROLLBARS_LUCID
index c3580e7..28dc5f8 100644 (file)
@@ -219,6 +219,10 @@ xm_update_label (widget_instance* instance, Widget widget, widget_value* val)
 
   if (val->value)
     {
+      /* #### Temporary fix. I though Motif was supposed to grok %_
+         type things. */
+      lw_remove_accelerator_spec (val->value);
+  
 #ifdef LWLIB_DIALOGS_MOTIF
       /*
        * Sigh.  The main text of a label is the name field for menubar
index 5fadadf..1d89c0b 100644 (file)
@@ -2325,7 +2325,7 @@ make_windows_if_needed (XlwMenuWidget mw, int n)
   int start_at;
   XSetWindowAttributes xswa;
   Widget p;
-  int mask;
+  unsigned long mask;
   int depth;
   Visual *visual;
   window_state *windows;
@@ -3004,10 +3004,6 @@ XlwMenuInitialize (Widget request, Widget new, ArgList args,
 {
   /* Get the GCs and the widget size */
   XlwMenuWidget mw = (XlwMenuWidget)new;
-
-  XSetWindowAttributes xswa;
-  int mask;
-
   Window window = RootWindowOfScreen (DefaultScreenOfDisplay (XtDisplay (mw)));
   Display *display = XtDisplay (mw);
 
@@ -3044,10 +3040,6 @@ XlwMenuInitialize (Widget request, Widget new, ArgList args,
   make_shadow_gcs      (mw);
   extract_font_extents (mw);
 
-  xswa.background_pixel = mw->core.background_pixel;
-  xswa.border_pixel     = mw->core.border_pixel;
-  mask = CWBackPixel | CWBorderPixel;
-
   mw->menu.popped_up              = False;
   mw->menu.pointer_grabbed        = False;
   mw->menu.next_release_must_exit = False;
@@ -3085,7 +3077,7 @@ XlwMenuRealize (Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
 {
   XlwMenuWidget mw = (XlwMenuWidget)w;
   XSetWindowAttributes xswa;
-  int mask;
+  unsigned long mask;
 
   (*xlwMenuWidgetClass->core_class.superclass->core_class.realize)
     (w, valueMask, attributes);
index 0ba2252..5bd2293 100644 (file)
@@ -1,3 +1,87 @@
+2000-12-05  Martin Buchholz <martin@xemacs.org>
+
+       * XEmacs 21.2.38 is released.
+
+2000-12-01  Martin Buchholz  <martin@xemacs.org>
+
+       * lispref/compile.texi:
+       Document differences between compiler and interpreter.
+
+2000-11-29  Stephen J. Turnbull  <stephen@xemacs.org>
+
+       * internals/index.texi:
+       internals/internals.texi:
+       Change "X Windows" to "the X Window System" randomly.
+       * internals/internals.texi (Glyphs): fiddling, move lwlib to new node.
+       (Lucid Widget Library): new node, added new text, ASCII art, subnode
+        structure.
+       * xemacs/frame.texi (GUI Components): new node.
+       * xemacs/packages.texi: minor updates.
+
+2000-11-10  Stephen J. Turnbull  <stephen@xemacs.org>
+
+       * info.texi (Creating an Info File): Fix typos in xrefs.
+
+2000-11-08  Stephen J. Turnbull  <stephen@xemacs.org>
+
+       * xemacs/cmdargs.texi (Command Switches):  Add documentation of
+       portable dumper switches.  Other minor edits.
+
+2000-11-21  Martin Buchholz  <martin@xemacs.org>
+
+       * lispref/positions.texi (Word Motion):
+       forward-word arg is now optional.
+       backward-word arg is now optional.
+       Remove vile comment advising lisp programmer to use (forward-word -1)
+       instead of (backward-word 1).
+       * lispref/syntax.texi (Parsing Expressions):
+       Similarly for forward-comment.
+       * lispref/text.texi (Deletion):
+       Similarly for delete-char.
+       Similarly for delete-backward-char.
+
+2000-11-09  Martin Buchholz  <martin@xemacs.org>
+
+       * cl.texi (Assertions):
+       Remove claim that elisp doesn't have continuable errors.
+       Document check-type as being continuable.
+
+2000-11-14  Adrian Aichner  <adrian@xemacs.org>
+
+       * xemacs/calendar.texi (Calendar/Diary): Correct INFO-FILE-NAME
+       from elisp to lispref and from emacs to xemacs in relevant ?xefs.
+       This should also serve as a reminder for future merges with GNU
+       Emacs.
+       Unify PRINTED-MANUAL-TITLE to "XEmacs Lisp Reference Manual" and
+       "XEmacs User's Manual" for lispref and xemacs respectively.
+
+2000-11-14  Adrian Aichner  <adrian@xemacs.org>
+
+       * lispref/abbrevs.texi (Abbrevs): Ditto.
+       * lispref/backups.texi (Auto-Saving): Ditto.
+       * lispref/backups.texi (Reverting): Ditto.
+       * lispref/display.texi (The Echo Area): Ditto.
+       * lispref/help.texi (Documentation Basics): Ditto.
+       * lispref/help.texi (Help Functions): Ditto.
+       * lispref/keymaps.texi (Scanning Keymaps): Ditto.
+       * lispref/locals.texi (Standard Buffer-Local Variables): Ditto.
+       * lispref/modes.texi (Auto Major Mode): Ditto.
+       * lispref/positions.texi (List Motion): Ditto.
+       * lispref/searching.texi (Regexp Search): Ditto.
+       * lispref/symbols.texi (Symbol Components): Ditto.
+       * lispref/tips.texi (Comment Tips): Ditto.
+       * lispref/tips.texi (Library Headers): Ditto.
+
+2000-11-14  Adrian Aichner  <adrian@xemacs.org>
+
+       * internals/internals.texi (The Buffer Object): Ditto.
+
+2000-11-14  Adrian Aichner  <adrian@xemacs.org>
+
+       * cl.texi (Hash Tables): Ditto.
+       * texinfo.texi (Other Info Files): Ditto.
+       * xemacs-faq.texi (Q1.0.14): Ditto.
+
 2000-11-14  Martin Buchholz <martin@xemacs.org>
 
        * XEmacs 21.2.37 is released.
index 27d6d72..7e8125a 100644 (file)
@@ -1073,7 +1073,7 @@ exactly equivalent to @code{(setq x y)}, and @code{setq} itself is
 strictly speaking redundant now that @code{setf} exists.  Many
 programmers continue to prefer @code{setq} for setting simple
 variables, though, purely for stylistic or historical reasons.
-The macro @code{(setf x y)} actually expands to @code{(setq x y)},
+The form @code{(setf x y)} actually expands to @code{(setq x y)},
 so there is no performance penalty for using it in compiled code.
 
 @item
@@ -4581,7 +4581,7 @@ This is equivalent to @code{(nconc (mapcar* 'cons @var{keys} @var{values})
 
 @noindent
 Hash tables are now implemented directly in the C code and documented in
-@ref{Hash Tables,,, lispref, XEmacs Lisp Programmer's Manual}.
+@ref{Hash Tables,,, lispref, XEmacs Lisp Reference Manual}.
 
 @ignore
 A @dfn{hash table} is a data structure that maps ``keys'' onto
@@ -5099,20 +5099,19 @@ will also include all non-constant arguments of the top-level
 (assert (> x 10) t "x is too small: %d")
 @end example
 
-This usage of @var{show-args} is an extension to Common Lisp.  In
+This usage of @var{show-args} is a change to Common Lisp.  In
 true Common Lisp, the second argument gives a list of @var{places}
 which can be @code{setf}'d by the user before continuing from the
-error.  Since Emacs Lisp does not support continuable errors, it
-makes no sense to specify @var{places}.
+error.
 @end defspec
 
-@defspec check-type form type [string]
-This form verifies that @var{form} evaluates to a value of type
+@defspec check-type place type &optional string
+This form verifies that @var{place} evaluates to a value of type
 @var{type}.  If so, it returns @code{nil}.  If not, @code{check-type}
-signals a @code{wrong-type-argument} error.  The default error message
-lists the erroneous value along with @var{type} and @var{form}
-themselves.  If @var{string} is specified, it is included in the
-error message in place of @var{type}.  For example:
+signals a continuable @code{wrong-type-argument} error.  The default
+error message lists the erroneous value along with @var{type} and
+@var{place} themselves.  If @var{string} is specified, it is included in
+the error message in place of @var{type}.  For example:
 
 @example
 (check-type x (integer 1 *) "a positive integer")
@@ -5121,10 +5120,10 @@ error message in place of @var{type}.  For example:
 @xref{Type Predicates}, for a description of the type specifiers
 that may be used for @var{type}.
 
-Note that in Common Lisp, the first argument to @code{check-type}
-must be a @var{place} suitable for use by @code{setf}, because
-@code{check-type} signals a continuable error that allows the
-user to modify @var{place}.
+Note that as in Common Lisp, the first argument to @code{check-type}
+should be a @var{place} suitable for use by @code{setf}, because
+@code{check-type} signals a continuable error that allows the user to
+modify @var{place}, most simply by returning a value from the debugger.
 @end defspec
 
 The following error-related macro is also defined:
index 6a12f76..8df0772 100644 (file)
@@ -3,7 +3,7 @@
 @setfilename ../info/info.info
 @settitle Info
 @comment %**end of header
-@comment $Id: info.texi,v 1.4.2.5 2000/09/13 10:57:18 martinb Exp $
+@comment $Id: info.texi,v 1.4.2.6 2000/11/29 08:27:28 stephent Exp $
 
 @dircategory Texinfo documentation system
 @direntry
@@ -886,10 +886,10 @@ function @code{Info-directory} is called.
 @xref{Top,, Overview of Texinfo, texinfo, Texinfo}, to learn how to
 write a Texinfo file.
 
-@xref{Creating an Info File,,, texinfo, Texinfo}, to learn how to create
-an Info file from a Texinfo file.
+@xref{Create an Info File, , Creating an Info File, texinfo, Texinfo},
+to learn how to create an Info file from a Texinfo file.
 
-@xref{Installing an Info File,,, texinfo, Texinfo}, to learn how to
-install an Info file after you have created one.
+@xref{Install an Info File, , Installing an Info File, texinfo, Texinfo},
+to learn how to install an Info file after you have created one.
 
 @bye
index d7e67c5..a59e3c1 100644 (file)
@@ -135,7 +135,7 @@ This Info file contains v1.0 of the XEmacs Internals Manual.
 * Specifiers::
 * Menus::
 * Subprocesses::
-* Interface to X Windows::
+* Interface to the X Window System::
 * Index::
 
 @detailmenu
@@ -7178,19 +7178,19 @@ Many are accessible indirectly in Lisp programs via Lisp primitives.
 @table @code
 @item name
 The buffer name is a string that names the buffer.  It is guaranteed to
-be unique.  @xref{Buffer Names,,, lispref, XEmacs Lisp Programmer's
+be unique.  @xref{Buffer Names,,, lispref, XEmacs Lisp Reference
 Manual}.
 
 @item save_modified
 This field contains the time when the buffer was last saved, as an
-integer.  @xref{Buffer Modification,,, lispref, XEmacs Lisp Programmer's
+integer.  @xref{Buffer Modification,,, lispref, XEmacs Lisp Reference
 Manual}.
 
 @item modtime
 This field contains the modification time of the visited file.  It is
 set when the file is written or read.  Every time the buffer is written
 to the file, this field is compared to the modification time of the
-file.  @xref{Buffer Modification,,, lispref, XEmacs Lisp Programmer's
+file.  @xref{Buffer Modification,,, lispref, XEmacs Lisp Reference
 Manual}.
 
 @item auto_save_modified
@@ -7202,39 +7202,39 @@ the last time the buffer was displayed in a window.
 
 @item undo_list
 This field points to the buffer's undo list.  @xref{Undo,,, lispref,
-XEmacs Lisp Programmer's Manual}.
+XEmacs Lisp Reference Manual}.
 
 @item syntax_table_v
 This field contains the syntax table for the buffer.  @xref{Syntax
-Tables,,, lispref, XEmacs Lisp Programmer's Manual}.
+Tables,,, lispref, XEmacs Lisp Reference Manual}.
 
 @item downcase_table
 This field contains the conversion table for converting text to lower
-case.  @xref{Case Tables,,, lispref, XEmacs Lisp Programmer's Manual}.
+case.  @xref{Case Tables,,, lispref, XEmacs Lisp Reference Manual}.
 
 @item upcase_table
 This field contains the conversion table for converting text to upper
-case.  @xref{Case Tables,,, lispref, XEmacs Lisp Programmer's Manual}.
+case.  @xref{Case Tables,,, lispref, XEmacs Lisp Reference Manual}.
 
 @item case_canon_table
 This field contains the conversion table for canonicalizing text for
 case-folding search.  @xref{Case Tables,,, lispref, XEmacs Lisp
-Programmer's Manual}.
+Reference Manual}.
 
 @item case_eqv_table
 This field contains the equivalence table for case-folding search.
-@xref{Case Tables,,, lispref, XEmacs Lisp Programmer's Manual}.
+@xref{Case Tables,,, lispref, XEmacs Lisp Reference Manual}.
 
 @item display_table
 This field contains the buffer's display table, or @code{nil} if it
 doesn't have one.  @xref{Display Tables,,, lispref, XEmacs Lisp
-Programmer's Manual}.
+Reference Manual}.
 
 @item markers
 This field contains the chain of all markers that currently point into
 the buffer.  Deletion of text in the buffer, and motion of the buffer's
 gap, must check each of these markers and perhaps update it.
-@xref{Markers,,, lispref, XEmacs Lisp Programmer's Manual}.
+@xref{Markers,,, lispref, XEmacs Lisp Reference Manual}.
 
 @item backed_up
 This field is a flag that tells whether a backup file has been made for
@@ -7243,7 +7243,7 @@ the visited file of this buffer.
 @item mark
 This field contains the mark for the buffer.  The mark is a marker,
 hence it is also included on the list @code{markers}.  @xref{The Mark,,,
-lispref, XEmacs Lisp Programmer's Manual}.
+lispref, XEmacs Lisp Reference Manual}.
 
 @item mark_active
 This field is non-@code{nil} if the buffer's mark is active.
@@ -7253,12 +7253,12 @@ This field contains the association list describing the variables local
 in this buffer, and their values, with the exception of local variables
 that have special slots in the buffer object.  (Those slots are omitted
 from this table.)  @xref{Buffer-Local Variables,,, lispref, XEmacs Lisp
-Programmer's Manual}.
+Reference Manual}.
 
 @item modeline_format
 This field contains a Lisp object which controls how to display the mode
 line for this buffer.  @xref{Modeline Format,,, lispref, XEmacs Lisp
-Programmer's Manual}.
+Reference Manual}.
 
 @item base_buffer
 This field holds the buffer's base buffer (if it is an indirect buffer),
@@ -8723,12 +8723,13 @@ Not yet documented.
 
 Glyphs are graphical elements that can be displayed in XEmacs buffers or
 gutters. We use the term graphical element here in the broadest possible
-sense since glyphs can be as mundane as text to as arcane as a native
+sense since glyphs can be as mundane as text or as arcane as a native
 tab widget.
 
 In XEmacs, glyphs represent the uninstantiated state of graphical
 elements, i.e. they hold all the information necessary to produce an
-image on-screen but the image does not exist at this stage.
+image on-screen but the image need not exist at this stage, and multiple
+screen images can be instantiated from a single glyph.
 
 Glyphs are lazily instantiated by calling one of the glyph
 functions. This usually occurs within redisplay when
@@ -8746,7 +8747,7 @@ and every usage - and this would be extremely memory and cpu intensive.
 Widget-glyphs (a.k.a native widgets) are not cached in this way. This is
 because widget-glyph image-instances on screen are toolkit windows, and
 thus cannot be reused in multiple XEmacs domains. Thus widget-glyphs are
-cached on a window basis.
+cached on an XEmacs window basis.  
 
 Any action on a glyph first consults the cache before actually
 instantiating a widget.
@@ -8757,28 +8758,10 @@ To Do
 
 @section Widget-Glyphs in the X Environment
 
-Widget-glyphs under X make heavy use of lwlib for manipulating the
-native toolkit objects. This is primarily so that different toolkits can
-be supported for widget-glyphs, just as they are supported for features
-such as menubars etc.
-
-Lwlib is extremely poorly documented and quite hairy so here is my
-understanding of what goes on.
-
-Lwlib maintains a set of widget_instances which mirror the hierarchical
-state of Xt widgets. I think this is so that widgets can be updated and
-manipulated generically by the lwlib library. For instance
-update_one_widget_instance can cope with multiple types of widget and
-multiple types of toolkit. Each element in the widget hierarchy is updated
-from its corresponding widget_instance by walking the widget_instance
-tree recursively.
-
-This has desirable properties such as lw_modify_all_widgets which is
-called from @file{glyphs-x.c} and updates all the properties of a widget
-without having to know what the widget is or what toolkit it is from.
-Unfortunately this also has hairy properties such as making the lwlib
-code quite complex. And of course lwlib has to know at some level what
-the widget is and how to set its properties.
+Widget-glyphs under X make heavy use of lwlib (@pxref{Lucid Widget
+Library}) for manipulating the native toolkit objects. This is primarily
+so that different toolkits can be supported for widget-glyphs, just as
+they are supported for features such as menubars etc.
 
 @node Specifiers, Menus, Glyphs, Top
 @chapter Specifiers
@@ -8837,7 +8820,7 @@ a function to call (either @code{eval} or @code{call-interactively}) and
 its argument, which is the callback function or form given in the menu's
 description.
 
-@node Subprocesses, Interface to X Windows, Menus, Top
+@node Subprocesses, Interface to the X Window System, Menus, Top
 @chapter Subprocesses
 
   The fields of a process are:
@@ -8910,10 +8893,139 @@ The name of the terminal that the subprocess is using,
 or @code{nil} if it is using pipes.
 @end table
 
-@node Interface to X Windows, Index , Subprocesses, Top
-@chapter Interface to X Windows
+@node Interface to the X Window System, Index, Subprocesses, Top
+@chapter Interface to the X Window System
 
-Not yet documented.
+Mostly undocumented.
+
+@menu
+* Lucid Widget Library::        An interface to various widget sets.
+@end menu
+
+@node Lucid Widget Library, , , Interface to the X Window System
+@section Lucid Widget Library
+
+Lwlib is extremely poorly documented and quite hairy.  The author(s)
+blame that on X, Xt, and Motif, with some justice, but also sufficient
+hypocrisy to avoid drawing the obvious conclusion about their own work.
+
+The Lucid Widget Library is composed of two more or less independent
+pieces.  The first, as the name suggests, is a set of widgets.  These
+widgets are intended to resemble and improve on widgets provided in the
+Motif toolkit but not in the Athena widgets, including menubars and
+scrollbars.  Recent additions by Andy Piper integrate some ``modern''
+widgets by Edward Falk, including checkboxes, radio buttons, progress
+gauges, and index tab controls (aka notebooks).
+
+The second piece of the Lucid widget library is a generic interface to
+several toolkits for X (including Xt, the Athena widget set, and Motif,
+as well as the Lucid widgets themselves) so that core XEmacs code need
+not know which widget set has been used to build the graphical user
+interface.
+
+@menu
+* Generic Widget Interface::    The lwlib generic widget interface.
+* Scrollbars::
+* Menubars::
+* Checkboxes and Radio Buttons::
+* Progress Bars::
+* Tab Controls::
+@end menu
+
+@node Generic Widget Interface, Scrollbars, , Lucid Widget Library
+@subsection Generic Widget Interface
+
+In general in any toolkit a widget may be a composite object.  In Xt,
+all widgets have an X window that they manage, but typically a complex
+widget will have widget children, each of which manages a subwindow of
+the parent widget's X window.  These children may themselves be
+composite widgets.  Thus a widget is actually a tree or hierarchy of
+widgets.
+
+For each toolkit widget, lwlib maintains a tree of @code{widget_values}
+which mirror the hierarchical state of Xt widgets (including Motif,
+Athena, 3D Athena, and Falk's widget sets).  Each @code{widget_value}
+has @code{contents} member, which points to the head of a linked list of
+its children.  The linked list of siblings is chained through the
+@code{next} member of @code{widget_value}.
+
+@example
+           +-----------+
+           | composite |
+           +-----------+
+                 |
+                 | contents
+                 V
+             +-------+ next +-------+ next +-------+
+             | child |----->| child |----->| child |
+             +-------+      +-------+      +-------+
+                                |
+                                | contents
+                                V
+                         +-------------+ next +-------------+
+                         | grand child |----->| grand child |
+                         +-------------+      +-------------+
+
+The @code{widget_value} hierarchy of a composite widget with two simple
+children and one composite child.
+@end example
+
+The @code{widget_instance} structure maintains the inverse view of the
+tree.  As for the @code{widget_value}, siblings are chained through the
+@code{next} member.  However, rather than naming children, the
+@code{widget_instance} tree links to parents.
+
+@example
+           +-----------+
+           | composite |
+           +-----------+
+                 A
+                 | parent
+                 |
+             +-------+ next +-------+ next +-------+
+             | child |----->| child |----->| child |
+             +-------+      +-------+      +-------+
+                                A
+                                | parent
+                                |
+                         +-------------+ next +-------------+
+                         | grand child |----->| grand child |
+                         +-------------+      +-------------+
+
+The @code{widget_value} hierarchy of a composite widget with two simple
+children and one composite child.
+@end example
+
+This permits widgets derived from different toolkits to be updated and
+manipulated generically by the lwlib library. For instance
+@code{update_one_widget_instance} can cope with multiple types of widget
+and multiple types of toolkit. Each element in the widget hierarchy is
+updated from its corresponding @code{widget_value} by walking the
+@code{widget_value} tree.  This has desirable properties.  For example,
+@code{lw_modify_all_widgets} is called from @file{glyphs-x.c} and
+updates all the properties of a widget without having to know what the
+widget is or what toolkit it is from.  Unfortunately this also has its
+hairy properties; the lwlib code quite complex. And of course lwlib has
+to know at some level what the widget is and how to set its properties.
+
+The @code{widget_instance} structure also contains a pointer to the root
+of its tree.  Widget instances are further confi
+
+
+@node Scrollbars, Menubars, Generic Widget Interface, Lucid Widget Library
+@subsection Scrollbars
+
+@node Menubars, Checkboxes and Radio Buttons, Scrollbars, Lucid Widget Library
+@subsection Menubars
+
+@node Checkboxes and Radio Buttons, Progress Bars, Menubars, Lucid Widget Library
+@subsection Checkboxes and Radio Buttons
+
+@node Progress Bars, Tab Controls, Checkboxes and Radio Buttons, Lucid Widget Library
+@subsection Progress Bars
+
+@node Tab Controls, , Progress Bars, Lucid Widget Library
+@subsection Tab Controls
 
 @include index.texi
 
index 1736cbe..2c7381c 100644 (file)
@@ -30,7 +30,7 @@ Therefore, it is safe to use them in an extremely nonstandard way.
 @xref{Creating Symbols}.
 
   For the user-level commands for abbrevs, see @ref{Abbrevs,, Abbrev
-Mode, emacs, The XEmacs Reference Manual}.
+Mode, xemacs, The XEmacs User's Manual}.
 
 @menu
 * Abbrev Mode::                 Setting up XEmacs for abbreviation.
index e1c0a18..6dbcb22 100644 (file)
@@ -358,9 +358,9 @@ called @dfn{auto-saving}.  Auto-saving prevents you from losing more
 than a limited amount of work if the system crashes.  By default,
 auto-saves happen every 300 keystrokes, or after around 30 seconds of
 idle time.  @xref{Auto-Save, Auto-Save, Auto-Saving: Protection Against
-Disasters, emacs, The XEmacs Reference Manual}, for information on auto-save
-for users.  Here we describe the functions used to implement auto-saving
-and the variables that control them.
+Disasters, xemacs, The XEmacs Lisp Reference Manual}, for information on
+auto-save for users.  Here we describe the functions used to implement
+auto-saving and the variables that control them.
 
 @defvar buffer-auto-save-file-name
 This buffer-local variable is the name of the file used for
@@ -579,7 +579,7 @@ name.
   If you have made extensive changes to a file and then change your mind
 about them, you can get rid of them by reading in the previous version
 of the file with the @code{revert-buffer} command.  @xref{Reverting, ,
-Reverting a Buffer, emacs, The XEmacs Reference Manual}.
+Reverting a Buffer, xemacs, The XEmacs Lisp Reference Manual}.
 
 @deffn Command revert-buffer &optional check-auto-save noconfirm preserve-modes
 This command replaces the buffer text with the text of the visited
index 7db86b7..e6426ae 100644 (file)
@@ -46,6 +46,7 @@ byte compilation.
 * Eval During Compile::        Code to be evaluated when you compile.
 * Compiled-Function Objects::  The data type used for byte-compiled functions.
 * Disassembly::                 Disassembling byte-code; how to read byte-code.
+* Different Behavior::          When compiled code gives different results.
 @end menu
 
 @node Speed of Byte-Code
@@ -784,3 +785,33 @@ The @code{silly-loop} function is somewhat more complex:
 @end example
 
 
+@node Different Behavior
+@section Different Behavior
+
+The intent is that compiled byte-code and the corresponding code
+executed by the Lisp interpreter produce identical results.  However,
+there are some circumstances where the results will differ.
+
+@itemize @bullet
+@item
+Arithmetic operations may be rearranged for efficiency or compile-time
+evaluation.  When floating point numbers are involved, this may produce
+different values or an overflow.
+@item
+Some arithmetic operations may be optimized away.  For example, the
+expression @code{(+ x)} may be optimized to simply @code{x}.  If the
+value of @code{x} is a marker, then the value will be a marker instead
+of an integer.  If the value of @samp{x} is a cons cell, then the
+interpreter will issue an error, while the bytecode will not.
+
+If you're trying to use @samp{(+ @var{object} 0)} to convert
+@var{object} to integer, consider using an explicit conversion function,
+which is clearer and guaranteed to work.
+Instead of @samp{(+ @var{marker} 0)}, use @samp{(marker-position @var{marker})}.
+Instead of @samp{(+ @var{char} 0)}, use @samp{(char-int @var{char})}.
+@end itemize
+
+For maximal equivalence between interpreted and compiled code, the
+variables @code{byte-compile-delete-errors} and
+@code{byte-compile-optimize} can be set to @code{nil}, but this is not
+recommended.
index 043f4e4..2efc741 100644 (file)
@@ -167,9 +167,9 @@ The @dfn{echo area} is used for displaying messages made with the
 @code{message} primitive, and for echoing keystrokes.  It is not the
 same as the minibuffer, despite the fact that the minibuffer appears
 (when active) in the same place on the screen as the echo area.  The
-@cite{XEmacs Reference Manual} specifies the rules for resolving conflicts
+@cite{XEmacs Lisp Reference Manual} specifies the rules for resolving conflicts
 between the echo area and the minibuffer for use of that screen space
-(@pxref{Minibuffer,, The Minibuffer, emacs, The XEmacs Reference Manual}).
+(@pxref{Minibuffer,, The Minibuffer, xemacs, The XEmacs Lisp Reference Manual}).
 Error messages appear in the echo area; see @ref{Errors}.
 
 You can write output in the echo area by using the Lisp printing
index 9ab8294..88ec58f 100644 (file)
@@ -94,7 +94,7 @@ information to read the documentation from the appropriate file; this is
 transparent to the user.
 
   For information on the uses of documentation strings, see @ref{Help, ,
-Help, emacs, The XEmacs Reference Manual}.
+Help, xemacs, The XEmacs Reference Manual}.
 
 @c Wordy to prevent overfull hbox.  --rjc 15mar92
   The @file{emacs/lib-src} directory contains two utilities that you can
@@ -456,7 +456,7 @@ XEmacs buffers are usually displayed).
   XEmacs provides a variety of on-line help functions, all accessible to
 the user as subcommands of the prefix @kbd{C-h}, or on some keyboards,
 @kbd{help}.  For more information about them, see @ref{Help, , Help,
-emacs, The XEmacs Reference Manual}.  Here we describe some
+emacs, The XEmacs Lisp Reference Manual}.  Here we describe some
 program-level interfaces to the same information.
 
 @deffn Command apropos regexp &optional do-all predicate
index a509fdf..d082258 100644 (file)
@@ -1520,8 +1520,8 @@ If @var{noindirect} is non-@code{nil}, @code{where-is-internal} doesn't
 follow indirect keymap bindings.  This makes it possible to search for
 an indirect definition itself.
 
-This function is used by @code{where-is} (@pxref{Help, , Help, emacs,
-The XEmacs Reference Manual}).
+This function is used by @code{where-is} (@pxref{Help, , Help, xemacs,
+The XEmacs Lisp Reference Manual}).
 
 @smallexample
 @group
index 5003ef5..18f6365 100644 (file)
@@ -473,8 +473,14 @@ Loading
 
 Byte Compilation
 
-* Compilation Functions::   Byte compilation functions.
-* Disassembly::             Disassembling byte-code; how to read byte-code.
+* Speed of Byte-Code::          An example of speedup from byte compilation.
+* Compilation Functions::       Byte compilation functions.
+* Docs and Compilation::        Dynamic loading of documentation strings.
+* Dynamic Loading::             Dynamic loading of individual functions.
+* Eval During Compile::        Code to be evaluated when you compile.
+* Compiled-Function Objects::  The data type used for byte-compiled functions.
+* Disassembly::                 Disassembling byte-code; how to read byte-code.
+* Different Behavior::          When compiled code gives different results.
 
 Debugging Lisp Programs
 
index 2d3ed27..0539ade 100644 (file)
@@ -68,7 +68,7 @@ define such variables for their internal use; we don't list them here.
 @pxref{Usual Display}
 
 @item comment-column
-@pxref{Comments,,, emacs, The XEmacs User's Manual}
+@pxref{Comments,,, xemacs, The XEmacs User's Manual}
 
 @item default-directory
 @pxref{System Environment}
@@ -80,7 +80,7 @@ define such variables for their internal use; we don't list them here.
 @pxref{Auto Filling}
 
 @item goal-column
-@pxref{Moving Point,,, emacs, The XEmacs User's Manual}
+@pxref{Moving Point,,, xemacs, The XEmacs User's Manual}
 
 @item left-margin
 @pxref{Indentation}
index 5db9648..ad3b31f 100644 (file)
@@ -502,7 +502,7 @@ list at the end of the file and in the @samp{-*-} line.  The variable
 If you run @code{normal-mode} interactively, the argument
 @var{find-file} is normally @code{nil}.  In this case,
 @code{normal-mode} unconditionally processes any local variables list.
-@xref{File variables, , Local Variables in Files, emacs, The XEmacs
+@xref{File variables, , Local Variables in Files, xemacs, The XEmacs
 Reference Manual}, for the syntax of the local variables section of a file.
 
 @cindex file mode specification error
@@ -542,7 +542,7 @@ line, on the visited file name (using @code{auto-mode-alist}), or on the
 value of a local variable.  However, this function does not look for
 the @samp{mode:} local variable near the end of a file; the
 @code{hack-local-variables} function does that.  @xref{Choosing Modes, ,
-How Major Modes are Chosen, emacs, The XEmacs Reference Manual}.
+How Major Modes are Chosen, xemacs, The XEmacs Lisp Reference Manual}.
 @end defun
 
 @defopt default-major-mode
index 85e05a7..7804917 100644 (file)
@@ -193,28 +193,27 @@ In an interactive call, @var{count} is the numeric prefix argument.
   These functions for parsing words use the syntax table to decide
 whether a given character is part of a word.  @xref{Syntax Tables}.
 
-@deffn Command forward-word count &optional buffer
+@deffn Command forward-word &optional count buffer
 This function moves point forward @var{count} words (or backward if
 @var{count} is negative).  Normally it returns @code{t}.  If this motion
 encounters the beginning or end of the buffer, or the limits of the
 accessible portion when narrowing is in effect, point stops there and
-the value is @code{nil}.  @var{buffer} defaults to the current buffer if
-omitted.
+the value is @code{nil}.  
+
+@var{count} defaults to @code{1} and @var{buffer} defaults to the
+current buffer.
 
 In an interactive call, @var{count} is set to the numeric prefix
 argument.
 @end deffn
 
-@deffn Command backward-word count &optional buffer
+@deffn Command backward-word &optional count buffer
 This function is just like @code{forward-word}, except that it moves
 backward until encountering the front of a word, rather than forward.
 @var{buffer} defaults to the current buffer if omitted.
 
 In an interactive call, @var{count} is set to the numeric prefix
 argument.
-
-This function is rarely used in programs, as it is more efficient to
-call @code{forward-word} with a negative argument.
 @end deffn
 
 @defvar words-include-escapes
@@ -612,7 +611,7 @@ expressions (also called @dfn{sexps} in connection with moving across
 them in XEmacs).  The syntax table controls how these functions interpret
 various characters; see @ref{Syntax Tables}.  @xref{Parsing
 Expressions}, for lower-level primitives for scanning sexps or parts of
-sexps.  For user-level commands, see @ref{Lists and Sexps,,, emacs, XEmacs
+sexps.  For user-level commands, see @ref{Lists and Sexps,,, xemacs, XEmacs
 Reference Manual}.
 
 @deffn Command forward-list &optional arg
index a8ec820..22df2d7 100644 (file)
@@ -652,8 +652,8 @@ beyond the minimum needed to end a sentence.
 
   In XEmacs, you can search for the next match for a regexp either
 incrementally or not.  Incremental search commands are described in the
-@cite{The XEmacs Reference Manual}.  @xref{Regexp Search, , Regular Expression
-Search, emacs, The XEmacs Reference Manual}.  Here we describe only the search
+@cite{The XEmacs Lisp Reference Manual}.  @xref{Regexp Search, , Regular Expression
+Search, xemacs, The XEmacs Lisp Reference Manual}.  Here we describe only the search
 functions useful in programs.  The principal one is
 @code{re-search-forward}.
 
index 268648d..3091876 100644 (file)
@@ -115,7 +115,8 @@ the four cells of the symbol @code{buffer-file-name}:
 @noindent
 Because this symbol is the variable which holds the name of the file
 being visited in the current buffer, the value cell contents we see are
-the name of the source file of this chapter of the XEmacs Lisp Manual.
+the name of the source file of this chapter of the XEmacs Lisp Reference
+Manual.
 The property list cell contains the list @code{(variable-documentation
 29529)} which tells the documentation functions where to find the
 documentation string for the variable @code{buffer-file-name} in the
index 2bbbdd6..2b75bc0 100644 (file)
@@ -666,13 +666,13 @@ end of a comment.  This limitation no longer exists.
 You can use @code{forward-comment} to move forward or backward over
 one comment or several comments.
 
-@defun forward-comment count &optional buffer
+@defun forward-comment &optional count buffer
 This function moves point forward across @var{count} comments (backward,
 if @var{count} is negative).  If it finds anything other than a comment
 or whitespace, it stops, leaving point at the place where it stopped.
-It also stops after satisfying @var{count}.
+It also stops after satisfying @var{count}.  @var{count} defaults to @code{1}.
 
-  Optional argument @var{buffer} defaults to the current buffer.
+Optional argument @var{buffer} defaults to the current buffer.
 @end defun
 
 To move forward over all comments and whitespace following point, use
index b4ec428..233e73c 100644 (file)
@@ -476,10 +476,11 @@ This command deletes the text in @var{buffer} in the region defined by
 argument @var{buffer} is @code{nil}, the current buffer is assumed.
 @end deffn
 
-@deffn Command delete-char count &optional killp
+@deffn Command delete-char &optional count killp
 This command deletes @var{count} characters directly after point, or
-before point if @var{count} is negative.  If @var{killp} is
-non-@code{nil}, then it saves the deleted characters in the kill ring.
+before point if @var{count} is negative.  @var{count} defaults to @code{1}.
+If @var{killp} is non-@code{nil}, then it saves the deleted characters
+in the kill ring.
 
 In an interactive call, @var{count} is the numeric prefix argument, and
 @var{killp} is the unprocessed prefix argument.  Therefore, if a prefix
@@ -490,11 +491,12 @@ the kill ring.
 The value returned is always @code{nil}.
 @end deffn
 
-@deffn Command delete-backward-char count &optional killp
+@deffn Command delete-backward-char &optional count killp
 @cindex delete previous char
 This command deletes @var{count} characters directly before point, or
-after point if @var{count} is negative.  If @var{killp} is
-non-@code{nil}, then it saves the deleted characters in the kill ring.
+after point if @var{count} is negative.  @var{count} defaults to 1.
+If @var{killp} is non-@code{nil}, then it saves the deleted characters
+in the kill ring.
 
 In an interactive call, @var{count} is the numeric prefix argument, and
 @var{killp} is the unprocessed prefix argument.  Therefore, if a prefix
index eb4be94..a8ce727 100644 (file)
@@ -534,7 +534,7 @@ The indentation commands of the Lisp modes in XEmacs, such as @kbd{M-;}
 (@code{indent-for-comment}) and @key{TAB} (@code{lisp-indent-line})
 automatically indent comments according to these conventions,
 depending on the number of semicolons.  @xref{Comments,,
-Manipulating Comments, emacs, The XEmacs Reference Manual}.
+Manipulating Comments, xemacs, The XEmacs User's Manual}.
 
 @node Library Headers
 @section Conventional Headers for XEmacs Libraries
index 73037d2..321f488 100644 (file)
@@ -1,5 +1,5 @@
 \input texinfo.tex    @c -*-texinfo-*-
-@c $Id: texinfo.texi,v 1.8.2.4 1999/12/05 19:02:24 martinb Exp $
+@c $Id: texinfo.texi,v 1.8.2.5 2000/11/14 23:29:15 adrian Exp $
 @c %**start of header
 
 @c All text is ignored before the setfilename.
@@ -5158,16 +5158,16 @@ The format looks like this:@refill
 @end example
 
 For example, to refer directly to the @samp{Outlining} and
-@samp{Rebinding} nodes in the @cite{Emacs Manual}, you would write a
-menu like this:@refill
+@samp{Rebinding} nodes in the @cite{XEmacs User's Manual}, you would
+write a menu like this:@refill
 
 @example
 @group
 @@menu
-* Outlining: (emacs)Outline Mode. The major mode for
-                                  editing outlines.
-* Rebinding: (emacs)Rebinding.    How to redefine the
-                                  meaning of a key.
+* Outlining: (xemacs)Outline Mode. The major mode for
+                                   editing outlines.
+* Rebinding: (xemacs)Rebinding.    How to redefine the
+                                   meaning of a key.
 @@end menu
 @end group
 @end example
index d683baa..4f4bdab 100644 (file)
@@ -7,7 +7,7 @@
 @finalout
 @titlepage
 @title XEmacs FAQ
-@subtitle Frequently asked questions about XEmacs @* Last Modified: $Date: 2000/11/02 21:51:16 $
+@subtitle Frequently asked questions about XEmacs @* Last Modified: $Date: 2000/11/14 23:29:27 $
 @sp 1
 @author Tony Rossini <rossini@@biostat.washington.edu>
 @author Ben Wing <ben@@xemacs.org>
@@ -713,7 +713,7 @@ XEmacs port, but never went any farther.
 No, but Alexander Nikolaev <avn_1251@@mail.ru> is working on it.
 
 @node Q1.0.14, Q1.1.1, Q1.0.13, Introduction
-@unnumberedsubsec Q1.0.14: Where can I obtain a printed copy of the XEmacs users manual?
+@unnumberedsubsec Q1.0.14: Where can I obtain a printed copy of the XEmacs User's Manual?
 
 Pre-printed manuals are not available.  If you are familiar with
 TeX, you can generate your own manual from the XEmacs sources.
index dce562a..b0b0172 100644 (file)
@@ -15,7 +15,7 @@ mode is Calendar mode.
 particular date; @kbd{Buttons3} brings up a menu of commonly used
 calendar features that are independent of any particular date.  To exit
 the calendar, type @kbd{q}.  @xref{Calendar, Customizing the Calendar
-and Diary,, elisp, The Emacs Lisp Reference Manual}, for customization
+and Diary,, lispref, The XEmacs Lisp Reference Manual}, for customization
 information about the calendar and diary.
  
 @menu
index 3863203..b21b596 100644 (file)
@@ -11,7 +11,7 @@ XEmacs under the X window system, you can also use a number of
 standard Xt command line arguments. Command line arguments are not usually
 needed for editing with Emacs; new users can skip this section.
 
-Many editors are designed to be started afresh each time you want to
+  Many editors are designed to be started afresh each time you want to
 edit.  You start the editor to edit one file; then exit the editor.  The
 next time you want to edit either another file or the same one, you
 start the editor again.  Under these circumstances, it makes sense to use a
@@ -28,9 +28,14 @@ command line arguments for specifying a file when Emacs is started are seldom
 needed.
 
   Emacs accepts command-line arguments that specify files to visit,
-functions to call, and other activities and operating modes.  If you are
-running XEmacs under the X window system, a number of standard
-Xt command line arguments are available as well. 
+functions to call, and other activities and operating modes.  If you
+are running XEmacs under the X window system, a number of standard Xt
+command line arguments are available, as well as a few X parameters
+that are XEmacs-specific.
+
+  Options with long names with a single initial hyphen are also
+recognized with the GNU double initial hyphen syntax.  (The reverse
+is not true.)
 
 The following subsections list:
 @itemize @bullet
@@ -78,7 +83,8 @@ Insert the contents of @var{file} into the current buffer.  This is like
 what @kbd{M-x insert-buffer} does; @xref{Misc File Ops}.
 
 @item -kill
-Exit from Emacs without asking for confirmation.
+Exit from Emacs without asking for confirmation.  Always the last
+argument processed, no matter where it appears in the command line.
 
 @item -version
 @itemx -V
@@ -99,7 +105,19 @@ command line.  If more than one of them appears, they must appear in the
 order in which they appear in this table.
 
 @table @samp
-@item -t @var{file}
+@item --show-dump-id
+@itemx -sd
+Print the ID for the new portable dumper's dump file on the terminal and
+exit.  (Prints an error message and exits if XEmacs was not configured
+@samp{--pdump}.)
+
+@item --no-dump-file
+@itemx -nd
+Don't load the dump file.  Roughly equivalent to old temacs.  (Ignored if
+XEmacs was not configured @samp{--pdump}.)
+
+@item --terminal @var{file}
+@itemx -t @var{file}
 Use @var{file} instead of the terminal for input and output.  This
 implies the @samp{-nw} option, documented below.
 
@@ -121,7 +139,8 @@ causes Emacs to kill itself after all command switches have been
 processed.  In addition, auto-saving is not done except in buffers for
 which it has been explicitly requested.
 
-@item -nw
+@item --no-windows
+@itemx -nw
 Start up XEmacs in TTY mode (using the TTY XEmacs was started from),
 rather than trying to connect to an X display.  Note that this happens
 automatically if the @samp{DISPLAY} environment variable is not set.
@@ -167,7 +186,7 @@ and the various user-specific initialization files.
 @itemx -u @var{user}
 Equivalent to @samp{-user-init-file ~@var{user}/.xemacs/init.el
 -user-init-directory ~@var{user}/.xemacs}, or @samp{-user-init-file
-~@var{user}/.emacs -user-init-directory ~@var{user}/.xemacs}.  whichever
+~@var{user}/.emacs -user-init-directory ~@var{user}/.xemacs}, whichever
 init file comes first.  @xref{Init File}.
 
 @end table
index 8dff083..5919818 100644 (file)
@@ -45,12 +45,12 @@ If you are running XEmacs under a graphical windowing system, a
 menu bar at the top of the frame makes shortcuts to several of the
 commands available (@pxref{Pull-down Menus}).
 @item
-If you are running XEmacs under a graphical windowing system, a
+Under a graphical windowing system, a
 toolbar at the top of the frame, just under the menu bar if it exists,
 provides ``one-touch'' shortcuts to several commands.  (Not yet
 documented.)
 @item
-If you are running XEmacs under a graphical windowing system, a
+Under a graphical windowing system, a
 gutter at the top (under the toolbar) and/or bottom of the frame
 provides advanced GUI facilities like tab controls for rapid switching
 among related windows and progress bars for time-consuming operations
@@ -80,9 +80,12 @@ visible in all XEmacs windows containing that buffer.
 @menu
 * Point::              The place in the text where editing commands operate.  
 * Echo Area::           Short messages appear at the bottom of the frame.  
-* Mode Line::          Interpreting the mode line.  
+* Mode Line::          Interpreting the mode line.
+* GUI Components::      Menubar, toolbars, gutters.
 * XEmacs under X::      Some information on using XEmacs under the X 
                         Window System. 
+* XEmacs under MS Windows:: Some information on using XEmacs under
+                        Microsoft Windows.
 @end menu
 
 @node Point, Echo Area, Frame, Frame
@@ -169,7 +172,7 @@ appears after the prompt.  You can always get out of the minibuffer by
 typing @kbd{C-g}.  @xref{Minibuffer}.
 @end itemize
 
-@node Mode Line, XEmacs under X, Echo Area, Frame
+@node Mode Line, GUI Components, Echo Area, Frame
 @comment  node-name,  next,  previous,  up
 @section The Mode Line
 @cindex mode line
@@ -272,7 +275,187 @@ the terminal supports it); @code{nil} means no inverse video.  The
 default is @code{t}.  For X frames, simply set the foreground and
 background colors appropriately.
   
-@node XEmacs under X, , Mode Line, Frame
+@node GUI Components, XEmacs under X, Mode Line, Frame
+@comment  node-name,  next,  previous,  up
+@section GUI Components
+
+When executed in a graphical windowing environment such as the X Window
+System or Microsoft Windows, XEmacs displays several graphical user
+interface components such as scrollbars, menubars, toolbars, and
+gutters.  By default there is a vertical scrollbar at the right of each
+frame, and at the top of the frame there is a menubar, a toolbar, and a
+gutter, in that order.  Gutters can contain any of several widgets, but
+the default configuration puts a set of "notebook tabs" which you can
+use as a shortcut for selecting any of several related buffers in a
+given frame.  Operating the GUI components is "obvious":  click on the
+menubar to pull down a menu, on a button in the toolbar to invoke a
+function, and on a tab in the gutter to switch buffers.
+
+@menu
+* Menubar Basics::      How XEmacs uses the menubar.
+* Scrollbar Basics::    How XEmacs uses scrollbars.
+* Toolbar Basics::      How XEmacs uses toolbars.
+* Gutter Basics::       How XEmacs uses gutters.
+* Inhibiting::          What if you don't like GUI?
+* Customizing::         Position, orientation, and appearance of GUI objects.
+@end menu
+
+@node Menubar Basics, Scrollbar Basics, , GUI Components
+@comment  node-name,  next,  previous,  up
+@section The XEmacs Menubar
+
+The XEmacs menubar is intended to be conformant to the usual conventions
+for menubars, although conformance is not yet perfect.  The menu at the
+extreme right is the @samp{Help} menu, which should always be
+available.  It provides access to all the XEmacs help facilities
+available through @kbd{C-h}, as well as samples of various configuration
+files like @samp{~/.Xdefaults} and @samp{~/.emacs}.  At the extreme left
+is the @samp{Files} menu, which provides the usual file reading,
+writing, and printing operations, as well as operations like revert
+buffer from most recent save.  The next menu from the left is the
+@samp{Edit} menu, which provides the @samp{Undo} operation as well as
+cutting and pasting, searching, and keyboard macro definition and
+execution.
+
+@c #### w3.el and VM should get cross-references here.
+XEmacs provides a very dynamic environment, and the Lisp language makes
+for highly flexible applications.  The menubar reflects this: many menus
+(eg, the @samp{Buffers} menu, @pxref{Buffers Menu}) contain items
+determined by the current state of XEmacs, and most major modes and many
+minor modes add items to menus and even whole menus to the menubar.  In
+fact, some applications like w3.el and VM provide so many menus that
+they define a whole new menubar and add a button that allows convenient
+switching between the ``XEmacs menubar'' and the ``application
+menubar''.  Such applications normally bind themselves to a particular
+frame, and this switching only takes place on frames where such an
+application is active (ie, the current window of the frame is displaying
+a buffer in the appropriate major mode).
+
+Other menus which are typically available are the @samp{Options},
+@samp{Tools}, @samp{Buffers}, @samp{Apps}, and @samp{Mule} menus.  For
+detailed descriptions of these menus, @ref{Pull-down Menus}.  (In 21.2
+XEmacsen, the @samp{Mule} menu will be moved under @samp{Options}.)
+
+@node Scrollbar Basics, Toolbar Basics, Menubar Basics, GUI Components
+@comment  node-name,  next,  previous,  up
+@section XEmacs Scrollbars
+
+XEmacs scrollbars provide the usual interface.  Arrow buttons at either
+end allow for line by line scrolling, including autorepeat.  Clicking in
+the scrollbar itself provides scrolling by windowsfull, depending on
+which side of the slider is clicked.  The slider itself may be dragged
+for smooth scrolling.
+
+The position of the slider corresponds to the position of the window in
+the buffer.  In particular, the length of the slider is proportional to
+the fraction of the buffer which appears in the window.
+
+The presence of the scrollbars is under control of the application or
+may be customized by the user.  By default a vertical scrollbar is
+present in all windows (except the minibuffer), and there is no
+horizontal scrollbar.
+
+@node Toolbar Basics, Gutter Basics, Scrollbar Basics, GUI Components
+@comment  node-name,  next,  previous,  up
+@section XEmacs Toolbars
+
+XEmacs has a default toolbar which provides shortcuts for some of the
+commonly used operations (such as opening files) and applications (such
+as the Info manual reader).  Operations which require arguments will pop
+up dialogs to get them.
+
+The position of the default toolbar can be customized.  Also, several
+toolbars may be present simultaneously (in different positions).  VM,
+for example, provides an application toolbar which shortcuts for
+mail-specific operations like sending, saving, and deleting messages.
+
+@node Gutter Basics, Inhibiting, Toolbar Basics, GUI Components
+@comment  node-name,  next,  previous,  up
+@section XEmacs Gutters
+
+Gutters are the most flexible of the GUI components described in this
+section.  In theory, the other GUI components could be implemented by
+customizing a gutter, but in practice the other components were
+introduced earlier and have their own special implementations.  Gutters
+tend to be more transient than the other components.  Buffer tabs, for
+example, change every time the selected buffer in the frame changes.
+And for progress gauges a gutter to contain the gauge is typically
+created on the fly when needed, then destroyed when the operation whose
+staus is being displayed is completed.
+
+Buffer tabs, having somewhat complex behavior, deserve a closer look.
+By default, a row of buffer tabs is displayed at the top of every frame.
+(The tabs could be placed in the bottom gutter, but would be oriented
+the same way and look rather odd.  The horizontal orientation makes
+putting them in a side gutter utterly impractical.)  The buffer
+displayed in the current window of a frame can be changed to a specific
+buffer by clicking [mouse-1] on the corresponding tab in the gutter.
+
+Each tab contains the name of its buffer.  The tab for the current
+buffer in each frame is displayed in raised relief.  The list of buffers
+chosen for display in the buffer tab row is derived by filtering the
+buffer list (like the @code{Buffers} menu).  The list starts out with
+all existing buffers, with more recently selected buffers coming earlier
+in the list.
+
+Then "uninteresting" buffers, like internal XEmacs buffers, the
+@code{*Message Log*} buffer, and so on are deleted from the list.  Next,
+the frame's selected buffer is determined.  Buffers with a different
+major mode from the selected buffer are removed from the list.  Finally,
+if the list is too long, the least recently used buffers are deleted
+from the list.  By default up to 6 most recently used buffers with the
+same mode are displayed on tabs in the gutter.
+
+@node Inhibiting, Customizing, Gutter Basics, GUI Components
+@comment  node-name,  next,  previous,  up
+@section Inhibiting Display of GUI Components
+
+Use of GUI facilities is a personal thing.  Almost everyone agrees that
+drawing via keyboard-based "turtle graphics" is acceptable to hardly
+anyone if a mouse is available, but conversely emulating a keyboard with
+a screenful of buttons is a painful experience.  But between those
+extremes the complete novice will require a fair amount of time before
+toolbars and menus become dispensable, but many an "Ancien Haquer" sees
+them as a complete waste of precious frame space that could be filled
+with text.
+
+Display of all of the GUI components created by XEmacs can be inhibited
+through the use of Customize.  Customize can be accessed through
+@samp{Options | Customize} in the menu bar, or via @kbd{M-x customize}.
+Then navigate through the Customize tree to @samp{Emacs | Environment}.
+Scrollbar and toolbar visibility is controlled via the @samp{Display}
+group, options @samp{Scrollbars visible} and  @samp{Toolbar visible}
+respectively.  Gutter visibility is controlled by group @samp{Gutter},
+option @samp{Visible}.
+
+Or they can be controlled directly by @kbd{M-x customize-variable}, by
+changing the values of the variables @code{menubar-visible-p},
+@code{scrollbars-visible-p}, @code{toolbar-visible-p}, or
+@code{gutter-buffers-tab-visible-p} respectively.  (The strange form of
+the last variable is due to the fact that gutters are often used to
+display transient widgets like progress gauges, which you probably don't
+want to inhibit.  It is more likely that you want to inhibit the default
+display of the buffers tab widget, which is what that variable controls.
+This interface is subject to change depending on developer experience
+and user feedback.)
+
+Control of frame configuration can controlled automatically according to
+various parameters such as buffer or frame because these are
+@dfn{specifiers} @ref{Specifiers, , , lispref}.  Using these features
+requires programming in Lisp; Customize is not yet that sophisticated.
+Also, components that appear in various positions and orientations can
+have display suppressed according to position.  @kbd{C-h a visible-p}
+gives a list of variables which can be customized.  E.g., to control the
+visibility of specifically the left-side toolbar only, customize
+@code{left-toolbar-visible-p}.
+
+@node Customizing, , Inhibiting, GUI Components
+@comment  node-name,  next,  previous,  up
+@section Changing the Position, Orientation, and Appearance of GUI Components
+
+  #### Not documented yet.
+
+@node XEmacs under X, XEmacs under MS Windows, GUI Components, Frame
 @section Using XEmacs Under the X Window System
 @comment  node-name,  next,  previous,  up
 
@@ -355,3 +538,15 @@ the name of the current frame (a frame's name is distinct from its
 title; the name is used for resource lookup, among other things, and the
 title is simply what appears above the window.)
 @end itemize
+
+@node XEmacs under MS Windows, , XEmacs under X, Frame
+@section Using XEmacs Under Microsoft Windows
+@comment  node-name,  next,  previous,  up
+
+Use of XEmacs under MS Windows is not separately documented here, but
+most operations available under the X Window System are also available
+with MS Windows.
+
+Where possible, native MS Windows GUI components and capabilities are
+used in XEmacs.
+
index ccd8f07..f263aac 100644 (file)
@@ -626,7 +626,7 @@ Another interface over patch.
 CVS frontend.
 
 @item prog-modes
-Miscellaneous single-file lisp files for various programming languages.
+Miscellaneous Lisp libraries for various programming languages.
 
 @item scheme
 Front-end support for Inferior Scheme.
@@ -635,11 +635,10 @@ Front-end support for Inferior Scheme.
 Support for editing shell scripts.
 
 @item vc
-Version Control for Free systems.
+Version control for free systems.
 
 @item vc-cc
-Version Control for ClearCase.  This package must be installed prior
-to building XEmacs [broken as of XEmacs 20.5-beta19].
+Version control for ClearCase.
 
 @item vhdl
 Support for VHDL.
index 90971b2..a4aee30 100644 (file)
@@ -1,3 +1,7 @@
+2000-12-05  Martin Buchholz <martin@xemacs.org>
+
+       * XEmacs 21.2.38 is released.
+
 2000-11-14  Martin Buchholz <martin@xemacs.org>
 
        * XEmacs 21.2.37 is released.
index 35a62a7..e5766ba 100644 (file)
@@ -221,8 +221,8 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you
        buffer's current directory.  We can't just have the child check
        for an error when it does the chdir, since it's in a vfork.  */
 
-    NGCPRO2 (current_dir, path);   /* Caller gcprotects args[] */
     current_dir = current_buffer->directory;
+    NGCPRO2 (current_dir, path);   /* Caller gcprotects args[] */
     current_dir = Funhandled_file_name_directory (current_dir);
     current_dir = expand_and_dir_to_file (current_dir, Qnil);
 #if 0
index 6e63f9a..da2727c 100644 (file)
@@ -1019,6 +1019,7 @@ Return value is the currently selected settings object.
       ldm_current->printer_name = xstrdup (ldm_new->printer_name);
     }
 
+  UNGCPRO;
   return DEVICE_MSPRINTER_DEVMODE (d);
 }
 \f
index 9e4b2b5..73dfe42 100644 (file)
@@ -187,7 +187,7 @@ mswindows_get_files (char *dirfile, int nowild, Lisp_Object pattern,
          /* PATTERN might be a flawed regular expression.  Rather than
             catching and signalling our own errors, we just call
             compile_pattern to do the work for us.  */
-         bufp = compile_pattern (pattern, 0, 0, 0, ERROR_ME);
+         bufp = compile_pattern (pattern, 0, Qnil, 0, ERROR_ME);
        }
       /* Now *bufp is the compiled form of PATTERN; don't call anything
         which might compile a new regexp until we're done with the loop! */
index 69142b7..48f9a28 100644 (file)
@@ -110,7 +110,7 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory
       /* MATCH might be a flawed regular expression.  Rather than
         catching and signalling our own errors, we just call
         compile_pattern to do the work for us.  */
-      bufp = compile_pattern (match, 0, 0, 0, ERROR_ME);
+      bufp = compile_pattern (match, 0, Qnil, 0, ERROR_ME);
     }
 
   /* Now *bufp is the compiled form of MATCH; don't call anything
index 88e95af..1a76998 100644 (file)
--- a/src/doc.c
+++ b/src/doc.c
@@ -168,7 +168,6 @@ get_doc_string (Lisp_Object filepos)
   /* !!#### This function has not been Mule-ized */
   REGISTER int fd;
   REGISTER char *name_nonreloc = 0;
-  int minsize;
   EMACS_INT position;
   Lisp_Object file, tem;
   Lisp_Object name_reloc = Qnil;
@@ -197,6 +196,7 @@ get_doc_string (Lisp_Object filepos)
   tem = Ffile_name_absolute_p (file);
   if (NILP (tem))
     {
+      size_t minsize;
       /* XEmacs: Move this check here.  OK if called during loadup to
         load byte code instructions. */
       if (!STRINGP (Vdoc_directory))
index 7a8df46..a8e04a0 100644 (file)
@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA.  */
 #include "frame.h"
 #include "insdel.h"
 #include "window.h"
+#include "casetab.h"
 #include "chartab.h"
 #include "line-number.h"
 
@@ -1717,7 +1718,7 @@ determines whether case is significant or ignored.
   REGISTER Charcount len1, len2, length, i;
   struct buffer *bp1, *bp2;
   Lisp_Object trt = ((!NILP (current_buffer->case_fold_search)) ?
-                    current_buffer->case_canon_table : Qnil);
+                    XCASE_TABLE_CANON (current_buffer->case_table) : Qnil);
 
   /* Find the first buffer and its substring.  */
 
index c118529..70a8603 100644 (file)
@@ -701,8 +701,6 @@ or `replace'. ATTR is the LDAP attribute type to modify.
   Lisp_Object values  = Qnil;
   struct gcpro gcpro1, gcpro2;
 
-  GCPRO2 (current, values);
-
   /* Do all the parameter checking  */
   CHECK_LIVE_LDAP (ldap);
   ld = XLDAP (ldap)->ld;
@@ -720,6 +718,8 @@ or `replace'. ATTR is the LDAP attribute type to modify.
   ldap_mods = alloca_array (LDAPMod, len);
   ldap_mods_ptrs = alloca_array (LDAPMod *, 1 + len);
   i = 0;
+
+  GCPRO2 (current, values);
   EXTERNAL_LIST_LOOP (mods, mods)
     {
       current = XCAR (mods);
index ddbb49d..2eb2fca 100644 (file)
@@ -1350,10 +1350,10 @@ x_event_to_emacs_event (XEvent *x_event, Lisp_Event *emacs_event)
            Lisp_Object l_dndlist = Qnil, l_item = Qnil;
            struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
 
-           GCPRO4 (l_type, l_data, l_dndlist, l_item);
-
            if (! frame)
              return 0; /* not for us */
+
+           GCPRO4 (l_type, l_data, l_dndlist, l_item);
            XSETFRAME (emacs_event->channel, frame);
 
            emacs_event->event_type = misc_user_event;
index a09c81f..ee3595f 100644 (file)
@@ -2794,8 +2794,6 @@ mswindows_wnd_proc (HWND hwnd, UINT message_, WPARAM wParam, LPARAM lParam)
          case CBN_SELCHANGE:
            if (!NILP (mswindows_handle_gui_wm_command (frame, cid, id)))
              return 0;
-         case BN_SETFOCUS:
-           
          }
        /* menubars always must come last since the hashtables do not
           always exist*/
index 68e6c12..d6a5cfe 100644 (file)
@@ -3372,7 +3372,7 @@ modify them.
     {
       Vrecent_keys_ring = make_vector (recent_keys_ring_size, Qnil);
       /* And return nothing in particular. */
-      return make_vector (0, Qnil);
+      RETURN_UNGCPRO (make_vector (0, Qnil));
     }
 
   if (NILP (XVECTOR_DATA (Vrecent_keys_ring)[recent_keys_ring_index]))
@@ -3430,7 +3430,6 @@ Set the maximum number of events to be stored internally.
   Lisp_Object new_vector = Qnil;
   int i, j, nkeys, start, min;
   struct gcpro gcpro1;
-  GCPRO1 (new_vector);
 
   CHECK_INT (size);
   if (XINT (size) <= 0)
@@ -3438,12 +3437,13 @@ Set the maximum number of events to be stored internally.
   if (XINT (size) == recent_keys_ring_size)
     return size;
 
+  GCPRO1 (new_vector);
   new_vector = make_vector (XINT (size), Qnil);
 
   if (NILP (Vrecent_keys_ring))
     {
       Vrecent_keys_ring = new_vector;
-      return size;
+      RETURN_UNGCPRO (size);
     }
 
   if (NILP (XVECTOR_DATA (Vrecent_keys_ring)[recent_keys_ring_index]))
index a726938..5a6d477 100644 (file)
@@ -748,7 +748,7 @@ See also the function `substitute-in-file-name'.
 */
        (name, default_directory))
 {
-  /* This function can GC.  GC-checked 2000-07-11 ben */
+  /* This function can GC.  GC-checked 2000-11-18 */
   Bufbyte *nm;
 
   Bufbyte *newdir, *p, *o;
@@ -761,14 +761,14 @@ See also the function `substitute-in-file-name'.
   struct passwd *pw;
 #endif /* WIN32_NATIVE */
   int length;
-  Lisp_Object handler;
+  Lisp_Object handler = Qnil;
 #ifdef CYGWIN
   char *user;
 #endif
-  struct gcpro gcpro1, gcpro2;
+  struct gcpro gcpro1, gcpro2, gcpro3;
 
   /* both of these get set below */
-  GCPRO2 (name, default_directory);
+  GCPRO3 (name, default_directory, handler);
 
   CHECK_STRING (name);
 
@@ -776,11 +776,8 @@ See also the function `substitute-in-file-name'.
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (name, Qexpand_file_name);
   if (!NILP (handler))
-    {
-      UNGCPRO;
-      return call3_check_string (handler, Qexpand_file_name, name,
-                                default_directory);
-    }
+    RETURN_UNGCPRO (call3_check_string (handler, Qexpand_file_name,
+                                       name, default_directory));
 
   /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted.  */
   if (NILP (default_directory))
@@ -792,10 +789,8 @@ See also the function `substitute-in-file-name'.
     {
       handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
       if (!NILP (handler))
-       {
-         UNGCPRO;
-         return call3 (handler, Qexpand_file_name, name, default_directory);
-       }
+       RETURN_UNGCPRO (call3 (handler, Qexpand_file_name,
+                              name, default_directory));
     }
 
   o = XSTRING_DATA (default_directory);
@@ -1322,14 +1317,30 @@ No component of the resulting pathname will be a symbolic link, as
           we just use our own version in realpath.c. */
        for (;;)
          {
-           p = (Extbyte *) memchr (p + 1, '/', elen - (p + 1 - path));
-           if (p)
-             *p = 0;
+           Extbyte *pos;
+
+#ifdef WIN32_NATIVE
+           if (IS_DRIVE (p[0]) && IS_DEVICE_SEP (p[1]) 
+               && IS_DIRECTORY_SEP (p[2]))
+             /* don't test c: on windows */
+             p = p+2;
+           else if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1]))
+             /* start after // */
+             p = p+1;
+#endif
+           for (pos = p + 1; pos < path + elen; pos++)
+             if (IS_DIRECTORY_SEP (*pos))
+               {
+                 *(p = pos) = 0;
+                 break;
+               }
+           if (p != pos)
+             p = 0;
 
            if (xrealpath ((char *) path, resolved_path))
              {
                if (p)
-                 *p = '/';
+                 *p = DIRECTORY_SEP;
                else
                  break;
 
@@ -1348,13 +1359,13 @@ No component of the resulting pathname will be a symbolic link, as
                  {
                    int plen = elen - (p - path);
 
-                   if (rlen > 1 && resolved_path[rlen - 1] == '/')
+                   if (rlen > 1 && IS_DIRECTORY_SEP (resolved_path[rlen - 1]))
                      rlen = rlen - 1;
 
                    if (plen + rlen + 1 > countof (resolved_path))
                      goto toolong;
 
-                   resolved_path[rlen] = '/';
+                   resolved_path[rlen] = DIRECTORY_SEP;
                    memcpy (resolved_path + rlen + 1, p + 1, plen + 1 - 1);
                  }
                break;
@@ -1367,12 +1378,12 @@ No component of the resulting pathname will be a symbolic link, as
     {
       Lisp_Object resolved_name;
       int rlen = strlen (resolved_path);
-      if (elen > 0 && XSTRING_BYTE (expanded_name, elen - 1) == '/'
-          && !(rlen > 0 && resolved_path[rlen - 1] == '/'))
+      if (elen > 0 && IS_DIRECTORY_SEP (XSTRING_BYTE (expanded_name, elen - 1))
+          && !(rlen > 0 && IS_DIRECTORY_SEP (resolved_path[rlen - 1])))
        {
          if (rlen + 1 > countof (resolved_path))
            goto toolong;
-         resolved_path[rlen++] = '/';
+         resolved_path[rlen++] = DIRECTORY_SEP;
          resolved_path[rlen] = '\0';
        }
       TO_INTERNAL_FORMAT (DATA, (resolved_path, rlen),
@@ -3394,7 +3405,7 @@ to the value of CODESYS.  If this is nil, no code conversion occurs.
         message ("Wrote %s", XSTRING_DATA (visit_file));
       else
        {
-         Lisp_Object fsp;
+         Lisp_Object fsp = Qnil;
          struct gcpro nngcpro1;
 
          NNGCPRO1 (fsp);
@@ -3735,7 +3746,7 @@ An argument specifies the modification time value to use
     }
   else
     {
-      Lisp_Object filename;
+      Lisp_Object filename = Qnil;
       struct stat st;
       Lisp_Object handler;
       struct gcpro gcpro1, gcpro2, gcpro3;
index 308565b..531000e 100644 (file)
@@ -320,6 +320,7 @@ lock_file (Lisp_Object fn)
     return;
 
   XSETBUFFER (old_current_buffer, current_buffer);
+  subject_buf = Qnil;
   GCPRO3 (fn, subject_buf, old_current_buffer);
   orig_fn = fn;
   fn = Fexpand_file_name (fn, Qnil);
index 5022b57..4dbd9ba 100644 (file)
@@ -491,6 +491,8 @@ log_gcpro (char *file, int line, struct gcpro *value, blocktype type)
       if (value == gcprolist->next->next) goto OK;
       if (! gcprolist->next->next) abort ();
       if (value == gcprolist->next->next->next) goto OK;
+      if (! gcprolist->next->next->next) abort ();
+      if (value == gcprolist->next->next->next->next) goto OK;
       abort ();
     OK:;
     }
@@ -587,6 +589,7 @@ show_gcprohist (void)
               gcprohist[j].type == gcpro2_type ? "GCPRO2" :
               gcprohist[j].type == gcpro3_type ? "GCPRO3" :
               gcprohist[j].type == gcpro4_type ? "GCPRO4" :
+              gcprohist[j].type == gcpro5_type ? "GCPRO5" :
               gcprohist[j].type == ungcpro_type ? "UNGCPRO" : "???"),
              gcprohist[j].value);
     }
index ed706f9..9a0e296 100644 (file)
@@ -2954,6 +2954,17 @@ image_instantiator_format_create_glyphs_x (void)
   IIFORMAT_HAS_METHOD (autodetect, validate);
   IIFORMAT_HAS_METHOD (autodetect, normalize);
   IIFORMAT_HAS_METHOD (autodetect, possible_dest_types);
+  /* #### autodetect is flawed IMO: 
+  1. It makes the assumption that you can detect whether the user
+  wanted a cursor or a string based on the data, since the data is a
+  string you have to prioritise cursors. Instead we will force users
+  to pick the appropriate image type, this is what we do under
+  MS-Windows anyway.
+  2. It doesn't fit with the new domain model - you cannot tell which
+  domain it needs to be instantiated in until you've actually
+  instantiated it, which mucks up caching.
+  3. It only copes with cursors and strings which seems bogus. */
+  IIFORMAT_HAS_SHARED_METHOD (autodetect, governing_domain, subwindow);
   IIFORMAT_HAS_METHOD (autodetect, instantiate);
   IIFORMAT_VALID_CONSOLE (x, autodetect);
 
index a3c3d46..40ebaca 100644 (file)
@@ -112,7 +112,7 @@ This function is the process handler for the GPM connection.
        Gpm_Event ev;
        int modifiers = 0;
        int button = 1;
-       Lisp_Object fake_event;
+       Lisp_Object fake_event = Qnil;
        Lisp_Event *event = NULL;
        struct gcpro gcpro1;
        static int num_events;
@@ -217,9 +217,9 @@ tty_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type
        struct device *d = decode_device (Qnil);
        int fd = DEVICE_INFD (d);
        char c = 3;
-       Lisp_Object output_stream;
-       Lisp_Object terminal_stream;
-       Lisp_Object output_string;
+       Lisp_Object output_stream = Qnil;
+       Lisp_Object terminal_stream = Qnil ;
+       Lisp_Object output_string = Qnil;
        struct gcpro gcpro1,gcpro2,gcpro3;
 
        GCPRO3(output_stream,terminal_stream,output_string);
index d3824d2..3db3be5 100644 (file)
@@ -44,6 +44,7 @@ Boston, MA 02111-1307, USA.  */
 #include "lisp.h"
 #include "buffer.h"
 #include "bytecode.h"
+#include "casetab.h"
 #include "chartab.h"
 #include "console.h"
 #include "device.h"
index 1d6ef6e..cd66cef 100644 (file)
@@ -1542,7 +1542,7 @@ key_desc_list_to_event (Lisp_Object list, Lisp_Object event,
 int
 event_matches_key_specifier_p (Lisp_Event *event, Lisp_Object key_specifier)
 {
-  Lisp_Object event2;
+  Lisp_Object event2 = Qnil;
   int retval;
   struct gcpro gcpro1;
 
index 34932dd..49c23a5 100644 (file)
@@ -1236,7 +1236,7 @@ command_builder_find_menu_accelerator (struct command_builder *builder)
   if (menubar_widget
       && CONSP (Vmenu_accelerator_modifiers))
     {
-      Lisp_Object fake;
+      Lisp_Object fake = Qnil;
       Lisp_Object last = Qnil;
       struct gcpro gcpro1;
       Lisp_Object matchp;
index 73f0960..cdb75af 100644 (file)
@@ -935,18 +935,19 @@ float_to_string (char *buf, double data)
 }
 #endif /* LISP_FLOAT_TYPE */
 
-/* Print NUMBER to BUFFER.  This is equivalent to sprintf(buffer,
-   "%ld", number), only much faster.
+/* Print NUMBER to BUFFER.
+   This is equivalent to sprintf (buffer, "%ld", number), only much faster.
 
    BUFFER should accept 24 bytes.  This should suffice for the longest
    numbers on 64-bit machines, including the `-' sign and the trailing
-   \0.  */
-void
+   '\0'.  Returns a pointer to the trailing '\0'. */
+char *
 long_to_string (char *buffer, long number)
 {
 #if (SIZEOF_LONG != 4) && (SIZEOF_LONG != 8)
   /* Huh? */
   sprintf (buffer, "%ld", number);
+  return buffer + strlen (buffer);
 #else /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */
   char *p = buffer;
   int force = 0;
@@ -984,6 +985,7 @@ long_to_string (char *buffer, long number)
 #undef FROB
   *p++ = number + '0';
   *p = '\0';
+  return p;
 #endif /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */
 }
 \f
@@ -1420,6 +1422,7 @@ print_symbol (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
              write_char_internal ("#", printcharfun);
              print_internal (XCDR (tem), printcharfun, escapeflag);
              write_char_internal ("#", printcharfun);
+             UNGCPRO;
              return;
            }
          else
index be14a42..94b4699 100644 (file)
@@ -23,18 +23,14 @@ Boston, MA 02111-1307, USA.  */
 /* Synched up with: Not in FSF. */
 
 #include <config.h>
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
+#include "lisp.h"
 #include <errno.h>
-#include <limits.h>
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 
-#if defined (HAVE_SYS_PARAM_H)
+#if defined (HAVE_SYS_PARAM_H) && !defined (WIN32_NATIVE)
 #include <sys/param.h>
 #endif
 
@@ -44,6 +40,133 @@ Boston, MA 02111-1307, USA.  */
 
 #include <sys/stat.h>                  /* for S_IFLNK */
 
+/* First char after start of absolute filename. */
+#define ABS_START(name) (name + ABS_LENGTH (name))
+
+#if defined (WIN32_NATIVE)
+/* Length of start of absolute filename. */
+# define ABS_LENGTH(name) (win32_abs_start (name))
+static int win32_abs_start (const char * name);
+/* System dependent version of readlink. */
+# define system_readlink win32_readlink
+#else
+# ifdef CYGWIN
+#  define ABS_LENGTH(name) (IS_DIRECTORY_SEP (*name) ? \
+                            (IS_DIRECTORY_SEP (name[1]) ? 2 : 1) : 0)
+#  define system_readlink cygwin_readlink
+# else
+#  define ABS_LENGTH(name) (IS_DIRECTORY_SEP (*name) ? 1 : 0)
+#  define system_readlink readlink
+# endif /* CYGWIN */
+#endif /* WIN32_NATIVE */
+
+#if defined (WIN32_NATIVE) || defined (CYGWIN)
+#include "syswindows.h"
+/* Emulate readlink on win32 - finds real name (i.e. correct case) of
+   a file. UNC servers and shares are lower-cased. Directories must be
+   given without trailing '/'. One day, this could read Win2K's
+   reparse points. */
+static int
+win32_readlink (const char * name, char * buf, int size)
+{
+  WIN32_FIND_DATA find_data;
+  HANDLE dir_handle = NULL;
+  int len = 0;
+  int err = 0;
+  const char* lastname;
+  int count = 0;
+  const char* tmp;
+  char* res = NULL;
+  
+  assert (*name);
+  
+  /* Sort of check we have a valid filename. */
+  if (strpbrk (name, "*?|<>\"") || strlen (name) >= MAX_PATH)
+    {
+      errno = EIO;
+      return -1;
+    }
+  
+  /* Find start of filename */
+  lastname = name + strlen (name);
+  while (lastname > name && !IS_DIRECTORY_SEP (lastname[-1]))
+    --lastname;
+
+  /* Count slashes in unc path */
+  if (ABS_LENGTH (name) == 2)
+    for (tmp = name; *tmp; tmp++)
+      if (IS_DIRECTORY_SEP (*tmp))
+       count++;
+
+  if (count >= 2 && count < 4)
+    {
+      /* UNC server or share name: just copy lowercased name. */
+      res = find_data.cFileName;
+      for (tmp = lastname; *tmp; tmp++)
+       *res++ = tolower (*tmp);
+      *res = '\0';
+    }
+  else
+    dir_handle = FindFirstFile (name, &find_data);
+
+  if (res || dir_handle != INVALID_HANDLE_VALUE)
+    {
+      if ((len = strlen (find_data.cFileName)) < size)
+       {
+         if (strcmp (lastname, find_data.cFileName) == 0)
+           /* Signal that the name is already OK. */
+           err = EINVAL;
+         else
+           memcpy (buf, find_data.cFileName, len + 1);
+       }
+      else
+       err = ENAMETOOLONG;
+      if (!res) FindClose (dir_handle);
+    }
+  else
+    err = ENOENT;
+
+  errno = err;
+  return err ? -1 : len;
+}
+#endif /* WIN32_NATIVE || CYGWIN */
+
+#ifdef CYGWIN
+/* Call readlink and try to find out the correct case for the file. */
+static int
+cygwin_readlink (const char * name, char * buf, int size)
+{
+  int n = readlink (name, buf, size);
+  if (n < 0)
+    {
+      /* The file may exist, but isn't a symlink. Try to find the
+         right name. */
+      char* tmp = alloca (cygwin_posix_to_win32_path_list_buf_size (name));
+      cygwin_posix_to_win32_path_list (name, tmp);
+      n = win32_readlink (tmp, buf, size);
+    }
+  return n;
+}
+#endif /* CYGWIN */
+
+#ifdef WIN32_NATIVE
+#ifndef ELOOP
+#define ELOOP 10062 /* = WSAELOOP in winsock.h */
+#endif
+/* Length of start of absolute filename. */
+static int 
+win32_abs_start (const char * name)
+{
+  if (isalpha (*name) && IS_DEVICE_SEP (name[1])
+      && IS_DIRECTORY_SEP (name[2]))
+    return 3;
+  else if (IS_DIRECTORY_SEP (*name))
+    return IS_DIRECTORY_SEP (name[1]) ? 2 : 1;
+  else 
+    return 0;
+}
+#endif /* WIN32_NATIVE */
+
 #if !defined (HAVE_GETCWD) && defined (HAVE_GETWD)
 #undef getcwd
 #define getcwd(buffer, len) getwd (buffer)
@@ -68,78 +191,63 @@ xrealpath (const char *path, char resolved_path [])
   char copy_path[PATH_MAX];
   char *new_path = resolved_path;
   char *max_path;
-#ifdef S_IFLNK
+#if defined (S_IFLNK) || defined (WIN32_NATIVE)
   int readlinks = 0;
   char link_path[PATH_MAX];
   int n;
+  int abslen = ABS_LENGTH (path);
 #endif
 
   /* Make a copy of the source path since we may need to modify it. */
   strcpy (copy_path, path);
   path = copy_path;
   max_path = copy_path + PATH_MAX - 2;
+
 #ifdef WIN32_NATIVE
-  /*
-  ** In NT we have two different cases:  (1) the path name begins
-  ** with a drive letter, e.g., "C:"; and (2) the path name begins
-  ** with just a slash, which roots to the current drive. In the
-  ** first case we are going to leave things alone, in the second
-  ** case we will prepend the drive letter to the given path.
-  ** Note: So far in testing, I'm only seeing case #1, even though
-  ** I've tried to get the other cases to happen.
-  ** August Hill, 31 Aug 1997.
-  **
-  ** Check for a driver letter...C:/...
-  */
-  if (*(path + 1) == ':')
+  /* Check for c:/... or //server/... */
+  if (abslen == 2 || abslen == 3)
     {
-      strncpy(new_path, path, 3);
-      new_path += 3;
-      path += 3;
+      strncpy (new_path, path, abslen);
+      new_path += abslen;
+      path += abslen;
     }
-
-  /*
-  ** No drive letter, but a beginning slash? Prepend the drive
-  ** letter...
-  */
-  else if (*path == '/')
+  /* No drive letter, but a beginning slash? Prepend drive letter. */
+  else if (abslen == 1)
     {
       getcwd (new_path, PATH_MAX - 1);
       new_path += 3;
       path++;
     }
-
-  /*
-  ** Just a path name, prepend the current directory
-  */
+  /* Just a path name, prepend the current directory */
   else
     {
       getcwd (new_path, PATH_MAX - 1);
-      new_path += strlen(new_path);
-      if (new_path[-1] != '/')
-       *new_path++ = '/';
+      new_path += strlen (new_path);
+      if (!IS_DIRECTORY_SEP (new_path[-1]))
+       *new_path++ = DIRECTORY_SEP;
     }
-
 #else
   /* If it's a relative pathname use getcwd for starters. */
-  if (*path != '/')
+  if (abslen == 0)
     {
       getcwd (new_path, PATH_MAX - 1);
-      new_path += strlen(new_path);
-      if (new_path[-1] != '/')
-       *new_path++ = '/';
+      new_path += strlen (new_path);
+      if (!IS_DIRECTORY_SEP (new_path[-1]))
+       *new_path++ = DIRECTORY_SEP;
     }
   else
     {
-      *new_path++ = '/';
-      path++;
+      /* Copy first directory sep. May have two on cygwin. */
+      strncpy (new_path, path, abslen);
+      new_path += abslen;
+      path += abslen;
     }
 #endif
   /* Expand each slash-separated pathname component. */
   while (*path != '\0')
     {
       /* Ignore stray "/". */
-      if (*path == '/')
+      if (IS_DIRECTORY_SEP (*path))
        {
          path++;
          continue;
@@ -148,7 +256,7 @@ xrealpath (const char *path, char resolved_path [])
       if (*path == '.')
        {
          /* Ignore ".". */
-         if (path[1] == '\0' || path[1] == '/')
+         if (path[1] == '\0' || IS_DIRECTORY_SEP (path[1]))
            {
              path++;
              continue;
@@ -156,23 +264,24 @@ xrealpath (const char *path, char resolved_path [])
 
          /* Handle ".." */
          if (path[1] == '.' &&
-             (path[2] == '\0' || path[2] == '/'))
+             (path[2] == '\0' || IS_DIRECTORY_SEP (path[2])))
            {
              path += 2;
 
              /* Ignore ".." at root. */
-             if (new_path == resolved_path + 1)
+             if (new_path == ABS_START (resolved_path))
                continue;
 
              /* Handle ".." by backing up. */
-             while ((--new_path)[-1] != '/')
-               ;
+             --new_path;
+             while (!IS_DIRECTORY_SEP (new_path[-1]))
+               --new_path;
              continue;
            }
        }
 
       /* Safely copy the next pathname component. */
-      while (*path != '\0' && *path != '/')
+      while (*path != '\0' && !IS_DIRECTORY_SEP (*path))
        {
          if (path > max_path)
            {
@@ -182,10 +291,10 @@ xrealpath (const char *path, char resolved_path [])
          *new_path++ = *path++;
        }
 
-#ifdef S_IFLNK
+#if defined (S_IFLNK) || defined (WIN32_NATIVE)
       /* See if latest pathname component is a symlink. */
       *new_path = '\0';
-      n = readlink (resolved_path, link_path, PATH_MAX - 1);
+      n = system_readlink (resolved_path, link_path, PATH_MAX - 1);
 
       if (n < 0)
        {
@@ -204,14 +313,14 @@ xrealpath (const char *path, char resolved_path [])
 
          /* Note: readlink doesn't add the null byte. */
          link_path[n] = '\0';
-
-         if (*link_path == '/')
+         
+         if (ABS_LENGTH (link_path) > 0)
            /* Start over for an absolute symlink. */
-           new_path = resolved_path;
+           new_path = resolved_path + ABS_LENGTH (link_path) - 1;
          else
            /* Otherwise back up over this component. */
-           while (*(--new_path) != '/')
-             ;
+           for (--new_path; !IS_DIRECTORY_SEP (*new_path); --new_path)
+             assert (new_path > resolved_path);
 
          /* Safe sex check. */
          if (strlen(path) + n >= PATH_MAX)
@@ -225,15 +334,21 @@ xrealpath (const char *path, char resolved_path [])
          strcpy(copy_path, link_path);
          path = copy_path;
        }
-#endif /* S_IFLNK */
-      *new_path++ = '/';
+#endif /* S_IFLNK || WIN32_NATIVE */
+      *new_path++ = DIRECTORY_SEP;
     }
 
   /* Delete trailing slash but don't whomp a lone slash. */
-  if (new_path != resolved_path + 1 && new_path[-1] == '/')
+  if (new_path != ABS_START (resolved_path) && IS_DIRECTORY_SEP (new_path[-1]))
     new_path--;
 
   /* Make sure it's null terminated. */
   *new_path = '\0';
+
+#ifdef WIN32_NATIVE
+  if (ABS_LENGTH (resolved_path) == 3)
+    /* Lowercase drive letter. */
+    *resolved_path = tolower (*resolved_path);
+#endif
   return resolved_path;
 }
index 08d8bd9..5fce8b3 100644 (file)
 #ifndef INCLUDED_regex_h_
 #define INCLUDED_regex_h_
 
+#ifdef emacs
+#define RE_TRANSLATE_TYPE Lisp_Object
+#else
+#define RE_TRANSLATE_TYPE char *
+#endif /* emacs */
+
 /* POSIX says that <sys/types.h> must be included (by the caller) before
    <regex.h>.  */
 
@@ -329,7 +335,7 @@ struct re_pattern_buffer
            comparing them, or zero for no translation.  The translation
            is applied to a pattern when it is compiled and to a string
            when it is matched.  */
-  char *translate;
+  RE_TRANSLATE_TYPE translate;
 
        /* Number of subexpressions found by the compiler.  */
   size_t re_nsub;
index 8a2c246..4b01e7f 100644 (file)
@@ -179,6 +179,12 @@ double     logb (double);
 
 #define NO_MATHERR
 
+/*
+ *      Define HAVE_PTYS if the system supports pty devices.
+ */
+
+#define HAVE_PTYS
+
 /* define MAIL_USE_FLOCK if the mailer uses flock
    to interlock access to /usr/spool/mail/$USER.
    The alternative is that a lock file named
index 739999b..df25cab 100644 (file)
@@ -375,4 +375,6 @@ void defvar_magic (const char *symbol_name, const struct symbol_value_forward *m
 #define DEFVAR_BOOL_MAGIC(lname, c_location, magicfun) \
        DEFVAR_SYMVAL_FWD_INT (lname, c_location, SYMVAL_BOOLEAN_FORWARD, magicfun)
 
+void flush_all_buffer_local_cache (void);
+
 #endif /* INCLUDED_symeval_h_ */
index a39fbc2..774c0fa 100644 (file)
@@ -53,7 +53,11 @@ unexec (char *, char *, void *, void *,      void *)
 ((((unsigned long)addr) + ALLOC_UNIT) & ALLOC_MASK)
 /* Note that all sections must be aligned on a 0x1000 boundary so
    this is the minimum size that our dummy bss can be. */
+#ifdef BROKEN_GDB
 #define BSS_PAD_SIZE   0x1000
+#else
+#define BSS_PAD_SIZE   0
+#endif
 
 /* To prevent zero-initialized variables from being placed into the bss
    section, use non-zero values to represent an uninitialized state.  */
@@ -121,7 +125,7 @@ void unexec (char *out_name, char *in_name, void *start_data,
     }
 
   if ((a_new = open (new_name, O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY,
-                    CREAT_MODE)) < 0)
+                    0755)) < 0)
     {
       PERROR (new_name);
     }
@@ -306,6 +310,9 @@ copy_executable_and_dump_data_section (int a_out, int a_new)
   lseek (a_new, 0, SEEK_SET);
   /* write file header */
   f_hdr.f_symptr += file_sz_change;
+#ifndef BROKEN_GDB
+  f_hdr.f_nscns--;
+#endif
 
   printf("writing file header\n");
   if (write(a_new, &f_hdr, sizeof(f_hdr)) != sizeof(f_hdr))
@@ -333,7 +340,7 @@ copy_executable_and_dump_data_section (int a_out, int a_new)
     {
       PERROR("failed to write text header");
     }
-
+#ifdef BROKEN_GDB
   /* Write small bss section. */
   if (!sections_reversed)
     {
@@ -345,7 +352,7 @@ copy_executable_and_dump_data_section (int a_out, int a_new)
          PERROR("failed to write bss header");
        }
     }
-
+#endif
   /* write new data header */
   printf("writing .data header\n");
 
@@ -353,7 +360,7 @@ copy_executable_and_dump_data_section (int a_out, int a_new)
     {
       PERROR("failed to write data header");
     }
-
+#ifdef BROKEN_GDB
   /* Write small bss section. */
   if (sections_reversed)
     {
@@ -365,7 +372,7 @@ copy_executable_and_dump_data_section (int a_out, int a_new)
          PERROR("failed to write bss header");
        }
     }
-
+#endif
   printf("writing following data header\n");
   f_nextdata.s_scnptr += file_sz_change;
   if (f_nextdata.s_lnnoptr != 0) f_nextdata.s_lnnoptr += file_sz_change;
@@ -392,7 +399,14 @@ copy_executable_and_dump_data_section (int a_out, int a_new)
          PERROR("failed to write data header");
        }
     }
-
+#ifndef BROKEN_GDB
+  /* dump bss to maintain offsets */
+  memset(&f_bss, 0, sizeof(f_bss));
+  if (write(a_new, &f_bss, sizeof(f_bss)) != sizeof(f_bss))
+    {
+      PERROR("failed to write bss header");
+    }
+#endif
   size=lseek(a_new, 0, SEEK_CUR);
   CHECK_AOUT_POS(size);
 
index f1da87a..54c48e1 100644 (file)
@@ -424,7 +424,7 @@ extern void fatal (const char *, ...);
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
-#if !defined (__NetBSD__) && !defined (__OpenBSD__)
+#ifdef HAVE_ELF_H
 #include <elf.h>
 #endif
 #include <sys/mman.h>
index ad54ccf..ee93167 100644 (file)
@@ -1,38 +1,27 @@
 /* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992, 1999, 2000
    Free Software Foundation, Inc.
 
-This file is part of XEmacs.
+   This file is part of XEmacs.
 
-XEmacs is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+   XEmacs is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
 
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   GNU Emacs is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
+   You should have received a copy of the GNU General Public License
+   along with GNU Emacs; see the file COPYING.  If not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
 
-In other words, you are welcome to use, share and improve this program.
-You are forbidden to forbid anyone else to use, share and improve
-what you give them.   Help stamp out software-hoarding!  */
+   In other words, you are welcome to use, share and improve this
+   program.  You are forbidden to forbid anyone else to use, share and
+   improve what you give them.  Help stamp out software-hoarding!  */
 
-/* 2000-10-31: Martin Buchholz
-
-   I noticed that xemacs on Irix 6.5 could not write to stderr, e.g.
-   (external-debugging-output "\n")
-   would produce NO output.
-   temacs worked fine, so this was clearly a dumping problem.
-
-   So I copied over the latest available unexelf.c from FSF Emacs,
-   and installed it as unexelfsgi.c in XEmacs.
-   In addition, I converted it to "Clean C", resulting in this file.
-*/
 
 /*
  * unexec.c - Convert a running program into an a.out file.
@@ -44,375 +33,40 @@ what you give them.   Help stamp out software-hoarding!  */
  * Modified heavily since then.
  *
  * Synopsis:
- *     unexec (new_name, old_name, data_start, bss_start, entry_address)
- *     char *new_name, *old_name;
- *     unsigned data_start, bss_start, entry_address;
- *
- * Takes a snapshot of the program and makes an a.out format file in the
- * file named by the string argument new_name.
- * If old_name is non-NULL, the symbol table will be taken from the given file.
- * On some machines, an existing old_name file is required.
- *
- * The boundaries within the a.out file may be adjusted with the data_start
- * and bss_start arguments.  Either or both may be given as 0 for defaults.
+ * void
+ * unexec (char *new_name,
+ *        char *old_name,
+ *        uintptr_t data_start,
+ *        uintptr_t bss_start,
+ *        uintptr_t entry_address)
  *
- * Data_start gives the boundary between the text segment and the data
- * segment of the program.  The text segment can contain shared, read-only
- * program code and literal data, while the data segment is always unshared
- * and unprotected.  Data_start gives the lowest unprotected address.
- * The value you specify may be rounded down to a suitable boundary
- * as required by the machine you are using.
+ * The basic idea is that we start with an ELF file which contains
+ * .bss (uninitialized global data) section which is normally not in
+ * the file. As we load lisp the variables, which were first set to 0,
+ * will change their values. We want to save those changed values into
+ * another ELF file, which will become a new xemacs image. To do this,
+ * we need to change several structures in the ELF file.
  *
- * Bss_start indicates how much of the data segment is to be saved in the
- * a.out file and restored when the program is executed.  It gives the lowest
- * unsaved address, and is rounded up to a page boundary.  The default when 0
- * is given assumes that the entire data segment is to be stored, including
- * the previous data and bss as well as any additional storage allocated with
- * break (2).
+ *   First of all, we need to change the programm header which tells
+ *   the linker how to load stuff into memory so that data will come
+ *   from the file and not from the /dev/zero. To do this, we find the
+ *   segment, which is marked as loadable (type PT_LOAD) and which
+ *   covers the old .bss section. We will next change the filesz and
+ *   memsz for that segment to extend over the new data section.
  *
- * The new file is set up to start at entry_address.
- *
- */
-
-/* Even more heavily modified by james@bigtex.cactus.org of Dell Computer Co.
- * ELF support added.
+ *   Next we have to make sure that section header for the stuff which
+ *   used to be uninitialized is changed to be initialized and to come
+ *   from the file. To do this, we change the size and the type of the old
+ *   .bss section (and all other section of the type SHT_NOBITS) to cover the
+ *   new section and to be of type SHT_PROCBITS.
  *
- * Basic theory: the data space of the running process needs to be
- * dumped to the output file.  Normally we would just enlarge the size
- * of .data, scooting everything down.  But we can't do that in ELF,
- * because there is often something between the .data space and the
- * .bss space.
+ *   We also insert a new SHT_NOBITS section to keep some tools, which expect
+ *   .bss happy.
  *
- * In the temacs dump below, notice that the Global Offset Table
- * (.got) and the Dynamic link data (.dynamic) come between .data1 and
- * .bss.  It does not work to overlap .data with these fields.
- *
- * The solution is to create a new .data segment.  This segment is
- * filled with data from the current process.  Since the contents of
- * various sections refer to sections by index, the new .data segment
- * is made the last in the table to avoid changing any existing index.
-
- * This is an example of how the section headers are changed.  "Addr"
- * is a process virtual address.  "Offset" is a file offset.
-
-raid:/nfs/raid/src/dist-18.56/src> dump -h temacs
-
-temacs:
-
-           **** SECTION HEADER TABLE ****
-[No]    Type    Flags   Addr         Offset       Size          Name
-        Link    Info    Adralgn      Entsize
-
-[1]     1       2       0x80480d4    0xd4         0x13          .interp
-        0       0       0x1          0
-
-[2]     5       2       0x80480e8    0xe8         0x388         .hash
-        3       0       0x4          0x4
-
-[3]     11      2       0x8048470    0x470        0x7f0         .dynsym
-        4       1       0x4          0x10
-
-[4]     3       2       0x8048c60    0xc60        0x3ad         .dynstr
-        0       0       0x1          0
-
-[5]     9       2       0x8049010    0x1010       0x338         .rel.plt
-        3       7       0x4          0x8
-
-[6]     1       6       0x8049348    0x1348       0x3           .init
-        0       0       0x4          0
-
-[7]     1       6       0x804934c    0x134c       0x680         .plt
-        0       0       0x4          0x4
-
-[8]     1       6       0x80499cc    0x19cc       0x3c56f       .text
-        0       0       0x4          0
-
-[9]     1       6       0x8085f3c    0x3df3c      0x3           .fini
-        0       0       0x4          0
-
-[10]    1       2       0x8085f40    0x3df40      0x69c         .rodata
-        0       0       0x4          0
-
-[11]    1       2       0x80865dc    0x3e5dc      0xd51         .rodata1
-        0       0       0x4          0
-
-[12]    1       3       0x8088330    0x3f330      0x20afc       .data
-        0       0       0x4          0
-
-[13]    1       3       0x80a8e2c    0x5fe2c      0x89d         .data1
-        0       0       0x4          0
-
-[14]    1       3       0x80a96cc    0x606cc      0x1a8         .got
-        0       0       0x4          0x4
-
-[15]    6       3       0x80a9874    0x60874      0x80          .dynamic
-        4       0       0x4          0x8
-
-[16]    8       3       0x80a98f4    0x608f4      0x449c        .bss
-        0       0       0x4          0
-
-[17]    2       0       0            0x608f4      0x9b90        .symtab
-        18      371     0x4          0x10
-
-[18]    3       0       0            0x6a484      0x8526        .strtab
-        0       0       0x1          0
-
-[19]    3       0       0            0x729aa      0x93          .shstrtab
-        0       0       0x1          0
-
-[20]    1       0       0            0x72a3d      0x68b7        .comment
-        0       0       0x1          0
-
-raid:/nfs/raid/src/dist-18.56/src> dump -h xemacs
-
-xemacs:
-
-           **** SECTION HEADER TABLE ****
-[No]    Type    Flags   Addr         Offset       Size          Name
-        Link    Info    Adralgn      Entsize
-
-[1]     1       2       0x80480d4    0xd4         0x13          .interp
-        0       0       0x1          0
-
-[2]     5       2       0x80480e8    0xe8         0x388         .hash
-        3       0       0x4          0x4
-
-[3]     11      2       0x8048470    0x470        0x7f0         .dynsym
-        4       1       0x4          0x10
-
-[4]     3       2       0x8048c60    0xc60        0x3ad         .dynstr
-        0       0       0x1          0
-
-[5]     9       2       0x8049010    0x1010       0x338         .rel.plt
-        3       7       0x4          0x8
-
-[6]     1       6       0x8049348    0x1348       0x3           .init
-        0       0       0x4          0
-
-[7]     1       6       0x804934c    0x134c       0x680         .plt
-        0       0       0x4          0x4
-
-[8]     1       6       0x80499cc    0x19cc       0x3c56f       .text
-        0       0       0x4          0
-
-[9]     1       6       0x8085f3c    0x3df3c      0x3           .fini
-        0       0       0x4          0
-
-[10]    1       2       0x8085f40    0x3df40      0x69c         .rodata
-        0       0       0x4          0
-
-[11]    1       2       0x80865dc    0x3e5dc      0xd51         .rodata1
-        0       0       0x4          0
-
-[12]    1       3       0x8088330    0x3f330      0x20afc       .data
-        0       0       0x4          0
-
-[13]    1       3       0x80a8e2c    0x5fe2c      0x89d         .data1
-        0       0       0x4          0
-
-[14]    1       3       0x80a96cc    0x606cc      0x1a8         .got
-        0       0       0x4          0x4
-
-[15]    6       3       0x80a9874    0x60874      0x80          .dynamic
-        4       0       0x4          0x8
-
-[16]    8       3       0x80c6800    0x7d800      0             .bss
-        0       0       0x4          0
-
-[17]    2       0       0            0x7d800      0x9b90        .symtab
-        18      371     0x4          0x10
-
-[18]    3       0       0            0x87390      0x8526        .strtab
-        0       0       0x1          0
-
-[19]    3       0       0            0x8f8b6      0x93          .shstrtab
-        0       0       0x1          0
-
-[20]    1       0       0            0x8f949      0x68b7        .comment
-        0       0       0x1          0
-
-[21]    1       3       0x80a98f4    0x608f4      0x1cf0c       .data
-        0       0       0x4          0
-
- * This is an example of how the file header is changed.  "Shoff" is
- * the section header offset within the file.  Since that table is
- * after the new .data section, it is moved.  "Shnum" is the number of
- * sections, which we increment.
- *
- * "Phoff" is the file offset to the program header.  "Phentsize" and
- * "Shentsz" are the program and section header entries sizes respectively.
- * These can be larger than the apparent struct sizes.
-
-raid:/nfs/raid/src/dist-18.56/src> dump -f temacs
-
-temacs:
-
-                    **** ELF HEADER ****
-Class        Data       Type         Machine     Version
-Entry        Phoff      Shoff        Flags       Ehsize
-Phentsize    Phnum      Shentsz      Shnum       Shstrndx
-
-1            1          2            3           1
-0x80499cc    0x34       0x792f4      0           0x34
-0x20         5          0x28         21          19
-
-raid:/nfs/raid/src/dist-18.56/src> dump -f xemacs
-
-xemacs:
-
-                    **** ELF HEADER ****
-Class        Data       Type         Machine     Version
-Entry        Phoff      Shoff        Flags       Ehsize
-Phentsize    Phnum      Shentsz      Shnum       Shstrndx
-
-1            1          2            3           1
-0x80499cc    0x34       0x96200      0           0x34
-0x20         5          0x28         22          19
-
- * These are the program headers.  "Offset" is the file offset to the
- * segment.  "Vaddr" is the memory load address.  "Filesz" is the
- * segment size as it appears in the file, and "Memsz" is the size in
- * memory.  Below, the third segment is the code and the fourth is the
- * data: the difference between Filesz and Memsz is .bss
-
-raid:/nfs/raid/src/dist-18.56/src> dump -o temacs
-
-temacs:
- ***** PROGRAM EXECUTION HEADER *****
-Type        Offset      Vaddr       Paddr
-Filesz      Memsz       Flags       Align
-
-6           0x34        0x8048034   0
-0xa0        0xa0        5           0
-
-3           0xd4        0           0
-0x13        0           4           0
-
-1           0x34        0x8048034   0
-0x3f2f9     0x3f2f9     5           0x1000
-
-1           0x3f330     0x8088330   0
-0x215c4     0x25a60     7           0x1000
-
-2           0x60874     0x80a9874   0
-0x80        0           7           0
-
-raid:/nfs/raid/src/dist-18.56/src> dump -o xemacs
-
-xemacs:
- ***** PROGRAM EXECUTION HEADER *****
-Type        Offset      Vaddr       Paddr
-Filesz      Memsz       Flags       Align
-
-6           0x34        0x8048034   0
-0xa0        0xa0        5           0
-
-3           0xd4        0           0
-0x13        0           4           0
-
-1           0x34        0x8048034   0
-0x3f2f9     0x3f2f9     5           0x1000
-
-1           0x3f330     0x8088330   0
-0x3e4d0     0x3e4d0     7           0x1000
-
-2           0x60874     0x80a9874   0
-0x80        0           7           0
-
-
- */
-\f
-/* Modified by wtien@urbana.mcd.mot.com of Motorola Inc.
- *
- * The above mechanism does not work if the unexeced ELF file is being
- * re-layout by other applications (such as `strip'). All the applications
- * that re-layout the internal of ELF will layout all sections in ascending
- * order of their file offsets. After the re-layout, the data2 section will
- * still be the LAST section in the section header vector, but its file offset
- * is now being pushed far away down, and causes part of it not to be mapped
- * in (ie. not covered by the load segment entry in PHDR vector), therefore
- * causes the new binary to fail.
- *
- * The solution is to modify the unexec algorithm to insert the new data2
- * section header right before the new bss section header, so their file
- * offsets will be in the ascending order. Since some of the section's (all
- * sections AFTER the bss section) indexes are now changed, we also need to
- * modify some fields to make them point to the right sections. This is done
- * by macro PATCH_INDEX. All the fields that need to be patched are:
- *
- * 1. ELF header e_shstrndx field.
- * 2. section header sh_link and sh_info field.
- * 3. symbol table entry st_shndx field.
- *
- * The above example now should look like:
-
-           **** SECTION HEADER TABLE ****
-[No]    Type    Flags   Addr         Offset       Size          Name
-        Link    Info    Adralgn      Entsize
-
-[1]     1       2       0x80480d4    0xd4         0x13          .interp
-        0       0       0x1          0
-
-[2]     5       2       0x80480e8    0xe8         0x388         .hash
-        3       0       0x4          0x4
-
-[3]     11      2       0x8048470    0x470        0x7f0         .dynsym
-        4       1       0x4          0x10
-
-[4]     3       2       0x8048c60    0xc60        0x3ad         .dynstr
-        0       0       0x1          0
-
-[5]     9       2       0x8049010    0x1010       0x338         .rel.plt
-        3       7       0x4          0x8
-
-[6]     1       6       0x8049348    0x1348       0x3           .init
-        0       0       0x4          0
-
-[7]     1       6       0x804934c    0x134c       0x680         .plt
-        0       0       0x4          0x4
-
-[8]     1       6       0x80499cc    0x19cc       0x3c56f       .text
-        0       0       0x4          0
-
-[9]     1       6       0x8085f3c    0x3df3c      0x3           .fini
-        0       0       0x4          0
-
-[10]    1       2       0x8085f40    0x3df40      0x69c         .rodata
-        0       0       0x4          0
-
-[11]    1       2       0x80865dc    0x3e5dc      0xd51         .rodata1
-        0       0       0x4          0
-
-[12]    1       3       0x8088330    0x3f330      0x20afc       .data
-        0       0       0x4          0
-
-[13]    1       3       0x80a8e2c    0x5fe2c      0x89d         .data1
-        0       0       0x4          0
-
-[14]    1       3       0x80a96cc    0x606cc      0x1a8         .got
-        0       0       0x4          0x4
-
-[15]    6       3       0x80a9874    0x60874      0x80          .dynamic
-        4       0       0x4          0x8
-
-[16]    1       3       0x80a98f4    0x608f4      0x1cf0c       .data
-        0       0       0x4          0
-
-[17]    8       3       0x80c6800    0x7d800      0             .bss
-        0       0       0x4          0
-
-[18]    2       0       0            0x7d800      0x9b90        .symtab
-        19      371     0x4          0x10
-
-[19]    3       0       0            0x87390      0x8526        .strtab
-        0       0       0x1          0
-
-[20]    3       0       0            0x8f8b6      0x93          .shstrtab
-        0       0       0x1          0
-
-[21]    1       0       0            0x8f949      0x68b7        .comment
-        0       0       0x1          0
-
+ *   Finally we need to patch up some references to the section
+ *   indexes since we change the order and undo the relocation info to
+ *   be the same as it was "before" because we actually used the data
+ *   from the memory which were changed by the run-time linker.
  */
 \f
 #ifndef emacs
@@ -430,7 +84,7 @@ extern void fatal (const char *, ...);
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
-#if !defined (__NetBSD__) && !defined (__OpenBSD__)
+#ifdef HAVE_ELF_H
 #include <elf.h>
 #endif
 #include <sys/mman.h>
@@ -442,85 +96,6 @@ extern void fatal (const char *, ...);
 #include <syms.h> /* for HDRR declaration */
 #endif /* __sgi */
 
-#if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__)
-/* Declare COFF debugging symbol table.  This used to be in
-   /usr/include/sym.h, but this file is no longer included in Red Hat
-   5.0 and presumably in any other glibc 2.x based distribution.  */
-typedef struct {
-       short magic;
-       short vstamp;
-       int ilineMax;
-       int idnMax;
-       int ipdMax;
-       int isymMax;
-       int ioptMax;
-       int iauxMax;
-       int issMax;
-       int issExtMax;
-       int ifdMax;
-       int crfd;
-       int iextMax;
-       long cbLine;
-       long cbLineOffset;
-       long cbDnOffset;
-       long cbPdOffset;
-       long cbSymOffset;
-       long cbOptOffset;
-       long cbAuxOffset;
-       long cbSsOffset;
-       long cbSsExtOffset;
-       long cbFdOffset;
-       long cbRfdOffset;
-       long cbExtOffset;
-} HDRR, *pHDRR;
-#define cbHDRR sizeof(HDRR)
-#define hdrNil ((pHDRR)0)
-#endif
-
-#ifdef __NetBSD__
-/*
- * NetBSD does not have normal-looking user-land ELF support.
- */
-# if defined __alpha__ || defined __sparc_v9__
-#  define ELFSIZE      64
-# else
-#  define ELFSIZE      32
-# endif
-# include <sys/exec_elf.h>
-
-# ifndef PT_LOAD
-#  define PT_LOAD      Elf_pt_load
-#  if 0                                                /* was in pkgsrc patches for 20.7 */
-#   define SHT_PROGBITS Elf_sht_progbits
-#  endif
-#  define SHT_SYMTAB   Elf_sht_symtab
-#  define SHT_DYNSYM   Elf_sht_dynsym
-#  define SHT_NULL     Elf_sht_null
-#  define SHT_NOBITS   Elf_sht_nobits
-#  define SHT_REL      Elf_sht_rel
-#  define SHT_RELA     Elf_sht_rela
-
-#  define SHN_UNDEF    Elf_eshn_undefined
-#  define SHN_ABS      Elf_eshn_absolute
-#  define SHN_COMMON   Elf_eshn_common
-# endif /* !PT_LOAD */
-
-# ifdef __alpha__
-#  include <sys/exec_ecoff.h>
-#  define HDRR         struct ecoff_symhdr
-#  define pHDRR                HDRR *
-# endif /* __alpha__ */
-
-#ifdef __mips__                        /* was in pkgsrc patches for 20.7 */
-# define SHT_MIPS_DEBUG        DT_MIPS_FLAGS
-# define HDRR          struct Elf_Shdr
-#endif /* __mips__ */
-#endif /* __NetBSD__ */
-
-#ifdef __OpenBSD__
-# include <sys/exec_elf.h>
-#endif
-
 #if __GNU_LIBRARY__ - 0 >= 6
 # include <link.h>     /* get ElfW etc */
 #endif
@@ -546,31 +121,7 @@ typedef struct {
 #endif
 
 /* Get the address of a particular section or program header entry,
- * accounting for the size of the entries.
- */
-/*
-   On PPC Reference Platform running Solaris 2.5.1
-   the plt section is also of type NOBI like the bss section.
-   (not really stored) and therefore sections after the bss
-   section start at the plt offset. The plt section is always
-   the one just before the bss section.
-   Thus, we modify the test from
-      if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
-   to
-      if (NEW_SECTION_H (nn).sh_offset >=
-               OLD_SECTION_H (old_bss_index-1).sh_offset)
-   This is just a hack. We should put the new data section
-   before the .plt section.
-   And we should not have this routine at all but use
-   the libelf library to read the old file and create the new
-   file.
-   The changed code is minimal and depends on prep set in m/prep.h
-   Erik Deumens
-   Quantum Theory Project
-   University of Florida
-   deumens@qtp.ufl.edu
-   Apr 23, 1996
-   */
+ * accounting for the size of the entries. */
 
 #define OLD_SECTION_H(n) \
      (*(ElfW(Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
@@ -583,8 +134,9 @@ typedef struct {
 
 #define PATCH_INDEX(n) \
   do { \
-        if ((int) (n) >= old_bss_index) \
+        if ((int) (n) >= growme_index) \
           (n)++; } while (0)
+
 typedef unsigned char byte;
 
 /* Round X up to a multiple of Y.  */
@@ -607,7 +159,7 @@ round_up (ElfW(Addr) x, ElfW(Addr) y)
 
 static int
 find_section (char *name,
-             char *section_names,
+             const char *section_names,
              char *file_name,
              ElfW(Ehdr) *old_file_h,
              ElfW(Shdr) *old_section_h,
@@ -623,17 +175,14 @@ find_section (char *name,
 #endif
       if (!strcmp (section_names + OLD_SECTION_H (idx).sh_name,
                   name))
-       break;
-    }
-  if (idx == old_file_h->e_shnum)
-    {
-      if (noerror)
-       return -1;
-      else
-       fatal ("Can't find %s in %s.\n", name, file_name);
+         return idx;
     }
 
-  return idx;
+  /* If we're here, we found nothing or return did not work */
+  if ( ! noerror)
+      fatal ("Can't find %s in %s.\n", name, file_name);
+
+  return -1;
 }
 
 /* ****************************************************************
@@ -652,158 +201,97 @@ unexec (char *new_name,
        uintptr_t bss_start,
        uintptr_t entry_address)
 {
-  int new_file, old_file, new_file_size;
+  int old_file;
 
-  /* Pointers to the base of the image of the two files. */
+  struct stat stat_buf;
   caddr_t old_base, new_base;
 
-  /* Pointers to the file, program and section headers for the old and new
-   * files.
-   */
-  ElfW(Ehdr) *old_file_h, *new_file_h;
-  ElfW(Phdr) *old_program_h, *new_program_h;
-  ElfW(Shdr) *old_section_h, *new_section_h;
-
-  /* Point to the section name table in the old file */
-  char *old_section_names;
-
-  ElfW(Addr) old_bss_addr, new_bss_addr;
-  ElfW(Word) old_bss_size, new_data2_size;
-  ElfW(Off)  new_data2_offset;
-  ElfW(Addr) new_data2_addr;
+  ElfW(Ehdr) *old_file_h, * new_file_h;
+  ElfW(Phdr) *old_program_h, * new_program_h;
+  ElfW(Shdr) *old_section_h, * new_section_h;
+  ElfW(Shdr) * growme = NULL, * grown = NULL;
+  ElfW(Addr) old_bss_addr = 0,  new_data2_addr = 0;
 
+  int growme_index = -1;
   int n, nn;
-  int old_bss_index, old_sbss_index;
-  int old_data_index, new_data2_index;
-  int old_mdebug_index;
-  struct stat stat_buf;
-
-  /* Open the old file & map it into the address space. */
+  const char *old_section_names;
+  int old_mdebug_index, old_data_index;
+  int new_bss_addr, new_data2_size, new_data2_offset, new_file, new_file_size;
 
-  old_file = open (old_name, O_RDONLY);
-
-  if (old_file < 0)
-    fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
+  /* Open the old file */
+  if ( (old_file = open (old_name, O_RDONLY)) < 0 )
+      fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
 
   if (fstat (old_file, &stat_buf) == -1)
-    fatal ("Can't fstat (%s): errno %d\n", old_name, errno);
-
-  old_base = (caddr_t) mmap ((caddr_t) 0, stat_buf.st_size,
-                            PROT_READ, MAP_SHARED, old_file, 0);
+      fatal ("Can't fstat (%s): errno %d\n", old_name, errno);
 
-  if (old_base == (caddr_t) -1)
-    fatal ("Can't mmap (%s): errno %d\n", old_name, errno);
-
-#ifdef DEBUG
-  fprintf (stderr, "mmap (%s, %x) -> %x\n", old_name, stat_buf.st_size,
-          old_base);
-#endif
+  /* map old file into the address space. */
+  if ( (old_base = (caddr_t) mmap ((caddr_t) 0, stat_buf.st_size,
+                                  PROT_READ, MAP_SHARED, old_file, 0)) < 0 )
+      fatal ("Can't mmap (%s): errno %d\n", old_name, errno);
 
-  /* Get pointers to headers & section names */
-
-  old_file_h = (ElfW(Ehdr) *) old_base;
+  old_file_h    = (ElfW(Ehdr) *) old_base;
   old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff);
   old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff);
-  old_section_names = (char *) old_base
-    + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
-
-  /* Find the mdebug section, if any.  */
-
-  old_mdebug_index = find_section (".mdebug", old_section_names,
-                                  old_name, old_file_h, old_section_h, 1);
-
-  /* Find the old .bss section.  Figure out parameters of the new
-   * data2 and bss sections.
-   */
-
-  old_bss_index = find_section (".bss", old_section_names,
-                               old_name, old_file_h, old_section_h, 0);
-
-  old_sbss_index = find_section (".sbss", old_section_names,
-                                old_name, old_file_h, old_section_h, 1);
-  if (old_sbss_index != -1)
-    if (OLD_SECTION_H (old_sbss_index).sh_type == SHT_PROGBITS)
-      old_sbss_index = -1;
-
-  if (old_sbss_index == -1)
-    {
-      old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
-      old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
-      new_data2_index = old_bss_index;
-    }
-  else
-    {
-      old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr;
-      old_bss_size = OLD_SECTION_H (old_bss_index).sh_size
-       + OLD_SECTION_H (old_sbss_index).sh_size;
-      new_data2_index = old_sbss_index;
-    }
+  old_section_names = (const char *) old_base
+      + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
+
+  /* Find a section which we will grow by looking for the SHT_NOBITS
+   * section with ALLOCATE flag and with the biggest address. */
+  for (n = 1; n < old_file_h->e_shnum; n++) {
+      ElfW(Shdr) * sh = & OLD_SECTION_H(n);
+
+      if ((sh->sh_type == SHT_NOBITS) && (sh->sh_flags & SHF_ALLOC)) {
+         if ( old_bss_addr < sh->sh_addr ) {
+             growme = sh;
+             growme_index = n;
+             new_data2_addr = old_bss_addr =  sh->sh_addr;
+         }
+      }
+  }
 
-  /* Find the old .data section.  Figure out parameters of
-     the new data2 and bss sections.  */
+  if (growme == NULL )
+      fatal ("Can't find a section to grow\n", 0, 0);
 
   old_data_index = find_section (".data", old_section_names,
                                 old_name, old_file_h, old_section_h, 0);
 
-#if defined (emacs) || !defined (DEBUG)
   new_bss_addr = (ElfW(Addr)) sbrk (0);
-#else
-  new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
-#endif
-  new_data2_addr = old_bss_addr;
   new_data2_size = new_bss_addr - old_bss_addr;
   new_data2_offset  = OLD_SECTION_H (old_data_index).sh_offset +
-    (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr);
-
-#ifdef DEBUG
-  fprintf (stderr, "old_bss_index %d\n", old_bss_index);
-  fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
-  fprintf (stderr, "old_bss_size %x\n", old_bss_size);
-  fprintf (stderr, "new_bss_addr %x\n", new_bss_addr);
-  fprintf (stderr, "new_data2_addr %x\n", new_data2_addr);
-  fprintf (stderr, "new_data2_size %x\n", new_data2_size);
-  fprintf (stderr, "new_data2_offset %x\n", new_data2_offset);
-#endif
-
-  if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
-    fatal (".bss shrank when undumping???\n", 0, 0);
+      (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr);
 
-  /* Set the output file to the right size and mmap it.  Set
-   * pointers to various interesting objects.  stat_buf still has
-   * old_file data.
-   */
+  if ( new_bss_addr < old_bss_addr + growme->sh_size )
+      fatal (".bss shrank when undumping???\n", 0, 0);
 
-  new_file = open (new_name, O_RDWR | O_CREAT, 0666);
-  if (new_file < 0)
-    fatal ("Can't creat (%s): errno %d\n", new_name, errno);
+  /* Set the output file to the right size and mmap it. */
+  if ( (new_file = open (new_name, O_RDWR | O_CREAT, 0666)) < 0 )
+      fatal ("Can't create (%s): errno %d\n", new_name, errno);
 
-  new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size;
+  new_file_size = stat_buf.st_size +  old_file_h->e_shentsize + new_data2_size;
 
   if (ftruncate (new_file, new_file_size))
-    fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
+      fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
 
-#ifdef UNEXEC_USE_MAP_PRIVATE
   new_base = (caddr_t) mmap ((caddr_t) 0, new_file_size,
                             PROT_READ | PROT_WRITE,
-                            MAP_PRIVATE, new_file, 0);
+#ifdef UNEXEC_USE_MAP_PRIVATE
+                            MAP_PRIVATE,
 #else
-  new_base = (caddr_t) mmap ((caddr_t) 0, new_file_size,
-                            PROT_READ | PROT_WRITE,
-                            MAP_SHARED, new_file, 0);
+                            MAP_SHARED,
 #endif
+                            new_file, 0);
 
   if (new_base == (caddr_t) -1)
-    fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
+      fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
 
   new_file_h = (ElfW(Ehdr) *) new_base;
   new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
-  new_section_h = (ElfW(Shdr) *)
-    ((byte *) new_base + old_file_h->e_shoff + new_data2_size);
+  new_section_h = (ElfW(Shdr) *) ((byte *) new_base + old_file_h->e_shoff +
+                                 new_data2_size);
 
   /* Make our new file, program and section headers as copies of the
-   * originals.
-   */
-
+   * originals.  */
   memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
   memcpy (new_program_h, old_program_h,
          old_file_h->e_phnum * old_file_h->e_phentsize);
@@ -812,245 +300,148 @@ unexec (char *new_name,
   PATCH_INDEX (new_file_h->e_shstrndx);
 
   /* Fix up file header.  We'll add one section.  Section header is
-   * further away now.
-   */
-
+   * further away now.  */
   new_file_h->e_shoff += new_data2_size;
   new_file_h->e_shnum += 1;
 
+  /* Fix up a new program header by extending the writable data
+   * segment so that the bss area is covered too. Find that segment by
+   * looking for one that starts before and ends after the .bss and is
+   * PT_LOADable. */
+  for (n = new_file_h->e_phnum - 1; n >= 0; n--) {
+      ElfW(Phdr) * ph = & NEW_PROGRAM_H(n);
 #ifdef DEBUG
-  fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff);
-  fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum);
-  fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff);
-  fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
+      printf ("%d @ %0x + %0x against %0x + %0x",
+             n, ph->p_vaddr, ph->p_memsz,growme->sh_addr, growme->sh_size);
 #endif
+      if ((ph->p_type == PT_LOAD) &&
+         (ph->p_vaddr <= growme->sh_addr) &&
+         ((ph->p_vaddr+ph->p_memsz) >= (growme->sh_addr + growme->sh_size))) {
+         /* Make sure that the size includes any padding before the
+          * old .bss section.  */
+         ph->p_memsz = ph->p_filesz = new_bss_addr - ph->p_vaddr;
+#ifdef DEBUG
+         puts (" That's the one!");
+#endif
+         break;
+      }
+#ifdef DEBUG
+      putchar ('\n');
+#endif
+  }
 
-  /* Fix up a new program header.  Extend the writable data segment so
-   * that the bss area is covered too. Find that segment by looking
-   * for a segment that ends just before the .bss area.  Make sure
-   * that no segments are above the new .data2.  Put a loop at the end
-   * to adjust the offset and address of any segment that is above
-   * data2, just in case we decide to allow this later.
-   */
-
-  for (n = new_file_h->e_phnum - 1; n >= 0; n--)
-    {
-      /* Compute maximum of all requirements for alignment of section.  */
-      ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align;
-      if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
-       alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
-
-#ifdef __sgi
-         /* According to r02kar@x4u2.desy.de (Karsten Kuenne)
-            and oliva@gnu.org (Alexandre Oliva), on IRIX 5.2, we
-            always get "Program segment above .bss" when dumping
-            when the executable doesn't have an sbss section.  */
-      if (old_sbss_index != -1)
-#endif /* __sgi */
-      if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz
-         > (old_sbss_index == -1
-            ? old_bss_addr
-            : round_up (old_bss_addr, alignment)))
-         fatal ("Program segment above .bss in %s\n", old_name, 0);
-
-      if (NEW_PROGRAM_H (n).p_type == PT_LOAD
-         && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
-                       + (NEW_PROGRAM_H (n)).p_filesz,
-                       alignment)
-             == round_up (old_bss_addr, alignment)))
-       break;
-    }
   if (n < 0)
-    fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
+      fatal ("Couldn't find segment which covers %s",
+            old_section_names + growme->sh_name);
+
+  /* Walk through all section headers, insert the new data2 section
+   * right before the new bss section. */
+  for (n = 1, nn = 1; n < (int) old_file_h->e_shnum;  n++, nn++) {
+      ElfW(Shdr) * nsec = & NEW_SECTION_H(nn);
+      ElfW(Shdr) * osec = & OLD_SECTION_H(n);
+
+      /* If this is the section we want to grow, insert the new data
+       * section before it. */
+      if ( osec == growme ) {
+         /* Steal the data section header for this data2 section but
+          * use the * 'grow' section's alignment. This * will assure
+          * that the new section * always be placed in the same spot
+          * * as the old section by any other * application. */
+         ElfW(Shdr) * od = &OLD_SECTION_H(old_data_index);
+
+         memcpy (nsec, od, new_file_h->e_shentsize);
+
+         nsec->sh_addr = new_data2_addr;
+         nsec->sh_offset =  new_data2_offset;
+         nsec->sh_size = new_data2_size;
+         nsec->sh_addralign = osec->sh_addralign;
+
+         /* Copy over what we have in memory now. */
+         memcpy (nsec->sh_offset + new_base, (caddr_t) osec->sh_addr,
+                 new_data2_size);
+         nn++;
+         grown = nsec++;
+      }
 
-  /* Make sure that the size includes any padding before the old .bss
-     section.  */
-  NEW_PROGRAM_H (n).p_filesz = new_bss_addr - NEW_PROGRAM_H (n).p_vaddr;
-  NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
+      memcpy (nsec, osec, old_file_h->e_shentsize);
+
+      if ( osec == growme ) {
+         /* The new bss section's size is zero, and its file offset
+          * and virtual address should be off by NEW_DATA2_SIZE.  */
+         nsec->sh_offset = grown->sh_offset + new_data2_size;
+         nsec->sh_addr = grown->sh_addr + new_data2_size;
+
+         /* Let the new bss section address alignment be the same as
+          * the section address alignment followed the old bss
+          * section, so this section will be placed in exactly the
+          * same place. */
+         nsec->sh_addralign = osec->sh_addralign;
+         nsec->sh_size = 0;
+      } else {
+         /* Any section that was originally placed AFTER the bss
+          * section should now be off by NEW_DATA2_SIZE. */
+         if ( round_up (nsec->sh_offset, growme->sh_addralign) >=
+              new_data2_offset)
+             nsec->sh_offset += new_data2_size;
+      }
 
-#if 0 /* Maybe allow section after data2 - does this ever happen? */
-  for (n = new_file_h->e_phnum - 1; n >= 0; n--)
-    {
-      if (NEW_PROGRAM_H (n).p_vaddr
-         && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr)
-       NEW_PROGRAM_H (n).p_vaddr += new_data2_size - old_bss_size;
+      /* Any section that was originally placed after the section *
+       * header table should now be off by the size of one section
+       * header table entry.  */
+      if (nsec->sh_offset > new_file_h->e_shoff)
+         nsec->sh_offset += new_file_h->e_shentsize;
 
-      if (NEW_PROGRAM_H (n).p_offset >= new_data2_offset)
-       NEW_PROGRAM_H (n).p_offset += new_data2_size;
-    }
-#endif
-
-  /* Fix up section headers based on new .data2 section.  Any section
-   * whose offset or virtual address is after the new .data2 section
-   * gets its value adjusted.  .bss size becomes zero and new address
-   * is set.  data2 section header gets added by copying the existing
-   * .data header and modifying the offset, address and size.
-   */
-  for (old_data_index = 1; old_data_index < (int) old_file_h->e_shnum;
-       old_data_index++)
-    if (!strcmp (old_section_names + OLD_SECTION_H (old_data_index).sh_name,
-                ".data"))
-      break;
-  if (old_data_index == old_file_h->e_shnum)
-    fatal ("Can't find .data in %s.\n", old_name, 0);
-
-  /* Walk through all section headers, insert the new data2 section right
-     before the new bss section. */
-  for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++)
-    {
-      caddr_t src;
-      /* If it is (s)bss section, insert the new data2 section before it.  */
-      /* new_data2_index is the index of either old_sbss or old_bss, that was
-        chosen as a section for new_data2.   */
-      if (n == new_data2_index)
-       {
-         /* Steal the data section header for this data2 section. */
-         memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
-                 new_file_h->e_shentsize);
-
-         NEW_SECTION_H (nn).sh_addr = new_data2_addr;
-         NEW_SECTION_H (nn).sh_offset = new_data2_offset;
-         NEW_SECTION_H (nn).sh_size = new_data2_size;
-         /* Use the bss section's alignment. This will assure that the
-            new data2 section always be placed in the same spot as the old
-            bss section by any other application. */
-         NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign;
-
-         /* Now copy over what we have in the memory now. */
-         memcpy (NEW_SECTION_H (nn).sh_offset + new_base,
-                 (caddr_t) OLD_SECTION_H (n).sh_addr,
-                 new_data2_size);
-         nn++;
-       }
-
-      memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
-             old_file_h->e_shentsize);
-
-      if (n == old_bss_index
-         /* The new bss and sbss section's size is zero, and its file offset
-            and virtual address should be off by NEW_DATA2_SIZE.  */
-         || n == old_sbss_index
-         )
-       {
-         /* NN should be `old_s?bss_index + 1' at this point. */
-         NEW_SECTION_H (nn).sh_offset =
-           NEW_SECTION_H (new_data2_index).sh_offset + new_data2_size;
-         NEW_SECTION_H (nn).sh_addr =
-           NEW_SECTION_H (new_data2_index).sh_addr + new_data2_size;
-         /* Let the new bss section address alignment be the same as the
-            section address alignment followed the old bss section, so
-            this section will be placed in exactly the same place. */
-         NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign;
-         NEW_SECTION_H (nn).sh_size = 0;
-       }
-      else
-       {
-         /* Any section that was original placed AFTER the bss
-            section should now be off by NEW_DATA2_SIZE. */
-#ifdef SOLARIS_POWERPC
-         /* On PPC Reference Platform running Solaris 2.5.1
-            the plt section is also of type NOBI like the bss section.
-            (not really stored) and therefore sections after the bss
-            section start at the plt offset. The plt section is always
-            the one just before the bss section.
-            It would be better to put the new data section before
-            the .plt section, or use libelf instead.
-            Erik Deumens, deumens@qtp.ufl.edu.  */
-         if (NEW_SECTION_H (nn).sh_offset
-             >= OLD_SECTION_H (old_bss_index-1).sh_offset)
-           NEW_SECTION_H (nn).sh_offset += new_data2_size;
-#else
-         if (round_up (NEW_SECTION_H (nn).sh_offset,
-                       OLD_SECTION_H (old_bss_index).sh_addralign)
-             >= new_data2_offset)
-           NEW_SECTION_H (nn).sh_offset += new_data2_size;
-#endif
-         /* Any section that was originally placed after the section
-            header table should now be off by the size of one section
-            header table entry.  */
-         if (NEW_SECTION_H (nn).sh_offset > new_file_h->e_shoff)
-           NEW_SECTION_H (nn).sh_offset += new_file_h->e_shentsize;
-       }
 
       /* If any section hdr refers to the section after the new .data
-        section, make it refer to next one because we have inserted
-        a new section in between.  */
-
-      PATCH_INDEX (NEW_SECTION_H (nn).sh_link);
-      /* For symbol tables, info is a symbol table index,
-        so don't change it.  */
-      if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB
-         && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM)
-       PATCH_INDEX (NEW_SECTION_H (nn).sh_info);
-
-      if (old_sbss_index != -1)
-       if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".sbss"))
-         {
-           NEW_SECTION_H (nn).sh_offset =
-             round_up (NEW_SECTION_H (nn).sh_offset,
-                       NEW_SECTION_H (nn).sh_addralign);
-           NEW_SECTION_H (nn).sh_type = SHT_PROGBITS;
+       * section, make it refer to next one because we have inserted a
+       * new section in between.  */
+      PATCH_INDEX (nsec->sh_link);
+
+      /* For symbol tables, info is a symbol table index, so don't
+       * change it.  */
+      if (nsec->sh_type != SHT_SYMTAB && nsec->sh_type != SHT_DYNSYM)
+         PATCH_INDEX (nsec->sh_info);
+
+      /* Any section which used to be NOBITS will now becomes PROGBITS
+       * if it's ALLOC-atable, unless, of cause, it's not the one we
+       * decided to grow */
+      if ( (osec->sh_type == SHT_NOBITS) && (osec->sh_flags & SHF_ALLOC) &&
+          (osec != growme ) ) {
+         nsec->sh_type = SHT_PROGBITS;
+      }
+
+      /* Now, start to copy the content of sections */
+      if ( nsec->sh_type != SHT_NULL || nsec->sh_type != SHT_NOBITS ) {
+
+         /* Write out the sections. .data and .data1 (and data2,
+          * called ".data" in the strings table) get copied from the
+          * current process instead of the old file.  */
+         caddr_t src =  old_base + osec->sh_offset;
+         const char * secname = old_section_names + nsec->sh_name;
+         const char * names[] = {
+             ".data",".sdata", ".lit4", ".lit8", ".sdata1", ".data1",
+             ".sbss", NULL};
+         int i;
+
+         for ( i=0; names[i] != NULL; i++ ) {
+             if ( ! strcmp (secname, names[i]) ) {
+                 src = (caddr_t) osec->sh_addr;
+                 break;
+             }
          }
 
-      /* Now, start to copy the content of sections.  */
-      if (NEW_SECTION_H (nn).sh_type == SHT_NULL
-         || NEW_SECTION_H (nn).sh_type == SHT_NOBITS)
-       continue;
-
-      /* Write out the sections. .data and .data1 (and data2, called
-        ".data" in the strings table) get copied from the current process
-        instead of the old file.  */
-      if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".sdata")
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".lit4")
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".lit8")
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".sdata1")
-         || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
-                     ".data1")
-         || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name,
-                     ".sbss"))
-       src = (caddr_t) OLD_SECTION_H (n).sh_addr;
-      else
-       src = old_base + OLD_SECTION_H (n).sh_offset;
-
-      memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
-             NEW_SECTION_H (nn).sh_size);
+         memcpy (nsec->sh_offset + new_base, src, nsec->sh_size);
+      }
 
-#ifdef __alpha__
-      /* Update Alpha COFF symbol table: */
-      if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug")
-         == 0)
-       {
-         pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base);
-
-         symhdr->cbLineOffset += new_data2_size;
-         symhdr->cbDnOffset += new_data2_size;
-         symhdr->cbPdOffset += new_data2_size;
-         symhdr->cbSymOffset += new_data2_size;
-         symhdr->cbOptOffset += new_data2_size;
-         symhdr->cbAuxOffset += new_data2_size;
-         symhdr->cbSsOffset += new_data2_size;
-         symhdr->cbSsExtOffset += new_data2_size;
-         symhdr->cbFdOffset += new_data2_size;
-         symhdr->cbRfdOffset += new_data2_size;
-         symhdr->cbExtOffset += new_data2_size;
-       }
-#endif /* __alpha__ */
+      old_mdebug_index = find_section (".mdebug", old_section_names,
+                                      old_name, old_file_h, old_section_h, 1);
 
 #if defined (__sony_news) && defined (_SYSTYPE_SYSV)
-      if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG
-         && old_mdebug_index != -1)
-        {
-         int diff = NEW_SECTION_H(nn).sh_offset
-               - OLD_SECTION_H(old_mdebug_index).sh_offset;
-         HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);
-
-         if (diff)
-           {
+      if (nsec->sh_type == SHT_MIPS_DEBUG && old_mdebug_index != -1) {
+         int diff = nsec->sh_offset-OLD_SECTION_H(old_mdebug_index).sh_offset;
+         HDRR *phdr = (HDRR *)(nsec->sh_offset + new_base);
+
+         if (diff) {
              phdr->cbLineOffset += diff;
              phdr->cbDnOffset   += diff;
              phdr->cbPdOffset   += diff;
@@ -1062,29 +453,29 @@ unexec (char *new_name,
              phdr->cbFdOffset   += diff;
              phdr->cbRfdOffset  += diff;
              phdr->cbExtOffset  += diff;
-           }
-       }
+         }
+      }
 #endif /* __sony_news && _SYSTYPE_SYSV */
 
 #if __sgi
-      /* Adjust  the HDRR offsets in .mdebug and copy the
-        line data if it's in its usual 'hole' in the object.
-        Makes the new file debuggable with dbx.
-        patches up two problems: the absolute file offsets
-        in the HDRR record of .mdebug (see /usr/include/syms.h), and
-        the ld bug that gets the line table in a hole in the
-        elf file rather than in the .mdebug section proper.
-        David Anderson. davea@sgi.com  Jan 16,1994.  */
-      if (n == old_mdebug_index)
-       {
+      /* Adjust the HDRR offsets in .mdebug and copy the line data if
+       * it's in its usual 'hole' in the object.  Makes the new file
+       * debuggable with dbx.  patches up two problems: the absolute
+       * file offsets in the HDRR record of .mdebug (see
+       * /usr/include/syms.h), and the ld bug that gets the line table
+       * in a hole in the elf file rather than in the .mdebug section
+       * proper.
+       *
+       * David Anderson. davea@sgi.com Jan 16,1994 */
 #define MDEBUGADJUST(__ct,__fileaddr)          \
   if (n_phdrr->__ct > 0)                       \
     {                                          \
       n_phdrr->__fileaddr += movement;         \
     }
 
-         HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset);
-         HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset);
+      if (n == old_mdebug_index) {
+         HDRR * o_phdrr = (HDRR *)((byte *)old_base + osec->sh_offset);
+         HDRR * n_phdrr = (HDRR *)((byte *)new_base + nsec->sh_offset);
          unsigned movement = new_data2_size;
 
          MDEBUGADJUST (idnMax, cbDnOffset);
@@ -1097,142 +488,112 @@ unexec (char *new_name,
          MDEBUGADJUST (ifdMax, cbFdOffset);
          MDEBUGADJUST (crfd, cbRfdOffset);
          MDEBUGADJUST (iextMax, cbExtOffset);
-         /* The Line Section, being possible off in a hole of the object,
-            requires special handling.  */
-         if (n_phdrr->cbLine > 0)
-           {
-             if (o_phdrr->cbLineOffset > (OLD_SECTION_H (n).sh_offset
-                                          + OLD_SECTION_H (n).sh_size))
-               {
-                 /* line data is in a hole in elf. do special copy and adjust
-                    for this ld mistake.
-                    */
+
+         /* The Line Section, being possible off in a hole of the
+          * object, requires special handling.  */
+         if (n_phdrr->cbLine > 0) {
+             if (o_phdrr->cbLineOffset >
+                 osec->sh_offset+ osec->sh_size){
+                 /* line data is in a hole in elf. do special copy
+                  * and adjust for this ld mistake.  */
                  n_phdrr->cbLineOffset += movement;
 
                  memcpy (n_phdrr->cbLineOffset + new_base,
                          o_phdrr->cbLineOffset + old_base, n_phdrr->cbLine);
-               }
-             else
-               {
-                 /* somehow line data is in .mdebug as it is supposed to be.  */
+             } else {
+                 /* somehow line data is in .mdebug as it is supposed
+                  * to be.  */
                  MDEBUGADJUST (cbLine, cbLineOffset);
-               }
-           }
-       }
+             }
+         }
+      }
 #endif /* __sgi */
-
-      /* If it is the symbol table, its st_shndx field needs to be patched.  */
-      if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
-         || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
-       {
-         ElfW(Shdr) *spt = &NEW_SECTION_H (nn);
-         unsigned int num = spt->sh_size / spt->sh_entsize;
-         ElfW(Sym) * sym = (ElfW(Sym) *) (NEW_SECTION_H (nn).sh_offset +
-                                          new_base);
-         for (; num--; sym++)
-           {
-             if ((sym->st_shndx == SHN_UNDEF)
-                 || (sym->st_shndx == SHN_ABS)
-                 || (sym->st_shndx == SHN_COMMON))
-               continue;
+      /* If it is the symbol table, its st_shndx field needs to be
+       * patched.  */
+      if (nsec->sh_type == SHT_SYMTAB || nsec->sh_type == SHT_DYNSYM) {
+         unsigned int num = nsec->sh_size / nsec->sh_entsize;
+         ElfW(Sym) * sym = (ElfW(Sym) *)(nsec->sh_offset + new_base);
+         byte *symnames = ((byte *) new_base +
+                           NEW_SECTION_H (nsec->sh_link).sh_offset);
+
+         for (; num--; sym++) {
+             const char * symnam = (char *) (symnames + sym->st_name);
+
+             /* Update the symbol values of _edata and _end. */
+             if (strcmp (symnam, "_end") == 0
+                 || strcmp (symnam, "end") == 0
+                 || strcmp (symnam, "_edata") == 0
+                 || strcmp (symnam, "edata") == 0)
+                 memcpy (&sym->st_value, &new_bss_addr,sizeof (new_bss_addr));
+
+
+             if ((sym->st_shndx == SHN_UNDEF) || (sym->st_shndx == SHN_ABS)
+                 || (sym->st_shndx == SHN_COMMON)
+                 || (sym->st_shndx >= SHN_LOPROC &&
+                     sym->st_shndx <= SHN_HIPROC))
+                 continue;
 
              PATCH_INDEX (sym->st_shndx);
-           }
-       }
-    }
-
-  /* Update the symbol values of _edata and _end.  */
-  for (n = new_file_h->e_shnum - 1; n; n--)
-    {
-      byte *symnames;
-      ElfW(Sym) *symp, *symendp;
-
-      if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM
-         && NEW_SECTION_H (n).sh_type != SHT_SYMTAB)
-       continue;
-
-      symnames = ((byte *) new_base
-                 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset);
-      symp = (ElfW(Sym) *) (NEW_SECTION_H (n).sh_offset + new_base);
-      symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
-
-      for (; symp < symendp; symp ++)
-       if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0
-           || strcmp ((char *) (symnames + symp->st_name), "end") == 0
-           || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0
-           || strcmp ((char *) (symnames + symp->st_name), "edata") == 0)
-         memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr));
-    }
+         }
+      }
+  }
 
   /* This loop seeks out relocation sections for the data section, so
-     that it can undo relocations performed by the runtime linker.  */
-  for (n = new_file_h->e_shnum - 1; n; n--)
-    {
+   * that it can undo relocations performed by the runtime linker.  */
+  for (n = new_file_h->e_shnum - 1; n; n--) {
       ElfW(Shdr) section = NEW_SECTION_H (n);
-      switch (section.sh_type) {
-      default:
-       break;
-      case SHT_REL:
-      case SHT_RELA:
-       /* This code handles two different size structs, but there should
-          be no harm in that provided that r_offset is always the first
-          member.  */
-       nn = section.sh_info;
-       if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
-           || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
-                       ".sdata")
-           || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
-                       ".lit4")
-           || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
-                       ".lit8")
-           || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
-                       ".sdata1")
-           || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
-                       ".data1"))
-         {
-           ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr -
-             NEW_SECTION_H (nn).sh_offset;
-           caddr_t reloc = old_base + section.sh_offset, end;
-           for (end = reloc + section.sh_size; reloc < end;
-                reloc += section.sh_entsize)
-             {
-               ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset;
+
+      if ( section.sh_type == SHT_REL || section.sh_type == SHT_RELA ) {
+         /* This code handles two different size structs, but there
+          * should be no harm in that provided that r_offset is
+          * always the first member.  */
+         ElfW(Shdr) * info = & NEW_SECTION_H(section.sh_info);
+         const char * nm = old_section_names + info->sh_name;
+
+         if (!strcmp (nm, ".data") || !strcmp (nm, ".sdata")
+             || !strcmp (nm, ".lit4") || !strcmp (nm, ".lit8")
+             || !strcmp (nm, ".sdata1") || !strcmp (nm, ".data1")) {
+             ElfW(Addr) offset =  info->sh_addr - info->sh_offset;
+             caddr_t end, reloc = old_base + section.sh_offset;
+
+             for (end = reloc + section.sh_size; reloc < end;
+                  reloc += section.sh_entsize) {
+                 ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset;
 #ifdef __alpha__
-               /* The Alpha ELF binutils currently have a bug that
-                  sometimes results in relocs that contain all
-                  zeroes.  Work around this for now...  */
-               if (((ElfW(Rel) *) reloc)->r_offset == 0)
-                   continue;
+                 /* The Alpha ELF binutils currently have a bug that
+                  * sometimes results in relocs that contain all
+                  * zeroes.  Work around this for now...  */
+                 if (((ElfW(Rel) *) reloc)->r_offset == 0)
+                     continue;
 #endif
-               memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr)));
+                 memcpy (new_base + addr, old_base + addr,
+                         sizeof(ElfW(Addr)));
              }
          }
-       break;
       }
-    }
+  }
 
 #ifdef UNEXEC_USE_MAP_PRIVATE
   if (lseek (new_file, 0, SEEK_SET) == -1)
-    fatal ("Can't rewind (%s): errno %d\n", new_name, errno);
+      fatal ("Can't rewind (%s): errno %d\n", new_name, errno);
 
   if (write (new_file, new_base, new_file_size) != new_file_size)
-    fatal ("Can't write (%s): errno %d\n", new_name, errno);
+      fatal ("Can't write (%s): errno %d\n", new_name, errno);
 #endif
 
   /* Close the files and make the new file executable.  */
-
   if (close (old_file))
-    fatal ("Can't close (%s): errno %d\n", old_name, errno);
+      fatal ("Can't close (%s): errno %d\n", old_name, errno);
 
   if (close (new_file))
-    fatal ("Can't close (%s): errno %d\n", new_name, errno);
+      fatal ("Can't close (%s): errno %d\n", new_name, errno);
 
   if (stat (new_name, &stat_buf) == -1)
-    fatal ("Can't stat (%s): errno %d\n", new_name, errno);
+      fatal ("Can't stat (%s): errno %d\n", new_name, errno);
 
   n = umask (777);
   umask (n);
   stat_buf.st_mode |= 0111 & ~n;
   if (chmod (new_name, stat_buf.st_mode) == -1)
-    fatal ("Can't chmod (%s): errno %d\n", new_name, errno);
+      fatal ("Can't chmod (%s): errno %d\n", new_name, errno);
 }
index 4accfc3..ee7e52d 100644 (file)
@@ -1,3 +1,35 @@
+2000-12-05  Martin Buchholz <martin@xemacs.org>
+
+       * XEmacs 21.2.38 is released.
+
+2000-12-01  Martin Buchholz  <martin@xemacs.org>
+
+       * automated/test-harness.el (test-harness-from-buffer): Throw away
+       all warnings, even those not influenced by byte-compiler-warnings.
+
+2000-11-30  Martin Buchholz  <martin@xemacs.org>
+
+       * automated/lisp-tests.el:
+       Test byte-compiler arithmetic optimizations.
+
+2000-11-27  Yoshiki Hayashi  <yoshiki@xemacs.org>
+
+       * automated/case-tests.el: Add more tests.
+
+2000-11-24  Yoshiki Hayashi  <yoshiki@xemacs.org>
+
+       * automated/regexp-tests.el: New file.
+
+2000-11-22  Martin Buchholz  <martin@xemacs.org>
+
+       * automated/lisp-tests.el: 
+       Add 64-bit-correctness format tests.
+       Don't quote the first arg to Check-Error.
+
+2000-11-14  Yoshiki Hayashi  <yoshiki@xemacs.org>
+
+       * automated/case-tests.el: New file.
+
 2000-11-14  Martin Buchholz <martin@xemacs.org>
 
        * XEmacs 21.2.37 is released.
index c4d22b1..7d6f321 100644 (file)
     (Assert (= two (max one two two)))
     (Assert (= two (max two two one)))))
 
+;; The byte compiler has special handling for these constructs:
+(let ((three 3) (five 5))
+  (Assert (= (+ three five 1) 9))
+  (Assert (= (+ 1 three five) 9))
+  (Assert (= (+ three five -1) 7))
+  (Assert (= (+ -1 three five) 7))
+  (Assert (= (+ three 1) 4))
+  (Assert (= (+ three -1) 2))
+  (Assert (= (+ -1 three) 2))
+  (Assert (= (+ -1 three) 2))
+  (Assert (= (- three five 1) -3))
+  (Assert (= (- 1 three five) -7))
+  (Assert (= (- three five -1) -1))
+  (Assert (= (- -1 three five) -9))
+  (Assert (= (- three 1) 2))
+  (Assert (= (- three 2 1) 0))
+  (Assert (= (- 2 three 1) -2))
+  (Assert (= (- three -1) 4))
+  (Assert (= (- three 0) 3))
+  (Assert (= (- three 0 five) -2))
+  (Assert (= (- 0 three 0 five) -8))
+  (Assert (= (- 0 three five) -8))
+  (Assert (= (* three 2) 6))
+  (Assert (= (* three -1 five) -15))
+  (Assert (= (* three 1 five) 15))
+  (Assert (= (* three 0 five) 0))
+  (Assert (= (* three 2 five) 30))
+  (Assert (= (/ three 1) 3))
+  (Assert (= (/ three -1) -3))
+  (Assert (= (/ (* five five) 2 2) 6))
+  (Assert (= (/ 64 five 2) 6)))
+
+
 ;;-----------------------------------------------------
 ;; Logical bit-twiddling operations
 ;;-----------------------------------------------------
 
 ;; The following 2 functions used to crash XEmacs via mapcar1().
 ;; We don't test the actual values of the mapcar, since they're undefined.
-(Assert 
+(Assert
  (let ((x (list (cons 1 1) (cons 2 2) (cons 3 3))))
    (mapcar
     (lambda (y)
       (car y))             ; sorry, hard landing
     x)))
 
-(Assert 
+(Assert
  (let ((x (list (cons 1 1) (cons 2 2) (cons 3 3))))
    (mapcar
     (lambda (y)
 (Assert (equal (split-string ",foo,,bar," ",+") '("" "foo" "bar" "")))
 
 (Assert (not (string-match "\\(\\.\\=\\)" ".")))
-(Assert (string= "" (let ((str "test string"))  
+(Assert (string= "" (let ((str "test string"))
                      (if (string-match "^.*$" str)
                          (replace-match "\\U" t nil str)))))
 (with-temp-buffer
 (Assert (equal (subseq '(1 2 3) 0) '(1 2 3)))
 (Assert (equal (subseq '(1 2 3 4) -3 nil) '(2 3 4)))
 
-(Check-Error 'wrong-type-argument (subseq 3 2))
-(Check-Error 'args-out-of-range (subseq [1 2 3] -42))
-(Check-Error 'args-out-of-range (subseq [1 2 3] 0 42))
+(Check-Error wrong-type-argument (subseq 3 2))
+(Check-Error args-out-of-range (subseq [1 2 3] -42))
+(Check-Error args-out-of-range (subseq [1 2 3] 0 42))
 
 ;;-----------------------------------------------------
 ;; Time-related tests
 (Assert (string= (format "%01.3d" 10) "10"))
 (Assert (string= (format "%1.3d" 10) "10"))
 (Assert (string= (format "%3.1d" 10) " 10"))
+
+;;; Check for 64-bit cleanness on LP64 platforms.
+(Assert (= (read (format "%d"  most-positive-fixnum)) most-positive-fixnum))
+(Assert (= (read (format "%ld" most-positive-fixnum)) most-positive-fixnum))
+(Assert (= (read (format "%u"  most-positive-fixnum)) most-positive-fixnum))
+(Assert (= (read (format "%lu" most-positive-fixnum)) most-positive-fixnum))
+(Assert (= (read (format "%d"  most-negative-fixnum)) most-negative-fixnum))
+(Assert (= (read (format "%ld" most-negative-fixnum)) most-negative-fixnum))
+
+;;; "%u" is undocumented, and Emacs Lisp has no unsigned type.
+;;; What to do if "%u" is used with a negative number?
+;;; The most reasonable thing seems to be to print an un-read-able number.
+;;; The printed value might be useful to a human, if not to Emacs Lisp.
+(Check-Error invalid-read-syntax (read (format "%u" most-negative-fixnum)))
+(Check-Error invalid-read-syntax (read (format "%u" -1)))
index 52093f4..8fcec7e 100644 (file)
@@ -236,8 +236,11 @@ The output file's name is made by appending `c' to the end of FILENAME."
       (princ "\nTesting Compiled Lisp\n\n")
       (let (code)
        (condition-case error-info
-           (setq code (let ((byte-compile-warnings nil))
-                        (byte-compile (test-harness-read-from-buffer inbuffer))))
+           (setq code
+                 ;; our lisp code is often intentionally dubious,
+                 ;; so throw away _all_ the byte compiler warnings.
+                 (letf (((symbol-function 'byte-compile-warn) 'ignore))
+                   (byte-compile (test-harness-read-from-buffer inbuffer))))
          (error
           (princ (format "Unexpected error %S while byte-compiling code\n"
                          error-info))))
index 78e3f2d..cd34ceb 100644 (file)
@@ -2,8 +2,8 @@
 emacs_is_beta=t
 emacs_major_version=21
 emacs_minor_version=2
-emacs_beta_version=37
-xemacs_codename="Pan"
+emacs_beta_version=38
+xemacs_codename="Peisino\e,Ak\e(B"
 infodock_major_version=4
 infodock_minor_version=0
 infodock_build_version=8