This commit was generated by cvs2svn to compensate for changes in r45, which
authortomo <tomo>
Mon, 17 May 1999 09:41:44 +0000 (09:41 +0000)
committertomo <tomo>
Mon, 17 May 1999 09:41:44 +0000 (09:41 +0000)
included commits to RCS files with non-trunk default branches.

68 files changed:
INSTALL
README.packages [new file with mode: 0644]
aclocal.m4
configure.usage
etc/NEWS
etc/recycle.xpm
lib-src/ChangeLog
lib-src/Makefile.in.in
lib-src/ellcc.c [new file with mode: 0644]
lib-src/ellcc.h.in [new file with mode: 0644]
lib-src/make-docfile.c
lib-src/movemail.c
lisp/about.el
lisp/buffer.el
lisp/cl-macs.el
lisp/font.el
lisp/ldap.el
lisp/loadup.el
lisp/minibuf.el
lisp/mouse.el
lisp/package-admin.el
lisp/package-get.el
lisp/replace.el
lisp/select.el
lisp/window.el
man/ChangeLog
man/emodules.texi [new file with mode: 0644]
man/internals/internals.texi
modules/README [new file with mode: 0644]
modules/base64/Makefile [new file with mode: 0644]
modules/base64/base64.c
modules/ldap/Makefile [new file with mode: 0644]
modules/ldap/eldap.c
modules/sample/Makefile [new file with mode: 0644]
modules/sample/sample.c [new file with mode: 0644]
modules/zlib/Makefile [new file with mode: 0644]
modules/zlib/zlib.c
nt/ChangeLog
nt/minitar.c [new file with mode: 0644]
nt/xemacs.mak
src/Makefile.in.in
src/backtrace.h
src/bytecode.c
src/device-x.c
src/eldap.c
src/emodules.c [new file with mode: 0644]
src/emodules.h [new file with mode: 0644]
src/event-msw.c
src/event-stream.c
src/frame-msw.c
src/glyphs-msw.c
src/glyphs-widget.c
src/glyphs-x.c
src/glyphs.h
src/gui.c
src/gui.h
src/menubar.c
src/paths.h.in
src/s/cygwin32.h
src/s/sco5-shr.h
src/s/sco5.h
src/sysdll.c
src/unexnt.c
tests/ChangeLog [new file with mode: 0644]
tests/automated/database-tests.el
tests/automated/lisp-tests.el
tests/glyph-test.el
version.sh

diff --git a/INSTALL b/INSTALL
index cab2f7b..2cef985 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -444,7 +444,7 @@ are installed in the following directories:
 By default, XEmacs installs its files in the following directories:
 
 `/usr/local/bin' holds the executable programs users normally run -
-               `xemacs', `etags', `ctags', `b2m', `emacsclient',
+               `xemacs', `etags', `ctags', `b2m', `emacsclient', `ellcc',
                `gnuclient', `gnudoit', `gnuattach', and `rcs-checkin'.
 
 `/usr/local/lib/xemacs-VERSION/lisp' holds the Emacs Lisp libraries;
@@ -483,6 +483,17 @@ By default, XEmacs installs its files in the following directories:
                kinds of machines share the file system XEmacs is
                installed on.
 
+`/usr/local/lib/xemacs-VERSION/CONFIGURATION-NAME/modules' holds the Emacs
+               dynamically loadable modules.  These are special programs
+               typically written in C that can be loaded in much the same
+               way that Lisp packages are.  Not all systems support
+               dynamic modules, so do not be alarmed if this directory
+               does not exist or is empty.
+
+               XEmacs searches for modules in this directory, or any
+               sub-directory of it, and then in
+               `/usr/local/lib/xemacs/site-modules/*'.
+
 `/usr/local/lib/xemacs-VERSION/info' holds the on-line documentation
                for XEmacs, known as "info files".
 
@@ -623,6 +634,15 @@ GNU software; here are some variables specific to XEmacs.
        above), is `/usr/local/lib/xemacs-VERSION/CONFIGURATION-NAME'
        (where VERSION and CONFIGURATION-NAME are as described above).
 
+`moduledir' indicates where XEmacs installs and expects to find
+       any dynamic modules.  Its default value, based on
+       `archlibdir' (see above) is
+       `/usr/local/lib/xemacs-VERSION/CONFIGURATION-NAME/modules'
+       (where VERSION and CONFIGURATION-NAME are as described above).
+       By their very nature, dynamic loadable modules are architecture-
+       dependant, and care should be taken not to set this directory
+       to a system- or architecture-independant directory.
+
 Remember that you must specify any variable values you need each time
 you run `make' in the top directory.  If you run `make' once to build
 xemacs, test it, and then run `make' again to install the files, you
diff --git a/README.packages b/README.packages
new file mode 100644 (file)
index 0000000..2d3f904
--- /dev/null
@@ -0,0 +1,227 @@
+The XEmacs Packages Quick Start Guide
+-------------------------------------
+
+This text is intended to help you get started installing a new XEmacs
+and its packages from start.  For details see the 'Startup Paths' and
+'Packages' sections of the XEmacs info manual.
+
+Real Real Quickstart FAQ
+------------------------
+
+Q. Do I need to have the packages to compile XEmacs?
+A. If you want to compile with MULE, you need the mule-base package installed.
+   Otherwise, no package is required before compilation.
+
+Q. I really liked the old way that packages were bundled and do not
+   want to mess with packages at all.
+A. You can grab all the packages at once like you used to with old
+   XEmacs versions, skip to the 'Sumo Tarball' section below.
+
+A note of caution
+-----------------
+
+The XEmacs package system is still in its infancy. Please expect a few 
+minor hurdles on the way. Also neither the interface nor the structure is 
+set in stone. The XEmacs maintainers reserve the right to sacrifice
+backwards compatibility as quirks are worked out over the coming
+releases. 
+
+Some Package Theory
+-------------------
+
+In order to reduce the size and increase the maintainability of XEmacs,
+the majority of the Elisp packages that came with previous releases
+have been unbundled. They have been replaced by the package system.
+Each elisp add-on (or groups of them when they are small) now comes
+in its own tarball that contains a small search hierarchy.
+
+You select just the ones you need. Install them by untarring them into 
+the right place. On startup XEmacs will find them, set up the load
+path correctly, install autoloads, etc, etc.
+
+Package hierarchies
+-------------------
+
+On Startup XEmacs looks for packages in so called package hierarchies.
+These can be specified by the 'package-path' parameter to the
+'configure' script. However by default there are three system wide
+hierarchies.
+
+$prefix/lib/xemacs/site-packages
+     Local and 3rd party packages go here.
+
+$prefix/lib/xemacs/mule-packages
+     Only searched by MULE-enabled XEmacsen.
+
+$prefix/lib/xemacs/xemacs-packages
+     Normal packages go here.
+
+Where to get the packages
+-------------------------
+
+Packages are available from ftp://ftp.xemacs.org/pub/xemacs/packages
+and its mirror.
+
+How to install the packages
+---------------------------
+
+1. All at once, using the 'Sumo Tarball'.
+2. By hand.
+3. Automatically, using the package tools from XEmacs.
+
+The Sumo Tarball
+----------------
+
+Those with little time, cheap connections and plenty of disk space can
+install all packages at once using the sumo tarballs.
+Download the files
+
+xemacs-sumo-<date>.tar.gz if you have a latin-1 XEmacs.
+
+or
+
+xemacs-mule-sumo-<date>.tar.gz if you have a MULE XEmacs.
+
+N.B. There are called 'Sumo Tarballs' for good reason. They are
+currently 15MB and 23MB (gzipped) respectively.
+
+Install them by
+
+cd $prefix/lib/xemacs ; gunzip -c <tarballname> | tar xf -
+
+As the Sumo tarballs are not regenerated as often as the individual
+packages, it is recommended that you use the automatic package tools
+afterwards to pick up any recent updates.
+
+Installing by Hand
+------------------
+
+Fetch the packages from the ftp site, CDROM whatever. The filenames
+have the form name-<version>-pkg.tar.gz and are gzipped tar files. For
+a fresh install it is sufficient to untar the file at the top of the
+package hierarchy. For example if we are installing the 'xemacs-base'
+package in version 1.27:
+
+mkdir $prefix/lib/xemacs/xemacs-packages # if it does not exist yet
+cd $prefix/lib/xemacs/xemacs-packages
+gunzip -c ...../xemacs-base-1.27-pkg.tar.gz | tar xf -
+
+For MULE related packages, it is best to untar in the mule-packages
+hierarchy, i.e. for the mule-base package, version 1.25
+
+mkdir $prefix/lib/xemacs/mule-packages # if it does not exist yet
+cd $prefix/lib/xemacs/mule-packages
+gunzip -c ...../mule-base-1.25-pkg.tar.gz | tar xf -
+
+Installing automatically
+------------------------
+
+XEmacs comes with some tools to make the periodic updating and
+installing easier. It will notice if new packages or versions are
+available and will fetch them from the ftp site.
+
+Unfortunately this requires that a few packages are alreadyin place. 
+You will have to install them by hand as above or use a SUMO tarball. 
+This requirement will hopefully go away in the future. The packages
+you need are:
+
+   efs          - To fetch the files from the ftp site or mirrors.
+   xemacs-base  - Needed by efs.
+
+and optionally:
+
+   mailcrypt    - If you have PGP installed and want to verify the
+                  signature of the index file.
+   mule-base    - Needed if you want to compile XEmacs with MULE.
+
+After installing these by hand, you can start XEmacs. (It is a good
+idea to use 'xemacs -vanilla' here as your startup files might need
+things now moved to packages.)
+
+ - First you need to specify an FTP site to use.
+      Use Options->Manage Packages->Add Download Site
+       or M-x customize-variable RET package-get-remote RET
+
+   Alternatively, if you already have the packages on a local disk
+   then you can specify this directly using 'M-x
+   pui-add-install-directory'. Please make sure you also have a
+   corresponding copy of the package index there.
+
+ - Invoke Options->Manage Packages->List & Install
+      or M-x pui-list-packages RET
+   XEmacs will now first try to fetch a new version of the package
+   index from the FTP site. Depending on whether you are using
+   'mailcrypt/PGP', you will get some question about keys to fetch or
+   whether to use the index without verifying the signature. If the
+   new index was different from the one already on disk, XEmacs will
+   offer you to overwrite the old index.
+
+-  XEmacs will show you a buffer named "*Packages*" with an overview
+   of available and installed packages, including a short description.
+   In this buffer you can select which packages you want using the
+   mouse or using RET.
+
+-  When you are finished choosing packages, invoke
+   'Packages->Install/Remove Select' from the menu or type 'x' to
+   begin installing packages.
+    
+After Installation
+------------------
+
+New packages can only be used by XEmacs after a restart.
+
+Note to MULE users
+------------------
+
+Unlike all other packages the mule-base package is used at build/dump 
+time. This means that you need this available before compiling XEmacs
+with MULE. Also it is a good idea to keep packages that are
+MULE-only separate by putting them in the mule-packages hierarchy.
+
+Which Packages to install?
+--------------------------
+
+This is difficult to say. When in doubt install a package. If you
+administrate a big site it might be a good idea to just install
+everything. A good minimal set of packages for XEmacs-latin1 would be
+
+xemacs-base, xemacs-devel, c-support, cc-mode, debug, dired, efs,
+edit-utils, fsf-compat, mail-lib, net-utils, os-utils, prog-modes,
+text-modes, time
+
+Unfortunately the package system currently provides neither
+dependencies nor conflicts. This will be a future enhancement. The
+above set includes most packages that are used by others.
+
+See also '.../etc/PACKAGES' for further descriptions of the individual
+packages (currently outdated).
+
+Upgrading/Removing Packages
+---------------------------
+
+As the exact files and their locations contained in a package may
+change it is recommend to remove a package first before installing a
+new version. In order to facilitate removal each package contains an
+pgkinfo/MANIFEST.pkgname file which list all the files belong to the
+package. M-x package-admin-delete-binary-package RET can be used to
+remove a package using this file.
+
+Note that the interactive package tools included with XEmacs already do
+this for you.
+
+User Package directories
+------------------------
+
+In addition to the system wide packages, each user can have his own
+packages installed in "./xemacs" (Note that this will most likely
+change to "./xemacs/packages" in the near future). If you want to
+install packages there using the interactive tools, you need to set
+'pui-package-install-dest-dir' to "/xemacs"
+
+Site lisp/Site start
+--------------------
+
+The site-packages hierarchy replaces the old 'site-lisp' directory.
+XEmacs no longer looks into a 'site-lisp' directly by default.
+A good place to put 'site-start.el' would be in
+$prefix/lib/xemacs/site-packages/lisp/
index c84a38b..1348285 100644 (file)
 dnl aclocal.m4 --- Dynamically linked library support for XEmacs
-dnl Copyright (C) 1998 Free Software Foundation, Inc.
-dnl Author: William Perry <wmperry@aventail.com>
-dnl This file is part of XEmacs
-
-AC_DEFUN(XE_MAKE_SHAREDLIB, [
-dll_ld="ld"
-dll_lflags="-shared"
-dll_cflags="-r"
-dll_oflags="-o "
-
-AC_MSG_CHECKING(how to build a shared library)
-case `uname -rs` in
-       UNIX_SV*|UNIX_System_V*)
-               dll_lflags="-G"
-               dll_cflags=-Kpic
-               dll_ld="ld"
-               ;;
-       BSD/OS*)
-               dll_cflags=
-               dll_lflags="-r"
-               dll_ld="shlicc2"
-               ;;
-       FreeBSD*2*)
-               dll_lflags="-Bshareable"
-               dll_cflags="-fPIC -DPIC"
-               dll_ld=ld
-               ;;
-       SunOS*4.*)
-               dll_cflags="-P"
-               dll_lflags="-dp -assert pure-text -assert nodefinitions"
-               ;;
-       SunOS*5.*)
-               dll_ld="cc"
-               dll_cflags="-KPIC"
-               dll_lflags="-G"
-               dll_oflags="-W0,-y-o -W0,-y"
-               ;;      
-       IRIX*5.*|IRIX*6.*)
-               dll_cflags="-KPIC"
-               ;;
-       OSF1*)
-               ;;
-       HP-UX*)
-               dll_ld="ld"
-               dll_lflags="-b"
-               dll_cflags="+z"
-               ;;
-       SCO_SV*)
-               dll_ld="ld"
-               dll_lflags="-G"
-               dll_cflags="-Kpic"
-               ;;
-       AIX*)
-               dll_lflags="-H512 -T512 -bhalt:4 -bM:SRE -bE:\${@:.ell=.exp} -b noentry -lc"
-               dll_ld="ld"
-               ;;
-       *)
-               ;;
-       esac
-
-       if test "$GCC" = "yes" ; then
-               dll_cflags="-fPIC"
-               case `uname -rs` in
-               SunOS*5.*)
-                       dll_ld="ld"
-                       dll_oflags="-o "
-                       dll_lflags="-G"
-                       ;;
-               SCO_SV*)
-                       dll_ld="ld"
-                       dll_lflags="-G"
-                       dll_cflags="-b elf"
-                       ;;
-               FreeBSD*)
-                       dll_cflags="-DDLSYM_NEEDS_UNDERSCORE -DPIC -fPIC"
-                       dll_lflags="-Bshareable"
-                       dll_ld=ld
-                       ;;
-               BSD/OS*)
-                       dll_cflags=
-                       dll_lflags="-r"
-                       dll_ld="shlicc2"
-                       ;;
-               UNIX_SV*)
-                       dll_cflags="-fPIC"
-                       ;;
-               *)
-                       dll_ld="$CC"
-                       dll_lflags="-shared"
-               esac
-       fi
-
-       AC_MSG_RESULT("lflags: $dll_lflags cflags: $dll_cflags")
+dnl Copyright (C) 1998, 1999 J. Kean Johnston.
+dnl Author: J. Kean Johnston <jkj@sco.com>, based on work in libtool.
+dnl This file is part of XEmacs.
+
+dnl
+dnl There are several things we care about here. First, we need to find
+dnl out how we create an executable that has its symbols exported, so
+dnl that dynamically loaded modules have access to the internal XEmacs
+dnl symbols. This is stored in ``ld_dynamic_link_flags'' and is used
+dnl in the main Makefile.
+dnl Next, we need to know how we compile actual shared libraries, and
+dnl the objects in them.  For these purposes, we need to determine the
+dnl C compiler flags used to produce shared objects (``dll_cflags''),
+dnl what linker to use to create the final shared object that will be
+dnl loaded (``dll_ld'') and the flags to pass to that linker
+dnl (``dll_ldflags''). This information is used by ellcc to build up
+dnl the command line when compiling modules. We build up two other commands
+dnl for extremely weird systems where special things need to be done.
+dnl The first is ``dll_ldo'', which is the flag used to specify the output
+dnl file name, and the second is ``dll_post'' which is inserted after the
+dnl list of objects.
+dnl After all of this, we should be able to:
+dnl    $(CC) $(CFLAGS) $(dll_cflags) -c module.c
+dnl to produce a single shared object
+dnl And then:
+dnl   $(dll_ld) $(dll_ldflags) $(dll_ldo) module.ell module.o $(dll_post)
+dnl to create the loadable shared library.
+dnl
+dnl NOTE: In the code below, where I have modified things to work with
+dnl XEmacs, we use $canonical instead of libtool's $host, and we use
+dnl $internal_configuration instead of $host_alias. To make typing
+dnl shorter we assign these to $xehost and $xealias
+
+AC_DEFUN(XE_SHLIB_STUFF,[
+dll_ld=
+dll_ldflags=
+dll_cflags=
+dll_post=
+dll_ldo="-o"
+ld_dynamic_link_flags=
+xehost=$canonical
+xealias=$internal_configuration
+
+AC_CHECKING([how to build dynamic libraries for ${xehost}])
+# Transform *-*-linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$xehost" in
+*-*-linux-gnu*) ;;
+*-*-linux*) xehost=`echo $xehost | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+changequote(<<, >>)dnl
+xehost_cpu=`echo $xehost | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+xehost_vendor=`echo $xehost | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+xehost_os=`echo $xehost | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+changequote([, ])dnl
+
+case "$xehost_os" in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "${COLLECT_NAMES+set}" != set; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Now see if the compiler is really GCC.
+if test "$GCC" = "yes"; then
+  XEGCC=yes
+else
+  AC_MSG_CHECKING(checking whether we are using GNU C)
+  AC_EGREP_CPP(yes,[
+#ifdef __GNUC__
+  yes;
+#endif
+],XEGCC=yes, XEGCC=no)
+  AC_MSG_RESULT([${XEGCC}])
+fi
+
+AC_MSG_CHECKING(how to produce PIC code)
+wl=
+
+can_build_shared=yes
+if test "$XEGCC" = yes; then
+  wl='-Wl,'
+
+  case "$xehost_os" in
+  aix3* | aix4* | irix5* | irix6* | osf3* | osf4*)
+    # PIC is the default for these OSes.
+    ;;
+
+  os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  amigaos*)
+    # FIXME: we need at least 68020 code to build shared libraries, but
+    # adding the `-m68020' flag to GCC prevents building anything better,
+    # like `-m68040'.
+    dll_cflags='-m68020 -resident32 -malways-restore-a4'
+    ;;
+  *)
+    dll_cflags='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$xehost_os" in
+  hpux9* | hpux10*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    dll_cflags='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    ;;
+
+  sco3.2v5*)
+    dll_cflags='-belf -Kpic'
+    wl='-Wl,'
+    ;;
+
+  unixware*)
+    dll_cflags="-KPIC"
+    wl="-Wl,"
+    ;;
+
+  sysv4*)
+    dll_cflags="-KPIC"
+    wl="-Wl,"
+    ;;
+
+  sysv5*)
+    dll_cflags="-KPIC"
+    wl="-Wl,"
+    ;;
+
+  solaris2*)
+    dll_cflags='-KPIC'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    dll_cflags='-PIC'
+    wl='-Qoption ld '
+    ;;
+
+  uts4*)
+    dll_cflags='-pic'
+    ;;
+
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$dll_cflags"; then
+  AC_MSG_RESULT([${dll_cflags}])
+  
+  # Check to make sure the dll_cflags actually works.
+  AC_MSG_CHECKING([if PIC flag ${dll_cflags} really works])
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $dll_cflags -DPIC"
+  AC_TRY_COMPILE(,[int x=0;],[
+    # On HP-UX, the stripped-down bundled CC doesn't accept +Z, but also
+    # reports no error.  So, we need to grep stderr for (Bundled).
+    if grep '(Bundled)' config.log >/dev/null; then
+      AC_MSG_RESULT(no)
+      can_build_shared=no
+      dll_cflags=
+    else
+      AC_MSG_RESULT(yes)
+    fi], [AC_MSG_RESULT(no)
+    can_build_shared=no
+    dll_cflags=])
+  CFLAGS="$save_CFLAGS"
+else
+  AC_MSG_RESULT(none)
+fi
+
+dnl
+dnl Now comes the LD trickery. We do things differently to libtool here.
+dnl I believe that libtool is incorrect in trying to drive the linker
+dnl directly. This can cause considerable problems if the module you are
+dnl compiling has C++ or other static initializers. If we use ld directly,
+dnl we dont end up with the crt stuff being linked in, and we dont end up
+dnl with any .init or .fini sections (or the moral equivalent thereof).
+dnl gcc takes great care to do this propperly when invoked in -shared
+dnl mode, and we really do want this behaviour. Perhaps the libtool folks
+dnl are not aware that any SVR4 based dynamic loader will automatically
+dnl execute code in the .init section before dlopen() returns. This is
+dnl vital, as the module may have been compiled to rely on that behaviour.
+dnl
+dnl So, having said all of that, we diverge from libtool significantly
+dnl here. We want to try and use the C compiler as much as possible. Only
+dnl if the C compiler itself cannot create shared libraries to we try to
+dnl find the linker.
+dnl
+dnl The other advantage to my scheme is that it removes the dependancy
+dnl on a given compiler version remaining static with relation to the
+dnl version of XEmacs. With the libtool way, it picks up the linker that
+dnl gcc uses, which can be the internal collect2 that comes with gcc.
+dnl If the user ever changes their compiler version, the paths will no
+dnl longer be correct, and ellcc will break. This is clearly unacceptable.
+dnl By using the compiler driver on the path, we dont have this problem.
+dnl If that is not clear, consider that gcc -print-prog-name=ld can
+dnl produce something along the lines of:
+dnl   /usr/local/lib/gcc-lib/OS-NAME/GCC-VERSION/ld
+dnl If you ever change GCC versions, then that path no longer exists.
+dnl
+dnl So, we change the check order here. We first check to see if we are
+dnl using GCC, and if so, we see if -shared works. If it does, great.
+dnl If we are not using gcc, but the system C compiler can produce
+dnl shared objects, we try that. Only if all of that fails do we revert
+dnl back to the libtool ld trickery.
+dnl
+dnl We dont do ANY of this if we can't produce shared objects.
+dnl
+if test "$can_build_shared" = "yes"; then
+cc_produces_so=no
+xldf=
+xcldf=
+AC_MSG_CHECKING(if C compiler can produce shared libraries)
+if test "$XEGCC" = yes; then
+  xcldf="-shared"
+  xldf="-shared"
+else # Not using GCC
+  case "$xehost_os" in
+    aix3* | aix4*)
+      xldf="-bE:ELLSONAME.exp -H512 -T512 -bhalt:4 -bM:SRE -bnoentry -lc"
+      xcldf="${wl}-bE:ELLSONAME.exp ${wl}-H512 ${wl}-T512 ${wl}-bhalt:4 ${wl}-bM:SRE ${wl}-bnoentry ${wl}-lc"
+      ;;
+
+    freebsd2* | netbsd* | openbsd*)
+      xldf="-Bshareable"
+      xcldf="${wl}-Bshareable"
+      ;;
+
+    freebsd3*)
+      xcldf="-shared"
+      ;;
+
+    hpux*)
+      xldf="-b +s"
+      xcldf="${wl}-b ${wl}+s"
+      ;;
+
+    irix5* | irix6* | osf3* | osf4*)
+      xcldf="${wl}-shared"
+      xldf="-shared"
+      ;;
+
+    sco3.2v5* | unixware* | sysv5* | sysv4* | solaris2* | solaris7* | uts4*)
+      xcldf="-G"
+      xldf="-G"
+      ;;
+
+    sunos4*)
+      xcldf="${wl}-assert ${wl}pure-text ${wl}-Bstatic"
+      xldf="-assert pure-text -Bstatic"
+      ;;
+  esac
+fi # End if if we are using gcc
+
+if test -n "$xcldf"; then
+  save_LDFLAGS=$LDFLAGS
+  save_LIBS=$LIBS
+  save_xe_libs=$xe_libs
+  LDFLAGS="$xcldf $LDFLAGS"
+  LIBS=
+  xe_libs=
+  ac_link='${CC-cc} -o conftest $CFLAGS '"$xe_cppflags $xe_ldflags"' conftest.$ac_ext '"$xe_libs"' 1>&AC_FD_CC'
+  AC_TRY_LINK(,[int x=0;],cc_produces_so=yes,cc_produces_so=no)
+  LDFLAGS=$save_LDFLAGS
+  LIBS=$save_LIBS
+  xe_libs=$save_xe_libs
+  ac_link='${CC-cc} -o conftest $CFLAGS '"$xe_cppflags $xe_ldflags"' conftest.$ac_ext '"$xe_libs"' 1>&AC_FD_CC'
+else
+  cc_produces_so=no
+fi
+AC_MSG_RESULT([${cc_produces_so}])
+
+LTLD=$LD
+if test -z "$LTLD"; then
+  ac_prog=ld
+  if test "$XEGCC" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    AC_MSG_CHECKING(for ld used by GCC)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    /*)
+      if test -z "$LTLD"; then
+        case "$ac_prog" in
+          *gcc-lib*) LTLD="$CC"
+                     ;;
+          *)         LTLD="$ac_prog"
+                     ;;
+        esac
+      fi
+      ;;
+    "")
+      # If it fails, then pretend we aren't using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  else
+    AC_MSG_CHECKING(for GNU ld)
+  fi
+
+  if test -z "$LTLD"; then
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog"; then
+        LTLD="$ac_dir/$ac_prog"
+        # Check to see if the program is GNU ld.  I'd rather use --version,
+        # but apparently some GNU ld's only accept -v.
+        # Break only if it was the GNU/non-GNU ld that we prefer.
+        if "$LTLD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+          xe_gnu_ld=yes
+        else
+          xe_gnu_ld=no
+        fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LTLD"; then
+    AC_MSG_RESULT([${LTLD}])
+  else
+    AC_MSG_RESULT(no)
+  fi
+
+  if test -z "$LTLD" -a "$cc_produces_so" = no; then
+    AC_MSG_ERROR(no acceptable linker found in \$PATH)
+    exit 1
+  fi
+fi
+
+dnl
+dnl Order of the tests changed somewhat to prevent repetition
+dnl
+ld_dynamic_link_flags=
+
+# Check to see if it really is or isn't GNU ld.
+AC_MSG_CHECKING(if the linker is GNU ld)
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LTLD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  xe_gnu_ld=yes
+else
+  xe_gnu_ld=no
+fi
+AC_MSG_RESULT([${xe_gnu_ld}])
+
+case "$xehost_os" in
+  amigaos* | sunos4*)
+    # On these operating systems, we should treat GNU ld like the system ld.
+    gnu_ld_acts_native=yes
+    ;;
+  *)
+    gnu_ld_acts_native=no
+    ;;
+esac
+
+if test "$cc_produces_so" = "yes"; then
+  dll_ld=$CC
+  dll_ldflags=$xcldf
+  can_build_shared=yes
+else
+  # OK - only NOW do we futz about with ld.
+  # See if the linker supports building shared libraries.
+  AC_MSG_CHECKING(whether the linker supports shared libraries)
+  dll_ld=$CC
+  dll_ldflags=$LDFLAGS
+  ld_shlibs=yes
+  can_build_shared=yes
+  if test "$xe_gnu_ld" = yes && test "$gnu_ld_acts_native" != yes; then
+    # See if GNU ld supports shared libraries.
+    if $LTLD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      dll_ld=$CC
+      dll_ldflags="-shared"
+      ld_shlibs=yes
+    else
+      ld_shlibs=no
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case "$xehost_os" in
+    aix3*)
+      dll_ld=$LTLD
+      dll_ldflags=$xldf
+      ;;
+
+    aix4*)
+      dll_ldflags=$xcldf
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # doesn't break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      dll_ld=$LTLD
+      dll_ldflags=$xldf
+      dll_post="/usr/lib/c++rt0.o"
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 don't have this feature.
+    freebsd2*)
+      dll_ld=$LTLD
+      dll_ldflags="-Bshareable"
+      ;;
+
+    # FreeBSD 3, at last, uses gcc -shared to do shared libraries.
+    freebsd3*)
+      dll_ldflags="-shared"
+      ;;
+
+    hpux*)
+      dll_ld=$LTLD
+      dll_ldflags=$xldf
+      ;;
+
+    irix5* | irix6*)
+      dll_ld=$LTLD
+      dll_ldflags=$xldf
+      ;;
+
+    netbsd*)
+      # Tested with NetBSD 1.2 ld
+      dll_ld=$LTLD
+      dll_ldflags=$xldf
+      ;;
+
+    openbsd*)
+      dll_ld=$LTLD
+      dll_ldflags=$xldf
+      ;;
+
+    osf3* | osf4*)
+      dll_ld=$LTLD
+      dll_ldflags=$xldf
+      ;;
+
+    # For both SCO and Solaris we MAY want to have LDFLAGS include -z text
+    sco3.2v5* | unixware* | sysv5* | sysv4* | solaris2* | solaris7*)
+      dll_ld=$LTLD
+      case "$dll_ld" in
+        *gcc*) dll_ldflags="-shared"
+               dll_ld=$CC
+               ;;
+        *)     dll_ldflags="-G"
+               ;;
+      esac
+      ;;
+
+    sunos4*)
+      if test "$XEGCC" = yes; then
+        dll_ld=$CC
+      else
+        dll_ld=$LTLD
+      fi
+      dll_ldflags=$xldf
+      ;;
+
+    uts4*)
+      dll_ld=$LTLD
+      dll_ldflags="-G"
+      ;;
+
+    bsdi*)
+      dll_ldflags="-r"
+      dll_ld="shlicc2"
+      ;;
+
+    *)
+      ld_shlibs=no
+      can_build_shared=no
+      ;;
+    esac
+  fi
+  AC_MSG_RESULT([${ld_shlibs}])
+  if test "$ld_shlibs" = "no"; then
+    can_build_shared=no
+  fi
+fi # End of if cc_produces_so = no
+
+dnl
+dnl Last thing, check how to get a linked executable to have its symbols
+dnl exported, so that the modules have access to them.
+dnl
+dnl XEmacs FIXME - we need to set ld_dynamic_link_flags propperly for
+dnl most of these systems, which was missing from libtool. I know they
+dnl all have a way of doing this, but someone needs to look at this
+dnl for each OS and make sure it is correct. Remember that the arguments
+dnl are passed when temacs is linked, this is NOT for modules. The sole
+dnl purpose of the argument is to get the internal XEmacs symbols exposed
+dnl for modules to use. This means that the COMPILER (and NOT the linker)
+dnl is most often used to create temacs, so arguments to the linker will
+dnl usually need to be prefix with ${wl} or some other such thing.
+dnl
+
+if test "$xe_gnu_ld" = yes; then
+  if test "$ld_shlibs" = yes; then
+    ld_dynamic_link_flags="${wl}-export-dynamic"
+  fi
+fi
+
+if test -z "$ld_dynamic_link_flags"; then
+  case "$xehost_os" in
+  aix3*)
+    ld_dynamic_link_flags=
+    ;;
+
+  aix4*)
+    ld_dynamic_link_flags=
+    ;;
+
+  freebsd2.2*)
+    ld_dynamic_link_flags=
+    ;;
+
+  freebsd2*)
+    ld_dynamic_link_flags=
+    ;;
+
+  freebsd3*)
+    ld_dynamic_link_flags=
+    ;;
+
+  hpux*)
+    ld_dynamic_link_flags="${wl}-E"
+    ;;
+
+  irix5* | irix6*)
+    ld_dynamic_link_flags=
+    ;;
+
+  netbsd*)
+    ld_dynamic_link_flags=
+    ;;
+
+  openbsd*)
+    ld_dynamic_link_flags=
+    ;;
+
+  osf3* | osf4*)
+    ld_dynamic_link_flags=
+    ;;
+
+  sco3.2v5* | unixware* | sysv5* | sysv4* | solaris2* | solaris7*)
+    ld_dynamic_link_flags="${wl}-Bexport"
+    ;;
+
+  sunos4*)
+    ld_dynamic_link_flags=
+    ;;
+
+  uts4*)
+    ld_dynamic_link_flags=
+    ;;
+
+  bsdi*)
+    ld_dynamic_link_flags=
+    ;;
+
+  esac
+fi # End of if -z ld_dynamic_link_flags
+fi # End of if test "$can_build_shared" = "yes"
+
 AC_SUBST(dll_ld)
 AC_SUBST(dll_cflags)
-AC_SUBST(dll_oflags)
-AC_SUBST(dll_lflags)
+AC_SUBST(dll_ldflags)
+AC_SUBST(dll_post)
+AC_SUBST(dll_ldo)
+AC_SUBST(ld_dynamic_link_flags)
 ])dnl
+
index fe0004b..b5154f6 100644 (file)
@@ -14,132 +14,134 @@ values which are PATHs (i.e. lists of directories).
 
 General options:
 
---help                 Issue this usage message.
---verbose              Display the results of configure tests.
---extra-verbose                Display even more information, useful for debugging.
+--help                  Issue this usage message.
+--verbose               Display the results of configure tests.
+--extra-verbose         Display even more information, useful for debugging.
 
 
 Compilation options:
 
---compiler=prog                C compiler to use.
---with-gcc (*)         Use GCC to compile XEmacs.
---without-gcc          Don't use GCC to compile XEmacs.
---cflags=FLAGS         Compiler flags (such as -O)
---cpp=prog             C preprocessor to use (e.g. /usr/ccs/lib/cpp or cc -E)
---cppflags=FLAGS       C preprocessor flags (e.g. -I/foo or -Dfoo=bar)
---libs=LIBS            Additional libraries (e.g. -lfoo)
---ldflags=FLAGS                Additional linker flags (e.g. -L/foo)
---site-includes=PATH   List of directories to search first for header files.
---site-libraries=PATH  List of directories to search first for libraries.
+--compiler=prog         C compiler to use.
+--with-gcc (*)          Use GCC to compile XEmacs.
+--without-gcc           Don't use GCC to compile XEmacs.
+--cflags=FLAGS          Compiler flags (such as -O)
+--cpp=prog              C preprocessor to use (e.g. /usr/ccs/lib/cpp or cc -E)
+--cppflags=FLAGS        C preprocessor flags (e.g. -I/foo or -Dfoo=bar)
+--libs=LIBS             Additional libraries (e.g. -lfoo)
+--ldflags=FLAGS         Additional linker flags (e.g. -L/foo)
+--site-includes=PATH    List of directories to search first for header files.
+--site-libraries=PATH   List of directories to search first for libraries.
 --site-prefixes=PATH    List of directories to search for include/ and lib/
                         subdirectories, just after 'site-includes' and
                         'site-libraries'.
 --site-runtime-libraries=PATH
-                       List of ALL directories to search for dynamically
-                       linked libraries at run time.
---dynamic=yes          Link dynamically if supported by system.
---dynamic=no           Force static linking on systems where dynamic
-                       linking is the default.
---srcdir=DIR           Look for the XEmacs source files in DIR.
-                       Works best when using GNU Make.
+                        List of ALL directories to search for dynamically
+                        linked libraries at run time.
+--dynamic=yes           Link dynamically if supported by system.
+--dynamic=no            Force static linking on systems where dynamic
+                        linking is the default.
+--srcdir=DIR            Look for the XEmacs source files in DIR.
+                        Works best when using GNU Make.
 --use-indexed-lrecord-implementation
 --use-minimal-tagbits
---gung-ho              Build with new-style Lisp_Objects.
-                       Equivalent to both of the 2 previous options combined.
+--gung-ho               Build with new-style Lisp_Objects.
+                        Equivalent to both of the 2 previous options combined.
 
 
 Installation options:
 
---prefix=DIR           Install files below DIR.  Defaults to `/usr/local'.
+--prefix=DIR            Install files below DIR.  Defaults to `/usr/local'.
 
 
 Window-system options:
 
---with-x11 (*)         Support the X Window System.
---without-x11          Don't support X.
---x-includes=DIR       Search for X header files in DIR.
---x-libraries=DIR      Search for X libraries in DIR.
---without-toolbars     Don't compile with any toolbar support.
---without-session      Compile without realized leader window which will
-                       keep the WM_COMMAND property. Required for proper
-                       session-management.
---with-menubars=TYPE   Use TYPE menubars (lucid, motif, or no).  The Lucid
-                       widgets emulate Motif (mostly) but are faster.
-                       *WARNING*  The Motif menubar is currently broken.
---with-scrollbars=TYPE Use TYPE scrollbars
-                       (lucid, motif, athena, athena3d, or no).
---with-dialogs=TYPE    Use TYPE dialog boxes (motif, athena, athena3d, or no).
-                       Lucid menubars and scrollbars are the default.
-                       Motif dialog boxes will be used if Motif can be found.
---with-dragndrop (*)   Compile in the generic drag and drop API. This is
-                       automatically added if one of the drag and drop
-                       protocols is found (currently CDE, OffiX, MSWindows).
-                       *WARNING*  The Drag'n'drop support is under development
-                                  and is considered experimental.
---with-cde (*)         Compile in support for CDE drag and drop.
---with-offix (*)       Compile in support for OffiX drag and drop.
-                       *WARNING*  If you compile in OffiX, you may not be
-                                  able to use multiple X displays success-
-                                  fully.  If the two servers are from
-                                  different vendors, the results may be
-                                  unpredictable.
---without-xmu (*)      For those unfortunates whose vendors don't ship Xmu.
---external-widget      Compile with external widget support.
---with-xpm (*)         Compile with support for XPM files.
-                       It is highly recommended that you obtain XPM
-                       (version 3.4h or better) if you don't already
-                       have it.  Get it from the XEmacs FTP site.
---with-xface (*)       Compile with support for X-Face mail header
-                       conversion.  Requires the compface library.
-                       Get it from the XEmacs FTP site.
---without-gif          Compile without the built-in support for GIF image
-                       conversion.
---with-jpeg (*)                Compile with support for JPEG image conversion.
-                       Requires libjpeg from the Independent JPEG Group.
-                       Get it from the XEmacs FTP site.
---with-png (*)         Compile with support for PNG image conversion.
-                       Requires libpng.  Get it from the XEmacs FTP site.
---with-tiff (*)                Compile with support for TIFF image conversion.
-                       Requires Sam Lefflier's libtiff library.
-                       Get if from the XEmacs FTP site.
+--with-x11 (*)          Support the X Window System.
+--without-x11           Don't support X.
+--x-includes=DIR        Search for X header files in DIR.
+--x-libraries=DIR       Search for X libraries in DIR.
+--without-toolbars      Don't compile with any toolbar support.
+--without-session       Compile without realized leader window which will
+                        keep the WM_COMMAND property. Required for proper
+                        session-management.
+--with-menubars=TYPE    Use TYPE menubars (lucid, motif, or no).  The Lucid
+                        widgets emulate Motif (mostly) but are faster.
+                        *WARNING*  The Motif menubar is currently broken.
+--with-scrollbars=TYPE  Use TYPE scrollbars
+                        (lucid, motif, athena, athena3d, or no).
+--with-dialogs=TYPE     Use TYPE dialog boxes (motif, athena, athena3d, or no).
+                        Lucid menubars and scrollbars are the default.
+                        Motif dialog boxes will be used if Motif can be found.
+--with-dragndrop (*)    Compile in the generic drag and drop API. This is
+                        automatically added if one of the drag and drop
+                        protocols is found (currently CDE, OffiX, MSWindows).
+                        *WARNING*  The Drag'n'drop support is under development
+                                   and is considered experimental.
+--with-cde (*)          Compile in support for CDE drag and drop.
+--with-offix (*)        Compile in support for OffiX drag and drop.
+                        *WARNING*  If you compile in OffiX, you may not be
+                                   able to use multiple X displays success-
+                                   fully.  If the two servers are from
+                                   different vendors, the results may be
+                                   unpredictable.
+--without-xmu (*)       For those unfortunates whose vendors don't ship Xmu.
+--external-widget       Compile with external widget support.
+--with-xpm (*)          Compile with support for XPM files.
+                        It is highly recommended that you obtain XPM
+                        (version 3.4h or better) if you don't already
+                        have it.  Get it from the XEmacs FTP site.
+--with-xface (*)        Compile with support for X-Face mail header
+                        conversion.  Requires the compface library.
+                        Get it from the XEmacs FTP site.
+--without-gif           Compile without the built-in support for GIF image
+                        conversion.
+--with-jpeg (*)         Compile with support for JPEG image conversion.
+                        Requires libjpeg from the Independent JPEG Group.
+                        Get it from the XEmacs FTP site.
+--with-png (*)          Compile with support for PNG image conversion.
+                        Requires libpng.  Get it from the XEmacs FTP site.
+--with-tiff (*)         Compile with support for TIFF image conversion.
+                        Requires Sam Lefflier's libtiff library.
+                        Get if from the XEmacs FTP site.
 
 
 TTY options:
 
---without-tty          Don't support TTY-s.
---with-ncurses (*)     Use the ncurses library for tty support.
---with-gpm (*)                 Compile in support for General Purpose Mouse.
+--without-tty           Don't support TTY-s.
+--with-ncurses (*)      Use the ncurses library for tty support.
+--with-gpm (*)          Compile in support for General Purpose Mouse.
 
 
 Additional features:
 
---with-tooltalk (*)    Support the ToolTalk IPC protocol.
---with-workshop                Support the Sun WorkShop (formerly Sparcworks)
-                       development environment.
---with-socks           Compile with support for SOCKS (an Internet proxy).
+--with-tooltalk (*)     Support the ToolTalk IPC protocol.
+--with-workshop         Support the Sun WorkShop (formerly Sparcworks)
+                        development environment.
+--with-socks            Compile with support for SOCKS (an Internet proxy).
 --with-database=TYPE (*) Compile with database support.  Valid types are
-                       `no' or a comma-separated list of one or more
-                       of `berkdb' and either `dbm' or `gnudbm'.
---with-sound=native (*)        Compile with native sound support.
---with-sound=nas       Compile with network sound support.
---with-sound=both      Compile with native and network sound support.
---native-sound-lib=LIB Native sound support library.  Needed on Suns
-                       with --with-sound=both because both sound libraries
-                       are called libaudio.
---with-pop             support POP for mail retrieval
---with-kerberos                support Kerberos-authenticated POP
---with-hesiod          support Hesiod to get the POP server host
---with-dnet (*)                Compile with support for DECnet.
+                        `no' or a comma-separated list of one or more
+                        of `berkdb' and either `dbm' or `gnudbm'.
+--with-sound=native (*) Compile with native sound support.
+--with-sound=nas        Compile with network sound support.
+--with-sound=both       Compile with native and network sound support.
+--native-sound-lib=LIB  Native sound support library.  Needed on Suns
+                        with --with-sound=both because both sound libraries
+                        are called libaudio.
+--with-pop              support POP for mail retrieval
+--with-kerberos         support Kerberos-authenticated POP
+--with-hesiod           support Hesiod to get the POP server host
+--with-dnet (*)         Compile with support for DECnet.
 --with-ldap (*)         Compile with support for the LDAP protocol (requires
                         installed LDAP libraries on the system).
---mail-locking=TYPE (*)        Specify the locking to be used by movemail to prevent
-                       concurrent updates of mail spool files. Valid types
-                       are `lockf', `flock', and `file'.
---with-site-lisp        Allow for a site-lisp directory in the XEmacs hierarchy
-                       searched before the installation packages.
+--mail-locking=TYPE (*) Specify the locking to be used by movemail to prevent
+                        concurrent updates of mail spool files. Valid types
+                        are `lockf', `flock', and `file'.
+--with-site-lisp=yes    Allow for a site-lisp directory in the XEmacs hierarchy
+                        searched before the installation packages.
+--with-site-modules=no  Disable site-modules directory in the XEmacs hierarchy,
+                        which is searched before the installation modules.
 --package-path=PATH     Directories to search for packages to dump with xemacs.
-                        PATH splits into three parts separated
-                        by double colons (::), an early, a late, and a last part,
+                        PATH splits into three parts separated by double
+                        colons (::), an early, a late, and a last part,
                         corresponding to their position in the various
                         system paths:  The early part is always first,
                         the late part somewhere in the middle, and the
@@ -149,75 +151,78 @@ Additional features:
                         is late.
                         If PATH has two components, the first is
                         early, the second is late.
---infodir=DIR          Directory to install the XEmacs Info manuals and dir in.
---infopath=PATH                Directories to search for Info documents, info dir
-                       and localdir files in case run-time searching
+--infodir=DIR           Directory to install XEmacs Info manuals and dir in.
+--infopath=PATH         Directories to search for Info documents, info dir
+                        and localdir files in case run-time searching
                         for them fails.
+--moduledir=DIR         Directory to install dynamic modules in.
 
 Internationalization options:
 
---with-mule            Compile with Mule (MUlti-Lingual Emacs) support,
-                       needed to support non-Latin-1 (including Asian) languages.
---with-xim=xlib                Compile with support for X input methods,
---with-xim=motif (*)   Used in conjunction with Mule support.
-                       Use either raw Xlib to provide XIM support, or
-                       the Motif XmIm* routines (when available).
-                       NOTE:  On some systems bugs in X11's XIM support
-                       will cause XEmacs to crash, so by default,
-                       no XIM support is compiled in, unless running
-                       on Solaris and the XmIm* routines are detected.
---with-canna (*)       Compile with support for Canna (a Japanese input method
-                       used in conjunction with Mule support).
---with-wnn (*)         Compile with support for WNN (a multi-language input method
-                       used in conjunction with Mule support).
---with-wnn6 (*)                Compile with support for the comercial package WNN version 6
---with-i18n3           Compile with I18N level 3 (support for message
-                       translation).  This doesn't currently work.
---with-xfs             Compile with XFontSet support for bilingual menubar.
-                       Can't use this option with --with-xim=motif or xlib.
-                       And should have --with-menubars=lucid.
+--with-mule             Compile with Mule (MUlti-Lingual Emacs) support,
+                        needed to support non-Latin-1 (including Asian)
+                        languages.
+--with-xim=xlib         Compile with support for X input methods,
+--with-xim=motif (*)    Used in conjunction with Mule support.
+                        Use either raw Xlib to provide XIM support, or
+                        the Motif XmIm* routines (when available).
+                        NOTE:  On some systems bugs in X11's XIM support
+                        will cause XEmacs to crash, so by default,
+                        no XIM support is compiled in, unless running
+                        on Solaris and the XmIm* routines are detected.
+--with-canna (*)        Compile with support for Canna (a Japanese input method
+                        used in conjunction with Mule support).
+--with-wnn (*)          Compile with support for WNN (a multi-language input
+                        method used in conjunction with Mule support).
+--with-wnn6 (*)         Compile with support for the comercial package WNN
+                        version 6
+--with-i18n3            Compile with I18N level 3 (support for message
+                        translation).  This doesn't currently work.
+--with-xfs              Compile with XFontSet support for bilingual menubar.
+                        Can't use this option with --with-xim=motif or xlib.
+                        And should have --with-menubars=lucid.
 
 
 Debugging options:
 
---debug                        Compile with support for debugging XEmacs.
-                       (Causes code-size increase and little loss of speed.)
+--debug                 Compile with support for debugging XEmacs.
+                        (Causes code-size increase and little loss of speed.)
 --error-checking=TYPE[,TYPE]...
-                       Compile with internal error-checking added.
-                       Causes noticeable loss of speed.  Valid types
-                       are extents, bufpos, malloc, gc, typecheck.
---error-checking=none  Disable all internal error-checking (the default).
---error-checking=all   Enable all internal error-checking.
---memory-usage-stats   Compile with additional code to allow you to
-                       determine what XEmacs's memory is being used
-                       for.  Causes a small code increase but no loss
-                       of speed.  Normally enabled when --debug is given.
---no-doc-file          Don't rebuild the DOC file unless it's explicitly
-                       deleted.  Only use during development. (It speeds
-                       up the compile-run-test cycle.)
---use-union-type       Enable or disable use of a union, instead of an
-                       int, for the fundamental Lisp_Object type; this
-                       provides stricter type-checking.  Only works with
-                       some systems and compilers.
+                        Compile with internal error-checking added.
+                        Causes noticeable loss of speed.  Valid types
+                        are extents, bufpos, malloc, gc, typecheck.
+--error-checking=none   Disable all internal error-checking (the default).
+--error-checking=all    Enable all internal error-checking.
+--memory-usage-stats    Compile with additional code to allow you to
+                        determine what XEmacs's memory is being used
+                        for.  Causes a small code increase but no loss
+                        of speed.  Normally enabled when --debug is given.
+--no-doc-file           Don't rebuild the DOC file unless it's explicitly
+                        deleted.  Only use during development. (It speeds
+                        up the compile-run-test cycle.)
+--use-union-type        Enable or disable use of a union, instead of an
+                        int, for the fundamental Lisp_Object type; this
+                        provides stricter type-checking.  Only works with
+                        some systems and compilers.
 
 
 Other options:
 
---puresize=VALUE       Override default amount of space for pure Lisp code.
---rel-alloc            Use the relocating allocator (default for this option
-                       is system-dependent).
---with-dlmalloc                Control usage of Doug Lea malloc on systems that have
-                       it in the standard C library (default is to use it if
-                       it is available).
---with-clash-detection Use lock files to detect multiple edits of the same file.
-                       The default is to not do clash detection.
---lockdir=DIR          The directory to put clash detection files in, such as
-                       `/var/lock/emacs'.
-    Defaults to `${statedir}/xemacs/lock'.
---with-system-malloc   Force use of the system malloc, rather than GNU malloc.
---with-debug-malloc    Use the debugging malloc package.
---with-quantify                Add support for performance debugging using Quantify.
---with-purify          Add support for memory debugging using Purify.
+--puresize=VALUE        Override default amount of space for pure Lisp code.
+--rel-alloc             Use the relocating allocator (default for this option
+                        is system-dependent).
+--with-dlmalloc         Control usage of Doug Lea malloc on systems that have
+                        it in the standard C library (default is to use it if
+                        it is available).
+--with-clash-detection  Use lock files to detect multiple edits of the same
+                        file.  The default is to not do clash detection.
+--lockdir=DIR           The directory to put clash detection files in, such as
+                        `/var/lock/emacs'.
+                        Defaults to `${statedir}/xemacs/lock'.
+--with-system-malloc    Force use of the system malloc, rather than GNU malloc.
+--with-debug-malloc     Use the debugging malloc package.
+--with-quantify         Add support for performance debugging using Quantify.
+--with-purify           Add support for memory debugging using Purify.
 
 You may also specify any of the `path' variables found in Makefile.in,
 including --bindir, --libdir, --lispdir, --sitelispdir, --datadir,
index 2e222f0..439f7c0 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -33,6 +33,16 @@ file.
 * Changes in XEmacs 21.2
 ========================
 
+** Interactive searching and matching case improvements:
+Case sensitiveness in searching operations is controled by the variable
+`case-fold-search' (if non-nil, case is ignored while searching). This
+mechanism has now been slightly improved in the case of an interactive
+search: if the search string (or regexp) happens to contain uppercase
+characters, the searching is forced to be case-sensitive, regardless of
+the value of `case-fold-search'. This behavior affects all functions
+performing interactive searches, like `zap-to-char', `tags-search',
+`occur' etc. 
+
 ** You can now create "indirect buffers", like in GNU Emacs.  An
 indirect buffer shares its text with another buffer ("base buffer"),
 but has its own major mode, local variables, extents, and narrowing.
index 6f16863..c5017e5 100644 (file)
@@ -5,12 +5,9 @@ static char *recycle[] = {
 "    51    51     4       1               26    23",
 /*  colors */
 "  c None              m None",
-/* "# c black          m black",       */
-/* "@ c black          m black",       */
-/* "- c white          m white",       */
-"# c black             m chartreuse4",
-"@ c chartreuse4       m chartreuse4",
-"- c chartreuse1       m chartreuse1",
+"# c black             m black",
+"- c chartreuse1       m #7fff0f",
+"@ c chartreuse4       m #4f8f0f",
 /*  pixels */
 "                                                   ",
 "                 ###################               ",
index a9429e0..bce323a 100644 (file)
@@ -1,3 +1,31 @@
+1999-02-02  XEmacs Build Bot <builds@cvs.xemacs.org>
+
+       * XEmacs 21.2.9 is released
+
+1999-01-27  Martin Buchholz  <martin@xemacs.org>
+
+       * movemail.c (strerror): Must be NON-static, since it is used by
+       the POP code, which got moved to a separate file.
+
+1999-01-11  Damon Lipparelli  <lipp@primus.com>
+
+       * Makefile.in.in: use ellcc (not ellc) everywhere
+
+1999-01-10  J. Kean Johnston  <jkj@sco.com>
+
+       * Makefile.in.in: Include moduledir and sitemoduledir as defined
+       by configure.
+       - Install ellcc if we're supporting shared objects
+       - Rules and dependancies for ellcc
+
+       * ellcc.c: New file. Front end to the compiler for making modules.
+
+       * ellcc.h.in: New file. Contains path definitions used by ellcc.
+
+       * make-docfile.c (main): Add check for -E argument used by ellcc.
+
+       * make-docfile.c: Changed output format when in -E mode.
+
 1998-12-28  Martin Buchholz <martin@xemacs.org>
 
        * XEmacs 21.2.8 is released.
index 036a225..1e62172 100644 (file)
@@ -55,6 +55,9 @@ libdir=@libdir@
 srcdir=@srcdir@
 archlibdir=@archlibdir@
 configuration=@configuration@
+moduledir=@moduledir@
+sitemoduledir=@sitemoduledir@
+
 ## ==================== Utility Programs for the Build =================
 
 INSTALL = @install_pp@ @INSTALL@
@@ -71,11 +74,19 @@ INSTALL_DATA = @INSTALL_DATA@
 ## which should be installed in bindir.
 INSTALLABLES_BASE = etags ctags b2m gnuclient ootags
 INSTALLABLE_SCRIPTS = rcs-checkin pstogif gnudoit gnuattach
+#ifdef HAVE_SHLIB
+#ifdef HAVE_MS_WINDOWS
+INSTALLABLES = $(INSTALLABLES_BASE) runxemacs rungnuclient ellcc
+#else
+INSTALLABLES = $(INSTALLABLES_BASE) ellcc
+#endif
+#else
 #ifdef HAVE_MS_WINDOWS
-INSTALLABLES = $(INSTALLABLES_BASE) runemacs
+INSTALLABLES = $(INSTALLABLES_BASE) runxemacs rungnuclient
 #else
 INSTALLABLES = $(INSTALLABLES_BASE) 
 #endif
+#endif
 
 
 ## Things that Emacs runs internally, or during the build process,
@@ -229,7 +240,7 @@ mostlyclean:
 clean: mostlyclean
        $(RM) ${INSTALLABLES} ${UTILITIES} *.exe
 distclean: clean
-       $(RM) DOC *.tab.c *.tab.h aixcc.c TAGS
+       $(RM) DOC *.tab.c *.tab.h aixcc.c TAGS ellcc.h
        $(RM) GNUmakefile Makefile Makefile.in blessmail config.values
 realclean: distclean
 extraclean: distclean
@@ -269,15 +280,30 @@ etags_deps   = ${srcdir}/etags.c $(GETOPTDEPS) regex.o ../src/config.h
 etags: ${etags_deps}
        $(CC) ${etags_args} -o $@
 
-runemacs_args = -I. $(cflags) -I${srcdir} -I${srcdir}/../src \
-       -DVERSION='"${version}"' ${srcdir}/../nt/runemacs.c \
-       $(ldflags) -Wl,--subsystem,windows
-runemacs_deps   = ${srcdir}/../nt/runemacs.c ${srcdir}/../nt/xemacs.ico ../src/config.h
+ellcc_args = -I. $(cflags) -I${srcdir} -I${srcdir}/../src \
+    ${srcdir}/ellcc.c $(ldflags)
+ellcc_deps = ${srcdir}/ellcc.c ellcc.h ../src/config.h
+
+ellcc: ${ellcc_deps}
+       $(CC) ${ellcc_args} -o $@
+
+run_args = -I. $(cflags) -I${srcdir} -I${srcdir}/../src \
+       -DVERSION='"${version}"' ${srcdir}/run.c \
+       $(ldflags) -Wl,--subsystem,windows -e _mainCRTStartup
+run_deps   = ${srcdir}/run.c ${srcdir}/run.h ${srcdir}/run.rc \
+       ${srcdir}/../nt/xemacs.ico ${srcdir}/../nt/file.ico \
+       ${srcdir}/../nt/lisp.ico
+
+run: ${run_deps}
+       windres --include-dir ${srcdir}/../nt -i run.rc -o run_res.o
+       $(CC) run_res.o ${run_args} -o $@
+       strip $@.exe
+
+runxemacs: run
+       cp run.exe $@.exe
 
-runemacs: ${runemacs_deps}
-       echo "runemacs ICON DISCARDABLE \"../nt/xemacs.ico\"" \
-       | windres -o runemacs_res.o
-       $(CC) runemacs_res.o ${runemacs_args} -o $@
+rungnuclient: run
+       cp run.exe $@.exe
 
 ootags_args = -I. $(cflags) -I${srcdir} -I${srcdir}/../src \
        -DVERSION='"${version}"' ${srcdir}/ootags.c \
diff --git a/lib-src/ellcc.c b/lib-src/ellcc.c
new file mode 100644 (file)
index 0000000..acc3abe
--- /dev/null
@@ -0,0 +1,681 @@
+/* ellcc.c - front-end for compiling Emacs modules
+Copyright (C) 1998, 1999 J. Kean Johnston.
+
+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 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 XEmacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Author: J. Kean Johnston (jkj@sco.com).
+Please mail bugs and suggestions to the XEmacs maintainer.
+*/
+
+/*
+Here's the scoop. We would really like this to be a shell script, but
+the various Windows platforms dont have reliable scripting that suits
+our needs. We dont want to reply on perl or some other such language
+so we have to roll our own executable to act as a front-end for the
+compiler.
+
+This program is used to invoke the compiler, the linker and to generate
+the module specific documentation and initialization code.  We assume we
+are in 'compile' mode unless we encounter an argument which tells us
+that we're not.  We take all arguments and pass them on directly to the
+compiler, except for a few which are specific to this program:
+
+  --mode=VALUE      This sets the program mode. VALUE can be one of
+                    compile, link, init or verbose.
+  --mod-name=NAME   Sets the module name to the string NAME.
+  --mod-title=TITLE Sets the module title to the string TITLE.
+  --mod-version=VER Sets the module version to the string VER.
+
+The idea is that Makefiles will use ellcc as the compiler for making
+dynamic Emacs modules, and life should be as simple as:
+
+  make CC=ellcc LD='ellcc --mode=link'
+
+The only additional requirement is an entry in the Makefile to produce
+the module initialization file, which will usually be something along
+the lines of:
+
+  modinit.c: $(SRCS)
+             ellcc --mode=init --mod-name=\"$(MODNAME)\" \
+               --mod-title=\"$(MODTITLE)\" --mod-version=\"$(MODVERSION)\" \
+               -o $@ $(SRCS)
+
+See the samples for more details.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef MSDOS
+# include <fcntl.h>
+# include <sys/param.h>
+# include <io.h>
+# ifndef HAVE_CONFIG_H
+#   define DOS_NT
+#   include <sys/config.h>
+# endif
+#endif /* MSDOS */
+
+#ifdef WINDOWSNT
+# include <stdlib.h>
+# include <fcntl.h>
+# include <string.h>
+# include <io.h>
+# define MAXPATHLEN _MAX_PATH
+# ifdef HAVE_CONFIG_H
+#   undef HAVE_NTGUI
+# else
+#   define DOS_NT
+#   define HAVE_GETCWD
+# endif /* not HAVE_CONFIG_H */
+#endif /* WINDOWSNT */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+  /* On some systems, Emacs defines static as nothing for the sake
+     of unexec.  We don't want that here since we don't use unexec. */
+# undef static
+#endif /* HAVE_CONFIG_H */
+
+#if !defined (WINDOWSNT) && defined (STDC_HEADERS)
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#else
+# ifdef HAVE_GETCWD
+    extern char *getcwd ();
+# endif
+#endif /* HAVE_UNISTD_H */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#ifndef errno
+  extern int errno;
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define EMODULES_GATHER_VERSION
+#include "emodules.h"
+#include "ellcc.h"
+
+#if !defined (S_ISREG) && defined (S_IFREG)
+# define S_ISREG(m)    (((m) & S_IFMT) == S_IFREG)
+#endif
+
+/* Exit codes for success and failure.  */
+#ifdef VMS
+# define       GOOD    1
+# define       BAD     0
+#else
+# define       GOOD    0
+# define       BAD     1
+#endif
+
+#define DEBUG
+
+#ifndef HAVE_SHLIB
+int
+main()
+{
+  fprintf (stderr, "Dynamic modules not supported on this platform\n");
+  return (BAD);
+}
+#else
+
+/*
+ * Try to figure out the commands we need to use to create shared objects,
+ * and how to compile for PIC mode.
+ */
+
+/*
+ *     xnew, xrnew -- allocate, reallocate storage
+ *
+ * SYNOPSIS:   Type *xnew (int n, Type);
+ *             Type *xrnew (OldPointer, int n, Type);
+ */
+#ifdef chkmalloc
+# include "chkmalloc.h"
+# define xnew(n,Type)    ((Type *) trace_malloc (__FILE__, __LINE__, \
+                                                 (n) * sizeof (Type)))
+# define xrnew(op,n,Type) ((Type *) trace_realloc (__FILE__, __LINE__, \
+                                                  (op), (n) * sizeof (Type)))
+#else
+# define xnew(n,Type)    ((Type *) xmalloc ((n) * sizeof (Type)))
+# define xrnew(op,n,Type) ((Type *) xrealloc ((op), (n) * sizeof (Type)))
+#endif
+long *xmalloc (), *xrealloc ();
+void fatal (), pfatal ();
+char *ellcc_strchr (), *ellcc_strrchr ();
+void add_to_argv ();
+void do_compile_mode(), do_link_mode(), do_init_mode();
+
+#define SSTR(S) ((S)?(S):"")
+
+#define ELLCC_COMPILE_MODE      0
+#define ELLCC_LINK_MODE         1
+#define ELLCC_INIT_MODE         2
+
+int ellcc_mode = ELLCC_COMPILE_MODE;
+char *progname;
+char *mod_name = (char *)0, *mod_version = (char *)0, *mod_title = (char *)0;
+char *mod_output = (char *)0;
+int verbose = 0;
+char **exec_argv;
+int exec_argc = 1, *exec_args;
+int real_argc = 0;
+int prog_argc;
+char **prog_argv;
+
+/*
+ * We allow the user to over-ride things in the environment
+ */
+char *ellcc, *ellld, *ellcflags, *ellldflags, *ellpicflags, *elldllflags;
+#define OVERENV(STR,EVAR,DFLT) \
+  STR = getenv(EVAR); \
+  if ((STR) == (char *)0) \
+    STR = DFLT
+
+int
+main (argc, argv)
+     int argc;
+     char *argv[];
+{
+  char *tmp;
+  int i, done_mode = 0;
+
+  prog_argc = argc;
+  prog_argv = argv;
+
+#if defined(MSDOS) || defined(WINDOWSNT)
+  tmp = ellcc_strrchr (argv[0], '\\');
+  if (tmp != (char *)0)
+    tmp++;
+#elif !defined (VMS)
+  tmp = ellcc_strrchr (argv[0], '/');
+  if (tmp != (char *)0)
+    tmp++;
+#else
+  tmp = argv[0];
+#endif
+
+  if (tmp != (char *)0)
+    progname = tmp;
+  else
+    progname = argv[0];
+
+  tmp = &progname[strlen(progname)-2];
+  if (strcmp (tmp, "cc") == 0)
+    ellcc_mode = ELLCC_COMPILE_MODE;
+  else if (strcmp (tmp, "ld") == 0)
+    ellcc_mode = ELLCC_LINK_MODE;
+  else if (strcmp (tmp, "it") == 0)
+    ellcc_mode = ELLCC_INIT_MODE;
+
+  exec_argv = xnew(argc + 20, char *);
+  exec_args = xnew(argc, int);
+  for (i = 0; i < argc; i++)
+    exec_args[i] = -1;
+
+  if (argc < 2)
+    fatal ("too few arguments", (char *)0);
+
+  exec_args[0] = 0;
+
+  for (i = 1; i < argc; i++)
+    {
+      if (strncmp (argv[i], "--mode=", 7) == 0)
+        {
+          char *modeopt = argv[i] + 7;
+
+          if (done_mode && strcmp (modeopt, "verbose"))
+            fatal ("more than one mode specified");
+          if (strcmp (modeopt, "link") == 0)
+            {
+              done_mode++;
+              ellcc_mode = ELLCC_LINK_MODE;
+            }
+          else if (strcmp (modeopt, "compile") == 0)
+            {
+              done_mode++;
+              ellcc_mode = ELLCC_COMPILE_MODE;
+            }
+          else if (strcmp (modeopt, "init") == 0)
+            {
+              done_mode++;
+              ellcc_mode = ELLCC_INIT_MODE;
+            }
+          else if (strcmp (modeopt, "verbose") == 0)
+            verbose += 1;
+        }
+      else if (strcmp (argv[i], "--mod-location") == 0)
+        {
+          printf ("%s\n", ELLCC_MODDIR);
+          return 0;
+        }
+      else if (strcmp (argv[i], "--mod-site-location") == 0)
+        {
+          printf ("%s\n", ELLCC_SITEMODS);
+          return 0;
+        }
+      else if (strcmp (argv[i], "--mod-archdir") == 0)
+        {
+          printf ("%s\n", ELLCC_ARCHDIR);
+          return 0;
+        }
+      else if (strcmp (argv[i], "--mod-config") == 0)
+        {
+          printf ("%s\n", ELLCC_CONFIG);
+          return 0;
+        }
+      else if (strncmp (argv[i], "--mod-name=", 10) == 0)
+        mod_name = argv[i] + 11;
+      else if (strncmp (argv[i], "--mod-title=", 11) == 0)
+        mod_title = argv[i] + 12;
+      else if (strncmp (argv[i], "--mod-version=", 13) == 0)
+        mod_version = argv[i] + 14;
+      else if (strncmp (argv[i], "--mod-output=", 12) == 0)
+        mod_output = argv[i] + 13;
+      else
+        {
+          exec_args[exec_argc] = i;
+          exec_argc++;
+        }
+    }
+
+  if (ellcc_mode == ELLCC_LINK_MODE && mod_output == (char *)0)
+    fatal ("must specify --mod-output when linking", (char *)0);
+  if (ellcc_mode == ELLCC_INIT_MODE && mod_output == (char *)0)
+    fatal ("must specify --mod-output when creating init file", (char *)0);
+  if (ellcc_mode == ELLCC_INIT_MODE && mod_name == (char *)0)
+    fatal ("must specify --mod-name when creating init file", (char *)0);
+
+  /*
+   * We now have the list of arguments to pass to the compiler or
+   * linker (or to process for doc files). We can do the real work
+   * now.
+   */
+  if (verbose)
+    printf ("ellcc driver version %s for EMODULES version %s (%ld)\n",
+            ELLCC_EMACS_VER, EMODULES_VERSION, EMODULES_REVISION);
+#ifdef DEBUG
+  if (verbose >= 2)
+    {
+      printf ("              mode = %d (%s)\n", ellcc_mode,
+              ellcc_mode == ELLCC_COMPILE_MODE ? "compile" :
+              ellcc_mode == ELLCC_LINK_MODE ? "link" : "init");
+      printf ("       module_name = \"%s\"\n", SSTR(mod_name));
+      printf ("      module_title = \"%s\"\n", SSTR(mod_title));
+      printf ("    module_version = \"%s\"\n", SSTR(mod_version));
+
+      printf ("                CC = %s\n", ELLCC_CC);
+      printf ("            CFLAGS = %s\n", ELLCC_CFLAGS);
+      printf ("      CC PIC flags = %s\n", ELLCC_DLL_CFLAGS);
+      printf ("                LD = %s\n", ELLCC_DLL_LD);
+      printf ("           LDFLAGS = %s\n", ELLCC_DLL_LDFLAGS);
+      printf ("      architecture = %s\n", ELLCC_CONFIG);
+      printf (" Include directory = %s/include\n", ELLCC_ARCHDIR);
+      printf ("\n");
+    }
+#endif
+
+  if (exec_argc < 2)
+    fatal ("too few arguments");
+
+  /*
+   * Get the over-rides from the environment
+   */
+  OVERENV(ellcc, "ELLCC", ELLCC_CC);
+  OVERENV(ellld, "ELLLD", ELLCC_DLL_LD);
+  OVERENV(ellcflags, "ELLCFLAGS", ELLCC_CFLAGS);
+  OVERENV(ellldflags, "ELLLDFLAGS", ELLCC_LDFLAGS);
+  OVERENV(elldllflags, "ELLDLLFLAGS", ELLCC_DLL_LDFLAGS);
+  OVERENV(ellpicflags, "ELLPICFLAGS", ELLCC_DLL_CFLAGS);
+
+  if (ellcc_mode == ELLCC_COMPILE_MODE)
+    do_compile_mode();
+  else if (ellcc_mode == ELLCC_LINK_MODE)
+    do_link_mode();
+  else
+    do_init_mode();
+
+  /*
+   * The arguments to pass on to the desired program have now been set
+   * up and we can run the program.
+   */
+  if (verbose)
+    {
+      for (i = 0; i < real_argc; i++)
+        printf ("%s ", exec_argv[i]);
+      printf ("\n");
+      fflush (stdout);
+    }
+  exec_argv[real_argc] = (char *)0; /* Terminate argument list */
+
+  i = execvp (exec_argv[0], exec_argv);
+  if (verbose)
+    printf ("%s exited with status %d\n", exec_argv[0], i);
+  return i;
+}
+
+/* Like malloc but get fatal error if memory is exhausted.  */
+long *
+xmalloc (size)
+     unsigned int size;
+{
+  long *result = (long *) malloc (size);
+  if (result == NULL)
+    fatal ("virtual memory exhausted", (char *)NULL);
+  return result;
+}
+
+long *
+xrealloc (ptr, size)
+     char *ptr;
+     unsigned int size;
+{
+  long *result =  (long *) realloc (ptr, size);
+  if (result == NULL)
+    fatal ("virtual memory exhausted", (char *)NULL);
+  return result;
+}
+
+/* Print error message and exit.  */
+void
+fatal (s1, s2)
+     char *s1, *s2;
+{
+  fprintf (stderr, "%s: ", progname);
+  fprintf (stderr, s1, s2);
+  fprintf (stderr, "\n");
+  exit (BAD);
+}
+
+void
+pfatal (s1)
+     char *s1;
+{
+  perror (s1);
+  exit (BAD);
+}
+
+/*
+ * Return the ptr in sp at which the character c last
+ * appears; NULL if not found
+ *
+ * Identical to System V strrchr, included for portability.
+ */
+char *
+ellcc_strrchr (sp, c)
+     register char *sp, c;
+{
+  register char *r;
+
+  r = NULL;
+  do
+    {
+      if (*sp == c)
+       r = sp;
+  } while (*sp++);
+  return r;
+}
+
+/*
+ * Return the ptr in sp at which the character c first
+ * appears; NULL if not found
+ *
+ * Identical to System V strchr, included for portability.
+ */
+char *
+ellcc_strchr (sp, c)
+     register char *sp, c;
+{
+  do
+    {
+      if (*sp == c)
+       return sp;
+    } while (*sp++);
+  return NULL;
+}
+
+/*
+ * Add a string to the argument vector list that will be passed on down
+ * to the compiler or linker. We need to split individual words into
+ * arguments, taking quoting into account. This can get ugly.
+ */
+void
+add_to_argv (str)
+     CONST char *str;
+{
+  int sm = 0;
+  CONST char *s = (CONST char *)0;
+
+  if ((str == (CONST char *)0) || (str[0] == '\0'))
+    return;
+
+  while (*str)
+    {
+      switch (sm)
+        {
+        case 0: /* Start of case - string leading whitespace */
+          if (isspace (*str))
+            str++;
+          else
+            {
+              sm = 1; /* Change state to non-whitespace */
+              s = str; /* Mark the start of THIS argument */
+            }
+          break;
+
+        case 1: /* Non-whitespace character. Mark the start */
+          if (isspace (*str))
+            {
+              /* Reached the end of the argument. Add it. */
+              int l = str-s;
+              exec_argv[real_argc] = xnew (l+2, char);
+              strncpy (exec_argv[real_argc], s, l);
+              exec_argv[real_argc][l] = '\0';
+              real_argc++;
+              sm = 0; /* Back to start state */
+              s = (CONST char *)0;
+              break;
+            }
+          else if (*str == '\\')
+            {
+              sm = 2; /* Escaped character */
+              str++;
+              break;
+            }
+          else if (*str == '\'')
+            {
+              /* Start of quoted string (single quotes) */
+              sm = 3;
+            }
+          else if (*str == '"')
+            {
+              /* Start of quoted string (double quotes) */
+              sm = 4;
+            }
+          else
+            {
+              /* This was just a normal character. Advance the pointer. */
+              str++;
+            }
+          break;
+
+        case 2: /* Escaped character */
+          str++; /* Preserve the quoted character */
+          sm = 1; /* Go back to gathering state */
+          break;
+
+        case 3: /* Inside single quoted string */
+          if (*str == '\'')
+            sm = 1;
+          str++;
+          break;
+
+        case 4: /* inside double quoted string */
+          if (*str == '"')
+            sm = 1;
+          str++;
+          break;
+        }
+    }
+
+  if (s != (CONST char *)0)
+    {
+      int l = str-s;
+      exec_argv[real_argc] = xnew (l+2, char);
+      strncpy (exec_argv[real_argc], s, l);
+      exec_argv[real_argc][l] = '\0';
+      real_argc++;
+      s = (CONST char *)0;
+    }
+}
+
+/*
+ * For compile mode, things are pretty straight forward. All we need to do
+ * is build up the argument vector and exec() it. We must just make sure
+ * that we get all of the required arguments in place.
+ */
+void
+do_compile_mode()
+{
+  int i;
+  char ts[4096]; /* Plenty big enough */
+
+  add_to_argv (ellcc);
+  add_to_argv (ellcflags);
+  add_to_argv (ellpicflags);
+  add_to_argv ("-DPIC");
+  add_to_argv ("-DEMACS_MODULE");
+#ifdef XEMACS
+  add_to_argv ("-DXEMACS_MODULE"); /* Cover both cases */
+  add_to_argv ("-Dxemacs");
+#endif
+  add_to_argv ("-Demacs");
+  sprintf (ts, "-I%s/include", ELLCC_ARCHDIR);
+  add_to_argv (ts);
+  add_to_argv (ELLCC_CF_ALL);
+  for (i = 1; i < exec_argc; i++)
+    exec_argv[real_argc++] = strdup (prog_argv[exec_args[i]]);
+}
+
+/*
+ * For link mode, things are a little bit more complicated. We need to
+ * insert the linker commands first, replace any occurrence of ELLSONAME
+ * with the desired output file name, insert the output arguments, then
+ * all of the provided arguments, then the final post arguments. Once
+ * all of this has been done, the argument vector is ready to run.
+ */
+void
+do_link_mode()
+{
+  int i,x;
+  char *t, ts[4096]; /* Plenty big enough */
+
+  add_to_argv (ellld);
+  add_to_argv (ellldflags);
+  add_to_argv (elldllflags);
+  add_to_argv (ELLCC_DLL_LDO);
+  add_to_argv (mod_output);
+  for (i = 1; i < exec_argc; i++)
+    exec_argv[real_argc++] = strdup (prog_argv[exec_args[i]]);
+  add_to_argv (ELLCC_DLL_POST);
+
+  /*
+   * Now go through each argument and replace ELLSONAME with mod_output.
+   */
+  for (i = 0; i < real_argc; i++)
+    {
+      x = 0;
+      ts[0] = '\0';
+
+      t = exec_argv[i];
+      while (*t)
+        {
+          if (*t == 'E')
+            {
+              if (strncmp (t, "ELLSONAME", 9) == 0)
+                {
+                  strcat (ts, mod_output);
+                  t += 8;
+                  x += strlen (mod_output);
+                }
+              else
+                {
+                  ts[x] = *t;
+                  x++;
+                  ts[x] = '\0';
+                }
+            }
+          else
+            {
+              ts[x] = *t;
+              x++;
+              ts[x] = '\0';
+            }
+          t++;
+        }
+      free (exec_argv[i]);
+      exec_argv[i] = strdup (ts);
+    }
+}
+
+/*
+ * In init mode, things are a bit easier. We assume that the only things
+ * passed on the command line are the names of source files which the
+ * make-doc program will be processing. We prepare the output file with
+ * the header information first, as make-doc will append to the file by
+ * special dispensation.
+ */
+void
+do_init_mode()
+{
+  int i;
+  char ts[4096]; /* Plenty big enough */
+  char *mdocprog;
+  FILE *mout = fopen (mod_output, "w");
+
+  if (mout == (FILE *)0)
+    fatal ("failed to open output file", mod_output);
+  fprintf (mout, "/* DO NOT EDIT - AUTOMATICALLY GENERATED */\n\n");
+  fprintf (mout, "#include <emodules.h>\n\n");
+  fprintf (mout, "const long emodule_compiler = %ld;\n", EMODULES_REVISION);
+  fprintf (mout, "const char *emodule_name = \"%s\";\n", SSTR(mod_name));
+  fprintf (mout, "const char *emodule_version = \"%s\";\n", SSTR(mod_version));
+  fprintf (mout, "const char *emodule_title = \"%s\";\n", SSTR(mod_title));
+  fprintf (mout, "\n\n");
+  fprintf (mout, "void docs_of_%s()\n", SSTR(mod_name));
+  fclose (mout);
+
+  sprintf (ts, "%s/make-docfile", ELLCC_ARCHDIR);
+  OVERENV(mdocprog, "ELLMAKEDOC", ts);
+  add_to_argv (mdocprog);
+  sprintf (ts, "-E %s", mod_output);
+  add_to_argv (ts);
+  for (i = 1; i < exec_argc; i++)
+    exec_argv[real_argc++] = strdup (prog_argv[exec_args[i]]);
+}
+
+#endif /* HAVE_SHLIB */
+
diff --git a/lib-src/ellcc.h.in b/lib-src/ellcc.h.in
new file mode 100644 (file)
index 0000000..7c3e49d
--- /dev/null
@@ -0,0 +1,33 @@
+/* DO NOT EDIT THIS FILE!!!! */
+
+/* Most of this is required due to a bug in the GCC compiler driver
+   which prevents us from passing this on the command line. It also
+   reduces the compiler command line length, which can be a problem
+   on some systems. */
+
+#ifndef ELLCC_HDR
+#define ELLCC_HDR
+
+#define ELLCC_CC            "@CC@"
+#define ELLCC_CFLAGS        "@CFLAGS@"
+#define ELLCC_CPPFLAGS      "@CPPFLAGS@"
+#define ELLCC_LDFLAGS       "@LDFLAGS@"
+#define ELLCC_CF_GENERAL    "@c_switch_general@"
+#define ELLCC_CF_ALL        "@c_switch_all@"
+#define ELLCC_LF_GENERAL    "@ld_switch_general@"
+#define ELLCC_LF_ALL        "@ld_switch_all@"
+#define ELLCC_LIBS_GENERAL  "@ld_libs_general@"
+#define ELLCC_DLL_CFLAGS    "@dll_cflags@"
+#define ELLCC_DLL_LDFLAGS   "@dll_ldflags@"
+#define ELLCC_DLL_POST      "@dll_post@"
+#define ELLCC_DLL_LD        "@dll_ld@"
+#define ELLCC_DLL_LDO       "@dll_ldo@"
+#define ELLCC_CONFIG        "@configuration@"
+#define ELLCC_EMACS_VER     "@version@"
+#define ELLCC_PROGNAME      "@PROGNAME@"
+#define ELLCC_ARCHDIR       "@ARCHLIBDIR@"
+#define ELLCC_MODDIR        "@MODULEDIR@"
+#define ELLCC_SITEMODS      "@SITEMODULEDIR@"
+
+#endif /* ELLCC_HDR */
+
index 467b388..79f79e1 100644 (file)
@@ -1,6 +1,7 @@
 /* Generate doc-string file for XEmacs from source files.
    Copyright (C) 1985, 1986, 1992, 1993, 1994 Free Software Foundation, Inc.
-   Copyright (C) 1995 Board of Trustees, University of Illinois
+   Copyright (C) 1995 Board of Trustees, University of Illinois.
+   Copyright (C) 1998, 1999 J. Kean Johnston.
 
 This file is part of XEmacs.
 
@@ -108,6 +109,9 @@ static int scan_lisp_file (CONST char *filename, CONST char *mode);
 /* Name this program was invoked with.  */
 char *progname;
 
+/* Set to 1 if this was invoked by ellcc */
+int ellcc = 0;
+
 /* Print error message.  `s1' is printf control string, `s2' is arg for it. */
 
 static void
@@ -213,6 +217,12 @@ main (int argc, char **argv)
       outfile = fopen (argv[i + 1], APPEND_BINARY);
       i += 2;
     }
+  if (argc > i + 1 && !strcmp (argv[i], "-E"))
+    {
+      outfile = fopen (argv[i + 1], APPEND_BINARY);
+      i += 2;
+      ellcc = 1;
+    }
   if (argc > i + 1 && !strcmp (argv[i], "-d"))
     {
       chdir (argv[i + 1]);
@@ -227,6 +237,9 @@ main (int argc, char **argv)
   if (outfile == 0)
     fatal ("No output file specified", "");
 
+  if (ellcc)
+    fprintf (outfile, "{\n");
+
   first_infile = i;
   for (; i < argc; i++)
     {
@@ -249,6 +262,8 @@ main (int argc, char **argv)
   }
 
   putc ('\n', outfile);
+  if (ellcc)
+    fprintf (outfile, "}\n\n");
 #ifndef VMS
   exit (err_count > 0);
 #endif /* VMS */
@@ -262,12 +277,12 @@ static int
 scan_file (CONST char *filename)
 {
   int len = strlen (filename);
-  if (len > 4 && !strcmp (filename + len - 4, ".elc"))
+  if (ellcc == 0 && len > 4 && !strcmp (filename + len - 4, ".elc"))
     {
       Current_file_type = elc_file;
       return scan_lisp_file (filename, READ_BINARY);
     }
-  else if (len > 3 && !strcmp (filename + len - 3, ".el"))
+  else if (ellcc == 0 && len > 3 && !strcmp (filename + len - 3, ".el"))
     {
       Current_file_type = el_file;
       return scan_lisp_file (filename, READ_TEXT);
@@ -314,7 +329,11 @@ read_c_string (FILE *infile, int printflag, int c_docstring)
              if (start != -1)
                {
                  if (printflag > 0)
-                   putc ('\n', outfile);
+            {
+              if (ellcc)
+                fprintf (outfile, "\\n\\");
+              putc ('\n', outfile);
+            }
                  else if (printflag < 0)
                    *p++ = '\n';
                }
@@ -339,8 +358,11 @@ read_c_string (FILE *infile, int printflag, int c_docstring)
          else
            {
              start = 0;
-             if (printflag > 0)
+             if (printflag > 0) {
+                if (ellcc && c == '"')
+                  putc ('\\', outfile);
                putc (c, outfile);
+              }
              else if (printflag < 0)
                *p++ = c;
            }
@@ -464,7 +486,8 @@ write_c_args (FILE *out, CONST char *func, char *buff, int minargs,
       need_space = 0;
 #endif
     }
-  putc ('\n', out); /* XEmacs addition */
+  if (!ellcc)
+    putc ('\n', out); /* XEmacs addition */
 }
 \f
 /* Read through a c file.  If a .o file is named,
@@ -639,9 +662,15 @@ scan_c_file (CONST char *filename, CONST char *mode)
 
       if (defunflag || defvarflag || c == '"')
        {
-         putc (037, outfile);
-         putc (defvarflag ? 'V' : 'F', outfile);
-         fprintf (outfile, "%s\n", buf);
+      if (ellcc)
+        fprintf (outfile, "  CDOC%s(\"%s\", \"\\\n",
+                 defvarflag ? "SYM" : "SUBR", buf);
+      else
+        {
+          putc (037, outfile);
+          putc (defvarflag ? 'V' : 'F', outfile);
+          fprintf (outfile, "%s\n", buf);
+        }
          c = read_c_string (infile, 1, (defunflag || defvarflag));
 
          /* If this is a defun, find the arguments and print them.  If
@@ -673,9 +702,14 @@ scan_c_file (CONST char *filename, CONST char *mode)
              while (c != ')');
              *p = '\0';
              /* Output them.  */
-             fprintf (outfile, "\n\n");
+          if (ellcc)
+            fprintf (outfile, "\\n\\\n\\n\\\n");
+          else
+            fprintf (outfile, "\n\n");
              write_c_args (outfile, buf, argbuf, minargs, maxargs);
            }
+      if (ellcc)
+        fprintf (outfile, "\\n\");\n\n");
        }
     }
  eof:
index fd578c0..7a91c6e 100644 (file)
@@ -79,7 +79,7 @@ extern char *optarg;
 extern int optind, opterr;
 
 #ifndef HAVE_STRERROR
-static char * strerror (int errnum);
+char * strerror (int errnum);
 #endif /* HAVE_STRERROR */
 
 #ifdef MSDOS
@@ -879,7 +879,7 @@ compile_regex (char* pattern)
 #endif /* MAIL_USE_POP */
 \f
 #ifndef HAVE_STRERROR
-static char *
+char *
 strerror (int errnum)
 {
   extern char *sys_errlist[];
index e70d07e..9f5d27b 100644 (file)
@@ -80,7 +80,7 @@
     (martin   "Martin Buchholz"   "martin@xemacs.org")
     (ograf    "Oliver Graf"       "ograf@fga.de")
     (pez      "Peter Pezaris"    "pez@dwwc.com")
-    (piper    "Andy Piper"        "andyp@parallax.co.uk")
+    (piper    "Andy Piper"        "andy@xemacs.org")
     (rickc    "Rick Campbell"     "rickc@lehman.com")
     (rossini  "Anthony Rossini"          "rossini@stat.sc.edu")
     (vin      "Vin Shelton"      "acs@acm.org")
@@ -88,7 +88,7 @@
     (slb      "SL Baur"           "steve@xemacs.org")
     (stig     "Jonathan Stigelman" "stig@hackvan.com")
     (stigb    "Stig Bjorlykke"   "stigb@tihlde.hist.no")
-    (thiessel "Marcus Thiessel"   "marcus_thiessel@hp.com")
+    (thiessel "Marcus Thiessel"   "marcus@xemacs.org")
     (vladimir "Vladimir Ivanovic" "vladimir@mri.com")
     (wing     "Ben Wing"          "ben@xemacs.org")
     (wmperry  "William Perry"     "wmperry@aventail.com"))
     (marcpa    . "http://www.positron911.com/products/power.htm")
     (ograf     . "http://www.fga.de/~ograf/")
     (pez       . "http://www.dwwc.com/")
-    (piper     . "http://www.parallax.co.uk/~andyp")
+    (piper     . "http://www.xemacs.freeserve.co.uk/")
     (vin       . "http://www.upa.org/")
     (stigb     . "http://www.tihlde.hist.no/~stigb/")
     (wget      . "ftp://gnjilux.cc.fer.hr/pub/unix/util/wget/")
@@ -817,15 +817,13 @@ He has a page at ")
      (widget-insert ".\n"))
     (thiessel
      (widget-insert "\
-Worked at University of Kaiserslautern where he took part in the 
-development and design of a CAD framework for analog integrated
-circuits with special emphasis on distributed software concepts. He 
-has now joined HP as technical consultant.  
-
-For XEmacs he does beta testing and tries to take care of XEmacs
-website at ")
-     (about-url-link 'xemacs "Visit XEmacs web site")
-     (widget-insert ".\n"))
+                      All of the buildings,
+                      all of the cars
+                      were once just a dream
+                      in somebody's head.\n
+                                     P. Gabriel\n\n
+")
+     (widget-insert "\n"))
     (sperber
      (widget-insert "\
 Mike ported EFS to XEmacs 20 and integrated EFS into XEmacs.  He's
@@ -1135,13 +1133,12 @@ XEmacs will speak Scheme.\n")
 Vin helps maintain the older, more mature (read: moldy) versions of
 XEmacs.  Vin has maintained the official XEmacs patch pages.\n")
     (about-show-linked-info 'thiessel "\
-On May 1, 1996 he started working at University of Kaiserslautern in
-the field of computer aided analog circuit design. His
-responsibilities include the development and design of a CAD-Tool for
-analog integrated circuits with special emphasis on distributed
-software concepts.
+Worked at University of Kaiserslautern where he took part in the 
+development and design of a CAD framework for analog integrated
+circuits with special emphasis on distributed software concepts. He 
+has now joined HP as technical consultant.  
 
-When all the daily hacking is done he tries to take care of XEmacs
+For XEmacs he does beta testing and tries to take care of XEmacs
 website at <http://www.xemacs.org>.\n")
     (about-show-linked-info 'ajc "\
 When not helping maintain the XEmacs website, Andrew is a Network
index 44f9221..c829284 100644 (file)
@@ -34,9 +34,9 @@
 
 (defun switch-to-buffer (bufname &optional norecord)
   "Select buffer BUFNAME in the current window.
-BUFNAME may be a buffer or a buffer name and is created if did not exist.
-Optional second arg NORECORD non-nil means
-do not put this buffer at the front of the list of recently selected ones.
+BUFNAME may be a buffer or a buffer name and is created if it did not exist.
+Optional second arg NORECORD non-nil means do not put this buffer at the
+front of the list of recently selected ones.
 
 WARNING: This is NOT the way to work on another buffer temporarily
 within a Lisp program!  Use `set-buffer' instead.  That avoids messing with
index b35f74f..db30575 100644 (file)
@@ -572,7 +572,7 @@ This is equivalent to `(return-from nil RESULT)'."
 ;;;###autoload
 (defmacro return-from (name &optional res)
   "(return-from NAME [RESULT]): return from the block named NAME.
-This jump out to the innermost enclosing `(block NAME ...)' form,
+This jumps out to the innermost enclosing `(block NAME ...)' form,
 returning RESULT from that form (or nil if RESULT is omitted).
 This is compatible with Common Lisp, but note that `defun' and
 `defmacro' do not create implicit blocks as they do in Common Lisp."
index b6baa29..28bb05d 100644 (file)
@@ -596,9 +596,10 @@ for use in the 'weight' field of an X font string.")
 ;;;###autoload
 (defun font-default-object-for-device (&optional device)
   (let ((font (font-default-font-for-device device)))
-    (unless (cdr-safe (assoc font font-default-cache))
-      (push (cons font (font-create-object font)) font-default-cache)
-      (cdr-safe (assoc font font-default-cache)))))
+    (or (cdr-safe (assoc font font-default-cache))
+       (let ((object (font-create-object font)))
+         (push (cons font object) font-default-cache)
+         object))))
 
 ;;;###autoload
 (defun font-default-family-for-device (&optional device)
index 7a06c6a..cad6f4f 100644 (file)
@@ -5,7 +5,7 @@
 ;; Author: Oscar Figueiredo <Oscar.Figueiredo@di.epfl.ch>
 ;; Maintainer: Oscar Figueiredo <Oscar.Figueiredo@di.epfl.ch>
 ;; Created: Jan 1998
-;; Version: $Revision: 1.7.2.2 $
+;; Version: $Revision: 1.7.2.3 $
 ;; Keywords: help comm
 
 ;; This file is part of XEmacs
@@ -35,9 +35,6 @@
 
 ;;; Code:
 
-(require 'ldap)
-(require 'custom)
-
 (defgroup ldap nil
   "Lightweight Directory Access Protocol"
   :group 'comm)
@@ -170,5 +167,7 @@ Additional search parameters can be specified through
                                 (plist-get host-plist 'scope)
                                 attributes attrsonly)
       (ldap-close ldap))))
+
+(provide 'ldap)
                
 ;;; ldap.el ends here
index 61188a9..ee86aa9 100644 (file)
     #'(lambda ()
        ;; message not defined yet ...
        (setq load-path (split-path (getenv "EMACSBOOTSTRAPLOADPATH")))
+       (setq module-load-path (split-path (getenv "EMACSBOOTSTRAPMODULEPATH")))
 
        (external-debugging-output (format "\nUsing load-path %s" load-path))
+       (external-debugging-output (format "\nUsing module-load-path %s" module-load-path))
 
        ;; We don't want to have any undo records in the dumped XEmacs.
        (buffer-disable-undo (get-buffer "*scratch*"))
index 6055b8f..4a8ad96 100644 (file)
@@ -67,7 +67,7 @@ The value may alternatively be a function, which is given three arguments:
   CODE, which says what kind of things to do.
 CODE can be nil, t or `lambda'.
 nil means to return the best completion of STRING, nil if there is none,
-  or t if it is was already a unique completion.
+  or t if it is already a unique completion.
 t means to return a list of all possible completions of STRING.
 `lambda' means to return t if STRING is a valid completion as it stands.")
 
index 7c07a20..5bd4db7 100644 (file)
@@ -1385,6 +1385,7 @@ and `mode-motion-hook'."
     (cond ((extentp help)
            (or inhibit-help-echo
                (eq help last-help-echo-object) ;save some time
+              (eq (selected-window) (minibuffer-window))
                (let ((hprop (extent-property help 'help-echo)))
                  (setq last-help-echo-object help)
                  (or (stringp hprop)
@@ -1395,11 +1396,12 @@ and `mode-motion-hook'."
                 (toolbar-button-enabled-p help))
           (or (not toolbar-help-enabled)
               (eq help last-help-echo-object) ;save some time
+              (eq (selected-window) (minibuffer-window))
               (let ((hstring (toolbar-button-help-string button)))
                 (setq last-help-echo-object help)
                 (or (stringp hstring)
                     (setq hstring (funcall hstring help)))
-                (show-help-echo hstring))))
+                (and hstring (show-help-echo hstring)))))
           (last-help-echo-object
           (clear-help-echo)))
     (if mouse-grabbed-buffer (setq buffer mouse-grabbed-buffer))
index dcc62a5..2c99440 100644 (file)
@@ -38,7 +38,9 @@
 (defvar package-admin-temp-buffer "*Package Output*"
   "Temporary buffer where output of backend commands is saved.")
 
-(defvar package-admin-install-function 'package-admin-default-install-function
+(defvar package-admin-install-function (if (eq system-type 'windows-nt)
+                                          'package-admin-install-function-mswindows
+                                        'package-admin-default-install-function)
   "The function to call to install a package.
 Three args are passed: FILENAME PKG-DIR BUF
 Install package FILENAME into directory PKG-DIR, with any messages output
@@ -126,7 +128,7 @@ The optional `pkg-dir' can be used to override the default package hierarchy
   (let ((default-directory (file-name-as-directory pkg-dir)))
     (unless (file-directory-p default-directory)
       (make-directory default-directory t))
-    (call-process "djtar" nil buf t "-x" file)))
+    (call-process "minitar" nil buf t file)))
 
 (defun package-admin-default-install-function (file pkg-dir buf)
   "Default function to install a package.
index 646aae7..3acf44e 100644 (file)
@@ -198,7 +198,7 @@ order until the package is found.  As a special case, `site-name' can be
     ("uniroma2.it" "ftp.uniroma2.it" "unix/misc/dist/XEMACS/packages")
     ("icm.edu.pl" "ftp.icm.edu.pl" "pub/unix/editors/xemacs/packages")
     ("sunet.se" "ftp.sunet.se" "pub/gnu/xemacs/packages")
-    ("doc.ic.ac.uk" "ftp.doc.ic.ac.uk" "packages/xemacs/packages")
+    ("doc.ic.ac.uk" "sunsite.doc.ic.ac.uk" "packages/xemacs/packages")
     ("srcc.msu.su" "ftp1.srcc.msu.su" "mirror/ftp.xemacs.org/packages")
 
     ;; Asia
index dd84f83..3b6165e 100644 (file)
@@ -53,6 +53,20 @@ or if the replacement text has any uppercase letters in it.")
   "Non-nil means `query-replace' uses the last search string.
 That becomes the \"string to replace\".")
 
+(defvar replace-search-function
+  (lambda (str limit)
+    (search-forward str limit t))
+  "Function used by perform-replace to search forward for a string. It will be 
+called with two arguments: the string to search for and a limit bounding the
+search.")
+
+(defvar replace-re-search-function
+  (lambda (regexp limit)
+    (re-search-forward regexp limit t))
+  "Function used by perform-replace to search forward for a regular
+expression. It will be called with two arguments: the regexp to search for and
+a limit bounding the search.")
+
 (defun query-replace-read-args (string regexp-flag)
   (let (from to)
     (if query-replace-interactive
@@ -209,24 +223,25 @@ Applies to all lines after point."
   (interactive (list (read-from-minibuffer
                      "Keep lines (containing match for regexp): "
                      nil nil nil 'regexp-history)))
-  (save-excursion
-    (or (bolp) (forward-line 1))
-    (let ((start (point)))
-      (while (not (eobp))
-       ;; Start is first char not preserved by previous match.
-       (if (not (re-search-forward regexp nil 'move))
-           (delete-region start (point-max))
-         (let ((end (save-excursion (goto-char (match-beginning 0))
-                                    (beginning-of-line)
-                                    (point))))
-           ;; Now end is first char preserved by the new match.
-           (if (< start end)
-               (delete-region start end))))
-       (setq start (save-excursion (forward-line 1)
-                                   (point)))
-       ;; If the match was empty, avoid matching again at same place.
-       (and (not (eobp)) (= (match-beginning 0) (match-end 0))
-            (forward-char 1))))))
+  (with-interactive-search-caps-disable-folding regexp t
+    (save-excursion
+      (or (bolp) (forward-line 1))
+      (let ((start (point)))
+       (while (not (eobp))
+         ;; Start is first char not preserved by previous match.
+         (if (not (re-search-forward regexp nil 'move))
+             (delete-region start (point-max))
+           (let ((end (save-excursion (goto-char (match-beginning 0))
+                                      (beginning-of-line)
+                                      (point))))
+             ;; Now end is first char preserved by the new match.
+             (if (< start end)
+                 (delete-region start end))))
+         (setq start (save-excursion (forward-line 1)
+                                     (point)))
+         ;; If the match was empty, avoid matching again at same place.
+         (and (not (eobp)) (= (match-beginning 0) (match-end 0))
+              (forward-char 1)))))))
 
 (define-function 'flush-lines 'delete-matching-lines)
 (defun delete-matching-lines (regexp)
@@ -236,13 +251,14 @@ Applies to lines after point."
   (interactive (list (read-from-minibuffer
                      "Flush lines (containing match for regexp): "
                      nil nil nil 'regexp-history)))
-  (save-excursion
-    (while (and (not (eobp))
-               (re-search-forward regexp nil t))
-      (delete-region (save-excursion (goto-char (match-beginning 0))
-                                    (beginning-of-line)
-                                    (point))
-                    (progn (forward-line 1) (point))))))
+  (with-interactive-search-caps-disable-folding regexp t
+    (save-excursion
+      (while (and (not (eobp))
+                 (re-search-forward regexp nil t))
+       (delete-region (save-excursion (goto-char (match-beginning 0))
+                                      (beginning-of-line)
+                                      (point))
+                      (progn (forward-line 1) (point)))))))
 
 (define-function 'how-many 'count-matches)
 (defun count-matches (regexp)
@@ -250,15 +266,16 @@ Applies to lines after point."
   (interactive (list (read-from-minibuffer
                      "How many matches for (regexp): "
                      nil nil nil 'regexp-history)))
-  (let ((count 0) opoint)
-    (save-excursion
-     (while (and (not (eobp))
-                (progn (setq opoint (point))
-                       (re-search-forward regexp nil t)))
-       (if (= opoint (point))
-          (forward-char 1)
-        (setq count (1+ count))))
-     (message "%d occurrences" count))))
+  (with-interactive-search-caps-disable-folding regexp t
+    (let ((count 0) opoint)
+      (save-excursion
+       (while (and (not (eobp))
+                   (progn (setq opoint (point))
+                          (re-search-forward regexp nil t)))
+         (if (= opoint (point))
+             (forward-char 1)
+           (setq count (1+ count))))
+       (message "%d occurrences" count)))))
 
 \f
 (defvar occur-mode-map ())
@@ -445,84 +462,86 @@ It serves as a menu to find any of the occurrences in this buffer.
        (setq occur-pos-list ()))
       (if (eq buffer standard-output)
          (goto-char (point-max)))
-      (save-excursion
-       (if list-matching-lines-whole-buffer
-           (beginning-of-buffer))
-       (message "Searching for %s ..." regexp)
-       ;; Find next match, but give up if prev match was at end of buffer.
-       (while (and (not (= prevpos (point-max)))
-                   (re-search-forward regexp nil t))
-         (goto-char (match-beginning 0))
-         (beginning-of-line)
-         (save-match-data
-            (setq linenum (+ linenum (count-lines prevpos (point)))))
-         (setq prevpos (point))
-         (goto-char (match-end 0))
-         (let* ((start (save-excursion
-                         (goto-char (match-beginning 0))
-                         (forward-line (if (< nlines 0) nlines (- nlines)))
-                         (point)))
-                (end (save-excursion
-                       (goto-char (match-end 0))
-                       (if (> nlines 0)
-                           (forward-line (1+ nlines))
+      (with-interactive-search-caps-disable-folding regexp t
+       (save-excursion
+         (if list-matching-lines-whole-buffer
+             (beginning-of-buffer))
+         (message "Searching for %s ..." regexp)
+         ;; Find next match, but give up if prev match was at end of buffer.
+         (while (and (not (= prevpos (point-max)))
+                     (re-search-forward regexp nil t))
+           (goto-char (match-beginning 0))
+           (beginning-of-line)
+           (save-match-data
+             (setq linenum (+ linenum (count-lines prevpos (point)))))
+           (setq prevpos (point))
+           (goto-char (match-end 0))
+           (let* ((start (save-excursion
+                           (goto-char (match-beginning 0))
+                           (forward-line (if (< nlines 0) nlines (- nlines)))
+                           (point)))
+                  (end (save-excursion
+                         (goto-char (match-end 0))
+                         (if (> nlines 0)
+                             (forward-line (1+ nlines))
                            (forward-line 1))
-                       (point)))
-                (tag (format "%5d" linenum))
-                (empty (make-string (length tag) ?\ ))
-                tem)
-           (save-excursion
-             (setq tem (make-marker))
-             (set-marker tem (point))
-             (set-buffer standard-output)
-             (setq occur-pos-list (cons tem occur-pos-list))
-             (or first (zerop nlines)
-                 (insert "--------\n"))
-             (setq first nil)
-             (insert-buffer-substring buffer start end)
-             (set-marker final-context-start 
-                         (- (point) (- end (match-end 0))))
-             (backward-char (- end start))
-             (setq tem (if (< nlines 0) (- nlines) nlines))
-             (while (> tem 0)
-               (insert empty ?:)
-               (forward-line 1)
-               (setq tem (1- tem)))
-             (let ((this-linenum linenum))
-               (while (< (point) final-context-start)
-                 (if (null tag)
-                     (setq tag (format "%5d" this-linenum)))
-                 (insert tag ?:)
-;; FSFmacs -- we handle this using mode-motion-highlight-line, above.
-;                (put-text-property (save-excursion
-;                                     (beginning-of-line)
-;                                     (point))
-;                                   (save-excursion
-;                                     (end-of-line)
-;                                     (point))
-;                                   'mouse-face 'highlight)
+                         (point)))
+                  (tag (format "%5d" linenum))
+                  (empty (make-string (length tag) ?\ ))
+                  tem)
+             (save-excursion
+               (setq tem (make-marker))
+               (set-marker tem (point))
+               (set-buffer standard-output)
+               (setq occur-pos-list (cons tem occur-pos-list))
+               (or first (zerop nlines)
+                   (insert "--------\n"))
+               (setq first nil)
+               (insert-buffer-substring buffer start end)
+               (set-marker final-context-start 
+                           (- (point) (- end (match-end 0))))
+               (backward-char (- end start))
+               (setq tem (if (< nlines 0) (- nlines) nlines))
+               (while (> tem 0)
+                 (insert empty ?:)
                  (forward-line 1)
-                 (setq tag nil)
-                 (setq this-linenum (1+ this-linenum)))
-               (while (<= (point) final-context-start)
+                 (setq tem (1- tem)))
+               (let ((this-linenum linenum))
+                 (while (< (point) final-context-start)
+                   (if (null tag)
+                       (setq tag (format "%5d" this-linenum)))
+                   (insert tag ?:)
+                   ;; FSFmacs -- 
+                   ;; we handle this using mode-motion-highlight-line, above.
+                   ;;            (put-text-property (save-excursion
+                   ;;                                 (beginning-of-line)
+                   ;;                                 (point))
+                   ;;                               (save-excursion
+                   ;;                                 (end-of-line)
+                   ;;                                 (point))
+                   ;;                               'mouse-face 'highlight)
+                   (forward-line 1)
+                   (setq tag nil)
+                   (setq this-linenum (1+ this-linenum)))
+                 (while (<= (point) final-context-start)
+                   (insert empty ?:)
+                   (forward-line 1)
+                   (setq this-linenum (1+ this-linenum))))
+               (while (< tem nlines)
                  (insert empty ?:)
                  (forward-line 1)
-                 (setq this-linenum (1+ this-linenum))))
-             (while (< tem nlines)
-               (insert empty ?:)
-               (forward-line 1)
-               (setq tem (1+ tem)))
-             (goto-char (point-max)))
-           (forward-line 1)))
-       (set-buffer standard-output)
-       ;; Put positions in increasing order to go with buffer.
-       (setq occur-pos-list (nreverse occur-pos-list))
-       (goto-char (point-min))
-       (if (= (length occur-pos-list) 1)
-           (insert "1 line")
-         (insert (format "%d lines" (length occur-pos-list))))
-       (if (interactive-p)
-           (message "%d matching lines." (length occur-pos-list)))))))
+                 (setq tem (1+ tem)))
+               (goto-char (point-max)))
+             (forward-line 1)))
+         (set-buffer standard-output)
+         ;; Put positions in increasing order to go with buffer.
+         (setq occur-pos-list (nreverse occur-pos-list))
+         (goto-char (point-min))
+         (if (= (length occur-pos-list) 1)
+             (insert "1 line")
+           (insert (format "%d lines" (length occur-pos-list))))
+         (if (interactive-p)
+             (message "%d matching lines." (length occur-pos-list))))))))
 \f
 ;; It would be nice to use \\[...], but there is no reasonable way
 ;; to make that display both SPC and Y.
@@ -604,14 +623,17 @@ Don't use this in your own program unless you want to query and set the mark
 just as `query-replace' does.  Instead, write a simple loop like this:
   (while (re-search-forward \"foo[ \t]+bar\" nil t)
     (replace-match \"foobar\" nil nil))
-which will run faster and probably do exactly what you want."
+which will run faster and probably do exactly what you want.
+When searching for a match, this function use `replace-search-function' and `replace-re-search-function'"
   (or map (setq map query-replace-map))
   (let* ((event (make-event))
         (nocasify (not (and case-fold-search case-replace
                            (string-equal from-string
                                          (downcase from-string)))))
         (literal (not regexp-flag))
-        (search-function (if regexp-flag 're-search-forward 'search-forward))
+        (search-function (if regexp-flag 
+                             replace-re-search-function 
+                           replace-search-function))
         (search-string from-string)
         (real-match-data nil)          ; the match data for the current match
         (next-replacement nil)
@@ -646,7 +668,7 @@ which will run faster and probably do exactly what you want."
        (setq next-replacement replacements)
       (or repeat-count (setq repeat-count 1)))
     (if delimited-flag
-       (setq search-function 're-search-forward
+       (setq search-function replace-re-search-function
              search-string (concat "\\b"
                                    (if regexp-flag from-string
                                      (regexp-quote from-string))
@@ -658,7 +680,7 @@ which will run faster and probably do exactly what you want."
        (while (and keep-going
                    (not (eobp))
                    (let ((case-fold-search qr-case-fold-search))
-                     (funcall search-function search-string limit t))
+                     (funcall search-function search-string limit))
                    ;; If the search string matches immediately after
                    ;; the previous match, but it did not match there
                    ;; before the replacement was done, ignore the match.
@@ -672,7 +694,7 @@ which will run faster and probably do exactly what you want."
                          ;; right after end of previous replacement.
                          (forward-char 1)
                          (let ((case-fold-search qr-case-fold-search))
-                           (funcall search-function search-string limit t)))
+                           (funcall search-function search-string limit)))
                      t))
 
          ;; Save the data associated with the real match.
index 824e2db..df593f8 100644 (file)
@@ -68,7 +68,7 @@
     (otherwise nil)))
 
 (defun selection-owner-p (&optional selection)
-  "Return t if current emacs process owns the given Selection.
+  "Return t if current XEmacs process owns the given Selection.
 The arg should be the name of the selection in question, typically one
 of the symbols PRIMARY, SECONDARY, or CLIPBOARD.  (For convenience,
 the symbol nil is the same as PRIMARY, and t is the same as
@@ -249,7 +249,7 @@ secondary selection instead of the primary selection."
 (defun cut-copy-clear-internal (mode)
   (or (memq mode '(cut copy clear)) (error "unkown mode %S" mode))
   (or (selection-owner-p)
-      (error "emacs does not own the primary selection"))
+      (error "XEmacs does not own the primary selection"))
   (setq last-command nil)
   (or primary-selection-extent
       (error "the primary selection is not an extent?"))
index 76d638f..faac28f 100644 (file)
@@ -293,17 +293,15 @@ or if the window is the only window of its frame."
                      (unwind-protect
                          (count-windows)
                        (select-frame frame))))
-              ;; check to make sure that we don't have horizontally
-              ;; split windows
-              (eq (frame-highest-window (window-frame window) 0)
-                  (frame-highest-window (window-frame window) -1))
+              ;; check to make sure that the window is the full width
+              ;; of the frame
+              (eq (nth 2 edges)
+                  (frame-pixel-width))
+              (zerop (nth 0 edges))
+              ;; The whole buffer must be visible.
               (pos-visible-in-window-p (point-min) window)
-              (not (eq mini 'only))
-              (or (not mini) (eq mini t)
-                  (< (nth 3 edges)
-                     (nth 1 (window-pixel-edges mini)))
-                  (> (nth 1 edges)
-                     0)))
+              ;; The frame must not be minibuffer-only.
+              (not (eq mini 'only)))
          (progn
            (save-window-excursion
              (goto-char (point-min))
index ce72582..779dde5 100644 (file)
@@ -1,3 +1,17 @@
+1999-02-02  XEmacs Build Bot <builds@cvs.xemacs.org>
+
+       * XEmacs 21.2.9 is released
+
+1999-01-14  Adrian Aichner  <aichner@ecf.teradyne.com>
+
+       * internals\internals.texi (Techniques for XEmacs Developers):
+       Fixing documentation.
+       (Basic Lisp Modules): ditto.
+
+1999-01-10  J. Kean Johnston  <jkj@sco.com>
+
+       * emodules.texi: New file to describe XEmacs modules.
+
 1998-12-28  Martin Buchholz <martin@xemacs.org>
 
        * XEmacs 21.2.8 is released.
diff --git a/man/emodules.texi b/man/emodules.texi
new file mode 100644 (file)
index 0000000..d20ccfb
--- /dev/null
@@ -0,0 +1,1006 @@
+\input texinfo  @c -*-texinfo-*-
+
+@c %**start of header
+@setfilename ../info/emodules.info
+@settitle Extending Emacs using C Modules
+@c %**end of header
+
+@c
+@c Use some macros so that we can format for either XEmacs
+@c or (shudder) GNU Emacs.
+@c
+
+@ifset XEMACS
+@macro emacs
+XEmacs
+@end macro
+@clear EMACS
+@set HAVE_EMACS
+@end ifset
+
+@ifset EMACS
+@macro emacs
+Emacs
+@end macro
+@clear XEMACS
+@set HAVE_EMACS
+@end ifset
+
+@ifclear HAVE_EMACS
+@set XEMACS
+@macro emacs
+XEmacs
+@end macro
+@end ifclear
+
+@ifinfo
+This file documents the module loading technology of @emacs{}.
+
+Copyright @copyright{} 1998 J. Kean Johnston.
+
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission notice
+identical to this one except for the removal of this paragraph (this
+paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation
+approved by the Foundation.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that the
+section entitled ``GNU General Public License'' is included exactly as
+in the original, and provided that the entire resulting derived work is
+distributed under the terms of a permission notice identical to this
+one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that the section entitled ``GNU General Public License'' may be
+included in a translation approved by the Free Software Foundation
+instead of in the original English.
+@end ifinfo
+
+@c Combine indices.
+@syncodeindex fn cp
+@syncodeindex vr cp
+@syncodeindex ky cp
+@syncodeindex pg cp
+@syncodeindex tp cp
+
+@setchapternewpage odd
+@finalout
+
+@titlepage
+@title Extending @emacs{} using C and C++
+@subtitle Version 1.0, September 1998
+
+@author J. Kean Johnston
+@page
+@vskip 0pt plus 1fill
+
+@noindent
+Copyright @copyright{} 1998 J. Kean Johnston. @*
+
+@sp 2
+Version 1.0 @*
+September, 1998.@*
+
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that the
+section entitled ``GNU General Public License'' is included
+exactly as in the original, and provided that the entire resulting
+derived work is distributed under the terms of a permission notice
+identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that the section entitled ``GNU General Public License'' may be
+included in a translation approved by the Free Software Foundation
+instead of in the original English.
+@end titlepage
+@page
+
+@ifinfo
+@node Top, Introduction, (dir), (dir)
+This Info file contains v1.0 of the @emacs{} dynamic loadable module
+support documentation.
+@menu
+* Introduction::                Introducing Emacs Modules
+* Annatomy of a Module::        Basic module layout and technology
+* Using ellcc::                 How to use the module compiler
+* Defining Functions::          Creating new Lisp primitives
+* Defining Variables::          Creating new Lisp variables
+* Index::                       Concept Index
+
+ --- The Detailed Node Listing ---
+
+Annatomy of a Module
+
+* Required Header File::        Always include <emodules.h>
+* Required Functions::          Functions you must always provide
+* Required Variables::          Variables whose values you must provide
+* Loading other Modules::       How to load dependant modules
+
+Using @code{ellcc}
+
+* Compile Mode::                Compiling modules using ellcc
+* Initialization Mode::         Generating documentation and variables
+* Link Mode::                   Creating the final loadable module
+* Other ellcc options::         Other useful options
+* Environment Variables::       How to control ellcc
+
+Defining Functions
+
+* Using DEFUN::                 Using the DEFUN macro to define functions
+* Declaring Functions::         Declaring functions to the Lisp reader
+@end menu
+
+@end ifinfo
+
+@node Introduction, Annatomy of a Module, Top, Top
+@chapter Introduction
+
+  @emacs{} is a powerful, extensible editor.  The traditional way of
+extending the functionality of @emacs{} is to use its built-in Lisp
+language (called Emacs Lisp, or Elisp for short).  However, while Elisp
+is a full programming language and capable of extending @emacs{} in more
+ways than you can imagine, it does have its short-comings.
+
+  Firstly, Elisp is an interpreted language, and this has serious speed
+implications.  Like all other interpreted languages (like Java), Elisp
+is often suitable only for certain types of application or extension.
+So although Elisp is a general purpose language, and very ligh level,
+there are times when it is desirable to descend to a lower level compiled 
+language for speed purposes.
+
+  Secondly, Elisp (or Lisp in general) is not a very common language any
+more, except for certain circles in the computer industry.  C is a far
+more commonly known language, and because it is compiled, more suited to 
+a wider range of applications, especially those that require low level
+access to a system or need to be as quick as possible.
+
+@cindex Emacs Modules
+@cindex DLL
+@cindex DSO
+@cindex shared object
+  This manual describes a new way of extending @emacs{}, by using dynamic
+loadable modules (also knows as dynamicaly loadable libraries (DLLs),
+dynamic shared objects (DSOs) or just simply shared objectcs), which can 
+be written in C or C++ and loaded into @emacs{} at any time.  I sometimes
+refer to this technology as @dfn{CEmacs}, which is short for @dfn{C
+Extensible Emacs}.
+
+  @emacs{} modules are configured into and installed with @emacs{} by
+default on all systems that support loading of shared objects.  From a
+users perspective, the internals of @emacs{} modules are irrelevant.
+All a user will ever need to know about shared objects is the name of
+the shared object when they want to load a given module.  From a
+developers perspective though, a lot more is provided.
+
+@itemize @bullet
+@item
+@pindex ellcc
+@cindex compiler
+@cindex linker
+  Of primary interest is the @code{ellcc} program.  This program is
+created during compile time, and is intended to abstract compiler
+specific characteristics from the developer.  This program is called to
+compile and link all objects that will make up the final shared object,
+and accepts all common C compiler flags.  @code{ellcc} also sets up the
+correct environment for compiling modules by enabling any special
+compiler modes (such as PIC mode), setting the correct include paths for 
+the location of @emacs{} internal header files etc.  The program will also
+invoke the linker correctly to created the final shared object which is
+loaded into @emacs{}.
+
+@item
+@cindex header files
+  CEmacs also makes all of the relevant @emacs{} internal header files
+availible for module authors to use.  This is often required to get data 
+structure definitions and external variable declarations.  The header
+files installed include the module specific header file
+@file{emodules.h}.  Due to the nature of dynamic modules, most of the
+internals of @emacs{} are exposed.
+@xref{Top,,,internals,@emacs{} Internals Manual}, for a 
+more complete discussion on how to extend and understand @emacs{}.  All of 
+the rules for C modules are discussed there.
+
+@item
+@cindex samples
+  Part of the @emacs{} distribution is a set of sample modules.  These are
+not installed when @emacs{} is, but remain in the @emacs{} source tree.
+These modules live in the directory @file{modules}, which is a
+sub-directory of the main @emacs{} source code directory.  Please look at
+the samples carefully, and maybe even use them as a basis for making
+your own modules.  Most of the concepts required for writing extension
+modules are covered in the samples.
+
+@item
+@cindex documentation
+@cindex help
+  Last, but not least is this manual.  This can be viewed from within
+@emacs{}, and it can be printed out as well.  It is the intention of this
+document that it will describe everything you need to know about
+extending @emacs{} in C.  If you do not find this to be the case, please
+contact the author(s).
+@end itemize
+
+  The rest of this document will discuss the actual mechanics of
+@emacs{} modules and work through several of the samples.  Please be
+sure that you have read the @emacs{} Internals Manual and understand
+everything in it.  The concepts there apply to all modules.  This
+document may have some overlap, but it is the internals manual which
+should be considered the final authority.  It will also help a great
+deal to look at the actual @emacs{} source code to see how things are
+done.
+
+@node Annatomy of a Module, Using ellcc, Introduction, Top
+@chapter Annatomy of a Module
+@cindex annatomy
+@cindex module skeleton
+@cindex skeleton, module
+@cindex module format
+@cindex format, module
+
+  Each dynamically loadable @emacs{} extension (hereafter refered to as a
+module) has a certain compulsory format, and must contain several 
+pieces of information and several mandatory functions.  This chapter 
+describes the basic layout of a module, and provides a very simple
+sample.  The source for this sample can be found in the file
+@file{modules/simple/sample.c} in the main @emacs{} source code tree.
+
+@menu
+* Required Header File::        Always include <emodules.h>
+* Required Functions::          Functions you must always provide
+* Required Variables::          Variables whose values you must provide
+* Loading other Modules::       How to load dependant modules
+@end menu
+
+@node Required Header File, Required Functions, Annatomy of a Module, Annatomy of a Module
+@section Required Header File
+@cindex required header
+@cindex include files
+
+@cindex emodules.h
+@cindex config.h
+  Every module must include the file @file{<emodules.h>}.  This
+will include several other @emacs{} internal header files, and will set up 
+certain vital macros.  One of the most important files included by
+@file{emodules.h} is the generated @file{config.h} file, which contains
+all of the required system abstraction macros and definitions.  Most
+modules will probably require some pre-processor conditionals based on
+constants defined in @file{config.h}.  Please read that file to
+familiarize yourself with the macros defined there.
+
+  Depending on exactly what your module will be doing, you will probably 
+need to include one or more of the @emacs{} internal header files.  When
+you @code{#include <emodules.h>}, you will get a few of the most important 
+@emacs{} header files included automatically for you.  The files included
+are:
+
+@table @file
+@item lisp.h
+This file contains most of the macros required for declaring Lisp object 
+types, macros for accessing Lisp objects, and global variable
+declarations.
+
+@item sysdep.h
+All system dependant declarations and abstraction macros live here.  You 
+should never call low level system functions directly.  Rather, you
+should use the abstraction macros provided in this header file.
+
+@item window.h
+This header file defines the window structures and Lisp types, and
+provides functions and macros for manipulating multiple @emacs{} windows.
+
+@item buffer.h
+All macros and function declarations for manipulating internal and user
+visible buffers appear in this file.
+
+@item insdel.h
+This header provides the information required for performing text
+insertion and deletion.
+
+@item frame.h
+Provides the required structure, macro and function definitions for
+manipulating @emacs{} frames.
+@end table
+
+@node Required Functions, Required Variables, Required Header File, Annatomy of a Module
+@section Required Functions
+@cindex initialization
+@cindex functions, required
+@cindex required functions
+
+Every module requires several initialization functions.  It is the
+responsibility of these functions to load in any dependant modules, and to 
+declare all variables and functions which are to be made visibile to the 
+@emacs{} Lisp reader.  Each of these functions performs a very specific
+task, and they are executed in the correct order by @emacs{}.  All of
+these functions are @code{void} functions which take no arguments.
+Here, briefly, are the required module functions.  Note that the actual
+function names do not end with the string @code{_module}, but rather
+they end with the abbreviated module name by which the module is known.
+More on the module name and its importance later.  Just bear in mind
+that the text @code{_module} in the functions below is simply a
+place-holder, not an actual function name.
+
+@table @code
+@item syms_of_module
+@findex syms_of_module
+This required function is responsible for introducing to the Lisp reader 
+all functions that you have defined in your module using
+@code{DEFUN()}.  Note that @emph{only} functions are declared here, using
+the @code{DEFSUBR()} macro.  No variables are declared.
+
+@item vars_of_module
+@findex vars_of_module
+This required function contains calls to macros such as
+@code{DEFVAR_LISP()}, @code{DEFVAR_BOOL()} etc, and its purpose is to
+declare and initialize all and any variables that your module defines.
+They syntax for declaring variables is identical to the syntax used for
+all internal @emacs{} source code.
+
+@item modules_of_module
+@findex modules_of_module
+This optional function should be used to load in any modules which your
+module depends on.  The @emacs{} module loading code makes sure that the 
+same module is not loaded twice, so several modules can safely call the
+module load function for the same module.  Only one copy of each module
+(at a given version) will ever be loaded.
+
+@item docs_of_module
+@findex docs_of_module
+This is a required function, but not one which you need ever write.
+This function is created automatically by @code{ellcc} when the module
+initialization code is produced.  It is required to document all
+functions and variables declared in your module.
+@end table
+
+@node Required Variables, Loading other Modules, Required Functions, Annatomy of a Module
+@section Required Variables
+@cindex initialization
+@cindex variables, required
+@cindex required variables
+
+Not only does a module need to declare the initialization functions
+mentioned above, it is also required to provide certain variables which
+the module loading code searches for in order to determine the viability 
+of a module.  You are @emph{not} required to provide these variables in
+your source files.  They are automatically set up in the module
+initialization file by the @code{ellcc} compiler.  These variables are
+discussed here simply for the sake of completeness.
+
+@table @code
+@item emodules_compiler
+This is a variable of type @code{long}, and is used to indicate the
+version of the @emacs{} loading technology that was used to produce the
+module being loaded.  This version number is completely unrelated to
+the @emacs{} version number, as a given module may quite well work
+regardless of the version of @emacs{} that was installed at the time the 
+module was created.
+
+The @emacs{} modules version is used to differentiate between major
+changes in the module loading technology, not versions of @emacs{}.
+
+@item emodules_name
+This is a short (typically 10 characters or less) name for the module,
+and it is used as a suffix for all of the required functions.  This is
+also the name by which the module is recognised when loading dependant
+modules.  The name does not necessarily have to be the same as the
+physical file name, although keeping the two names in sync is a pretty
+good idea.  The name must not be empty, and it must be a valid part of a 
+C function name.  The value of this variable is appended to the function 
+names @code{syms_of_}, @code{vars_of_}, @code{modules_of_} and
+@code{docs_of_} to form the actual function names that the module
+loading code looks for when loading a module.
+
+This variable is set by the @code{--mod-name} argument to @code{ellcc}.
+
+@item emodules_version
+This string variable is used to load specific versions of a module.
+Rarely will two or more versions of a module be left lying around, but
+just in case this does happen, this variable can be used to control
+exactly which module should be loaded.  See the Lisp function
+@code{load-module} for more details.  This variable is set by the
+@code{--mod-version} argument to @code{ellcc}.
+
+@item emodules_title
+This is a string which describes the module, and can contain spaces or
+other special characters.  It is used solely for descriptive purposes,
+and does not affect the loading of the module.  The value is set by the
+@code{--mod-title} argument to @code{ellcc}.
+@end table
+
+@node Loading other Modules,  , Required Variables, Annatomy of a Module
+@section Loading other Modules
+@cindex dependancies
+@findex modules_of_module
+@findex emodules_load
+
+During the loading of a module, it is the responsibility of the function
+@code{modules_of_module} to load in any modules which the current module
+depends on.  If the module is stand-alone, and does not depend on other
+modules, then this function can be left empty or even undeclared.
+However, if it does have dependnacies, it must call
+@code{emodules_load}:
+
+@example @code
+@cartouche
+int emodules_load (CONST char *module,
+                   CONST char *modname,
+                   CONST char *modver)
+@end cartouche
+@end example
+
+The first argument @var{module} is the name of the actual shared object 
+or DLL.  You can omit the @file{.so}, @file{.ell} or @file{.dll}
+extension of you wish.  If you do not specify an absolute path name,
+then the same rules as apply to loading Lisp modules are applied when
+searching for the module.  If the module cannot be found in any of the
+standard places, and an absolute path name was not specified,
+@code{emodules_load} will signal an error and loading of the module 
+will stop.
+
+The second argument (@var{modname}) is the module name to load, and
+must match the contents of the variable @var{emodule_name} in the
+module to be loaded. A mis-match will cause the module load to fail.  If 
+this parameter is @code{NULL} or empty, then no checks are performed
+against the target module's @var{emodule_name} variable.
+
+The last argument, @var{modver}, is the desired version of the module
+to load, and is compared to the target module's
+@var{emodule_version} value.  If this parameter is not @code{NULL}
+or empty, and the match fails, then the load of the module will fail.
+
+@code{emodules_load} can be called recursively.  If, at any point
+during the loading of modules a failure is encountered, then all modules 
+that were loaded since the top level call to @code{emodules_load}
+will be unloaded.  This means that if any child modules fail to load,
+then their parents will also fail to load.  This does not include
+previous successful calls to @code{emodules_load} at the top level.
+
+@node Using ellcc, Defining Functions, Annatomy of a Module, Top
+@chapter Using @code{ellcc}
+@cindex @code{ellcc}
+@cindex module compiler
+
+Before discussing the anatomy of a module in greater detail, you should
+be aware of the steps required in order to correctly compile and link a
+module for use within @emacs{}.  There is little difference between
+compiling normal C code and compiling a module.  In fact, all that
+changes is the command used to compile the module, and a few extra
+arguments to the compiler.
+
+@emacs{} now ships with a new user utility, called @code{ellcc}.  This
+is the @dfn{Emacs Loadable Library C Compiler}.  This is a wrapper
+program that will invoke the real C compiler with the correct arguments
+to compile and link your module.  With the exception of a few command
+line options, this program can be considered a replacement for your C
+compiler.  It accepts all of the same flags and arguments that your C
+compiler does, so in many cases you can simply set the @code{make}
+variable @code{CC} to @code{ellcc} and your code will be compiled as
+an Emacs module rather than a static C object.
+
+@code{ellcc} has three distinct modes of operation.  It can be run in
+compile, link or initialization mode.  These modes are discussed in more 
+detail below.  If you want @code{ellcc} to show the commands it is
+executing, you can specify the option @code{--mode=verbose} to
+@code{ellcc}.  Specifying this option twice will enable certain extra
+debugging messages to be displayed on the standard output.
+
+@menu
+* Compile Mode::                Compiling modules using ellcc
+* Initialization Mode::         Generating documentation and variables
+* Link Mode::                   Creating the final loadable module
+* Other ellcc options::         Other useful options
+* Environment Variables::       How to control ellcc
+@end menu
+
+@node Compile Mode, Initialization Mode, Using ellcc, Using ellcc
+@section Compile Mode
+@cindex compiling
+
+By default, @code{ellcc} is in @dfn{compile} mode.  This means that it
+assumes that all of the command line arguments are C compiler arguments, 
+and that you want to compile the specified source file or files.  You
+can force compile mode by specifying the @code{--mode=compile} argument
+to @code{ellcc}.
+
+In this mode, @code{ellcc} is simply a front-end to the same C compiler
+that was used to create the @emacs{} binary itself.  All @code{ellcc}
+does in this mode is insert a few extra command line arguments before
+the arguments you specify to @code{ellcc} itself.  @code{ellcc} will
+then invoke the C compiler to compile your module, and will return the
+same exit codes and messages that your C compiler does.
+
+By far the easiest way to compile modules is to construct a
+@file{Makefile} as you would for a normal program, and simply insert, at 
+some appropriate place something similar to:
+
+@example @code
+@cartouche
+CC=ellcc --mode=compile
+
+.c.o:
+    $(CC) $(CFLAGS) -c $<
+@end cartouche
+@end example
+
+After this, all you need to do is provide simple @code{make} rules for
+compiling your module source files.  Since modules are most useful when
+they are small and self-contained, most modules will have a single
+source file, aside from the module specific initialization file (see
+below for details).
+
+@node Initialization Mode, Link Mode, Compile Mode, Using ellcc
+@section Initialization Mode
+@cindex initialization
+@cindex documentation
+
+@emacs{} uses a rather bizarre way of documenting variables and
+functions.  Rather than have the documentation for compiled functions
+and variables passed as static strings in the source code, the
+documentation is included as a C comment.  A special program, called
+@file{make-docfile}, is used to scan the source code files and extract
+the documentation from these comments, producing the @emacs{} @file{DOC} 
+file, which the internal help engine scans when the documentation for a
+function or variable is requested.
+
+Due to the internal construction of Lisp objects, subrs and other such
+things, adding documentation for a compiled function or variable in a
+compiled module, at any time after @emacs{} has been @dfn{dumped} is
+somewhat problematic.  Fortunately, as a module writer you are insulated 
+from the difficulties thanks to your friend @code{ellcc} and some
+internal trickery in the module loading code.  This is all done using
+the @dfn{initialization} mode of @code{ellcc}.
+
+The result of running @code{ellcc} in initialization mode is a C source
+file which you compile with (you guessed it) @code{ellcc} in compile
+mode.  Initialization mode is where you set the module name, version,
+title and gather together all of the documentaion strings for the
+functions and vairables in your module.  There are several options that
+you are required to pass @code{ellcc} in initialization mode, the first
+of which is the mode switch itself, @code{--mode=init}.
+
+Next, you need to specify the name of the C source code file that
+@code{ellcc} will produce, and you specify this using the
+@code{--mod-output=FILENAME} argument.  @var{FILENAME} is the name of
+the C source code file that will contain the module variables and
+@code{docs_of_module} function.
+
+As discussed previously, each module requires a short @dfn{handle} or
+module name.  This is specified with the @code{--mod-name=NAME} option,
+where @var{NAME} is the abbreviated module name.  This @var{NAME} must
+consist only of characters that are valid in C function and variable
+names.
+
+The module version is specified using @code{--mod-version=VERSION}
+argument, with @var{VERSION} being any arbitrary version string.  This
+version can be passed as an optional second argument to the Lisp
+function @code{load-module}, and as the third argument to the internal
+module loading command @code{emodules_load}.  This version string is
+used to distinguish between different versions of the same module, and
+to ensure that the module is loaded at a specific version.
+
+Last, but not least, is the module title.  Specified using the
+@code{--mod-title=TITLE} option, the specified @var{TITLE} is used when
+the list of loaded modules is displayed.  The module title serves no
+purpose other than to inform the user of the function of the module.
+This string should be brief, as it has to be formatted to fit the
+screen.
+
+Following all of these parameters, you need to provide the list of all
+source code modules that make up your module.  These are the files which 
+are scanned by @file{make-docfile}, and provide the information required 
+to populate the @code{docs_of_module} function.  Below is a sample
+@file{Makefile} fragment which indicates how all of this is used.
+
+@example @code
+@cartouche
+CC=ellcc --mode=compile
+LD=ellcc --mode=link
+MODINIT=ellcc --mode=init
+CFLAGS=-O2 -DSOME_STUFF
+
+.c.o:
+    $(CC) $(CFLAGS) -c $<
+
+MODNAME=sample
+MODVER=1.0.0
+MODTITLE="Small sample module"
+
+SRCS=modfile1.c modfile2.c modfile3.c
+OBJS=$(SRCS:.c=.o)
+
+all: sample.ell
+clean:
+    rm -f $(OBJS) sample_init.o sample.ell
+
+install: all
+    mkdir `ellcc --mod-location`/mymods > /dev/null
+    cp sample.ell `ellcc --mod-location`/mymods/sample.ell
+
+sample.ell: $(OBJS) sample_init.o
+    $(LD) --mod-output=$@ $(OBJS) sample_init.o
+
+sample_init.o: sample_init.c
+sample_init.c: $(SRCS)
+    $(MODINIT) --mod-name=$(MODNAME) --mod-version=$(MODVER) \
+    --mod-title=$(MODTITLE) --mod-output=$@ $(SRCS)
+@end cartouche
+@end example
+
+The above @file{Makefile} is, in fact, complete, and would compile the
+sample module, and optionally install it.  The @code{--mod-location}
+argument to @code{ellcc} will produce, on the standard output, the base
+location of the @emacs{} module directory.  Each sub-directory of that
+directory is automatically searched for for modules when they are loaded
+with @code{load-module}.  An alternative location would be
+@file{/usr/local/lib/xemacs/site-modules}.  That path can change
+depending on the options the person who compiled @emacs{} chose, so you
+can always determine the correct site location using the
+@code{--mod-site-location} option.  This directory is treated the same
+way as the main module directory.  Each sub-directory within it is
+searched for a given module when the user attempts to load it.  The
+valid extensions that the loader attempts to use are @file{.so},
+@file{.ell} and @file{.dll}.  You can use any of these extensions,
+although @file{.ell} is the prefered extension.
+
+@node Link Mode, Other ellcc options, Initialization Mode, Using ellcc
+@section Link Mode
+@cindex linking
+
+Once all of your source code files have been compiled (including the
+generated init file) you need to link them all together to created the
+loadable module.  To do this, you invoke @code{ellcc} in link mode, by
+pasing the @code{--mode-link} command.  You need to specify the final
+output file using the @code{--mod-output=NAME} command, but other than
+that all other arguments are passed on directly to the system compiler
+or linker, along with any other required arguments to create the
+loadable module.
+
+The module has complete access to all symbols that were present in the
+dumped @emacs{}, so you do not need to link against libraries that were
+linked in with the main executable.  If your library uses some other
+extra libraries, you will need to link with those.  There is nothing
+particularly complicated about link mode.  All you need to do is make
+sure you invoke it correctly in the @file{Makefile}.  See the sample
+@file{Makefile} above for an example of a well constructed
+@file{Makefile} that invoked the linker correctly.
+
+@node Other ellcc options, Environment Variables, Link Mode, Using ellcc
+@section Other @code{ellcc} options
+@cindex paths
+
+Aside from the three main @code{ellcc} modes described above,
+@code{ellcc} can accept several other options.  These are typically used
+in a @file{Makefile} to determine installation paths.  @code{ellcc} also 
+allows you to over-ride several of its built-in compiler and linker
+options using environment variables.  Here is the complete list of
+options that @code{ellcc} accepts.
+
+@table @code
+@item --mode=compile
+Enables compilation mode.  Use this to compile source modules.
+
+@item --mode=link
+Enabled link edit mode.  Use this to create the final module.
+
+@item --mode=init
+Used to create the documentation function and to initialize other
+required variables.  Produces a C source file that must be compiled with 
+@code{ellcc} in compile mode before linking the final module.
+
+@item --mode=verbose
+Enables verbose mode.  This will show you the commands that are being
+executed, as well as the version number of @code{ellcc}.  If you specify 
+this option twice, then some extra debugging information is displayed.
+
+@item --mod-name=NAME
+Sets the short internaml module @var{NAME} to the string specified,
+which must consist only of valid C identifiers.  Required during
+initialization mode.
+
+@item --mod-version=VERSION
+Sets the internal module @var{VERSION} to the specified string.
+Required during initialization mode.
+
+@item --mod-title=TITLE
+Sets the module descriptive @var{TITLE} to the string specified.  This
+string can contain any printable characters, but should not be too
+long.  It is required during initialization mode.
+
+@item --mod-output=FILENAME
+Used to control the output file name.  This is used during
+initialization mode to set the name of the C source file that will be
+created to @var{FILENAME}.  During link mode, it sets the name of the
+final loadable module to @var{FILENAME}.
+
+@item --mod-location
+This will print the name of the standard module installation path on the 
+standard output and immediately exit @code{ellcc}.  Use this option to
+determine the directory prefix of where you should install your modules.
+
+@item --mod-site-location
+This will print the name of the site specific module location and exit.
+
+@item --mod-archdir
+Prints the name of the root of the architecture-dependant directory that 
+@emacs{} searches for architecture-dependant files.
+
+@item --mod-config
+Prints the name of the configuration for which @emacs{} and @code{ellcc} 
+were compiled.
+@end table
+
+@node Environment Variables,  , Other ellcc options, Using ellcc
+@section Environment Variables
+@cindex environment variables
+
+During its normal operation, @code{ellcc} uses the compiler and linker
+flags that were determined at the time @emacs{} was configured.  In
+certain rare circumstances you may wish to over-ride the flags passed to 
+the compiler or linker, and you can do so using environment variables.
+The table below lists all of the environment variables that @code{ellcc} 
+recognises.
+
+@table @code
+@item ELLCC
+@cindex @code{ELLCC}
+This is used to over-ride the name of the C compiler that is invoked by
+@code{ellcc}.
+
+@item ELLLD
+@cindex @code{ELLLD}
+Sets the name of the link editor to use to created the final module.
+
+@item ELLCFLAGS
+@cindex @code{ELLCFLAGS}
+Sets the compiler flags passed on when compiling source modules.  This
+only sets the basic C compiler flags.  There are certain hard-coded
+flags that will always be passed.
+
+@item ELLLDFLAGS
+@cindex @code{ELLLDFLAGS}
+Sets the flags passed on to the linker.  This does @strong{not} include
+the flags for enabling PIC mode.  This just sets basic linker flags.
+
+@item ELLDLLFLAGS
+@cindex @code{ELLDLLFLAGS}
+Sets the flags passed to the linker that are required to created shared
+and loadable objects.
+
+@item ELLPICFLAGS
+@cindex @code{ELLPICFLAGS}
+Sets the C compiler option required to produce an object file that is
+suitable for including in a shared library.  This option should turn on
+PIC mode, or the moral equivalent thereof on the target system.
+
+@item ELLMAKEDOC
+@cindex @code{ELLMAKEDOC}
+Sets the name of the @file{make-docfile} program to use.  Usually
+@code{ellcc} will use the version that was compiled and installed with
+@emacs{}, but this option allows you to specify an alternative path.
+Used during the compile phase of @emacs{} itself.
+@end table
+
+@node Defining Functions, Defining Variables, Using ellcc, Top
+@chapter Defining Functions
+@cindex defining functions
+
+  One of the main reasons you would ever write a module is to
+provide one or more @dfn{functions} for the user or the editor to use.
+The term 
+@dfn{function} is a bit overloaded here, as it refers to both a C
+function and the way it appears to Lisp, which is a @dfn{subroutine}, or
+simply a @dfn{subr}.  A Lisp subr is also known as a Lisp primitive, but
+that term applies less to dynamic modules.  @xref{Writing Lisp
+Primitives,,,internals,@emacs{} Internals Manual}, for details on how to
+declare functions.  You should familiarize yourself with the
+instructions there.  The format of the function declaration is identical 
+in modules.
+
+  Normal Lisp primitives document the functions they defining by including 
+the documentation as a C comment.  During the build process, a program
+called @file{make-docfile} is run, which will extract all of these
+comments, build up a single large documentation file, and will store
+pointers to the start of each documentation entry in the dumped @emacs{}.
+This, of course, will not work for dynamic modules, as they are loaded
+long after @emacs{} has been dumped.  For this reason, we require a
+special means for adding documentation for new subrs.  This is what the
+macro @code{CDOCSUBR} is used for, and this is used extensively during
+@code{ellcc} initialization mode.
+
+  When using @code{DEFUN} in normal @emacs{} C code, the sixth
+``parameter'' is a C comment which documents the function.  For a
+dynamic module, we of course need to convert the C comment to a usable
+string, and we need to set the documentation pointer of the subr to this 
+string.  As a module programmer, you don't actually need to do any work
+for this to happen.  It is all taken care of in the
+@code{docs_of_module} function created by @code{ellcc}.
+
+@menu
+* Using DEFUN::                 Using the DEFUN macro to define functions
+* Declaring Functions::         Declaring functions to the Lisp reader
+@end menu
+
+@node Using DEFUN, Declaring Functions, Defining Functions, Defining Functions
+@section Using @code{DEFUN}
+@cindex subrs
+@findex DEFUN
+@cindex functions, Lisp
+@cindex functions, defining
+
+  Although the full syntax of a function declaration is discussed in the 
+@emacs{} internals manual in greater depth, what follows is a brief
+description of how to define and implement a new Lisp primitive in a
+module.  This is done using the @code{DEFUN} macro.  Here is a small
+example:
+
+@example @code
+@cartouche
+DEFUN ("my-function", Fmy_function, 1, 1, "FFile name: ", /*
+Sample Emacs primitive function.
+
+The specified FILE is frobricated before it is fnozzled.
+*/
+    (file))
+@{
+  char *filename;
+
+  if (NILP(file))
+    return Qnil;
+
+  filename = (char *)XSTRING_DATA(file);
+  frob(filename);
+  return Qt;
+@}
+@end cartouche
+@end example
+
+The first argument is the name of the function as it will appear to the
+Lisp reader.  This must be provided as a string.  The second argument is 
+the name of the actual C function that will be created.  This is
+typically the Lisp function name with a preceding capital @code{F}, with 
+hyphens converted to underscores.  This must be a valid C function
+name.  Next come the minimum and maximum number of arguments,
+respectively.  This is used to ensure that the correct number of
+arguments are passed to the function.  Next is the @code{interactive}
+definition.  If this function is meant to be run by a user
+interactively, then you need to specify the argument types and prompts
+in this string.  Please consult the @emacs{} Lisp manual for more
+details.  Next comes a C comment that is the documentation for this
+function.  This comment @strong{must} exist.  Last comes the list of
+function argument names, if any.
+
+@node Declaring Functions,  , Using DEFUN, Defining Functions
+@section Declaring Functions
+@findex DEFSUBR
+@cindex functions, declaring
+
+Simply writing the code for a function is not enough to make it
+availible to the Lisp reader.  You have to, during module
+initialization, let the Lisp reader know about the new function.  This
+is done by calling @code{DEFSUBR} with the name of the function.  This
+is the sole purpose of the initialization function
+@code{syms_of_module}.  @xref{Required Functions}, for more details.
+
+Each call to @code{DEFSUBR} takes as its only argument the name of the
+function, which is the same as the second argument to the call to
+@code{DEFUN}.  Using the example function above, you would insert the
+following code in the @code{syms_of_module} function:
+
+@example @code
+@cartouche
+DEFSUBR(Fmy_function);
+@end cartouche
+@end example
+
+This call will instruct @emacs{} to make the function visible to the Lisp
+reader and will prepare for the insertion of the documentation into
+the right place.  Once this is done, the user can call the Lisp
+function @code{my-function}, if it was defined as an interactive
+function (which in this case it was).
+
+Thats all there is to defining and announcing new functions.  The rules
+for what goes inside the functions, and how to write good modules, is
+beyond the scope of this document.  Please consult the @emacs{}
+internals manual for more details.
+
+@node Defining Variables, Index, Defining Functions, Top
+@chapter Defining Variables
+@cindex defining variables
+@cindex defining objects
+@findex DEFVAR_LISP
+@findex DEFVAR_BOOL
+@findex DEFVAR_INT
+@cindex variables, Lisp
+@cindex variables, defining
+@cindex objects, defining
+@cindex objects, Lisp
+
+  Rarely will you write a module that only contains functions.  It is
+common to also provide variables which can be used to control the
+behaviour of the function, or store the results of the function being
+executed.  The actual C variable types are the same for modules
+and internal @emacs{} primitives, and the declaration of the variables
+is identical.
+
+  @xref{Adding Global Lisp Variables,,,internals,XEmacs Internals Manual}, 
+for more information on variables and naming conventions.
+
+  Once your variables are defined, you need to initialize them and make
+the Lisp reader aware of them.  This is done in the
+@code{vars_of_module} initialization function using special @emacs{}
+macros such as @code{DEFVAR_LISP}, @code{DEFVAR_BOOL}, @code{DEFVAR_INT} 
+etc.  The best way to see how to use these macros is to look at existing 
+source code, or read the internals manual.
+
+  One @emph{very} important difference between @emacs{} variables and
+module variables is how you use pure space.  Simply put, you
+@strong{never} use pure space in @emacs{} modules.  The pure space
+storage is of a limited size, and is initialized propperly during the
+dumping of @emacs{}.  Because variables are being added dynamically to
+an already running @emacs{} when you load a module, you cannot use pure
+space.  Be warned: @strong{do not use pure space in modules.  Repeat, do
+not use pure space in modules.}  Once again, to remove all doubts:
+@strong{DO NOT USE PURE SPACE IN MODULES!!!}
+
+  Below is a small example which declares and initializes two
+variables.  You will note that this code takes into account the fact
+that this module may very well be compiled into @emacs{} itself.  This
+is a prudent thing to do.
+
+@example @code
+@cartouche
+Lisp_Object Vsample_string;
+int sample_boolean;
+
+void
+vars_of_module()
+@{
+  DEFVAR_LISP ("sample-string", &Vsample_string /*
+This is a sample string, declared in a module.
+
+Nothing magical about it.
+*/);
+
+  DEFVAR_BOOL("sample-boolean", &sample_boolean /*
+*Sample user-settable boolean.
+*/);
+
+  sample_boolean = 0;
+  Vsample_string = build_string("My string");
+@}
+@end cartouche
+@end example
+
+@c Print the tables of contents
+@contents
+@c That's all
+
+@node Index,  , Defining Variables, Top
+@unnumbered Index
+
+@printindex cp
+
+@bye
+
index d9043c3..f6894c5 100644 (file)
@@ -2676,7 +2676,7 @@ Header files should @emph{not} include @code{<config.h>} and
 use it to do so.
 
 @item
-If the header uses @code{INLINE}, either directly or though
+If the header uses @code{INLINE}, either directly or through
 @code{DECLARE_LRECORD}, then it must be added to @file{inline.c}'s
 includes.
 
@@ -2968,7 +2968,7 @@ low-level macros.
 As a general rule, all typedefs should go into the typedefs section of
 @file{lisp.h} rather than into a module-specific header file even if the
 structure is defined elsewhere.  This allows function prototypes that
-use the typedef to placed into other header files.  Forward structure
+use the typedef to be placed into other header files.  Forward structure
 declarations (i.e. a simple declaration like @code{struct foo;} where
 the structure itself is defined elsewhere) should be placed into the
 typedefs section as necessary.
diff --git a/modules/README b/modules/README
new file mode 100644 (file)
index 0000000..8240cc0
--- /dev/null
@@ -0,0 +1,17 @@
+This directory contains a number of sample Emacs dynamic modules.
+These modules can be loaded with the command 'M-x load-module'.
+
+To compile one of these modules, simply enter the desired directory
+and type 'make'. Then, from within Emacs, load the module by
+specifying the path to the directory which contains the compiled
+module.
+
+Each of these samples describes different features and limitations
+of the Emacs module loading technology. Please refer to the README
+files in each directory for a brief discussion on what the sample
+in that directory is demonstrating.  For a complete discussion on
+Emacs dynamic modules, please consult the Emacs Module Writers Guide,
+which can be found in the ../info directory.
+
+NOTE: As this technology matures, this directory will eventually contain
+large parts of XEmacs itself, which will be loaded in as required.
diff --git a/modules/base64/Makefile b/modules/base64/Makefile
new file mode 100644 (file)
index 0000000..43a70e3
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# Sample makefile for a simple Emacs module.
+# This is slightly more complicated than would normally be the case,
+# as this makefile has been tailored to work in the Emacs source tree.
+# For samples of how to compile modules outside of the source tree
+# (as would be the case if a user had downloaded a module and wanted
+# to compile it for use within Emacs), see the samples in the sub-directory
+# 'installed'.
+#
+
+CC=../../lib-src/ellcc
+CFLAGS=-I. -I../../src
+LD=$(CC) --mode=link
+MKINIT=$(CC) --mode=init
+
+SRCS=base64.c
+OBJS=$(SRCS:.c=.o)
+
+.c.o:
+       $(CC) $(CFLAGS) -c $<
+
+MODNAME=base64
+MODVER=1.0.0
+MODTITLE="Encode objects in Base 64"
+
+all: $(MODNAME).ell
+
+clean:
+       rm -f $(MODNAME).ell $(OBJS) base64_i.o base64_i.c
+
+$(MODNAME).ell: $(OBJS) base64_i.o
+       $(LD) --mod-output=$@ $(OBJS) base64_i.o
+
+base64_i.o: base64_i.c
+base64_i.c: $(SRCS)
+       ELLMAKEDOC=../../lib-src/make-docfile $(MKINIT) --mod-output=$@ \
+       --mod-name=$(MODNAME) --mod-version=$(MODVER) \
+       --mod-title=$(MODTITLE) $(SRCS)
+
index b65625f..48459a7 100644 (file)
@@ -1,5 +1,5 @@
 /* base64 interface for XEmacs.
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
 
 This file is part of XEmacs.
 
@@ -22,15 +22,7 @@ Boston, MA 02111-1307, USA.  */
 
 /* Author: William Perry <wmperry@aventail.com> */
 
-#include <config.h>
-
-#include "lisp.h"
-#include "buffer.h"
-#include "insdel.h"
-#include "lstream.h"
-#ifdef FILE_CODING
-#include "file-coding.h"
-#endif
+#include <emodules.h>
 
 unsigned char alphabet[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
@@ -416,14 +408,14 @@ determined.  Else assume binary coding if all else fails.
 }
 
 void
-syms_of (void)
+syms_of_base64 (void)
 {
   DEFSUBR(Fbase64_encode);
   DEFSUBR(Fbase64_decode);
 }
 
 void
-vars_of (void)
+vars_of_base64 (void)
 {
   Fprovide (intern ("base64"));
 }
diff --git a/modules/ldap/Makefile b/modules/ldap/Makefile
new file mode 100644 (file)
index 0000000..e0f1976
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# Sample makefile for a simple Emacs module.
+# This is slightly more complicated than would normally be the case,
+# as this makefile has been tailored to work in the Emacs source tree.
+# For samples of how to compile modules outside of the source tree
+# (as would be the case if a user had downloaded a module and wanted
+# to compile it for use within Emacs), see the samples in the sub-directory
+# 'installed'.
+#
+
+CC=../../lib-src/ellcc
+CFLAGS=-I. -I../../src
+LD=$(CC) --mode=link
+MKINIT=$(CC) --mode=init
+
+SRCS=eldap.c
+OBJS=$(SRCS:.c=.o)
+
+.c.o:
+       $(CC) $(CFLAGS) -c $<
+
+MODNAME=ldap
+MODVER=1.0.0
+MODTITLE="LDAP Client Interface for XEmacs"
+
+all: $(MODNAME).ell
+
+clean:
+       rm -f $(MODNAME).ell $(OBJS) eldap_i.o eldap_i.c
+
+$(MODNAME).ell: $(OBJS) eldap_i.o
+       $(LD) --mod-output=$@ $(OBJS) eldap_i.o
+
+eldap_i.o: eldap_i.c
+eldap_i.c: $(SRCS)
+       ELLMAKEDOC=../../lib-src/make-docfile $(MKINIT) --mod-output=$@ \
+       --mod-name=$(MODNAME) --mod-version=$(MODVER) \
+       --mod-title=$(MODTITLE) $(SRCS)
+
index d902d57..e9bdf0c 100644 (file)
@@ -28,16 +28,11 @@ Boston, MA 02111-1307, USA.  */
    - UMich LDAP 3.3 (http://www.umich.edu/~dirsvcs/ldap/)
    - Netscape's LDAP SDK 1.0 (http://developer.netscape.com) */
 
-
-
-#include <config.h>
+#include <emodules.h>
 
 #if defined (HAVE_LDAP)
-
 /* The entire file is within this conditional */
 
-#include "lisp.h"
-
 #include "eldap.h"
 #include <lber.h>
 #include <ldap.h>
@@ -409,7 +404,7 @@ an alist of attribute/values.
 }
 
 void
-syms_of (void)
+syms_of_ldap (void)
 {
   DEFSUBR(Fldap_search_internal);
 
@@ -440,7 +435,7 @@ syms_of (void)
 }
 
 void
-vars_of (void)
+vars_of_ldap (void)
 {
   Fprovide (intern ("ldap-internal"));
 
diff --git a/modules/sample/Makefile b/modules/sample/Makefile
new file mode 100644 (file)
index 0000000..09390d1
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# Sample makefile for a simple Emacs module.
+# This is slightly more complicated than would normally be the case,
+# as this makefile has been tailored to work in the Emacs source tree.
+# For samples of how to compile modules outside of the source tree
+# (as would be the case if a user had downloaded a module and wanted
+# to compile it for use within Emacs), see the samples in the sub-directory
+# 'installed'.
+#
+
+CC=../../lib-src/ellcc
+CFLAGS=-I. -I../../src
+LD=$(CC) --mode=link
+MKINIT=$(CC) --mode=init
+
+SRCS=sample.c
+OBJS=$(SRCS:.c=.o)
+
+.c.o:
+       $(CC) $(CFLAGS) -c $<
+
+MODNAME=sample
+MODVER=1.0.0
+MODTITLE="Sample loadable module"
+
+all: $(MODNAME).ell
+
+clean:
+       rm -f $(MODNAME).ell $(OBJS) sample_i.o sample_i.c
+
+$(MODNAME).ell: $(OBJS) sample_i.o
+       $(LD) --mod-output=$@ $(OBJS) sample_i.o
+
+sample_i.o: sample_i.c
+sample_i.c: $(SRCS)
+       ELLMAKEDOC=../../lib-src/make-docfile $(MKINIT) --mod-output=$@ \
+       --mod-name=$(MODNAME) --mod-version=$(MODVER) \
+       --mod-title=$(MODTITLE) $(SRCS)
+
diff --git a/modules/sample/sample.c b/modules/sample/sample.c
new file mode 100644 (file)
index 0000000..1f519fc
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Very simple sample module. Illustrates most of the salient features
+ * of Emacs dynamic modules.
+ * (C) Copyright 1998, 1999 J. Kean Johnston. All rights reserved.
+ */
+
+#include <emodules.h>
+
+/*
+ * This sample introduces three new Lisp objects to the Lisp reader.
+ * The first, a simple boolean value, and the second a string. The
+ * Third is a sample function that simply prints a message.
+ */
+int sample_bool;
+Lisp_Object Vsample_string;
+
+DEFUN ("sample-function", Fsample_function, 0, 0, "", /*
+This is a sample function loaded dynamically.
+
+You will notice in the source code for this module that the
+declaration is identical to internal Emacs functions.  This
+makes it possible to use the exact same code in a dumped
+version of Emacs.
+*/
+        ())
+{
+  message ("Eureka! It worked");
+  return Qt;
+}
+
+/*
+ * Each dynamically loaded Emacs module is given a name at compile
+ * time. This is a short name, and must be a valid part of a C
+ * identifier.  This name is used to contruct the name of several
+ * functions which must appear in the module source code.
+ * The first such function, modules_of_XXXX, should load in any dependant
+ * modules. This function is optional, and the module will still load if
+ * it is not present in the module.
+ *
+ * The second function, which is NOT optional, is syms_of_XXXX, in which
+ * all functions that the module will be provided are declared. This
+ * function will contain calls to DEFSUBR().
+ *
+ * The third function, which is also NOT optional, is vars_of_XXXX, in
+ * which you declare all variables that the module provides. This
+ * function will contain calls to DEFVAR_LISP(), DEFVAR_BOOL() etc.
+ *
+ * When declaring functions and variables in the syms_of_XXXX and
+ * vars_of_XXXX functions, you use the exact same syntax that you
+ * would as if this module were being compiled into the pure Emacs.
+ *
+ * All three of these functions are declared as void functions,
+ * taking no parameters. Since this sample module is called 'sample',
+ * the functions will be named 'modules_of_sample', 'syms_of_sample'
+ * and 'vars_of_sample'.
+ */
+
+void
+modules_of_sample()
+{
+  /*
+   * This function isn't actually required as we will not be loading
+   * in any dependant modules, but if we were, we would do something like:
+   * emodules_load ("dependant.ell", "sample2", "1.0.0");
+   */
+}
+
+void
+syms_of_sample()
+{
+  DEFSUBR(Fsample_function);
+}
+
+void
+vars_of_sample()
+{
+  DEFVAR_LISP ("sample-string", &Vsample_string /*
+This is a sample string, declared in a dynamic module.
+
+The syntax and conventions used for all normal Emacs variables
+apply equally to modules, using an identical syntax.
+*/ );
+
+  DEFVAR_BOOL ("sample-boolean", &sample_bool /*
+*Sample boolean value, in a dynamic module.
+
+This is a user-settable variable, as indicated by the *
+as the first character of the description. Declared in
+a module exactly as it would be internally in Emacs.
+*/ );
+}
+
diff --git a/modules/zlib/Makefile b/modules/zlib/Makefile
new file mode 100644 (file)
index 0000000..cb7aecd
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# Sample makefile for a simple Emacs module.
+# This is slightly more complicated than would normally be the case,
+# as this makefile has been tailored to work in the Emacs source tree.
+# For samples of how to compile modules outside of the source tree
+# (as would be the case if a user had downloaded a module and wanted
+# to compile it for use within Emacs), see the samples in the sub-directory
+# 'installed'.
+#
+
+CC=../../lib-src/ellcc
+CFLAGS=-I. -I../../src
+LD=$(CC) --mode=link
+MKINIT=$(CC) --mode=init
+
+SRCS=zlib.c
+OBJS=$(SRCS:.c=.o)
+
+.c.o:
+       $(CC) $(CFLAGS) -c $<
+
+MODNAME=zlib
+MODVER=1.0.4
+MODTITLE="ZLIB compression library interface"
+
+all: $(MODNAME).ell
+
+clean:
+       rm -f $(MODNAME).ell $(OBJS) zlib_i.o zlib_i.c
+
+$(MODNAME).ell: $(OBJS) zlib_i.o
+       $(LD) --mod-output=$@ $(OBJS) zlib_i.o
+
+zlib_i.o: zlib_i.c
+zlib_i.c: $(SRCS)
+       ELLMAKEDOC=../../lib-src/make-docfile $(MKINIT) --mod-output=$@ \
+       --mod-name=$(MODNAME) --mod-version=$(MODVER) \
+       --mod-title=$(MODTITLE) $(SRCS)
+
index 55adcaf..f5fb817 100644 (file)
@@ -22,9 +22,7 @@ Boston, MA 02111-1307, USA.  */
 
 /* Author: William Perry <wmperry@aventail.com> */
 
-#include <config.h>
-
-#include "lisp.h"
+#include <emodules.h>
 
 DEFUN ("compress", Fcompress, 1, 6, 0, /*
 Return the compressed version of an object.
@@ -58,14 +56,14 @@ determined.  Else assume binary coding if all else fails.
 }
 
 void
-syms_of (void)
+syms_of_zlib (void)
 {
   DEFSUBR(Fcompress);
   DEFSUBR(Fdecompress);
 }
 
 void
-vars_of (void)
+vars_of_zlib (void)
 {
   Fprovide (intern ("zlib"));
 }
index 37ef852..7a0a030 100644 (file)
@@ -1,3 +1,27 @@
+1999-02-02  XEmacs Build Bot <builds@cvs.xemacs.org>
+
+       * XEmacs 21.2.9 is released
+
+1999-01-14  Adrian Aichner  <aichner@ecf.teradyne.com>
+
+       * xemacs.mak (MODULES): Adding variable.
+       (update-elc): Setting EMACSBOOTSTRAPMODULEPATH.
+
+1998-12-17  Charles G. Waldman <cgw@pgt.com>
+
+       * minitar.c:  New file
+       * minitar.mak: New file
+
+1998-12-29  Jonathan Harris  <jhar@tardis.ed.ac.uk>
+
+       * xemacs.mak:
+         Changed x86 EMACS_CONFIGURATION to i586-pc-win32 since we
+         build optimised for Pentium.
+         Created CFLAGS variable, used in building all objects and in
+         constructing config.values.
+         Added glyphs-widget.c and gui-msw.c to list of sources.
+         Added PACKAGE_PATH to EMACSBOOTSTRAPLOADPATH for mule builds.
+
 1998-12-28  Martin Buchholz <martin@xemacs.org>
 
        * XEmacs 21.2.8 is released.
diff --git a/nt/minitar.c b/nt/minitar.c
new file mode 100644 (file)
index 0000000..4d89875
--- /dev/null
@@ -0,0 +1,211 @@
+
+/* Minitar:  extract .tar.gz files on Win32 platforms. 
+   Uses zlib for decompression.
+   
+   This is very simple-minded, it ignores checksums, and any type of file 
+   that is not a plain file or a directory.  Nonetheless it is useful.
+
+   Author: Charles G. Waldman (cgw@pgt.com),  Aug 4 1998
+
+   This file is placed in the public domain; you can
+   do whatever you like with it.  There is NO WARRANTY. 
+   If it breaks, you get to keep both pieces */
+
+
+#include <stdio.h>
+#include <Errno.h>
+
+#include <zlib.h>
+
+Usage(char *name)
+{
+  fprintf(stderr,"Usage: %s file.tar.gz [base-dir]\n",name);
+  fprintf(stderr,"\tExtracts the contents compressed tar file to base-dir\n");
+  exit(-1);
+}
+
+
+#define BLOCKSIZE 512
+#define MAXNAMELEN 1024
+
+int octal(char *str)
+{
+  int ret = -1;
+  sscanf(str,"%o",&ret);
+  return ret;
+}
+
+/* this is like mkdir -p, except if there is no trailing slash,
+   the final component is assumed to be a file, rather than a
+   path component, so it is not created as a directory */
+
+int makepath(char *path)
+{
+  char tmp[MAXNAMELEN];
+  char *cp;
+  extern int errno;
+
+  for (cp=path; cp; cp = (char*)strchr(cp+1,'/')){
+    if (!*cp)
+      break;
+    if (*cp != '/')
+      continue;
+    strncpy(tmp, path, cp-path);
+    tmp[cp-path] = '\0';
+    if (strlen(tmp) == 0)
+      continue;
+    if (mkdir(tmp,0777)){
+      if (errno == EEXIST)
+       continue;
+      else
+       return -1;
+    }
+  }
+  return 0;
+}
+
+  
+                    
+
+main(int argc, char **argv)
+{
+  char fullname[MAXNAMELEN];
+  char *basedir = ".";
+  char *tarfile;
+  char *cp;
+  int size;
+  char osize[13];
+  char name[101];
+  char magic[7];
+  char type;
+  
+  gzFile *infile = (gzFile*)0;
+  FILE *outfile = (FILE*)0;
+
+  char block[BLOCKSIZE];
+  int nbytes, nread, nwritten;
+
+  int in_block = 0;
+  int directory = 0;
+
+  if (argc < 2 || argc > 3)
+    Usage(argv[0]);
+
+  tarfile = argv[1];
+  if (argc==3)
+    basedir = argv[2];
+
+  if (! (infile = gzopen(tarfile,"rb"))){
+    fprintf(stderr,"Cannot open %s\n", tarfile);
+    exit(-2);
+  }
+  
+  while (1){
+  
+
+    nread = gzread(infile,block,512);
+
+    if (!in_block && nread == 0)
+      break;
+
+    if (nread != BLOCKSIZE){
+      fprintf(stderr,"Error: incomplete block read. Exiting.\n");
+      exit(-2);
+    }
+
+    if (!in_block){
+      if (block[0]=='\0')  /* We're done */
+       break;
+
+      strncpy(magic,block+257,6);
+      magic[6] = '\0';
+      if (strcmp(magic,"ustar ")){
+       fprintf(stderr,
+               "Error: incorrect magic number in tar header. Exiting\n");
+      }
+
+      strncpy(name,block,100);
+      name[100] = '\0';
+      sprintf(fullname,"%s/%s",basedir,name);
+      printf("%s\n",fullname);
+      type = block[156];
+      
+      switch(type){
+      case '0':
+      case '\0':
+       directory = 0;
+       break;
+      case '5':
+       directory = 1;
+       break;
+      default:
+       fprintf(stderr,"Error: unknown type flag %c. Exiting.\n",type);
+       break;
+      }
+      
+      if (directory){
+       in_block = 0;
+       
+       /* makepath will ignore the final path component, so make sure 
+          dirnames have a trailing slash */
+
+       if (fullname[strlen(fullname)-1] != '/')
+         strcat(fullname,"/");
+       if (makepath(fullname)){
+         fprintf(stderr, "Error: cannot create directory %s. Exiting.\n",
+                 fullname);
+         exit(-2);
+       }
+       continue;
+      } else { /*file */
+       in_block = 1;
+       if (outfile){
+         if (fclose(outfile)){
+           fprintf(stderr,"Error: cannot close file %s. Exiting.\n",
+                   fullname);
+           exit(-2);
+         }
+         outfile = (FILE*)0;
+       }
+
+       if ( !(outfile = fopen(fullname,"wb"))){
+         /*try creating the directory, maybe it's not there */
+         if (makepath(fullname)){
+           fprintf(stderr,"Error: cannot create file %s. Exiting.\n",
+                   fullname);
+           exit(-2);
+         }
+         /* now try again to open the file */
+         if (!(outfile = fopen(fullname,"wb"))){
+           fprintf(stderr,"Error: cannot create file %s. Exiting.\n",
+                   fullname);
+           exit(-2);
+         }
+       }
+
+       strncpy(osize,block+124,12);
+       osize[12] = '\0';
+       size = octal(osize);
+       if (size<0){
+         fprintf(stderr,"Error: invalid size in tar header. Exiting.\n");
+         exit(-2);
+       }
+      }
+    } else { /* write or continue writing file contents */
+      nbytes = size>512? 512:size;
+      
+      nwritten = fwrite(block, 1, nbytes, outfile);
+      if (nwritten != nbytes){
+       fprintf(stderr, "Error: only wrote %d bytes to file %s. Exiting.\n",
+               nwritten, fullname);
+      }
+      size -= nbytes;
+      if (size==0)
+       in_block = 0;
+    }
+  }
+}      
+
+
+
+  
index de64bc6..4743085 100644 (file)
@@ -26,6 +26,7 @@
 
 XEMACS=..
 LISP=$(XEMACS)\lisp
+MODULES=$(XEMACS)\modules
 NT=$(XEMACS)\nt
 
 # Program name and version
@@ -125,9 +126,9 @@ USE_INDEXED_LRECORD_IMPLEMENTATION=0
 # System configuration
 #
 !if !defined(PROCESSOR_ARCHITECTURE) && "$(OS)" != "Windows_NT"
-EMACS_CONFIGURATION=i386-pc-win32
+EMACS_CONFIGURATION=i586-pc-win32
 !else if "$(PROCESSOR_ARCHITECTURE)" == "x86"
-EMACS_CONFIGURATION=i386-pc-win32
+EMACS_CONFIGURATION=i586-pc-win32
 !else if "$(PROCESSOR_ARCHITECTURE)" == "MIPS"
 EMACS_CONFIGURATION=mips-pc-win32
 !else if "$(PROCESSOR_ARCHITECTURE)" == "ALPHA"
@@ -291,9 +292,9 @@ USE_INDEXED_LRECORD_IMPLEMENTATION=$(GUNG_HO)
 VERBOSECC=0
 !endif
 !if $(VERBOSECC)
-CCV=$(CC) -nologo
+CCV=$(CC)
 !else
-CCV=@$(CC) -nologo
+CCV=@$(CC)
 !endif
 
 !if $(DEBUG_XEMACS)
@@ -302,7 +303,7 @@ OPT=-Od -Zi
 OPT=-O2 -G5 -Zi
 !endif
 
-WARN_CPP_FLAGS = -W3
+CFLAGS=-nologo -W3 $(OPT)
 
 !if $(HAVE_X)
 X_DEFINES=-DHAVE_X_WINDOWS
@@ -416,7 +417,7 @@ OUTDIR=obj
 # Compiler Information
 !if defined(CCV) &&\
 [echo What compiler should XEmacs be built with?>>Installation] &&\
-[echo $(CCV)>>Installation]
+[echo $(CC) $(CFLAGS)>>Installation]
 !endif
 # Window System Information
 !if [echo What window system should XEmacs use?>>Installation]
@@ -499,7 +500,7 @@ CONFIG_VALUES = $(LIB_SRC)\config.values
 # Inferred rule
 {$(LIB_SRC)}.c{$(LIB_SRC)}.exe :
        @cd $(LIB_SRC)
-       $(CCV) -I. -I$(XEMACS)/src -I$(XEMACS)/nt/inc $(LIB_SRC_DEFINES) -O2 -W3 -Fe$@ $**
+       $(CCV) -I. -I$(XEMACS)/src -I$(XEMACS)/nt/inc $(LIB_SRC_DEFINES) $(CFLAGS) -Fe$@ $**
        @cd $(NT)
 
 # Individual dependencies
@@ -507,7 +508,7 @@ ETAGS_DEPS = $(LIB_SRC)/getopt.c $(LIB_SRC)/getopt1.c $(LIB_SRC)/../src/regex.c
 $(LIB_SRC)/etags.exe : $(LIB_SRC)/etags.c $(ETAGS_DEPS)
 $(LIB_SRC)/movemail.exe: $(LIB_SRC)/movemail.c $(LIB_SRC)/pop.c $(ETAGS_DEPS)
        @cd $(LIB_SRC)
-       $(CCV) -I. -I$(XEMACS)/src -I$(XEMACS)/nt/inc $(LIB_SRC_DEFINES) -O2 -W3 -Fe$@ $** wsock32.lib
+       $(CCV) -I. -I$(XEMACS)/src -I$(XEMACS)/nt/inc $(LIB_SRC_DEFINES) $(CFLAGS) -Fe$@ $** wsock32.lib
        @cd $(NT)
 
 LIB_SRC_TOOLS = \
@@ -521,12 +522,15 @@ LIB_SRC_TOOLS = \
 
 #------------------------------------------------------------------------------
 
-# runemacs proglet
+# runxemacs proglet
 
-RUNEMACS = $(XEMACS)\src\runemacs.exe
+RUNEMACS = $(XEMACS)\src\runxemacs.exe
 
-$(RUNEMACS): $(NT)\runemacs.c $(NT)\xemacs.res
-       $(CCV) -I. -I$(XEMACS)/src -I$(XEMACS)/nt/inc -O2 -W3 -Fe$@ $** kernel32.lib user32.lib
+$(RUNEMACS): $(LIB_SRC)\run.c $(LIB_SRC)\run.res
+       $(CCV) -I$(LIB_SRC) -O2 -Fe$@ $** kernel32.lib user32.lib
+
+$(LIB_SRC)\run.res: $(LIB_SRC)\run.rc
+       rc -I$(LIB_SRC) -FO$(LIB_SRC)\run.res $(LIB_SRC)\run.rc
 
 #------------------------------------------------------------------------------
 
@@ -534,7 +538,7 @@ $(RUNEMACS): $(NT)\runemacs.c $(NT)\xemacs.res
 
 LASTFILE=$(OUTDIR)\lastfile.lib
 LASTFILE_SRC=$(XEMACS)\src
-LASTFILE_FLAGS=$(WARN_CPP_FLAGS) $(OPT) $(INCLUDES) -Fo$@ -c
+LASTFILE_FLAGS=$(CFLAGS) $(INCLUDES) -Fo$@ -c
 LASTFILE_OBJS= \
        $(OUTDIR)\lastfile.obj
 
@@ -552,7 +556,7 @@ $(OUTDIR)\lastfile.obj:     $(LASTFILE_SRC)\lastfile.c
 
 LWLIB=$(OUTDIR)\lwlib.lib
 LWLIB_SRC=$(XEMACS)\lwlib
-LWLIB_FLAGS=$(WARN_CPP_FLAGS) $(OPT) $(INCLUDES) $(DEFINES) \
+LWLIB_FLAGS=$(CFLAGS) $(INCLUDES) $(DEFINES) \
  -DNEED_ATHENA -DNEED_LUCID \
  -D_WINDOWS -DMENUBARS_LUCID -DSCROLLBARS_LUCID -DDIALOGS_ATHENA \
  -Fo$@ -c
@@ -637,6 +641,7 @@ DOC_SRC3=\
  $(XEMACS)\src\general.c \
  $(XEMACS)\src\glyphs.c \
  $(XEMACS)\src\glyphs-eimage.c \
+ $(XEMACS)\src\glyphs-widget.c \
  $(XEMACS)\src\gmalloc.c \
  $(XEMACS)\src\gui.c  \
  $(XEMACS)\src\hash.c \
@@ -670,7 +675,6 @@ DOC_SRC4=\
  $(XEMACS)\src\redisplay.c \
  $(XEMACS)\src\regex.c \
  $(XEMACS)\src\scrollbar.c \
- $(XEMACS)\src\scrollbar-msw.c \
  $(XEMACS)\src\search.c \
  $(XEMACS)\src\signal.c \
  $(XEMACS)\src\sound.c 
@@ -720,6 +724,7 @@ DOC_SRC7=\
  $(XEMACS)\src\event-msw.c  \
  $(XEMACS)\src\frame-msw.c \
  $(XEMACS)\src\glyphs-msw.c \
+ $(XEMACS)\src\gui-msw.c \
  $(XEMACS)\src\menubar-msw.c \
  $(XEMACS)\src\objects-msw.c \
  $(XEMACS)\src\redisplay-msw.c \
@@ -733,11 +738,13 @@ DOC_SRC7=\
 
 !if $(HAVE_MULE)
 DOC_SRC8=\
- $(XEMACS)\src\input-method-xlib.c \
  $(XEMACS)\src\mule.c \
  $(XEMACS)\src\mule-charset.c \
  $(XEMACS)\src\mule-ccl.c \
  $(XEMACS)\src\mule-coding.c
+! if $(HAVE_X)
+ DOC_SRC8=$(DOC_SRC8) $(XEMACS)\src\input-method-xlib.c
+! endif
 !endif
 
 !if $(DEBUG_XEMACS)
@@ -759,13 +766,13 @@ TEMACS=$(TEMACS_DIR)\temacs.exe
 TEMACS_BROWSE=$(TEMACS_DIR)\temacs.bsc
 TEMACS_SRC=$(XEMACS)\src
 TEMACS_LIBS=$(LASTFILE) $(LWLIB) $(X_LIBS) $(MSW_LIBS) \
- kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib \
- shell32.lib ole32.lib oleaut32.lib uuid.lib wsock32.lib winmm.lib libc.lib
+ kernel32.lib user32.lib gdi32.lib advapi32.lib \
+ shell32.lib wsock32.lib winmm.lib libc.lib
 TEMACS_LFLAGS=-nologo $(LIBRARIES) $(DEBUG_FLAGS) -base:0x1000000\
  -stack:0x800000 -entry:_start -subsystem:console\
  -pdb:$(TEMACS_DIR)\temacs.pdb -map:$(TEMACS_DIR)\temacs.map \
  -heap:0x00100000 -out:$@
-TEMACS_CPP_FLAGS= $(WARN_CPP_FLAGS) $(INCLUDES) $(DEFINES) $(DEBUG_DEFINES) \
+TEMACS_CPP_FLAGS=-ML -c $(CFLAGS) $(INCLUDES) $(DEFINES) $(DEBUG_DEFINES) \
  -DEMACS_MAJOR_VERSION=$(emacs_major_version) \
  -DEMACS_MINOR_VERSION=$(emacs_minor_version) \
  $(EMACS_BETA_VERSION) \
@@ -773,8 +780,6 @@ TEMACS_CPP_FLAGS= $(WARN_CPP_FLAGS) $(INCLUDES) $(DEFINES) $(DEBUG_DEFINES) \
  -DEMACS_CONFIGURATION=\"$(EMACS_CONFIGURATION)\" \
  -DPATH_PACKAGEPATH=\"$(PATH_PACKAGEPATH)\"
 
-TEMACS_FLAGS=-ML $(WARN_CPP_FALGS) $(OPT) -c $(TEMACS_CPP_FLAGS)
-
 !if $(HAVE_X)
 TEMACS_X_OBJS=\
        $(OUTDIR)\balloon-x.obj \
@@ -807,6 +812,7 @@ TEMACS_MSW_OBJS=\
        $(OUTDIR)\event-msw.obj \
        $(OUTDIR)\frame-msw.obj \
        $(OUTDIR)\glyphs-msw.obj \
+       $(OUTDIR)\gui-msw.obj \
        $(OUTDIR)\menubar-msw.obj \
        $(OUTDIR)\objects-msw.obj \
        $(OUTDIR)\redisplay-msw.obj \
@@ -820,11 +826,14 @@ TEMACS_MSW_OBJS=\
 
 !if $(HAVE_MULE)
 TEMACS_MULE_OBJS=\
-       $(OUTDIR)\input-method-xlib.obj \
        $(OUTDIR)\mule.obj \
        $(OUTDIR)\mule-charset.obj \
        $(OUTDIR)\mule-ccl.obj \
        $(OUTDIR)\mule-coding.obj
+! if $(HAVE_X)
+TEMACS_MULE_OBJS=\
+       $(TEMACS_MULE_OBJS) $(OUTDIR)\input-method-xlib.obj
+! endif
 !endif
 
 !if $(DEBUG_XEMACS)
@@ -879,6 +888,7 @@ TEMACS_OBJS= \
        $(OUTDIR)\general.obj \
        $(OUTDIR)\glyphs.obj \
        $(OUTDIR)\glyphs-eimage.obj \
+       $(OUTDIR)\glyphs-widget.obj \
        $(OUTDIR)\gmalloc.obj \
        $(OUTDIR)\gui.obj \
        $(OUTDIR)\hash.obj \
@@ -934,13 +944,13 @@ TEMACS_OBJS= \
 
 # nmake rule
 {$(TEMACS_SRC)}.c{$(OUTDIR)}.obj:
-       $(CCV) $(TEMACS_FLAGS) $< -Fo$@ -Fr$*.sbr
+       $(CCV) $(TEMACS_CPP_FLAGS) $< -Fo$@ -Fr$*.sbr
 
 $(OUTDIR)\TopLevelEmacsShell.obj:      $(TEMACS_SRC)\EmacsShell-sub.c
-       $(CCV) $(TEMACS_FLAGS) -DDEFINE_TOP_LEVEL_EMACS_SHELL $** -Fo$@
+       $(CCV) $(TEMACS_CPP_FLAGS) -DDEFINE_TOP_LEVEL_EMACS_SHELL $** -Fo$@
 
 $(OUTDIR)\TransientEmacsShell.obj: $(TEMACS_SRC)\EmacsShell-sub.c
-       $(CCV) $(TEMACS_FLAGS) -DDEFINE_TRANSIENT_EMACS_SHELL $** -Fo$@
+       $(CCV) $(TEMACS_CPP_FLAGS) -DDEFINE_TRANSIENT_EMACS_SHELL $** -Fo$@
 
 $(OUTDIR)\alloc.obj: $(TEMACS_SRC)\alloc.c $(TEMACS_SRC)\puresize-adjust.h
 
@@ -987,7 +997,8 @@ $(LISP)\Installation.el: Installation.el
        copy Installation.el $(LISP)
 
 update-elc: $(LISP)\Installation.el
-       set EMACSBOOTSTRAPLOADPATH=$(LISP)
+       set EMACSBOOTSTRAPLOADPATH=$(LISP);$(PACKAGE_PATH)
+       set EMACSBOOTSTRAPMODULEPATH=$(MODULES)
        $(TEMACS) -batch -l $(TEMACS_DIR)\..\lisp\update-elc.el
 
 # This rule dumps xemacs and then possibly spawns sub-make if PURESPACE
@@ -995,7 +1006,7 @@ update-elc: $(LISP)\Installation.el
 dump-xemacs: $(TEMACS)
        @echo >$(TEMACS_DIR)\SATISFIED
        cd $(TEMACS_DIR)
-       set EMACSBOOTSTRAPLOADPATH=$(LISP)
+       set EMACSBOOTSTRAPLOADPATH=$(LISP);$(PACKAGE_PATH)
        -1 $(TEMACS) -batch -l $(TEMACS_DIR)\..\lisp\loadup.el dump
        @cd $(NT)
        @if not exist $(TEMACS_DIR)\SATISFIED nmake -nologo -f xemacs.mak $@
@@ -1065,7 +1076,7 @@ distclean:
        -del /s /q *.bak *.elc *.orig *.rej
 
 depend:
-       mkdepend -f xemacs.mak -p$(OUTDIR)\ -o.obj -w9999 -- $(TEMACS_CPP_FLAGS) --  $(DOC_SRC1) $(DOC_SRC2) $(DOC_SRC3) $(DOC_SRC4) $(DOC_SRC5) $(DOC_SRC6) $(DOC_SRC7) $(DOC_SRC8) $(DOC_SRC9) $(LASTFILE_SRC)\lastfile.c $(LIB_SRC)\make-docfile.c .\runemacs.c
+       mkdepend -f xemacs.mak -p$(OUTDIR)\ -o.obj -w9999 -- $(TEMACS_CPP_FLAGS) --  $(DOC_SRC1) $(DOC_SRC2) $(DOC_SRC3) $(DOC_SRC4) $(DOC_SRC5) $(DOC_SRC6) $(DOC_SRC7) $(DOC_SRC8) $(DOC_SRC9) $(LASTFILE_SRC)\lastfile.c $(LIB_SRC)\make-docfile.c $(LIB_SRC)\run.c
 
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
index bbb3127..723d739 100644 (file)
@@ -2,6 +2,7 @@
 ##   Copyright (C) 1985, 1987, 1988, 1993, 1994 Free Software Foundation, Inc.
 ##   Copyright (C) 1994, 1995 Board of Trustees, University of Illinois
 ##   Copyright (C) 1996, 1997 Sun Microsystems, Inc.
+##   Copyright (C) 1998, 1999 J. Kean Johnston.
 
 ## This file is part of XEmacs.
 
@@ -42,6 +43,7 @@ SHELL=/bin/sh
 RM = rm -f
 
 lispdir = ${srcdir}/../lisp/
+moduledir = ${srcdir}/../modules/
 libsrc = ../lib-src/
 etcdir = ../etc/
 
@@ -308,8 +310,9 @@ mo_dir = ${etcdir}
 mo_file = ${mo_dir}emacs.mo
 #endif
 
-LOADPATH =  EMACSBOOTSTRAPLOADPATH="${lispdir}:${blddir}"
-DUMPENV = $(LOADPATH)
+LOADPATH   =  EMACSBOOTSTRAPLOADPATH="${lispdir}:${blddir}"
+MODULEPATH =  EMACSBOOTSTRAPMODULEPATH="${moduledir}:${blddir}"
+DUMPENV = $(LOADPATH) $(MODULEPATH)
 temacs_loadup = $(DUMPENV) ./temacs -batch -l ${srcdir}/../lisp/loadup.el
 dump_temacs   = ${temacs_loadup} dump
 run_temacs    = ${temacs_loadup} run-temacs
@@ -709,6 +712,33 @@ unlock:
 relock:
        chmod -w $(SOURCES)
 
+## Header files for ellcc
+#ifdef HAVE_SHLIB
+MAKEPATH=../lib-src/make-path
+install: ${PROGNAME}
+       ${MAKEPATH} ${archlibdir}/include ${archlibdir}/include/m ${archlibdir}/include/s
+       -@echo "Copying include files for ellcc..."
+       -@hdir=`pwd`; \
+       cd ${srcdir}; hdrdir2=`pwd`; cd $$hdir; \
+       test "$$hdrdir2" != "$$hdir" && hdir="$$hdir $$hdrdir2"; \
+       (for thisdir in $$hdir; do \
+               cd $$hdir && \
+               (hdrtars=; \
+               for hdrfile in *.h; do \
+                       hdrtars="$$hdrtars $$hdrfile"; \
+               done; \
+               test -d s && hdrtars="$$hdrtars s/*"; \
+               test -d m && hdrtars="$$hdrtars m/*"; \
+               test -n "$$hdrtars" && (tar cf - $$hdrtars) | \
+                       (cd ${archlibdir}/include && umask 022 && tar xf -); \
+               chmod 755 ${archlibdir}/include; \
+               test -d ${archlibdir}/include/s && \
+                 chmod 755 ${archlibdir}/include/s; \
+               test -d ${archlibdir}/include/m && \
+                 chmod 755 ${archlibdir}/include/s;) \
+       done)
+#endif
+
 ## Dependency processing using home-grown script, not makedepend
 .PHONY: depend
 FRC.depend:
index 1f57911..126ac25 100644 (file)
@@ -277,6 +277,9 @@ extern int specpdl_size;
 #define CHECK_SPECBIND_VARIABLE DO_NOTHING
 #endif
 
+#if 0
+/* Unused.  It's too hard to guarantee that the current bindings
+   contain only variables.  */
 /* Another inline version of unbind_to().  VALUE is GC-protected.
    Caller guarantees that:
    - all of the elements on the binding stack are variable bindings.
@@ -303,6 +306,7 @@ extern int specpdl_size;
        }                                                       \
     }                                                          \
 } while (0)
+#endif /* unused */
 
 /* A faster, but less safe inline version of Fset().
    Caller guarantees that:
index b6a79b9..09e4908 100644 (file)
@@ -529,7 +529,11 @@ funcall_compiled_function (Lisp_Object fun, int nargs, Lisp_Object args[])
                                 f->stack_depth,
                                 XVECTOR_DATA (f->constants));
 
-    UNBIND_TO_GCPRO_VARIABLES_ONLY (speccount, value);
+    /* The attempt to optimize this by only unbinding variables failed
+       because using buffer-local variables as function parameters
+       leads to specpdl_ptr->func != 0 */
+    /* UNBIND_TO_GCPRO_VARIABLES_ONLY (speccount, value); */
+    UNBIND_TO_GCPRO (speccount, value);
     return value;
   }
 
index 0ffbd65..c9ded38 100644 (file)
@@ -1649,6 +1649,69 @@ Release a keyboard grab made with `x-grab-keyboard'.
   return Qnil;
 }
 
+DEFUN ("x-get-font-path", Fx_get_font_path, 0, 1, 0, /*
+Get the X Server's font path.
+
+See also `x-set-font-path'.
+*/
+       (device))
+{
+  Display *dpy = get_x_display (device);
+  int ndirs_return;
+  CONST char **directories = (CONST char **) XGetFontPath (dpy, &ndirs_return);
+  Lisp_Object font_path = Qnil;
+
+  if (!directories)
+    signal_simple_error ("Can't get X font path", device);
+
+  while (ndirs_return--)
+      font_path = Fcons (build_ext_string (directories[ndirs_return], 
+                                           FORMAT_FILENAME), font_path);
+
+  return font_path;
+}
+
+DEFUN ("x-set-font-path", Fx_set_font_path, 1, 2, 0, /*
+Set the X Server's font path to FONT-PATH.
+
+There is only one font path per server, not one per client.  Use this
+sparingly.  It uncaches all of the X server's font information.
+
+Font directories should end in the path separator and should contain
+a file called fonts.dir usually created with the program mkfontdir.
+
+Setting the FONT-PATH to nil tells the X server to use the default
+font path.
+
+See also `x-get-font-path'.
+*/
+       (font_path, device))
+{
+  Display *dpy = get_x_display (device);
+  Lisp_Object path_entry;
+  CONST char **directories;
+  int i=0,ndirs=0;
+
+  EXTERNAL_LIST_LOOP (path_entry, font_path)
+    {
+      CHECK_STRING (XCAR (path_entry));
+      ndirs++;
+    }
+
+  directories = alloca_array (CONST char *, ndirs);
+
+  EXTERNAL_LIST_LOOP (path_entry, font_path)
+    {
+      GET_C_STRING_FILENAME_DATA_ALLOCA (XCAR (path_entry), directories[i++]);
+    }
+
+  expect_x_error (dpy);
+  XSetFontPath (dpy, (char **) directories, ndirs);
+  signal_if_x_error (dpy, 1/*resumable_p*/);
+
+  return Qnil;
+}
+
 \f
 /************************************************************************/
 /*                            initialization                            */
@@ -1677,6 +1740,9 @@ syms_of_device_x (void)
   DEFSUBR (Fx_grab_keyboard);
   DEFSUBR (Fx_ungrab_keyboard);
 
+  DEFSUBR (Fx_get_font_path);
+  DEFSUBR (Fx_set_font_path);
+
   defsymbol (&Qx_error, "x-error");
   defsymbol (&Qinit_pre_x_win, "init-pre-x-win");
   defsymbol (&Qinit_post_x_win, "init-post-x-win");
index 0b7117f..325daa8 100644 (file)
@@ -27,7 +27,7 @@ Boston, MA 02111-1307, USA.  */
    It has been tested with:
    - UMich LDAP 3.3 (http://www.umich.edu/~dirsvcs/ldap/)
    - OpenLDAP 1.0.3 (http://www.openldap.org/)
-   - Netscape's LDAP SDK 1.0 (http://developer.netscape.com) */
+   - Netscape's LDAP SDK 1.0 (http://developer.netscape.com/) */
 
 
 #include <config.h>
@@ -288,7 +288,10 @@ the LDAP library XEmacs was compiled with: `simple', `krbv41' and `krbv42'.
     }
 
   /* Connect to the server and bind */
+  slow_down_interrupts ();
   ld = ldap_open ((char *)XSTRING_DATA (host), ldap_port);
+  speed_up_interrupts ();
+
   if (ld == NULL )
     signal_simple_error_2 ("Failed connecting to host",
                            host,
@@ -563,7 +566,6 @@ syms_of_eldap (void)
 void
 vars_of_eldap (void)
 {
-  Fprovide (intern ("ldap"));
 
   ldap_default_port = LDAP_PORT;
   Vldap_default_base =  Qnil;
diff --git a/src/emodules.c b/src/emodules.c
new file mode 100644 (file)
index 0000000..1a5d896
--- /dev/null
@@ -0,0 +1,579 @@
+/* emodules.c - Support routines for dynamic module loading
+(C) Copyright 1998, 1999 J. Kean Johnston. All rights reserved.
+
+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 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 XEmacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "emodules.h"
+#include "sysdll.h"
+
+#ifdef HAVE_SHLIB
+
+/* CE-Emacs version number */
+Lisp_Object Vmodule_version;
+
+/* Do we do our work quietly? */
+int load_modules_quietly;
+
+/* Load path */
+Lisp_Object Vmodule_load_path;
+
+typedef struct _emodules_list
+{
+  int used;             /* Is this slot used?                           */
+  char *soname;         /* Name of the shared object loaded (full path) */
+  char *modname;        /* The name of the module                       */
+  char *modver;         /* The version that the module is at            */
+  char *modtitle;       /* How the module announces itself              */
+  dll_handle dlhandle;  /* Dynamic lib handle                           */
+} emodules_list;
+
+static int emodules_depth;
+static dll_handle dlhandle;
+static emodules_list *modules;
+static int modnum;
+
+static int find_make_module (CONST char *mod, CONST char *name, CONST char *ver, int make_or_find);
+static Lisp_Object module_load_unwind (Lisp_Object);
+static void attempt_module_delete (int mod);
+
+DEFUN ("load-module", Fload_module, 1, 3, "FLoad dynamic module: ", /*
+Load in a C Emacs Extension module named FILE.
+The optional NAME and VERSION are used to identify specific modules.
+
+This function is similar in intent to `load' except that it loads in
+pre-compiled C or C++ code, using dynamic shared objects.  If NAME is
+specified, then the module is only loaded if its internal name matches
+the NAME specified.  If VERSION is specified, then the module is only
+loaded if it matches that VERSION.  This function will check to make
+sure that the same module is not loaded twice.  Modules are searched
+for in the same way as Lisp files, except that the valid file
+extensions are `.so', `.dll' or `.ell'.
+
+All symbols in the shared module must be completely resolved in order
+for this function to be successful.  Any modules which the specified
+FILE depends on will be automatically loaded.  You can determine which
+modules have been loaded as dynamic shared objects by examining the
+return value of the function `list-modules'.
+
+It is possible, although unwise, to unload modules using `unload-module'.
+The prefered mechanism for unloading or reloading modules is to quit
+XEmacs, and then reload those new or changed modules that are required.
+
+Messages informing you of the progress of the load are displayed unless
+the variable `load-modules-quietly' is non-NIL.
+*/
+       (file,name,version))
+{
+  char *mod, *mname, *mver;
+  int speccount = specpdl_depth();
+
+  CHECK_STRING(file);
+
+  mod = (char *)XSTRING_DATA (file);
+
+  if (NILP (name))
+    mname = "";
+  else
+    mname = (char *)XSTRING_DATA (name);
+
+  if (NILP (version))
+    mver = "";
+  else
+    mver = (char *)XSTRING_DATA (version);
+
+  dlhandle = 0;
+  record_unwind_protect (module_load_unwind, make_int(modnum));
+  emodules_load (mod, mname, mver);
+  unbind_to (speccount, Qnil);
+
+  return Qt;
+}
+
+#ifdef DANGEROUS_NASTY_SCARY_MONSTER
+
+DEFUN ("unload-module", Fmodule_unload, 1, 3, 0, /*
+Unload a module previously loaded with load-module.
+
+As with load-module, this function requires at least the module FILE, and
+optionally the module NAME and VERSION to unload.  It may not be possible
+for the module to be unloaded from memory, as there may be Lisp objects
+refering to variables inside the module code.  However, once you have
+requested a module to be unloaded, it will be unloaded from memory as
+soon as the last reference to symbols within the module is destroyed.
+*/
+       (file,name,version))
+{
+  int x;
+  char *mod, *mname, *mver;
+
+  CHECK_STRING(file);
+
+  mod = (char *)XSTRING_DATA (file);
+
+  if (NILP (name))
+    mname = "";
+  else
+    mname = (char *)XSTRING_DATA (name);
+
+  if (NILP (version))
+    mver = "";
+  else
+    mver = (char *)XSTRING_DATA (version);
+
+  x = find_make_module (mod, mname, mver, 1);
+  if (x != -1)
+    attempt_module_delete (x);
+  return Qt;
+}
+#endif /* DANGEROUS_NASTY_SCARY_MONSTER */
+
+DEFUN ("list-modules", Flist_modules, 0, 0, "", /*
+Produce a list of loaded dynamic modules.
+
+This function will return a list of all the loaded dynamic modules.
+Each element in the list is a list in the form (SONAME NAME VER DESC),
+where SONAME is the name of the shared object that was loaded, NAME
+is the internal module name, VER is the version of the module, and DESC
+is how the module describes itself.
+
+This function returns a list, so you will need to assign the return value
+to a variable and then examine the variable with `describe-variable'.
+For example:
+
+  (setq mylist (list-modules))
+  (describe-variable 'mylist)
+
+
+NOTE: It is possible for the same module to be loaded more than once,
+at different versions.  However, you should never see the same module,
+with the same name and version, loaded more than once.  If you do, this
+is a bug, and you are encouraged to report it.
+*/
+       ())
+{
+  Lisp_Object mlist = Qnil;
+  int i;
+
+  for (i = 0; i < modnum; i++)
+    {
+      if (modules[i].used == 1)
+        mlist = Fcons (list4 (build_string (modules[i].soname),
+                              build_string (modules[i].modname),
+                              build_string (modules[i].modver),
+                              build_string (modules[i].modtitle)), mlist);
+    }
+
+  return mlist;
+}
+
+static int
+find_make_module (CONST char *mod, CONST char *name, CONST char *ver, int mof)
+{
+  int i, fs = -1;
+
+  for (i = 0; i < modnum; i++)
+    {
+      if (fs == -1 && modules[i].used == 0)
+        fs = i;
+      if (strcmp (modules[i].soname, mod) == 0)
+        {
+          if (name && name[0] && strcmp (modules[i].modname, name))
+            continue;
+          if (ver && ver[0] && strcmp (modules[i].modver, ver))
+            continue;
+          return i; /* Found a match */
+        }
+    }
+
+  if (mof)
+    return fs;
+
+  if (fs != -1)
+    return fs; /* First free slot */
+
+  /*
+   * We only get here if we havent found a free slot and the module was
+   * not previously loaded.
+   */
+  if (modules == (emodules_list *)0)
+    modules = (emodules_list *)xmalloc (sizeof(emodules_list));
+  modnum++;
+  modules = xrealloc (modules, modnum * sizeof(emodules_list));
+
+  fs = modnum - 1;
+  memset (&modules[fs], 0, sizeof(emodules_list));
+  return fs;
+}
+
+static void
+attempt_module_delete (int mod)
+{
+  if (dll_close (modules[mod].dlhandle) == 0)
+    {
+      xfree (modules[mod].soname);
+      xfree (modules[mod].modname);
+      xfree (modules[mod].modver);
+      xfree (modules[mod].modtitle);
+      modules[mod].dlhandle = 0;
+      modules[mod].used = 0;
+    }
+  else if (modules[mod].used > 1)
+    modules[mod].used = 1; /* We couldn't delete it - it stays */
+}
+
+static Lisp_Object
+module_load_unwind (Lisp_Object upto)
+{
+  int x,l=0;
+
+  /*
+   * First close off the current handle if it is open.
+   */
+  if (dlhandle != 0)
+    dll_close (dlhandle);
+  dlhandle = 0;
+
+  if (CONSP (upto))
+    {
+      if (INTP (XCAR (upto)))
+        l = XINT (XCAR (upto));
+      free_cons (XCONS (upto));
+    }
+  else
+    l = XINT (upto);
+
+  /*
+   * Here we need to go through and dlclose() (IN REVERSE ORDER!) any
+   * modules that were loaded as part of this load chain. We only mark
+   * the slots as closed if the dlclose() succeeds.
+   */
+  for (x = modnum-1; x >= l; x--)
+    {
+      if (modules[x].used > 1)
+        attempt_module_delete (x);
+    }
+  emodules_depth = 0;
+
+  return Qnil;
+}
+
+/*
+ * Do the actual grunt-work of loading in a module. We first try and
+ * dlopen() the module. If that fails, we have an error and we bail
+ * out immediately. If the dlopen() succeeds, we need to check for the
+ * existance of certain special symbols.
+ *
+ * All modules will have complete access to the variables and functions
+ * defined within XEmacs itself.  It is up to the module to declare any
+ * variables or functions it uses, however.  Modules will also have access
+ * to other functions and variables in other loaded modules, unless they
+ * are defined as STATIC.
+ *
+ * We need to be very careful with how we load modules. If we encounter an
+ * error along the way, we need to back out completely to the point at
+ * which the user started. Since we can be called resursively, we need to
+ * take care with marking modules as loaded. When we first start loading
+ * modules, we set the counter to zero. As we enter the function each time,
+ * we incremement the counter, and before we leave we decrement it. When
+ * we get back down to 0, we know we are at the end of the chain and we
+ * can mark all the modules in the list as loaded.
+ *
+ * When we signal an error, we need to be sure to unwind all modules loaded
+ * thus far (but only for this module chain). It is assumed that if any
+ * modules in a chain fail, then they all do. This is logical, considering
+ * that the only time we recurse is when we have dependant modules. So in
+ * the error handler we take great care to close off the module chain before
+ * we call "error" and let the Fmodule_load unwind_protect() function handle
+ * the cleaning up.
+ */
+void
+emodules_load(CONST char *module, CONST char *modname, CONST char *modver)
+{
+  Lisp_Object filename;
+  Lisp_Object foundname;
+  int fd, x, mpx;
+  char *soname, *tmod;
+  CONST char **f;
+  CONST long *ellcc_rev;
+  char *mver, *mname, *mtitle, *symname;
+  void (*modload)(void) = 0;
+  void (*modsyms)(void) = 0;
+  void (*modvars)(void) = 0;
+  void (*moddocs)(void) = 0;
+  emodules_list *mp;
+  struct gcpro gcpro1,gcpro2;
+
+  filename = Qnil;
+  foundname = Qnil;
+
+  emodules_depth++;
+  dlhandle = 0;
+
+  if ((module == (CONST char *)0) || (module[0] == '\0'))
+    error ("Empty module name");
+
+  /* This is to get around the fact that build_string() is not declared
+     as taking a const char * as an argument. I HATE compiler warnings. */
+  tmod = (char *)alloca (strlen (module) + 1);
+  strcpy (tmod, module);
+
+  GCPRO2(filename, foundname);
+  filename = build_string (tmod);
+  fd = locate_file(Vmodule_load_path, filename, ":.ell:.so:.dll", &foundname, -1);
+  UNGCPRO;
+
+  if (fd < 0)
+    signal_simple_error ("Cannot open dynamic module", filename);
+
+  soname = (char *)alloca (XSTRING_LENGTH (foundname) + 1);
+  strcpy (soname, (char *)XSTRING_DATA (foundname));
+
+  dlhandle = dll_open (soname);
+  if (dlhandle == (dll_handle)0)
+    error ("Opening dynamic module: %s", dll_error (dlhandle));
+
+  ellcc_rev = (CONST long *)dll_variable (dlhandle, "emodule_compiler");
+  if ((ellcc_rev == (CONST long *)0) || (*ellcc_rev <= 0))
+    error ("Missing symbol `emodule_compiler': Invalid dynamic module");
+  if (*ellcc_rev > EMODULES_REVISION)
+    error ("Unsupported version `%ld(%ld)': Invalid dynamic module",
+           *ellcc_rev, EMODULES_REVISION);
+
+  f = (CONST char **)dll_variable (dlhandle, "emodule_name");
+  if ((f == (CONST char **)0) || (*f == (CONST char *)0))
+    error ("Missing symbol `emodule_name': Invalid dynamic module");
+
+  mname = (char *)alloca (strlen (*f) + 1);
+  strcpy (mname, *f);
+  if (mname[0] == '\0')
+    error ("Empty value for `emodule_name': Invalid dynamic module");
+
+  f = (CONST char **)dll_variable (dlhandle, "emodule_version");
+  if ((f == (CONST char **)0) || (*f == (CONST char *)0))
+    error ("Missing symbol `emodule_version': Invalid dynamic module");
+
+  mver = (char *)alloca (strlen (*f) + 1);
+  strcpy (mver, *f);
+
+  f = (CONST char **)dll_variable (dlhandle, "emodule_title");
+  if ((f == (CONST char **)0) || (*f == (CONST char *)0))
+    error ("Missing symbol `emodule_title': Invalid dynamic module");
+
+  mtitle = (char *)alloca (strlen (*f) + 1);
+  strcpy (mtitle, *f);
+
+  symname = (char *)alloca (strlen (mname) + 15);
+
+  strcpy (symname, "modules_of_");
+  strcat (symname, mname);
+  modload = (void (*)(void))dll_function (dlhandle, symname);
+  /*
+   * modload is optional. If the module doesnt require other modules it can
+   * be left out.
+   */
+
+  strcpy (symname, "syms_of_");
+  strcat (symname, mname);
+  modsyms = (void (*)(void))dll_function (dlhandle, symname);
+  if (modsyms == (void (*)(void))0)
+    error ("Missing symbol `%s': Invalid dynamic module", symname);
+
+  strcpy (symname, "vars_of_");
+  strcat (symname, mname);
+  modvars = (void (*)(void))dll_function (dlhandle, symname);
+  if (modvars == (void (*)(void))0)
+    error ("Missing symbol `%s': Invalid dynamic module", symname);
+
+  strcpy (symname, "docs_of_");
+  strcat (symname, mname);
+  moddocs = (void (*)(void))dll_function (dlhandle, symname);
+  if (moddocs == (void (*)(void))0)
+    error ("Missing symbol `%s': Invalid dynamic module", symname);
+
+  if (modname && modname[0] && strcmp (modname, mname))
+    error ("Module name mismatch");
+
+  if (modver && modver[0] && strcmp (modver, mver))
+    error ("Module version mismatch");
+
+  /*
+   * Attempt to make a new slot for this module. If this really is the
+   * first time we are loading this module, the used member will be 0.
+   * If that is non-zero, we know that we have a previously loaded module
+   * of the same name and version, and we dont need to go any further.
+   */
+  mpx = find_make_module (soname, mname, mver, 0);
+  mp = &modules[mpx];
+  if (mp->used > 0)
+    {
+      emodules_depth--;
+      dll_close (dlhandle);
+      return;
+    }
+
+  if (!load_modules_quietly)
+    message ("Loading %s v%s (%s)", mname, mver, mtitle);
+
+  /*
+   * We have passed the basic initialization, and can now add this
+   * module to the list of modules.
+   */
+  mp->used = emodules_depth + 1;
+  mp->soname = xstrdup (soname);
+  mp->modname = xstrdup (mname);
+  mp->modver = xstrdup (mver);
+  mp->modtitle = xstrdup (mtitle);
+  mp->dlhandle = dlhandle;
+  dlhandle = 0;
+
+  /*
+   * Now we need to call the module init function and perform the various
+   * startup tasks.
+   */
+  if (modload != 0)
+    (*modload)();
+
+  /*
+   * Now we can get the module to initialize its symbols, and then its
+   * variables, and lastly the documentation strings.
+   */
+  (*modsyms)();
+  (*modvars)();
+  (*moddocs)();
+
+  if (!load_modules_quietly)
+    message ("Loaded module %s v%s (%s)", mname, mver, mtitle);
+
+
+  emodules_depth--;
+  if (emodules_depth == 0)
+    {
+      /*
+       * We have reached the end of the load chain. We now go through the
+       * list of loaded modules and mark all the valid modules as just
+       * that.
+       */
+      for (x = 0; x < modnum; x++)
+        if (modules[x].used > 1)
+          modules[x].used = 1;
+    }
+}
+
+void
+emodules_doc_subr(CONST char *symname, CONST char *doc)
+{
+  Bytecount len = strlen (symname);
+  Lisp_Object sym = oblookup (Vobarray, (CONST Bufbyte *)symname, len);
+  struct Lisp_Subr *subr;
+
+  if (SYMBOLP(sym))
+    {
+      subr = XSUBR( XSYMBOL(sym)->function);
+      subr->doc = xstrdup (doc);
+    }
+  /*
+   * FIXME: I wish there was some way to avoid the xstrdup(). Is it
+   * possible to just set a pointer to the string, or somehow create a
+   * symbol whose value we can point to the constant string? Can someone
+   * look into this?
+   */
+}
+
+void
+emodules_doc_sym (CONST char *symname, CONST char *doc)
+{
+  Bytecount len = strlen (symname);
+  Lisp_Object sym = oblookup (Vobarray, (CONST Bufbyte *)symname, len);
+  Lisp_Object docstr;
+  struct gcpro gcpro1;
+
+  if (SYMBOLP(sym))
+    {
+      docstr = build_string (doc);
+      GCPRO1(docstr);
+      Fput (sym, Qvariable_documentation, docstr);
+      UNGCPRO;
+    }
+}
+
+\f
+void
+syms_of_module (void)
+{
+  DEFSUBR(Fload_module);
+  DEFSUBR(Flist_modules);
+#ifdef DANGEROUS_NASTY_SCARY_MONSTER
+  DEFSUBR(Funload_module);
+#endif
+}
+
+void
+vars_of_module (void)
+{
+  DEFVAR_LISP ("module-version", &Vmodule_version /*
+Emacs dynamic loading mechanism version, as a string.
+
+This string is in the form XX.YY.ppp, where XX is the major version
+number, YY is the minor version number, and ppp is the patch level.
+This variable can be used to distinquish between different versions of
+the dynamic loading technology used in Emacs, if required.  It is not
+a given that this value will be the same as the Emacs version number.
+*/ );
+  Vmodule_version = Fpurecopy (build_string (EMODULES_VERSION));
+
+  DEFVAR_BOOL ("load-modules-quietly", &load_modules_quietly /*
+*Set to t if module loading is to be silent.
+
+Normally, when loading dynamic modules, Emacs will inform you of its
+progress, and will display the module name and version if the module
+is loaded correctly.  Setting this variable to `t' will suppress these
+messages.  This would normally only be done if `load-module' was being
+called by a Lisp function.
+*/);
+
+  DEFVAR_LISP ("module-load-path", &Vmodule_load_path /*
+*List of directories to search for dynamic modules to load.
+Each element is a string (directory name) or nil (try default directory).
+
+Note that elements of this list *may not* begin with "~", so you must
+call `expland-file-name' on them before adding them to this list.
+
+Initialized based on EMACSMODULEPATH environment variable, if any, otherwise
+to default specified the file `paths.h' when XEmacs was built.  If there
+were no paths specified in `paths.h', then XEmacs chooses a default
+value for this variable by looking around in the file-system near the
+directory in which the XEmacs executable resides.
+
+Due to the nature of dynamic modules, the path names should almost always
+refer to architecture-dependant directories.  It is unwise to attempt to
+store dynamic modules in a hetrogenous environment.  Some environments
+are similar enough to each other that XEmacs will be unable to determine
+the correctness of a dynamic module, which can have unpredictable results
+when a dynamic module is loaded.
+*/);
+
+  load_modules_quietly = 0;
+  emodules_depth = 0;
+  modules = (emodules_list *)0;
+  modnum = 0;
+  Vmodule_load_path = Qnil;
+  Fprovide (intern ("modules"));
+}
+
+#endif /* HAVE_SHLIB */
+
diff --git a/src/emodules.h b/src/emodules.h
new file mode 100644 (file)
index 0000000..9cfd639
--- /dev/null
@@ -0,0 +1,86 @@
+/* emodules.h - Declarations and definitions for XEmacs loadable modules.
+(C) Copyright 1998, 1999 J. Kean Johnston. All rights reserved.
+
+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 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 XEmacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#ifndef EMODULES_HDR
+
+#ifndef EMODULES_GATHER_VERSION
+#define EMODULES_HDR
+#endif
+
+#define EMODULES_VERSION    "1.0.0"
+#define EMODULES_MAJOR      1
+#define EMODULES_MINOR      0
+#define EMODULES_PATCH      0
+#define EMODULES_REVISION   (long)((EMODULES_MAJOR * 1000) + \
+                             (EMODULES_MINOR * 10) + \
+                             (EMODULES_PATCH))
+
+#ifndef EMODULES_GATHER_VERSION
+#include <config.h>
+#include "lisp.h"
+#include "sysdep.h"
+#include "window.h"
+#include "buffer.h"
+#include "insdel.h"
+#include "frame.h"
+#include "lstream.h"
+#ifdef FILE_CODING
+#include "file-coding.h"
+#endif
+
+/* Module loading technology version number */
+extern Lisp_Object Vmodule_version;
+
+/* Load path */
+extern Lisp_Object Vmodule_load_path;
+
+/* XEmacs version Information */
+extern Lisp_Object Vemacs_major_version;
+extern Lisp_Object Vemacs_minor_version;
+
+/*
+ * Load in a C module. The first argument is the name of the .so file, the
+ * second is the name of the module, and the third is the module version.
+ * If the module name is NULL, we will always reload the .so. If it is not
+ * NULL, we check to make sure we haven't loaded it before. If the version
+ * is specified, we check to make sure we didnt load the module of the
+ * specified version before. We also use these as checks when we open the
+ * module to make sure we have the right module.
+ */
+extern void emodules_load (CONST char *module, CONST char *name, CONST char *version);
+
+/*
+ * Because subrs and symbols added by a dynamic module are not part of
+ * the make-docfile process, we need a clean way to get the variables
+ * and functions documented. Since people dont like the idea of making
+ * shared modules use different versions of DEFSUBR() and DEFVAR_LISP()
+ * and friends, we need these two functions to insert the documentation
+ * into the right place. These functions will be called by the module
+ * init code, generated by ellcc during initialization mode.
+ */
+extern void emodules_doc_subr (CONST char *objname, CONST char *docstr);
+extern void emodules_doc_sym (CONST char *objname, CONST char *docstr);
+
+#define CDOCSUBR(Fname, DOC) emodules_doc_subr (Fname, DOC)
+#define CDOCSYM(Sname, DOC)  emodules_doc_sym  (Sname, DOC)
+#endif /* EMODULES_GATHER_VERSION */
+
+#endif /* EMODULES_HDR */
+
index c2b0030..cd67be2 100644 (file)
@@ -1672,7 +1672,14 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
          int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd)));
          BYTE keymap_orig[256];
          POINT pnt = { LOWORD (GetMessagePos()), HIWORD (GetMessagePos()) };
-         MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), pnt };
+         MSG msg;
+         
+         msg.hwnd = hwnd;
+         msg.message = message;
+         msg.wParam = wParam;
+         msg.lParam = lParam;
+         msg.time = GetMessageTime();
+         msg.pt = pnt;
 
          /* GetKeyboardState() does not work as documented on Win95. We have
           * to loosely track Left and Right modifiers on behalf of the OS,
@@ -2157,7 +2164,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;
-       default:                /* do nothing */
        }
       /* menubars always must come last since the hashtables do not
          always exist*/
index 2b955fe..1829140 100644 (file)
@@ -5047,7 +5047,7 @@ Errors running the hook are caught and ignored.
 *Variable to control XEmacs behavior with respect to focus changing.
 If this variable is set to t, then XEmacs will not gratuitously change
 the keyboard focus.  XEmacs cannot in general detect when this mode is
-use by the window manager, so it is up to the user to set it.
+used by the window manager, so it is up to the user to set it.
 */ );
   focus_follows_mouse = 0;
 
index e7c19a0..5a88a67 100644 (file)
@@ -181,7 +181,9 @@ mswindows_init_frame_1 (struct frame *f, Lisp_Object props)
   hwnd = CreateWindowEx (exstyle,
                         XEMACS_CLASS,
                         STRINGP(f->name) ? XSTRING_DATA(f->name) :
-                        (STRINGP(name) ? XSTRING_DATA(name) : XEMACS_CLASS),
+                        (STRINGP(name) ? 
+                         (CONST Extbyte*)XSTRING_DATA(name) : 
+                         (CONST Extbyte*)XEMACS_CLASS),
                         style,
                         rect_default.left, rect_default.top,
                         rect_default.width, rect_default.height,
index f95c1e8..70b948a 100644 (file)
@@ -47,6 +47,9 @@ Boston, MA 02111-1307, USA.  */
 #endif
 #include <stdio.h>
 #include <ctype.h>
+#ifdef HAVE_XFACE
+#include <setjmp.h>
+#endif
 
 #define WIDGET_GLYPH_SLOT 0
 
@@ -54,6 +57,9 @@ Boston, MA 02111-1307, USA.  */
 DEFINE_DEVICE_IIFORMAT (mswindows, xpm);
 #endif
 DEFINE_DEVICE_IIFORMAT (mswindows, xbm);
+#ifdef HAVE_XFACE
+DEFINE_DEVICE_IIFORMAT (mswindows, xface);
+#endif
 DEFINE_DEVICE_IIFORMAT (mswindows, button);
 DEFINE_DEVICE_IIFORMAT (mswindows, edit);
 #if 0
@@ -64,6 +70,7 @@ DEFINE_DEVICE_IIFORMAT (mswindows, widget);
 DEFINE_DEVICE_IIFORMAT (mswindows, label);
 DEFINE_DEVICE_IIFORMAT (mswindows, scrollbar);
 DEFINE_DEVICE_IIFORMAT (mswindows, combo);
+DEFINE_DEVICE_IIFORMAT (mswindows, progress);
 
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp);
 Lisp_Object Qbmp;
@@ -1176,8 +1183,7 @@ mswindows_resource_instantiate (Lisp_Object image_instance, Lisp_Object instanti
 #ifdef __CYGWIN32__
       CYGWIN_WIN32_PATH (f, fname);
 #else
-      /* #### FIXME someone who knows ... */
-      fname = f
+      fname = f;
 #endif
       
       if (NILP (resource_id))
@@ -1562,7 +1568,7 @@ xbm_create_bitmap_from_data (HDC hdc, char *data,
                             int mask, COLORREF fg, COLORREF bg)
 {
   int old_width = (width + 7)/8;
-  int new_width = 2*((width + 15)/16);
+  int new_width = BPLINE (2*((width + 15)/16));
   unsigned char *offset;
   void *bmp_buf = 0;
   unsigned char *new_data, *new_offset;
@@ -1574,7 +1580,7 @@ xbm_create_bitmap_from_data (HDC hdc, char *data,
   if (!bmp_info)
     return NULL;
   
-  new_data = (unsigned char *) xmalloc (height * new_width);
+  new_data = (unsigned char *) xmalloc_and_zero (height * new_width);
       
   if (!new_data)
     {
@@ -1587,8 +1593,6 @@ xbm_create_bitmap_from_data (HDC hdc, char *data,
       offset = data + i*old_width;
       new_offset = new_data + i*new_width;
 
-      new_offset[new_width - 1] = 0; /* there may be an extra byte
-                                        that needs to be padded */
       for (j=0; j<old_width; j++)
        {
          int byte = offset[j];
@@ -1608,7 +1612,7 @@ xbm_create_bitmap_from_data (HDC hdc, char *data,
     }
 
   bmp_info->bmiHeader.biWidth=width;
-  bmp_info->bmiHeader.biHeight=-height;
+  bmp_info->bmiHeader.biHeight=-(LONG)height;
   bmp_info->bmiHeader.biPlanes=1;
   bmp_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
   bmp_info->bmiHeader.biBitCount=1; 
@@ -1833,6 +1837,93 @@ mswindows_xbm_instantiate (Lisp_Object image_instance,
                     XINT (XCAR (XCDR (data))), gcc_go_home);
 }
 
+#ifdef HAVE_XFACE
+/**********************************************************************
+ *                             X-Face                                 *
+ **********************************************************************/
+#if defined(EXTERN)
+/* This is about to get redefined! */
+#undef EXTERN
+#endif
+/* We have to define SYSV32 so that compface.h includes string.h
+   instead of strings.h. */
+#define SYSV32
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <compface.h>
+#ifdef __cplusplus
+}
+#endif
+/* JMP_BUF cannot be used here because if it doesn't get defined
+   to jmp_buf we end up with a conflicting type error with the
+   definition in compface.h */
+extern jmp_buf comp_env;
+#undef SYSV32
+
+static void
+mswindows_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+                            Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+                            int dest_mask, Lisp_Object domain)
+{
+  Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
+  int i, stattis;
+  char *p, *bits, *bp;
+  CONST char * volatile emsg = 0;
+  CONST char * volatile dstring;
+
+  assert (!NILP (data));
+
+  GET_C_STRING_BINARY_DATA_ALLOCA (data, dstring);
+
+  if ((p = strchr (dstring, ':')))
+    {
+      dstring = p + 1;
+    }
+
+  /* Must use setjmp not SETJMP because we used jmp_buf above not JMP_BUF */
+  if (!(stattis = setjmp (comp_env)))
+    {
+      UnCompAll ((char *) dstring);
+      UnGenFace ();
+    }
+
+  switch (stattis)
+    {
+    case -2:
+      emsg = "uncompface: internal error";
+      break;
+    case -1:
+      emsg = "uncompface: insufficient or invalid data";
+      break;
+    case 1:
+      emsg = "uncompface: excess data ignored";
+      break;
+    }
+
+  if (emsg)
+    signal_simple_error_2 (emsg, data, Qimage);
+
+  bp = bits = (char *) alloca (PIXELS / 8);
+
+  /* the compface library exports char F[], which uses a single byte per
+     pixel to represent a 48x48 bitmap.  Yuck. */
+  for (i = 0, p = F; i < (PIXELS / 8); ++i)
+    {
+      int n, b;
+      /* reverse the bit order of each byte... */
+      for (b = n = 0; b < 8; ++b)
+       {
+         n |= ((*p++) << b);
+       }
+      *bp++ = (char) n;
+    }
+
+  xbm_instantiate_1 (image_instance, instantiator, pointer_fg,
+                    pointer_bg, dest_mask, 48, 48, bits);
+}
+#endif /* HAVE_XFACE */
+
 \f
 /************************************************************************/
 /*                      image instance methods                          */
@@ -2159,10 +2250,21 @@ mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
   int flags = BS_NOTIFY;
   Lisp_Object style;
   struct gui_item* pgui = &IMAGE_INSTANCE_WIDGET_ITEM (ii);
-  
+  Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
+
   if (!gui_item_active_p (pgui))
     flags |= WS_DISABLED;
 
+  if (!NILP (glyph))
+    {
+      if (!IMAGE_INSTANCEP (glyph))
+       glyph = glyph_image_instance (glyph, domain, ERROR_ME, 1);
+
+      if (IMAGE_INSTANCEP (glyph))
+       flags |= XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ? 
+         BS_BITMAP : BS_ICON;
+    }
+
   style = pgui->style;
 
   if (EQ (style, Qradio))
@@ -2186,6 +2288,16 @@ mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiat
     SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); 
   else
     SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+  /* add the image if one was given */
+  if (!NILP (glyph) && IMAGE_INSTANCEP (glyph))
+    {
+      SendMessage (wnd, BM_SETIMAGE, 
+                  (WPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ? 
+                            IMAGE_BITMAP : IMAGE_ICON),
+                  (LPARAM) (XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) ?
+                            XIMAGE_INSTANCE_MSWINDOWS_BITMAP (glyph) :
+                            XIMAGE_INSTANCE_MSWINDOWS_ICON (glyph)));
+    }
 }
 
 /* instantiate an edit control */
@@ -2201,6 +2313,38 @@ mswindows_edit_instantiate (Lisp_Object image_instance, Lisp_Object instantiator
                                WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
 }
 
+/* instantiate an edit control */
+static void
+mswindows_progress_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+                               Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+                               int dest_mask, Lisp_Object domain)
+{
+  HWND wnd;
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+                               pointer_bg, dest_mask, domain, PROGRESS_CLASS, 
+                               WS_TABSTOP | WS_BORDER | PBS_SMOOTH,
+                               WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
+  wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+  /* set the colors */
+#ifdef PBS_SETBKCOLOR
+  SendMessage (wnd, PBS_SETBKCOLOR, 0, 
+              (LPARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR 
+                        (XCOLOR_INSTANCE 
+                         (FACE_BACKGROUND 
+                          (XIMAGE_INSTANCE_WIDGET_FACE (ii),
+                           XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
+#endif
+#ifdef PBS_SETBARCOLOR
+  SendMessage (wnd, PBS_SETBARCOLOR, 0, 
+              (L:PARAM) (COLOR_INSTANCE_MSWINDOWS_COLOR 
+                         (XCOLOR_INSTANCE 
+                          (FACE_FOREGROUND 
+                           (XIMAGE_INSTANCE_WIDGET_FACE (ii),
+                            XIMAGE_INSTANCE_SUBWINDOW_FRAME (ii))))));
+#endif
+}
+
 /* instantiate a static control possible for putting other things in */
 static void
 mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
@@ -2283,7 +2427,7 @@ mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
   struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
   /* get the text from a control */
-  if (EQ (prop, Qtext))
+  if (EQ (prop, Q_text))
     {
       Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
       Extbyte* buf =alloca (len+1);
@@ -2301,7 +2445,7 @@ mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
   struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
   /* check the state of a button */
-  if (EQ (prop, Qselected))
+  if (EQ (prop, Q_selected))
     {
       if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
        return Qt;
@@ -2318,7 +2462,7 @@ mswindows_combo_property (Lisp_Object image_instance, Lisp_Object prop)
   struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
   HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
   /* get the text from a control */
-  if (EQ (prop, Qtext))
+  if (EQ (prop, Q_text))
     {
       long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
       Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
@@ -2336,7 +2480,7 @@ mswindows_widget_set_property (Lisp_Object image_instance, Lisp_Object prop,
 {
   struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
 
-  if (EQ (prop, Qtext))
+  if (EQ (prop, Q_text))
     {
       Extbyte* lparam=0;
       CHECK_STRING (val);
@@ -2348,6 +2492,23 @@ mswindows_widget_set_property (Lisp_Object image_instance, Lisp_Object prop,
   return Qunbound;
 }
 
+/* set the properties of a progres guage */
+static Lisp_Object
+mswindows_progress_set_property (Lisp_Object image_instance, Lisp_Object prop,
+                                Lisp_Object val)
+{
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+  if (EQ (prop, Q_percent))
+    {
+      CHECK_INT (val);
+      SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+                  PBM_SETPOS, (WPARAM)XINT (val), 0);
+      return Qt;
+    }
+  return Qunbound;
+}
+
 \f
 /************************************************************************/
 /*                            initialization                            */
@@ -2386,7 +2547,10 @@ image_instantiator_format_create_glyphs_mswindows (void)
 #endif
   INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm);
   IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate);
-
+#ifdef HAVE_XFACE
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, xface);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, xface, instantiate);
+#endif
   INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
   IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
   IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
@@ -2414,6 +2578,10 @@ image_instantiator_format_create_glyphs_mswindows (void)
   INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
   IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
 
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, progress);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, progress, set_property);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, progress, instantiate);
+
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
 
   IIFORMAT_HAS_METHOD (bmp, validate);
@@ -2454,6 +2622,7 @@ This is used by the `make-image-instance' function.
   Fprovide (Qcombo);
   Fprovide (Qscrollbar);
   Fprovide (Qlabel);
+  Fprovide (Qprogress);
 }
 
 void
index 4bb451f..3e2162b 100644 (file)
@@ -20,6 +20,8 @@ Boston, MA 02111-1307, USA.  */
 
 /* Synched up with: Not in FSF. */
 
+/* written by Andy Piper <andy@xemacs.org> */
+
 #include <config.h>
 #include "lisp.h"
 #include "lstream.h"
@@ -28,7 +30,7 @@ Boston, MA 02111-1307, USA.  */
 #include "faces.h"
 #include "glyphs.h"
 #include "objects.h"
-
+#include "bytecode.h"
 #include "window.h"
 #include "buffer.h"
 #include "frame.h"
@@ -49,8 +51,11 @@ Lisp_Object Qgroup;
 #endif
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (label);
 Lisp_Object Qlabel;
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (progress);
+Lisp_Object Qprogress;
 
 Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items;
+Lisp_Object Q_image, Q_text, Q_percent;
 
 #define WIDGET_BORDER_HEIGHT 2
 #define WIDGET_BORDER_WIDTH 4
@@ -58,7 +63,6 @@ Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items;
 /* TODO:
    - more complex controls.
    - tooltips for controls.
-   - images in controls.
  */
 
 /* In windows normal windows work in pixels, dialog boxes work in
@@ -99,16 +103,47 @@ widget_possible_dest_types (void)
   return IMAGE_WIDGET_MASK;
 }
 
-#if 0 /* currently unused */
 static void
-check_valid_glyph (Lisp_Object data)
+check_valid_glyph_or_image (Lisp_Object data)
 {
+  Lisp_Object glyph = data;
   if (SYMBOLP (data))
-    CHECK_BUFFER_GLYPH (XSYMBOL (data)->value);
-  else
-    CHECK_BUFFER_GLYPH (data);
+    glyph = XSYMBOL (data)->value;
+
+  if (IMAGE_INSTANCEP (glyph))
+    CHECK_IMAGE_INSTANCE (glyph);
+  else if (!CONSP (glyph))
+    CHECK_BUFFER_GLYPH (glyph);
+}
+
+static void
+check_valid_anything (Lisp_Object data)
+{
+}
+
+static void
+check_valid_callback (Lisp_Object data)
+{
+    if (!SYMBOLP (data)
+       && !COMPILED_FUNCTIONP (data)
+       && !CONSP (data))
+    {
+       signal_simple_error (":callback must be a function or expression", data);
+    }
+}
+
+static void
+check_valid_symbol (Lisp_Object data)
+{
+    CHECK_SYMBOL (data);
+}
+
+static void
+check_valid_string_or_vector (Lisp_Object data)
+{
+    if (!STRINGP (data) && !VECTORP (data))
+       signal_simple_error (":descriptor must be a string or a vector", data);
 }
-#endif /* currently unused */
 
 static void
 check_valid_item_list (Lisp_Object data)
@@ -204,7 +239,8 @@ widget_validate (Lisp_Object instantiator)
   if (NILP (desc))
     signal_simple_error ("Must supply :descriptor", instantiator);
 
-  gui_parse_item_keywords (desc, &gui);
+  if (VECTORP (desc))
+      gui_parse_item_keywords (desc, &gui);
 
   if (!NILP (find_keyword_in_vector (instantiator, Q_width))
             && !NILP (find_keyword_in_vector (instantiator, Q_pixel_width)))
@@ -223,6 +259,40 @@ combo_validate (Lisp_Object instantiator)
     signal_simple_error ("Must supply item list", instantiator);
 }
 
+/* we need to convert things like glyphs to images, eval expressions
+   etc.*/
+static Lisp_Object
+widget_normalize (Lisp_Object inst, Lisp_Object console_type)
+{
+  /* This function can call lisp */
+  Lisp_Object glyph = find_keyword_in_vector (inst, Q_image);
+
+  /* we need to eval glyph if its an expression, we do this for the
+     same reasons we normalize file to data. */
+  if (!NILP (glyph))
+    {
+      int i;
+      struct gcpro gcpro1;
+      if (SYMBOLP (glyph))
+       glyph = XSYMBOL (glyph)->value;
+      GCPRO1 (glyph);
+
+      if (CONSP (glyph))
+       glyph = Feval (glyph);
+      /* substitute the new glyph */
+      for (i = 0; i < XVECTOR_LENGTH (inst); i++)
+       {
+         if (EQ (Q_image, XVECTOR_DATA (inst)[i]))
+           {
+             XVECTOR_DATA (inst)[i+1] = glyph;
+             break;
+           }
+       }
+      UNGCPRO;
+    }
+  return inst;
+}
+
 static void
 initialize_widget_image_instance (struct Lisp_Image_Instance *ii, Lisp_Object type)
 {
@@ -253,6 +323,7 @@ widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
   Lisp_Object pixwidth = find_keyword_in_vector (instantiator, Q_pixel_width);
   Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height);
   Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
+  Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
   int pw=0, ph=0, tw=0, th=0;
   
   /* this just does pixel type sizing */
@@ -272,12 +343,17 @@ widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
   IMAGE_INSTANCE_WIDGET_PROPS (ii) = 
     find_keyword_in_vector (instantiator, Q_properties);
 
-  /* retrieve the gui item information */
+  /* retrieve the gui item information. This is easy if we have been
+     provided with a vector, more difficult if we have just been given
+     keywords */
   if (STRINGP (desc) || NILP (desc))
-    IMAGE_INSTANCE_WIDGET_TEXT (ii) = desc;
+    {
+      /* big cheat - we rely on the fact that a gui item looks like an instantiator */
+      gui_parse_item_keywords_no_errors (instantiator, pgui);
+      IMAGE_INSTANCE_WIDGET_TEXT (ii) = desc;
+    }
   else
-    gui_parse_item_keywords (find_keyword_in_vector (instantiator, Q_descriptor),
-                            pgui);
+    gui_parse_item_keywords_no_errors (desc, pgui);
 
   /* normalize size information */
   if (!NILP (width))
@@ -289,6 +365,18 @@ widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
   if (!NILP (pixheight))
     ph = XINT (pixheight);
 
+  /* for a widget with an image pick up the dimensions from that */
+  if (!NILP (glyph))
+    {
+      if (!pw && !tw)
+       pw = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain) 
+         + 2 * WIDGET_BORDER_WIDTH;
+      if (!ph && !th)
+       ph = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain) 
+         + 2 * WIDGET_BORDER_HEIGHT;
+    }
+
+  /* if we still don' t have sizes, guess from text size */
   if (!tw && !pw && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
     tw = XSTRING_LENGTH (IMAGE_INSTANCE_WIDGET_TEXT (ii));
   if (!th && !ph)
@@ -300,7 +388,7 @@ widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
       else
        ph = default_pixheight;
     }
-
+  
   if (tw !=0 || th !=0)
     widget_text_to_pixel_conversion (domain,
                                     IMAGE_INSTANCE_WIDGET_FACE (ii),
@@ -355,11 +443,36 @@ syms_of_glyphs_widget (void)
   defkeyword (&Q_width, ":width");
   defkeyword (&Q_properties, ":properties");
   defkeyword (&Q_items, ":items");
+  defkeyword (&Q_image, ":image");
+  defkeyword (&Q_percent, ":percent");
+  defkeyword (&Q_text, "text");
 }
 
 void
 image_instantiator_format_create_glyphs_widget (void)
 {
+#define VALID_GUI_KEYWORDS(type) \
+  IIFORMAT_VALID_KEYWORD (type, Q_active, check_valid_anything); \
+  IIFORMAT_VALID_KEYWORD (type, Q_suffix, check_valid_anything); \
+  IIFORMAT_VALID_KEYWORD (type, Q_keys, check_valid_string);           \
+  IIFORMAT_VALID_KEYWORD (type, Q_style, check_valid_symbol);          \
+  IIFORMAT_VALID_KEYWORD (type, Q_selected, check_valid_anything);     \
+  IIFORMAT_VALID_KEYWORD (type, Q_filter, check_valid_anything);               \
+  IIFORMAT_VALID_KEYWORD (type, Q_config, check_valid_symbol);         \
+  IIFORMAT_VALID_KEYWORD (type, Q_included, check_valid_anything);     \
+  IIFORMAT_VALID_KEYWORD (type, Q_key_sequence, check_valid_string);   \
+  IIFORMAT_VALID_KEYWORD (type, Q_accelerator, check_valid_string);    \
+  IIFORMAT_VALID_KEYWORD (type, Q_label, check_valid_anything);                \
+  IIFORMAT_VALID_KEYWORD (type, Q_callback, check_valid_callback);             \
+  IIFORMAT_VALID_KEYWORD (type, Q_descriptor, check_valid_string_or_vector)
+
+#define VALID_WIDGET_KEYWORDS(type) \
+  IIFORMAT_VALID_KEYWORD (type, Q_width, check_valid_int);             \
+  IIFORMAT_VALID_KEYWORD (type, Q_height, check_valid_int);            \
+  IIFORMAT_VALID_KEYWORD (type, Q_pixel_width, check_valid_int);       \
+  IIFORMAT_VALID_KEYWORD (type, Q_pixel_height, check_valid_int);      \
+  IIFORMAT_VALID_KEYWORD (type, Q_face, check_valid_face)
+
   /* we only do this for properties */
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM (widget, "widget");
   IIFORMAT_HAS_METHOD (widget, property);
@@ -370,58 +483,58 @@ image_instantiator_format_create_glyphs_widget (void)
   IIFORMAT_HAS_SHARED_METHOD (button, validate, widget);
   IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget);
   IIFORMAT_HAS_SHARED_METHOD (button, instantiate, widget);
+  IIFORMAT_HAS_SHARED_METHOD (button, normalize, widget);
+  IIFORMAT_VALID_KEYWORD (button, Q_image, check_valid_glyph_or_image);
+  VALID_WIDGET_KEYWORDS (button);
+  VALID_GUI_KEYWORDS (button);
 
-  IIFORMAT_VALID_KEYWORD (button, Q_width, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (button, Q_height, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (button, Q_pixel_width, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (button, Q_pixel_height, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (button, Q_face, check_valid_face);
-  IIFORMAT_VALID_KEYWORD (button, Q_descriptor, check_valid_vector);
   /* edit fields */
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (edit, "edit");
   IIFORMAT_HAS_SHARED_METHOD (edit, validate, widget);
   IIFORMAT_HAS_SHARED_METHOD (edit, possible_dest_types, widget);
   IIFORMAT_HAS_SHARED_METHOD (edit, instantiate, widget);
+  VALID_WIDGET_KEYWORDS (edit);
+  VALID_GUI_KEYWORDS (edit);
 
-  IIFORMAT_VALID_KEYWORD (edit, Q_width, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (edit, Q_height, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (edit, Q_pixel_width, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (edit, Q_pixel_height, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (edit, Q_face, check_valid_face);
-  IIFORMAT_VALID_KEYWORD (edit, Q_descriptor, check_valid_vector);
   /* combo box */
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (combo, "combo");
   IIFORMAT_HAS_METHOD (combo, validate);
   IIFORMAT_HAS_SHARED_METHOD (combo, possible_dest_types, widget);
   IIFORMAT_HAS_METHOD (combo, instantiate);
+  VALID_GUI_KEYWORDS (combo);
 
   IIFORMAT_VALID_KEYWORD (combo, Q_width, check_valid_int);
   IIFORMAT_VALID_KEYWORD (combo, Q_height, check_valid_int);
   IIFORMAT_VALID_KEYWORD (combo, Q_pixel_width, check_valid_int);
   IIFORMAT_VALID_KEYWORD (combo, Q_face, check_valid_face);
-  IIFORMAT_VALID_KEYWORD (combo, Q_descriptor, check_valid_vector);
   IIFORMAT_VALID_KEYWORD (combo, Q_properties, check_valid_item_list);
+
   /* scrollbar */
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (scrollbar, "scrollbar");
   IIFORMAT_HAS_SHARED_METHOD (scrollbar, validate, widget);
   IIFORMAT_HAS_SHARED_METHOD (scrollbar, possible_dest_types, widget);
   IIFORMAT_HAS_SHARED_METHOD (scrollbar, instantiate, widget);
+  VALID_GUI_KEYWORDS (scrollbar);
 
   IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_width, check_valid_int);
   IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_height, check_valid_int);
   IIFORMAT_VALID_KEYWORD (scrollbar, Q_face, check_valid_face);
-  IIFORMAT_VALID_KEYWORD (scrollbar, Q_descriptor, check_valid_vector);
+
+  /* progress guage */
+  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (progress, "progress");
+  IIFORMAT_HAS_SHARED_METHOD (progress, validate, widget);
+  IIFORMAT_HAS_SHARED_METHOD (progress, possible_dest_types, widget);
+  IIFORMAT_HAS_SHARED_METHOD (progress, instantiate, widget);
+  VALID_WIDGET_KEYWORDS (progress);
+  VALID_GUI_KEYWORDS (progress);
+
   /* labels */
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (label, "label");
   IIFORMAT_HAS_SHARED_METHOD (label, possible_dest_types, widget);
   IIFORMAT_HAS_SHARED_METHOD (label, instantiate, static);
-
-  IIFORMAT_VALID_KEYWORD (label, Q_pixel_width, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (label, Q_pixel_height, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (label, Q_width, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (label, Q_height, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (label, Q_face, check_valid_face);
+  VALID_WIDGET_KEYWORDS (label);
   IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string);
+
 #if 0
   /* group */
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (group, "group");
index c6015e4..aed51bf 100644 (file)
@@ -87,8 +87,7 @@ DEFINE_DEVICE_IIFORMAT (x, xpm);
 DEFINE_DEVICE_IIFORMAT (x, xbm);
 DEFINE_DEVICE_IIFORMAT (x, subwindow);
 #ifdef HAVE_XFACE
-DEFINE_IMAGE_INSTANTIATOR_FORMAT (xface);
-Lisp_Object Qxface;
+DEFINE_DEVICE_IIFORMAT (x, xface);
 #endif
 
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor_font);
@@ -1487,73 +1486,6 @@ x_xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
 /**********************************************************************
  *                             X-Face                                 *
  **********************************************************************/
-
-static void
-xface_validate (Lisp_Object instantiator)
-{
-  file_or_data_must_be_present (instantiator);
-}
-
-static Lisp_Object
-xface_normalize (Lisp_Object inst, Lisp_Object console_type)
-{
-  /* This function can call lisp */
-  Lisp_Object file = Qnil, mask_file = Qnil;
-  struct gcpro gcpro1, gcpro2, gcpro3;
-  Lisp_Object alist = Qnil;
-
-  GCPRO3 (file, mask_file, alist);
-
-  /* Now, convert any file data into inline data for both the regular
-     data and the mask data.  At the end of this, `data' will contain
-     the inline data (if any) or Qnil, and `file' will contain
-     the name this data was derived from (if known) or Qnil.
-     Likewise for `mask_file' and `mask_data'.
-
-     Note that if we cannot generate any regular inline data, we
-     skip out. */
-
-  file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
-                                            console_type);
-  mask_file = potential_pixmap_file_instantiator (inst, Q_mask_file,
-                                                 Q_mask_data, console_type);
-
-  if (CONSP (file)) /* failure locating filename */
-    signal_double_file_error ("Opening bitmap file",
-                             "no such file or directory",
-                             Fcar (file));
-
-  if (NILP (file) && NILP (mask_file)) /* no conversion necessary */
-    RETURN_UNGCPRO (inst);
-
-  alist = tagged_vector_to_alist (inst);
-
-  {
-    Lisp_Object data = make_string_from_file (file);
-    alist = remassq_no_quit (Q_file, alist);
-    /* there can't be a :data at this point. */
-    alist = Fcons (Fcons (Q_file, file),
-                  Fcons (Fcons (Q_data, data), alist));
-  }
-
-  alist = xbm_mask_file_munging (alist, file, mask_file, console_type);
-
-  {
-    Lisp_Object result = alist_to_tagged_vector (Qxface, alist);
-    free_alist (alist);
-    RETURN_UNGCPRO (result);
-  }
-}
-
-static int
-xface_possible_dest_types (void)
-{
-  return
-    IMAGE_MONO_PIXMAP_MASK  |
-    IMAGE_COLOR_PIXMAP_MASK |
-    IMAGE_POINTER_MASK;
-}
-
 #if defined(EXTERN)
 /* This is about to get redefined! */
 #undef EXTERN
@@ -1575,9 +1507,9 @@ extern jmp_buf comp_env;
 #undef SYSV32
 
 static void
-xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
-                  Lisp_Object pointer_fg, Lisp_Object pointer_bg,
-                  int dest_mask, Lisp_Object domain)
+x_xface_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+                    Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+                    int dest_mask, Lisp_Object domain)
 {
   Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
   int i, stattis;
@@ -2200,19 +2132,8 @@ image_instantiator_format_create_glyphs_x (void)
   IIFORMAT_VALID_KEYWORD (font, Q_background, check_valid_string);
 
 #ifdef HAVE_XFACE
-  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xface, "xface");
-
-  IIFORMAT_HAS_METHOD (xface, validate);
-  IIFORMAT_HAS_METHOD (xface, normalize);
-  IIFORMAT_HAS_METHOD (xface, possible_dest_types);
-  IIFORMAT_HAS_METHOD (xface, instantiate);
-
-  IIFORMAT_VALID_KEYWORD (xface, Q_data, check_valid_string);
-  IIFORMAT_VALID_KEYWORD (xface, Q_file, check_valid_string);
-  IIFORMAT_VALID_KEYWORD (xface, Q_hotspot_x, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (xface, Q_hotspot_y, check_valid_int);
-  IIFORMAT_VALID_KEYWORD (xface, Q_foreground, check_valid_string);
-  IIFORMAT_VALID_KEYWORD (xface, Q_background, check_valid_string);
+  INITIALIZE_DEVICE_IIFORMAT (x, xface);
+  IIFORMAT_HAS_DEVMETHOD (x, xface, instantiate);
 #endif
 
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (autodetect,
@@ -2229,10 +2150,6 @@ image_instantiator_format_create_glyphs_x (void)
 void
 vars_of_glyphs_x (void)
 {
-#ifdef HAVE_XFACE
-  Fprovide (Qxface);
-#endif
-
   DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path /*
 A list of the directories in which X bitmap files may be found.
 If nil, this is initialized from the "*bitmapFilePath" resource.
index 97d825e..8535ab4 100644 (file)
@@ -620,13 +620,13 @@ DECLARE_LRECORD (glyph, struct Lisp_Glyph);
 #define XGLYPH_BASELINE(g) GLYPH_BASELINE (XGLYPH (g))
 #define XGLYPH_FACE(g) GLYPH_FACE (XGLYPH (g))
 
-extern Lisp_Object Qxpm;
+extern Lisp_Object Qxpm, Qxface;
 extern Lisp_Object Q_data, Q_file, Q_color_symbols, Qconst_glyph_variable;
-extern Lisp_Object Qxbm, Qedit, Qgroup, Qlabel, Qcombo, Qscrollbar;
+extern Lisp_Object Qxbm, Qedit, Qgroup, Qlabel, Qcombo, Qscrollbar, Qprogress;
 extern Lisp_Object Q_mask_file, Q_mask_data, Q_hotspot_x, Q_hotspot_y;
 extern Lisp_Object Q_foreground, Q_background, Q_face, Q_descriptor, Q_group;
-extern Lisp_Object Q_width, Q_height, Q_pixel_width, Q_pixel_height;
-extern Lisp_Object Q_items, Q_properties, Qimage_conversion_error;
+extern Lisp_Object Q_width, Q_height, Q_pixel_width, Q_pixel_height, Q_text;
+extern Lisp_Object Q_items, Q_properties, Q_image, Q_percent, Qimage_conversion_error;
 extern Lisp_Object Vcontinuation_glyph, Vcontrol_arrow_glyph, Vhscroll_glyph;
 extern Lisp_Object Vinvisible_text_glyph, Voctal_escape_glyph, Vtruncation_glyph;
 extern Lisp_Object Vxemacs_logo;
index bcd5e1b..8c3bf42 100644 (file)
--- a/src/gui.c
+++ b/src/gui.c
@@ -31,7 +31,7 @@ Boston, MA 02111-1307, USA.  */
 
 Lisp_Object Q_active, Q_suffix, Q_keys, Q_style, Q_selected;
 Lisp_Object Q_filter, Q_config, Q_included, Q_key_sequence;
-Lisp_Object Q_accelerator, Q_label;
+Lisp_Object Q_accelerator, Q_label, Q_callback;
 Lisp_Object Qtoggle, Qradio;
 
 #ifdef HAVE_POPUPS
@@ -123,7 +123,8 @@ gui_item_init (struct gui_item *pgui_item)
  */
 void
 gui_item_add_keyval_pair (struct gui_item *pgui_item,
-                         Lisp_Object key, Lisp_Object val)
+                         Lisp_Object key, Lisp_Object val, 
+                         Error_behavior errb)
 {
   if (!KEYWORDP (key))
     signal_simple_error_2 ("Non-keyword in gui item", key, pgui_item->name);
@@ -136,9 +137,10 @@ gui_item_add_keyval_pair (struct gui_item *pgui_item,
   else if (EQ (key, Q_style))   pgui_item->style    = val;
   else if (EQ (key, Q_selected)) pgui_item->selected = val;
   else if (EQ (key, Q_keys))    pgui_item->keys     = val;
+  else if (EQ (key, Q_callback))        pgui_item->callback     = val;
   else if (EQ (key, Q_key_sequence)) ;   /* ignored for FSF compatability */
   else if (EQ (key, Q_label)) ;   /* ignored for 21.0 implement in 21.2  */
-  else
+  else if (ERRB_EQ (errb, ERROR_ME))
     signal_simple_error_2 ("Unknown keyword in gui item", key, pgui_item->name);
 }
 
@@ -147,8 +149,9 @@ gui_item_add_keyval_pair (struct gui_item *pgui_item,
  * function extracts the description of the item into the PGUI_ITEM
  * structure.
  */
-void
-gui_parse_item_keywords (Lisp_Object item, struct gui_item *pgui_item)
+static void
+gui_parse_item_keywords_internal (Lisp_Object item, struct gui_item *pgui_item,
+                                 Error_behavior errb)
 {
   int length, plist_p, start;
   Lisp_Object *contents;
@@ -201,11 +204,23 @@ gui_parse_item_keywords (Lisp_Object item, struct gui_item *pgui_item)
        {
          Lisp_Object key = contents [i++];
          Lisp_Object val = contents [i++];
-         gui_item_add_keyval_pair (pgui_item, key, val);
+         gui_item_add_keyval_pair (pgui_item, key, val, errb);
        }
     }
 }
 
+void
+gui_parse_item_keywords (Lisp_Object item, struct gui_item *pgui_item)
+{
+  gui_parse_item_keywords_internal (item, pgui_item, ERROR_ME);
+}
+
+void
+gui_parse_item_keywords_no_errors (Lisp_Object item, struct gui_item *pgui_item)
+{
+  gui_parse_item_keywords_internal (item, pgui_item, ERROR_ME_NOT);
+}
+
 /*
  * Decide whether a GUI item is active by evaluating its :active form
  * if any
@@ -403,6 +418,7 @@ syms_of_gui (void)
   defkeyword (&Q_included, ":included");
   defkeyword (&Q_accelerator, ":accelerator");
   defkeyword (&Q_label, ":label");
+  defkeyword (&Q_callback, ":callback");
 
   defsymbol (&Qtoggle, "toggle");
   defsymbol (&Qradio, "radio");
index d65f1f8..010b41f 100644 (file)
--- a/src/gui.h
+++ b/src/gui.h
@@ -68,12 +68,14 @@ struct gui_item
 
 extern Lisp_Object Q_accelerator, Q_active, Q_config, Q_filter, Q_included;
 extern Lisp_Object Q_keys, Q_selected, Q_suffix, Qradio, Qtoggle;
-extern Lisp_Object Q_key_sequence, Q_label;
+extern Lisp_Object Q_key_sequence, Q_label, Q_callback;
 
 void gui_item_init (struct gui_item *pgui_item);
 void gui_item_add_keyval_pair (struct gui_item *pgui_item,
-                              Lisp_Object key, Lisp_Object val);
+                              Lisp_Object key, Lisp_Object val,
+                              Error_behavior errb);
 void gui_parse_item_keywords (Lisp_Object item, struct gui_item *pgui_item);
+void gui_parse_item_keywords_no_errors (Lisp_Object item, struct gui_item *pgui_item);
 int  gui_item_active_p (CONST struct gui_item *pgui_item);
 int  gui_item_selected_p (CONST struct gui_item *pgui_item);
 int  gui_item_included_p (CONST struct gui_item *pgui_item, Lisp_Object into);
index 819dd0f..bd03ead 100644 (file)
@@ -130,7 +130,7 @@ menu_parse_submenu_keywords (Lisp_Object desc, struct gui_item* pgui_item)
       desc = XCDR (desc);
       if (!NILP (desc))
        CHECK_CONS (desc);
-      gui_item_add_keyval_pair (pgui_item, key, val);
+      gui_item_add_keyval_pair (pgui_item, key, val, ERROR_ME);
     }
 
   /* Return the rest - supposed to be a list of items */
index d1524e5..579fb58 100644 (file)
 
    PATH_LOADSEARCH     The default value of `load-path'.
 
+   PATH_MODULESEARCH   The default value of `module-load-path'.
+
    PATH_PACKAGEPATH     The default value of `package-path'.
 
    PATH_SITE            The default location of site-specific Lisp files.
 
+   PATH_SITE_MODULES   The default location of site-specific modules.
+
    PATH_EXEC           The default value of `exec-directory' and `exec-path'.
                        (exec-path also contains the value of whatever is in
                        the PATH environment variable.)
 #define  PATH_LOADSEARCH "@LISPDIR@"
 #endif
 
+#ifdef MODULEDIR_USER_DEFINED
+#define  PATH_MODULESEARCH "@MODULEDIR@"
+#endif
+
+#ifdef SITELISPDIR_USER_DEFINED
+#define  PATH_SITE "@SITELISPDIR@"
+#endif
+
+#ifdef SITEMODULEDIR_USER_DEFINED
+#define  PATH_SITE_MODULES "@SITEMODULEDIR@"
+#endif
+
 #ifdef PACKAGE_PATH_USER_DEFINED
 #define PATH_PACKAGEPATH "@PACKAGE_PATH@"
 #endif
index 3155383..b3a423b 100644 (file)
@@ -28,44 +28,16 @@ Boston, MA 02111-1307, USA.  */
  * horribly. What does get defined is HAVE_MS_WINDOWS, but this is 
  * done by configure and only applies to the window system.
  *
- * The important thing about building is that it is done on a binary
- * mounted filesystem. i.e. something mounted like: mount -b c:
- * /binary. If you do not do this then compilation of el files may
- * produce garbage.  As of b24 there are fixes in xemacs to make
- * building on text mounts but I don't generally do this. Make sure
- * you have installed cygwin32 b18 + patched dll (which can be found
- * at http://www.lexa.ru/sos or on my home page
- * http://www.parallax.co.uk/~andyp. Alternatively when b19 comes out
- * the patched dll will be unnecessary. Also make sure your HOME path
- * is unix style - i.e. without a drive letter.
+ * When building make sure your HOME path is unix style - i.e. without
+ * a drive letter.
  *
- * Note that some people have reported problems with the patched
- * cygwin.dll on Sergey's home page so you may want to use the one on
- * mine which I *know* works.
- *
- * once you have done this, configure and make. If you want unexec
- * support you need to download a.out.h from my web page or use cygwin
- * b19. You probably want to build with mule support since this
- * addresses crlf issues in a sensible way.
+ * once you have done this, configure and make.
  *
  * windows '95 - I haven't tested this under '95, it will probably
  * build but I konw there are some limitations with cygwin under 95 so
  * YMMV. I build with NT4 SP3.
  *
- * What I want to do:
- *
- * the fileio stuff merely uses the unix system calls this means that
- * the mount type of your fs will determine how files are edited. This
- * is fine except in the instance that you want to convert one to the
- * other. In this instance I would like to bring the buffer_file_type
- * code into the picture without all the other windows-nt
- * cruft. Apparently the best way to do this is use the mule coding
- * stuff.
- *
- * process support needs fixing although basic support works (a la
- * make-docfile)
- *
- * Andy Piper <andyp@parallax.co.uk> 8/1/98 
+ * Andy Piper <andy@xemacs.org> 8/1/98 
  * http://www.parallax.co.uk/~andyp */
 
 /* cheesy way to determine cygwin version */
@@ -133,6 +105,8 @@ extern long random();
 #endif
 #endif
 
+#define PBS_SMOOTH              0x01
+
 #ifdef HAVE_MS_WINDOWS
 #define HAVE_NTGUI
 #define HAVE_FACES
@@ -270,7 +244,7 @@ cygwin32_posix_to_win32_path_list(src, dst)
 
 /* Pseudo-terminal support under SVR4 only loops to deal with errors. */
 
-#define PTY_ITERATION for (i = 0; i < 1; i++)
+#define PTY_ITERATION for (i = 0, c = 0; i < 1; i++)
 
 /* This sets the name of the master side of the PTY. */
 
index 2f6a7bb..ac43fef 100644 (file)
@@ -7,15 +7,16 @@
 #undef C_OPTIMIZE_SWITCH
 #undef C_DEBUG_SWITCH
 #undef C_SWITCH_SYSTEM
-#define C_SWITCH_SYSTEM "-D_NO_STATIC -D_SCO_ELF"
 
 #ifndef __GNUC__
-#define LINKER "cc -dy -Xc"
-#define C_OPTIMIZE_SWITCH "-O3 -Xc -dy"
-#define C_DEBUG_SWITCH "-g -Xc -dy"
+#define LINKER "cc -belf -dy -Xc"
+#define C_OPTIMIZE_SWITCH "-O3 -Xc"
+#define C_DEBUG_SWITCH "-g -Xc"
+#define C_SWITCH_SYSTEM "-belf -D_NO_STATIC -D_SCO_ELF"
 #else
 #define LINKER "gcc -melf -Xc"
-#define C_OPTIMIZE_SWITCH "-O99 -m486 -fomit-frame-pointer -Xc -melf"
-#define C_DEBUG_SWITCH "-g -Xc -melf"
+#define C_OPTIMIZE_SWITCH "-O99 -m486 -fomit-frame-pointer -Xc"
+#define C_DEBUG_SWITCH "-g -Xc"
+#define C_SWITCH_SYSTEM "-melf -D_NO_STATIC -D_SCO_ELF"
 #endif
 
index a404b70..f900f12 100644 (file)
@@ -125,14 +125,8 @@ could #define sco and I think everything would work. rjl */
 #ifdef _SCO_ELF
 #undef COFF /* coz we're NOT */
 #define UNEXEC "unexelf.o"
-#if defined (__GNUC_MINOR__)
-#if ((__GNUC__ == 2) && (__GNUC_MINOR__ > 7)) || ((__GNUC__ > 2))
-#define LIB_GCC "-lgcc"
-#else
-#define LIB_GCC "-lgcc-elf"
-#endif
-#else /* __GNUC_MINOR__ is undefined */
-#define LIB_GCC "-lgcc-elf"
-#endif
 #endif
 
+/* For GCC 2.7.2.3 we require the "JKJ" version of gcc.
+   Works fine with egcs and gcc 2.8.x. */
+#define LIB_GCC "`$(LD) $(LDFLAGS) -print-libgcc-file-name`"
index f339873..d6e7df9 100644 (file)
@@ -25,18 +25,18 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
 #include "sysdll.h"
 
-/* This whole file is conditional upon HAVE_DLL */
+/* This whole file is conditional upon HAVE_SHLIB */
 #ifdef HAVE_SHLIB
 
 /* Thankfully, most systems follow the ELFish dlopen() method.
 ** HAVE__DLOPEN is lame, but SCO has their dl* functions as _dl*, and
 ** unless you include dlfcn.h you don't get the macros to mask them, and
-** autoconf fails to find them.
+** autoconf fails to find them. No longer true as of 5.0.5.
 **
 ** Anybody who wants to use this on SCO needs to have their configure.in
 ** look for _dlopen() as well as dlopen()
 */
-#if defined(HAVE_DLOPEN) || defined(HAVE__DLOPEN)
+#if defined(HAVE_DLOPEN) || defined(HAVE__DLOPEN) || defined(HAVE_DLFCN_H)
 #include <dlfcn.h>
 
 #ifndef RTLD_LAZY
@@ -80,14 +80,22 @@ dll_function (dll_handle h, CONST char *n)
 dll_var
 dll_variable (dll_handle h, CONST char *n)
 {
+#ifdef DLSYM_NEEDS_UNDERSCORE
+  char *buf = alloca_array (char, strlen (n) + 2);
+  *buf = '_';
+  (void)strcpy(buf + 1, n);
+  n = buf;
+#endif
   return (dll_var)dlsym ((void *)h, n);
 }
 
 CONST char *
 dll_error (dll_handle h)
 {
-#ifdef HAVE_DLERROR
+#if defined(HAVE_DLERROR) || defined(dlerror)
   return (CONST char *)dlerror ();
+#elif defined(HAVE__DLERROR)
+  return (const char *)_dlerror();
 #else
   return "Shared library error";
 #endif
index ac4b78e..d8d613a 100644 (file)
@@ -549,7 +549,7 @@ copy_executable_and_dump_data_section (file_data *p_infile,
 static void
 dump_bss_and_heap (file_data *p_infile, file_data *p_outfile)
 {
-    unsigned char *heap_data, *bss_data;
+    unsigned char *heap_data;
     unsigned long size, index;
 
     DUMP_MSG (("Dumping heap onto end of executable...\n"));
@@ -565,16 +565,15 @@ dump_bss_and_heap (file_data *p_infile, file_data *p_outfile)
     memcpy ((PUCHAR) p_outfile->file_base + index, heap_data, size);
 
 #ifndef DUMP_SEPARATE_SECTION
-    printf ("Dumping bss onto end of executable...\n");
+    DUMP_MSG (("Dumping bss onto end of executable...\n"));
     
     index += size;
     size = bss_size;
-    bss_data = bss_start;
 
-    DUMP_MSG (("\t0x%08x BSS start in process.\n", bss_data));
+    DUMP_MSG (("\t0x%08x BSS start in process.\n", bss_start));
     DUMP_MSG (("\t0x%08x BSS offset in executable.\n", index));
     DUMP_MSG (("\t0x%08x BSS size in bytes.\n", size));
-    memcpy ((char *) p_outfile->file_base + index, bss_data, size);
+    memcpy ((char *) p_outfile->file_base + index, bss_start, size);
 #endif
 }
 
diff --git a/tests/ChangeLog b/tests/ChangeLog
new file mode 100644 (file)
index 0000000..cfda4f2
--- /dev/null
@@ -0,0 +1,15 @@
+1999-02-02  XEmacs Build Bot <builds@cvs.xemacs.org>
+
+       * XEmacs 21.2.9 is released
+
+1999-01-30  Martin Buchholz  <martin@xemacs.org>
+
+       * automated/lisp-tests.el: Add test for buffer-local function
+       parameter crash
+
+1998-12-30  Martin Buchholz  <martin@xemacs.org>
+
+       * automated/database-tests.el: Minor tweaks
+
+       * ChangeLog: new file
+
index 7a46c34..01d195a 100644 (file)
@@ -29,7 +29,7 @@
 ;;; Test database functionality
 ;;; See test-harness.el
 
-(condition-case err
+(condition-case nil
     (require 'test-harness)
   (file-error
    (when (and (boundp 'load-file-name) (stringp load-file-name))
@@ -53,7 +53,7 @@
   (let ((filename (expand-file-name "test-harness" (temp-directory))))
 
     (dolist (fn (list filename (concat filename ".db")))
-      (condition-case nil (delete-file fn) (file-error nil)))
+      (ignore-file-errors (delete-file fn)))
 
     (dolist (db-type `(dbm berkeley-db))
       (when (featurep db-type)
index 840afc1..3a45ce1 100644 (file)
 (Assert (equal (bit-vector 0 1 0) #*010))
 (Assert (equal (make-bit-vector 3 1) #*111))
 (Assert (equal (make-bit-vector 3 0) #*000))
+
+;;-----------------------------------------------------
+;; Test buffer-local variables used as (ugh!) function parameters
+;;-----------------------------------------------------
+(make-local-variable 'test-emacs-buffer-local-variable)
+(byte-compile
+ (defun test-emacs-buffer-local-parameter (test-emacs-buffer-local-variable)
+   (setq test-emacs-buffer-local-variable nil)))
+(test-emacs-buffer-local-parameter nil)
index 8a61ceb..d0aaf9a 100644 (file)
@@ -1,6 +1,6 @@
 (set-extent-begin-glyph 
  (make-extent (point) (point))
- (make-glyph [xpm :file "../etc/xemacs-icon.xpm"]))
+ (setq icon (make-glyph [xpm :file "../etc/xemacs-icon.xpm"])))
 
 (defun foo ()
   (interactive) 
 ;; normal pushbutton
 (set-extent-begin-glyph 
  (make-extent (point) (point))
- (setq pbutton (make-glyph [button :width 10 :height 2 
-                                  :face modeline-mousable
-                                  :descriptor ["ok" foo :selected t]])))
+ (setq pbutton (make-glyph 
+               [button :width 10 :height 2 
+                       :face modeline-mousable
+                       :descriptor "ok" :callback foo 
+                       :selected t])))
+;; progress gauge
+(set-extent-begin-glyph 
+ (make-extent (point) (point))
+ (setq pgauge (make-glyph 
+              [progress :width 10 :height 2 
+                        :descriptor "ok"])))
+;; progress the progress ...
+(let ((x 0))
+  (while (<= x 100)
+    (set-image-instance-property (glyph-image-instance pgauge) :percent x)
+    (setq x (+ x 5))
+    (sit-for 0.1)))
+
+;; progress gauge in the modeline
+(setq global-mode-string 
+      (cons (make-extent nil nil)
+           (setq pg (make-glyph 
+                     [progress :width 5 :pixel-height 16
+                               :descriptor "ok"]))))
+;; progress the progress ...
+(let ((x 0))
+  (while (<= x 100)
+    (set-image-instance-property (glyph-image-instance pg) :percent x)
+    (setq x (+ x 5))
+    (sit-for 0.1)))
+
+(set-extent-begin-glyph 
+ (make-extent (point) (point))
+ (make-glyph 
+  [button :face modeline-mousable
+         :descriptor "ok" :callback foo
+         :image (make-glyph 
+                 [xpm :file "../etc/xemacs-icon.xpm"])]))
+
 ;; normal pushbutton
 (set-extent-begin-glyph 
  (make-extent (point) (point))
index 04b14a6..00a59b0 100644 (file)
@@ -1,8 +1,8 @@
 #!/bin/sh
 emacs_major_version=21
 emacs_minor_version=2
-emacs_beta_version=8
-xemacs_codename="Artemis"
+emacs_beta_version=9
+xemacs_codename="Athena"
 infodock_major_version=4
 infodock_minor_version=0
 infodock_build_version=1